Initial revision
This commit is contained in:
14
src/Makefile.am
Executable file
14
src/Makefile.am
Executable file
@@ -0,0 +1,14 @@
|
||||
# $calcurse: Makefile.am,v 1.1 2006/07/31 21:00:02 culot Exp $
|
||||
|
||||
AUTOMAKE_OPTIONS= gnu
|
||||
bin_PROGRAMS= calcurse
|
||||
calcurse_SOURCES= calcurse.c apoint.c event.c todo.c utils.c\
|
||||
calendar.c vars.c io.c help.c custom.c args.c\
|
||||
day.c recur.c\
|
||||
apoint.h event.h todo.h utils.h calendar.h\
|
||||
vars.h io.h help.h custom.h args.h i18n.h\
|
||||
day.h recur.h
|
||||
LIBS= -lncurses -lm
|
||||
LDADD= @LTLIBINTL@
|
||||
man_MANS= calcurse.1
|
||||
EXTRA_DIST= calcurse.1
|
||||
235
src/apoint.c
Executable file
235
src/apoint.c
Executable file
@@ -0,0 +1,235 @@
|
||||
/* $calcurse: apoint.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "vars.h"
|
||||
#include "event.h"
|
||||
#include "apoint.h"
|
||||
#include "day.h"
|
||||
#include "custom.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct apoint_s *apointlist;
|
||||
|
||||
struct apoint_s *apoint_new(char *mesg, long start, long dur)
|
||||
{
|
||||
struct apoint_s *o, **i;
|
||||
o = (struct apoint_s *) malloc(sizeof(struct apoint_s));
|
||||
o->mesg = (char *) malloc(strlen(mesg) + 1);
|
||||
strcpy(o->mesg, mesg);
|
||||
o->start = start;
|
||||
o->dur = dur;
|
||||
i = &apointlist;
|
||||
for (;;) {
|
||||
if (*i == 0 || (*i)->start > start) {
|
||||
o->next = *i;
|
||||
*i = o;
|
||||
break;
|
||||
}
|
||||
i = &(*i)->next;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
unsigned apoint_inday(struct apoint_s *i, long start)
|
||||
{
|
||||
if (i->start <= start + 3600 * 24 && i->start + i->dur > start) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void apoint_sec2str(struct apoint_s *o, int type, long day, char *start, char *end)
|
||||
{
|
||||
struct tm *lt;
|
||||
time_t t;
|
||||
|
||||
if (o->start < day && type == APPT) {
|
||||
strcpy(start, "..:..");
|
||||
} else {
|
||||
t = o->start;
|
||||
lt = localtime(&t);
|
||||
snprintf(start, HRMIN_SIZE, "%02u:%02u", lt->tm_hour,
|
||||
lt->tm_min);
|
||||
}
|
||||
if (o->start + o->dur > day + 24 * 3600 && type == APPT) {
|
||||
strcpy(end, "..:..");
|
||||
} else {
|
||||
t = o->start + o->dur;
|
||||
lt = localtime(&t);
|
||||
snprintf(end, HRMIN_SIZE, "%02u:%02u", lt->tm_hour,
|
||||
lt->tm_min);
|
||||
}
|
||||
}
|
||||
|
||||
void apoint_write(struct apoint_s *o, FILE * f)
|
||||
{
|
||||
struct tm *lt;
|
||||
time_t t;
|
||||
|
||||
t = o->start;
|
||||
lt = localtime(&t);
|
||||
fprintf(f, "%02u/%02u/%04u @ %02u:%02u",
|
||||
lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year,
|
||||
lt->tm_hour, lt->tm_min);
|
||||
|
||||
t = o->start + o->dur;
|
||||
lt = localtime(&t);
|
||||
fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u |%s\n",
|
||||
lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year,
|
||||
lt->tm_hour, lt->tm_min, o->mesg);
|
||||
}
|
||||
|
||||
struct apoint_s *apoint_scan(FILE * f, struct tm start, struct tm end)
|
||||
{
|
||||
struct tm *lt;
|
||||
char buf[MESG_MAXSIZE], *nl;
|
||||
time_t tstart, tend, t;
|
||||
|
||||
t = time(NULL);
|
||||
lt = localtime(&t);
|
||||
|
||||
/* Read the appointment description */
|
||||
fgets(buf, MESG_MAXSIZE, f);
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl) {
|
||||
*nl = '\0';
|
||||
}
|
||||
|
||||
start.tm_sec = end.tm_sec = 0;
|
||||
start.tm_isdst = end.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
end.tm_year -= 1900;
|
||||
end.tm_mon--;
|
||||
|
||||
tstart = mktime(&start);
|
||||
tend = mktime(&end);
|
||||
if (tstart == -1 || tend == -1 || tstart > tend) {
|
||||
fputs(_("FATAL ERROR in apoint_scan: date error in the appointment\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return apoint_new(buf, tstart, tend - tstart);
|
||||
}
|
||||
|
||||
void apoint_delete_bynum(long start, unsigned num)
|
||||
{
|
||||
unsigned n;
|
||||
struct apoint_s *i, **iptr;
|
||||
|
||||
n = 0;
|
||||
iptr = &apointlist;
|
||||
for (i = apointlist; i != 0; i = i->next) {
|
||||
if (apoint_inday(i, start)) {
|
||||
if (n == num) {
|
||||
*iptr = i->next;
|
||||
free(i->mesg);
|
||||
free(i);
|
||||
return;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
iptr = &i->next;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
fputs(_("FATAL ERROR in apoint_delete_bynum: no such appointment\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print an item date in the appointment panel.
|
||||
*/
|
||||
void display_item_date(WINDOW *win, int incolor, struct apoint_s *i,
|
||||
int type, long date, int y, int x)
|
||||
{
|
||||
char a_st[100], a_end[100];
|
||||
|
||||
apoint_sec2str(i, type, date, a_st, a_end);
|
||||
|
||||
if (incolor == 0)
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
mvwprintw(win, y, x, " - %s -> %s", a_st, a_end);
|
||||
if (incolor == 0)
|
||||
custom_remove_attr(awin, ATTR_HIGHEST);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the line number of an item (either an appointment or an event) in
|
||||
* the appointment panel. This is to help the appointment scroll function
|
||||
* to place beggining of the pad correctly.
|
||||
*/
|
||||
int get_item_line(int item_nb, int nb_events_inday)
|
||||
{
|
||||
int separator = 2;
|
||||
int line = 0;
|
||||
|
||||
if (item_nb <= nb_events_inday)
|
||||
line = item_nb - 1;
|
||||
else
|
||||
line = nb_events_inday + separator +
|
||||
(item_nb - (nb_events_inday + 1))*3 - 1;
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update (if necessary) the first displayed pad line to make the
|
||||
* appointment panel scroll down next time pnoutrefresh is called.
|
||||
*/
|
||||
void scroll_pad_down(int item_nb, int nb_events_inday, int win_length)
|
||||
{
|
||||
int pad_last_line = 0;
|
||||
int item_first_line = 0, item_last_line = 0;
|
||||
int borders = 6;
|
||||
int awin_length = win_length - borders;
|
||||
|
||||
item_first_line = get_item_line(item_nb, nb_events_inday);
|
||||
if (item_nb < nb_events_inday)
|
||||
item_last_line = item_first_line;
|
||||
else
|
||||
item_last_line = item_first_line + 1;
|
||||
pad_last_line = apad->first_onscreen + awin_length;
|
||||
if (item_last_line >= pad_last_line)
|
||||
apad->first_onscreen = item_last_line - awin_length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update (if necessary) the first displayed pad line to make the
|
||||
* appointment panel scroll up next time pnoutrefresh is called.
|
||||
*/
|
||||
void scroll_pad_up(int item_nb, int nb_events_inday)
|
||||
{
|
||||
int item_first_line = 0;
|
||||
|
||||
item_first_line = get_item_line(item_nb, nb_events_inday);
|
||||
if (item_first_line < apad->first_onscreen)
|
||||
apad->first_onscreen = item_first_line;
|
||||
}
|
||||
56
src/apoint.h
Executable file
56
src/apoint.h
Executable file
@@ -0,0 +1,56 @@
|
||||
/* $calcurse: apoint.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_APOINT_H
|
||||
#define CALCURSE_APOINT_H
|
||||
|
||||
#include <ncurses.h>
|
||||
|
||||
#define HRMIN_SIZE 6
|
||||
#define MESG_MAXSIZE 256
|
||||
|
||||
struct apoint_s {
|
||||
struct apoint_s *next;
|
||||
long start; /* seconds since 1 jan 1970 */
|
||||
long dur; /* duration of the appointment in seconds */
|
||||
char *mesg;
|
||||
};
|
||||
|
||||
extern struct apoint_s *apointlist;
|
||||
|
||||
struct apoint_s *apoint_new(char *, long, long);
|
||||
unsigned apoint_inday(struct apoint_s *o, long start);
|
||||
void apoint_sec2str(struct apoint_s *o, int type, long day, char *start, char *end);
|
||||
void apoint_write(struct apoint_s *o, FILE * f);
|
||||
struct apoint_s *apoint_scan(FILE * f, struct tm start, struct tm end);
|
||||
void apoint_delete_bynum(long start, unsigned num);
|
||||
void display_item_date(WINDOW *win, int color, struct apoint_s *i,
|
||||
int type, long date, int y, int x);
|
||||
int get_item_line(int item_nb, int nb_events_inday);
|
||||
void scroll_pad_down(int item_nb, int nb_events_inday, int win_length);
|
||||
void scroll_pad_up(int item_nb, int nb_events_inday);
|
||||
|
||||
#endif /* CALCURSE_APOINT_H */
|
||||
431
src/args.c
Executable file
431
src/args.c
Executable file
@@ -0,0 +1,431 @@
|
||||
/* $calcurse: args.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "utils.h"
|
||||
#include "args.h"
|
||||
#include "vars.h"
|
||||
#include "event.h"
|
||||
#include "apoint.h"
|
||||
#include "recur.h"
|
||||
#include "day.h"
|
||||
#include "todo.h"
|
||||
#include "io.h"
|
||||
|
||||
/*
|
||||
* Parse the command-line arguments and call the appropriate
|
||||
* routines to handle those arguments. Also initialize the data paths.
|
||||
*/
|
||||
int parse_args(int argc, char **argv, int colr)
|
||||
{
|
||||
int ch, add_line = 0;
|
||||
int unknown_flag = 0, app_found = 0;
|
||||
int aflag = 0, cflag = 0, dflag = 0, vflag = 0, hflag = 0, tflag = 0;
|
||||
int non_interactive = 0, multiple_flag = 0, load_data = 0;
|
||||
int no_file = 1;
|
||||
char *ddate = "", *cfile = NULL;
|
||||
|
||||
while ((ch = getopt(argc, argv, "hvtad:c:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
aflag = 1;
|
||||
multiple_flag++;
|
||||
load_data++;
|
||||
break;
|
||||
case 'd':
|
||||
dflag = 1;
|
||||
multiple_flag++;
|
||||
load_data++;
|
||||
ddate = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
cflag = 1;
|
||||
multiple_flag++;
|
||||
load_data++;
|
||||
cfile = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
hflag = 1;
|
||||
break;
|
||||
case 't':
|
||||
tflag = 1;
|
||||
multiple_flag++;
|
||||
load_data++;
|
||||
add_line = 1;
|
||||
break;
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
usage_try();
|
||||
unknown_flag = 1;
|
||||
non_interactive = 1;
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc >= 1) { /* incorrect arguments */
|
||||
usage();
|
||||
usage_try();
|
||||
return 1;
|
||||
} else {
|
||||
if (unknown_flag) {
|
||||
non_interactive = 1;
|
||||
} else if (hflag) {
|
||||
help_arg();
|
||||
non_interactive = 1;
|
||||
} else if (vflag) {
|
||||
version_arg();
|
||||
non_interactive = 1;
|
||||
} else if (multiple_flag) {
|
||||
if (load_data) {
|
||||
io_init(cfile);
|
||||
no_file = check_data_files();
|
||||
if (dflag || aflag)
|
||||
load_app(colr);
|
||||
}
|
||||
if (tflag) {
|
||||
todo_arg(colr);
|
||||
non_interactive = 1;
|
||||
}
|
||||
if (dflag) {
|
||||
date_arg(ddate, add_line);
|
||||
non_interactive = 1;
|
||||
} else if (aflag) {
|
||||
app_found = app_arg(add_line,0,0,0,0);
|
||||
non_interactive = 1;
|
||||
}
|
||||
} else {
|
||||
non_interactive = 0;
|
||||
io_init(cfile);
|
||||
no_file = check_data_files();
|
||||
}
|
||||
return non_interactive;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print Calcurse version with a short copyright text and exit.
|
||||
*/
|
||||
void version_arg()
|
||||
{
|
||||
char vtitle[50];
|
||||
char *vtext =
|
||||
_("\nCopyright (c) 2004-2006 Frederic Culot.\n"
|
||||
"This is free software; see the source for copying conditions.\n");
|
||||
|
||||
sprintf(vtitle, _("Calcurse %s - text-based organizer\n"), VERSION);
|
||||
fputs(vtitle, stdout);
|
||||
fputs(vtext, stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the command line options and exit.
|
||||
*/
|
||||
void help_arg()
|
||||
{
|
||||
char htitle[50];
|
||||
char *htext =
|
||||
_("\nMiscellaneous:\n"
|
||||
" -h print this help and exit.\n"
|
||||
" -v print calcurse version and exit.\n"
|
||||
"\nOptions:\n"
|
||||
" -c <file> specify the calendar <file> to use.\n"
|
||||
"\nNon-interactive:\n"
|
||||
" -a print events and appointments for current day and exit.\n"
|
||||
" -d <date|num> print events and appointments for <date> "
|
||||
"or <num> upcoming\n\t\tdays and exit. Possible formats are: "
|
||||
"'mm/dd/yyyy' or 'n'.\n"
|
||||
" -t print todo list and exit.\n"
|
||||
"\nFor more information, type '?' from within Calcurse, "
|
||||
"or read the manpage.\n"
|
||||
"Mail bug reports and suggestions to <calcurse@culot.org>.\n");
|
||||
|
||||
sprintf(htitle, _("Calcurse %s - text-based organizer\n"), VERSION);
|
||||
fputs(htitle, stdout);
|
||||
usage();
|
||||
fputs(htext, stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print todo list and exit.
|
||||
*/
|
||||
void todo_arg(int colr)
|
||||
{
|
||||
struct todo_s *i;
|
||||
int nb_tod;
|
||||
|
||||
nb_tod = load_todo(colr);
|
||||
fputs(_("to do:\n"),stdout);
|
||||
for (i = todolist; i != 0; i = i->next) {
|
||||
fputs(" - ",stdout);
|
||||
fputs(i->mesg,stdout);
|
||||
fputs("\n",stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print appointments for given day and exit.
|
||||
* If no year, month, and day is given, the given date is used.
|
||||
* If there is also no date given, current date is considered.
|
||||
*/
|
||||
int app_arg(int add_line, int year, int month, int day, long date)
|
||||
{
|
||||
struct recur_event_s *re;
|
||||
struct event_s *j;
|
||||
struct recur_apoint_s *ra;
|
||||
struct apoint_s *i;
|
||||
long today;
|
||||
bool print_date = true;
|
||||
int app_found = 0;
|
||||
char apoint_start_time[100];
|
||||
char apoint_end_time[100];
|
||||
|
||||
if (date == 0) {
|
||||
today = get_sec_date(year, month, day);
|
||||
} else today = date;
|
||||
|
||||
/*
|
||||
* Calculate and print the selected date if there is an event for
|
||||
* that date and it is the first one, and then print all the events for
|
||||
* that date.
|
||||
*/
|
||||
for (re = recur_elist; re != 0; re = re->next) {
|
||||
if (recur_item_inday(re->day, re->rpt->type, re->rpt->freq,
|
||||
re->rpt->until, today)) {
|
||||
app_found = 1;
|
||||
if (add_line) {
|
||||
fputs("\n", stdout);
|
||||
add_line = 0;
|
||||
}
|
||||
if (print_date) {
|
||||
arg_print_date(today);
|
||||
print_date = false;
|
||||
}
|
||||
fputs(" o ", stdout);
|
||||
fputs(re->mesg, stdout); fputs("\n", stdout);
|
||||
}
|
||||
}
|
||||
|
||||
for (j = eventlist; j != 0; j = j->next) {
|
||||
if (event_inday(j, today)) {
|
||||
app_found = 1;
|
||||
if (add_line) {
|
||||
fputs("\n",stdout);
|
||||
add_line = 0;
|
||||
}
|
||||
if (print_date) {
|
||||
arg_print_date(today);
|
||||
print_date = false;
|
||||
}
|
||||
fputs(" o ",stdout);
|
||||
fputs(j->mesg,stdout); fputs("\n",stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* Same process is performed but this time on the appointments. */
|
||||
for (ra = recur_alist; ra != 0; ra = ra->next) {
|
||||
if (recur_item_inday(ra->start, ra->rpt->type, ra->rpt->freq,
|
||||
ra->rpt->until, today)) {
|
||||
app_found = 1;
|
||||
if (add_line) {
|
||||
fputs("\n",stdout);
|
||||
add_line = 0;
|
||||
}
|
||||
if (print_date) {
|
||||
arg_print_date(today);
|
||||
print_date = false;
|
||||
}
|
||||
apoint_sec2str(recur_apoint_s2apoint_s(ra),
|
||||
RECUR_APPT, today, apoint_start_time,
|
||||
apoint_end_time);
|
||||
fputs(" - ",stdout);
|
||||
fputs(apoint_start_time,stdout);
|
||||
fputs(" -> ",stdout);
|
||||
fputs(apoint_end_time,stdout); fputs("\n\t",stdout);
|
||||
fputs(ra->mesg,stdout); fputs("\n",stdout);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = apointlist; i != 0; i = i->next) {
|
||||
if (apoint_inday(i, today)) {
|
||||
app_found = 1;
|
||||
if (add_line) {
|
||||
fputs("\n",stdout);
|
||||
add_line = 0;
|
||||
}
|
||||
if (print_date) {
|
||||
arg_print_date(today);
|
||||
print_date = false;
|
||||
}
|
||||
apoint_sec2str(i, APPT, today, apoint_start_time,
|
||||
apoint_end_time);
|
||||
fputs(" - ",stdout);
|
||||
fputs(apoint_start_time,stdout);
|
||||
fputs(" -> ",stdout);
|
||||
fputs(apoint_end_time,stdout); fputs("\n\t",stdout);
|
||||
fputs(i->mesg,stdout); fputs("\n",stdout);
|
||||
}
|
||||
}
|
||||
return app_found;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print appointment for the given date or for the given n upcoming
|
||||
* days.
|
||||
*/
|
||||
void date_arg(char *ddate, int add_line)
|
||||
{
|
||||
int i;
|
||||
int year = 0, month = 0, day = 0;
|
||||
int numdays = 0, num_digit = 0;
|
||||
int arg_len = 0, app_found = 0;
|
||||
int date_valid = 0;
|
||||
long today, ind;
|
||||
int sec_in_day = 86400;
|
||||
|
||||
/*
|
||||
* Check (with the argument length) if a date or a number of days
|
||||
* was entered, and then call app_arg() to print appointments
|
||||
*/
|
||||
arg_len = strlen(ddate);
|
||||
if (arg_len <= 4) { /* a number of days was entered */
|
||||
for (i = 0; i <= arg_len-1; i++) {
|
||||
if (isdigit(ddate[i])) num_digit++;
|
||||
}
|
||||
if (num_digit == arg_len) numdays = atoi(ddate);
|
||||
|
||||
/*
|
||||
* Get current date, and print appointments for each day
|
||||
* in the chosen interval. app_found and add_line are used
|
||||
* to format the output correctly.
|
||||
*/
|
||||
today = get_sec_date(year, month, day);
|
||||
ind = today;
|
||||
for (i = 0; i < numdays; i++) {
|
||||
app_found = app_arg(add_line, 0, 0, 0, ind);
|
||||
add_line = app_found;
|
||||
ind = ind + sec_in_day;
|
||||
}
|
||||
} else { /* a date was entered */
|
||||
date_valid = check_date(ddate);
|
||||
if (date_valid) {
|
||||
sscanf(ddate, "%d / %d / %d", &month, &day, &year);
|
||||
app_found = app_arg(add_line, year, month, day, 0);
|
||||
} else {
|
||||
fputs(_("Argument to the '-d' flag is not valid\n"),stdout);
|
||||
fputs(_("Possible argument formats are : 'mm/dd/yyyy' or 'n'\n"),stdout);
|
||||
fputs(_("\nFor more information, type '?' from within Calcurse, or read the manpage.\n"),stdout);
|
||||
fputs
|
||||
(_("Mail bug reports and suggestions to <calcurse@culot.org>.\n"),
|
||||
stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the entered date is of a valid format.
|
||||
* First check the format by itself, and then check the
|
||||
* numbers correctness.
|
||||
*/
|
||||
int
|
||||
check_date(char *date)
|
||||
{
|
||||
int ok = 0;
|
||||
char month[] = " ";
|
||||
char day[] = " ";
|
||||
char year[] = " ";
|
||||
if (
|
||||
(strlen(date) == 10) &
|
||||
(isdigit(date[0]) != 0) &
|
||||
(isdigit(date[1]) != 0) &
|
||||
(date[2] == '/') &
|
||||
(isdigit(date[3]) != 0) &
|
||||
(isdigit(date[4]) != 0) &
|
||||
(date[5] == '/') &
|
||||
(isdigit(date[6])!=0) & (isdigit(date[7])!=0) &
|
||||
(isdigit(date[8])!=0) & (isdigit(date[9])!=0)
|
||||
) {
|
||||
strncpy(month, date, 2);
|
||||
strncpy(day, date + 3, 2);
|
||||
strncpy(year, date + 6, 4);
|
||||
if ( (atoi(month) <= 12) &
|
||||
(atoi(month) >= 1) &
|
||||
(atoi(day) <= 31) &
|
||||
(atoi(day) >= 1) &
|
||||
(atoi(year) <= 9999) &
|
||||
(atoi(year) > 1))
|
||||
ok = 1;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the date on stdout.
|
||||
*/
|
||||
void arg_print_date(long date)
|
||||
{
|
||||
char date_str[30];
|
||||
time_t t;
|
||||
struct tm *lt;
|
||||
|
||||
t = date;
|
||||
lt = localtime(&t);
|
||||
sprintf(date_str,"%02u/%02u/%04u",lt->tm_mon+1,
|
||||
lt->tm_mday, 1900+lt->tm_year);
|
||||
fputs(date_str,stdout);
|
||||
fputs(":\n",stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print Calcurse usage and exit.
|
||||
*/
|
||||
void usage()
|
||||
{
|
||||
char *arg_usage =
|
||||
_("Usage: calcurse [-h | -v] [-at] [-d date|num] [-c file]\n");
|
||||
|
||||
fputs(arg_usage, stdout);
|
||||
}
|
||||
|
||||
void usage_try()
|
||||
{
|
||||
char *arg_usage_try =
|
||||
_("Try 'calcurse -h' for more information.\n");
|
||||
|
||||
fputs(arg_usage_try, stdout);
|
||||
}
|
||||
41
src/args.h
Executable file
41
src/args.h
Executable file
@@ -0,0 +1,41 @@
|
||||
/* $calcurse: args.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_ARGS_H
|
||||
#define CALCURSE_ARGS_H
|
||||
|
||||
void usage();
|
||||
void usage_try();
|
||||
int parse_args(int argc, char **argv, int colr);
|
||||
void version_arg();
|
||||
void help_arg();
|
||||
void todo_arg(int colr);
|
||||
int app_arg(int add_line, int year, int month, int day, long date);
|
||||
void date_arg(char *ddate, int add_line);
|
||||
int check_date(char *date);
|
||||
void arg_print_date(long date);
|
||||
|
||||
#endif /* CALCURSE_ARGS_H */
|
||||
158
src/calcurse.1
Executable file
158
src/calcurse.1
Executable file
@@ -0,0 +1,158 @@
|
||||
.\" $calcurse: calcurse.1,v 1.1 2006/07/31 21:00:03 culot Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2004-2006 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
|
||||
.\" the Free Software Foundation; either version 2 of the License, or
|
||||
.\" (at your option) any later version.
|
||||
.\"
|
||||
.\" This program is distributed in the hope that it will be useful,
|
||||
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
.\" GNU General Public License for more details.
|
||||
.\"
|
||||
.\" You should have received a copy of the GNU General Public License
|
||||
.\" along with this program; if not, write to the Free Software
|
||||
.\" Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
.\" Boston, MA 02111-1307, USA.
|
||||
.\"
|
||||
.TH CALCURSE 1 "May 07, 2006" "Version 1.4" "Calcurse Manual"
|
||||
.SH NAME
|
||||
Calcurse \- text-based organizer
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
.B "calcurse "
|
||||
[
|
||||
.B "-h "
|
||||
|
|
||||
.B "-v "
|
||||
] [
|
||||
.B "-at "
|
||||
] [
|
||||
.B "-d "
|
||||
\fIdate\fP|\fInum\fP ] [
|
||||
.B "-c "
|
||||
\fIfile\fP ]
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
Calcurse is a text-based personal organizer which helps keeping track of
|
||||
events and everyday tasks. It contains a calendar, a 'todo' list, and
|
||||
puts your appointments in order. The user interface is configurable,
|
||||
and one can choose between different color schemes and layouts.
|
||||
All of the commands are documented within an online help system.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
The following options are supported:
|
||||
.TP
|
||||
.B \-a
|
||||
Print the appointments and events for the current day and exit.
|
||||
.br
|
||||
\fINote:\fP the calendar from which to read the appointments can be specified using
|
||||
the '\-c' flag.
|
||||
.TP
|
||||
.B \-c
|
||||
Specify the calendar file to use. The default calendar is
|
||||
.B "'~/.calcurse/apts'"
|
||||
(see section \fIFILES\fP below).
|
||||
.TP
|
||||
.B \-d
|
||||
Print the appointments and events for the given date or for
|
||||
the given number of upcoming days, depending on the argument format.
|
||||
Two possible formats are supported:
|
||||
.RS 9
|
||||
.TP 2
|
||||
\(bu a date of the form 'mm/dd/yyyy'.
|
||||
.TP 2
|
||||
\(bu a number 'n'.
|
||||
.RE
|
||||
.RS 7
|
||||
.LP
|
||||
In the first case, the appointments and events list for the specified
|
||||
date will be returned, while in the second case the appointments and events
|
||||
list for the 'n' upcoming days will be returned.
|
||||
.br
|
||||
As an example, typing 'calcurse -d 3' will display your appointments
|
||||
and events for today, tomorrow, and the day after tomorrow.
|
||||
.br
|
||||
\fINote:\fP as for the '-a' flag, the calendar from which to read the
|
||||
appointments can be specified using the '\-c' flag.
|
||||
.RE
|
||||
.TP
|
||||
.B \-h
|
||||
Print a short help text describing the supported command-line options,
|
||||
and then exit.
|
||||
.TP
|
||||
.B \-t
|
||||
Print the 'todo' list and exit.
|
||||
.TP
|
||||
.B \-v
|
||||
Display calcurse version and exit.
|
||||
.SH NOTES
|
||||
Calcurse interface contains three different panels (calendar,
|
||||
appointment list, and todo list) on which you can perform different
|
||||
actions. All the possible actions, together with their associated
|
||||
keystrokes, are listed on the status bar. This status bar
|
||||
takes place at the bottom of the screen.
|
||||
.PP
|
||||
At any time, the built-in help system can be invoked by pressing the '?'
|
||||
key. Once viewing the help screens, informations on a specific command
|
||||
can be accessed by pressing the keystroke corresponding to that command.
|
||||
.PP
|
||||
.SH CONFIGURATION
|
||||
The calcurse options can be changed from the configuration menu (shown
|
||||
when 'C' is hit). Three possible categories are to be chosen from : the
|
||||
color scheme, the layout (the location of the three panels on the
|
||||
screen), and more general options (such as automatic save before
|
||||
quitting). All of these options are detailed in the configuration menu.
|
||||
.PP
|
||||
.SH FILES
|
||||
The following structure is created in your $HOME directory the first
|
||||
time calcurse is run :
|
||||
.PP
|
||||
.HP 10
|
||||
$HOME/.calcurse/
|
||||
.br
|
||||
|___conf
|
||||
.br
|
||||
|___apts
|
||||
.br
|
||||
|___todo
|
||||
.PP
|
||||
The \fIconf\fP file contains the user configuration. The \fIapts\fP
|
||||
file contains all of the user's appointments, and the \fItodo\fP
|
||||
file contains the todo list.
|
||||
.PP
|
||||
.SH LICENCE
|
||||
Copyright (c) 2004-2006 by Frederic Culot.
|
||||
.br
|
||||
This software is released under the GNU General Public License. Please
|
||||
read the COPYING file for more information.
|
||||
.PP
|
||||
.SH BUGS
|
||||
Incorrect highlighting of items appear when using calcurse black and
|
||||
white theme together with a \fB$TERM\fP variable set to
|
||||
\fIxterm-color\fP.
|
||||
To fix this bug, and as advised by Thomas E. Dickey (xterm maintainer),
|
||||
\fIxterm-xfree86\fP should be used instead of \fIxterm-color\fP to set
|
||||
the \fB$TERM\fP variable:
|
||||
"The xterm-color value for $TERM is a bad choice for XFree86
|
||||
xterm because it is commonly used for a terminfo entry which
|
||||
happens to not support bce. Use the xterm-xfree86 entry
|
||||
which is distributed with XFree86 xterm (or the similar one
|
||||
distributed with ncurses)."
|
||||
.PP
|
||||
If you find other bugs, please send a report to calcurse@culot.org or to the
|
||||
author, below.
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
\fBFrederic Culot\fP <frederic@culot.org>.
|
||||
.PP
|
||||
.SH SEE ALSO
|
||||
ncurses(3), gettext(3)
|
||||
.br
|
||||
Calcurse home page : http://culot.org/calcurse/
|
||||
.br
|
||||
Calcurse manual found in the doc/ directory of the source package, or
|
||||
at:
|
||||
http://culot.org/calcurse/manual.html
|
||||
1156
src/calcurse.c
Executable file
1156
src/calcurse.c
Executable file
File diff suppressed because it is too large
Load Diff
227
src/calendar.c
Executable file
227
src/calendar.c
Executable file
@@ -0,0 +1,227 @@
|
||||
/* $calcurse: calendar.c,v 1.1 2006/07/31 21:00:02 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "day.h"
|
||||
#include "apoint.h"
|
||||
#include "event.h"
|
||||
#include "calendar.h"
|
||||
#include "custom.h"
|
||||
#include "vars.h"
|
||||
#include "utils.h"
|
||||
|
||||
static unsigned months_to_days(unsigned);
|
||||
static long years_to_days(unsigned);
|
||||
|
||||
/* Load the calendar */
|
||||
void
|
||||
update_cal_panel(WINDOW *cwin, int nl_cal,
|
||||
int nc_cal, int sel_month, int sel_year, int sel_day,
|
||||
int day, int month, int year,
|
||||
bool monday_first)
|
||||
{
|
||||
int c_day, c_day_1, day_1_sav, numdays, j;
|
||||
unsigned yr, mo;
|
||||
int ofs_x, ofs_y;
|
||||
int item_this_day = 0;
|
||||
int title_lines = 3;
|
||||
int sunday_first = 0;
|
||||
|
||||
// Inits
|
||||
erase_window_part(cwin, 1, title_lines, nc_cal - 2, nl_cal - 2);
|
||||
mo = sel_month;
|
||||
yr = sel_year;
|
||||
if (!monday_first) sunday_first = 1;
|
||||
|
||||
// Offset for centering calendar in window
|
||||
ofs_y = 2 + (nl_cal - 9) / 2;
|
||||
ofs_x = (nc_cal - 27) / 2;
|
||||
|
||||
|
||||
//checking the number of days in february
|
||||
numdays = days[mo - 1];
|
||||
if (2 == mo && isBissextile(yr))
|
||||
++numdays;
|
||||
|
||||
//the first calendar day will be monday or sunday, depending on the
|
||||
//value of week_begins_on_monday
|
||||
c_day_1 = (int) ((ymd_to_scalar(yr, mo, 1 + sunday_first)
|
||||
- (long) 1) % 7L);
|
||||
|
||||
//Write the current month and year on top of the calendar
|
||||
custom_apply_attr(cwin, ATTR_HIGH);
|
||||
mvwprintw(cwin, ofs_y,
|
||||
(nc_cal - (strlen(_(monthnames[mo - 1])) + 5)) / 2,
|
||||
"%s %d", _(monthnames[mo - 1]), sel_year);
|
||||
custom_remove_attr(cwin, ATTR_HIGH);
|
||||
++ofs_y;
|
||||
|
||||
//prints the days, with regards to the first day of the week
|
||||
custom_apply_attr(cwin, ATTR_HIGH);
|
||||
for (j = 0; j < 7; j++) {
|
||||
mvwprintw(cwin, ofs_y, ofs_x + 4 * j, "%s",
|
||||
_(daynames[1 + j - sunday_first]));
|
||||
}
|
||||
custom_remove_attr(cwin, ATTR_HIGH);
|
||||
|
||||
day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7;
|
||||
|
||||
for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) {
|
||||
//check if the day contains an event or an appointment
|
||||
item_this_day = day_check_if_item(sel_year, sel_month, c_day);
|
||||
|
||||
/* Go to next line, the week is over. */
|
||||
if (!c_day_1 && 1 != c_day) {
|
||||
++ofs_y;
|
||||
ofs_x = 2 - day_1_sav - 4 * c_day - 1;
|
||||
}
|
||||
/* This is today, so print it in yellow. */
|
||||
if (c_day == day && month == sel_month
|
||||
&& year == sel_year && day != sel_day)
|
||||
{
|
||||
custom_apply_attr(cwin, ATTR_LOWEST);
|
||||
mvwprintw(cwin, ofs_y + 1,
|
||||
ofs_x + day_1_sav + 4 * c_day + 1, "%2d",
|
||||
c_day);
|
||||
custom_remove_attr(cwin, ATTR_LOWEST);
|
||||
} else if (c_day == sel_day && ( (day != sel_day) |
|
||||
(month != sel_month) | (year != sel_year) ))
|
||||
/* This is the selected day, print it in red. */
|
||||
{
|
||||
custom_apply_attr(cwin, ATTR_MIDDLE);
|
||||
mvwprintw(cwin, ofs_y + 1,
|
||||
ofs_x + day_1_sav + 4 * c_day + 1, "%2d",
|
||||
c_day);
|
||||
custom_remove_attr(cwin, ATTR_MIDDLE);
|
||||
} else if (c_day == sel_day && day == sel_day && month == sel_month && year == sel_year) //today is the selected day
|
||||
{
|
||||
custom_apply_attr(cwin, ATTR_MIDDLE);
|
||||
mvwprintw(cwin, ofs_y + 1,
|
||||
ofs_x + day_1_sav + 4 * c_day + 1, "%2d",
|
||||
c_day);
|
||||
custom_remove_attr(cwin, ATTR_MIDDLE);
|
||||
} else if (item_this_day) {
|
||||
custom_apply_attr(cwin, ATTR_LOW);
|
||||
mvwprintw(cwin, ofs_y + 1,
|
||||
ofs_x + day_1_sav + 4 * c_day + 1, "%2d",
|
||||
c_day);
|
||||
custom_remove_attr(cwin, ATTR_LOW);
|
||||
}
|
||||
|
||||
else // otherwise, print normal days in black
|
||||
mvwprintw(cwin, ofs_y + 1,
|
||||
ofs_x + day_1_sav + 4 * c_day + 1, "%2d",
|
||||
c_day);
|
||||
|
||||
}
|
||||
wnoutrefresh(cwin);
|
||||
}
|
||||
|
||||
int isBissextile(unsigned annee)
|
||||
{
|
||||
return annee % 400 == 0 || (annee % 4 == 0 && annee % 100 != 0);
|
||||
}
|
||||
|
||||
// convertion functions
|
||||
unsigned months_to_days(unsigned mois)
|
||||
{
|
||||
return (mois * 3057 - 3007) / 100;
|
||||
}
|
||||
|
||||
|
||||
long years_to_days(unsigned annee)
|
||||
{
|
||||
return annee * 365L + annee / 4 - annee / 100 + annee / 400;
|
||||
}
|
||||
|
||||
long ymd_to_scalar(unsigned annee, unsigned mois, unsigned jour)
|
||||
{
|
||||
long scalaire;
|
||||
scalaire = jour + months_to_days(mois);
|
||||
if (mois > 2)
|
||||
scalaire -= isBissextile(annee) ? 1 : 2;
|
||||
annee--;
|
||||
scalaire += years_to_days(annee);
|
||||
return scalaire;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask for a date to jump to, then check the correctness of that date
|
||||
* and jump to it.
|
||||
* If the entered date is empty, automatically jump to the current date.
|
||||
* day, month, year are the current day given to that routine, and
|
||||
* sel_day, sel_month and sel_year represent the day given back.
|
||||
*/
|
||||
void
|
||||
goto_day(int colr, int day, int month, int year,
|
||||
int *sel_day, int *sel_month, int *sel_year)
|
||||
{
|
||||
char selected_day[50] = "";
|
||||
int dday, dmonth, dyear;
|
||||
int wrong_day = 0;
|
||||
char *mesg_line1 = _("The day you entered is not valid");
|
||||
char *mesg_line2 = _("Press [ENTER] to continue");
|
||||
char *request_date = _("Enter the day to go to [ENTER for today] : dd/mm/yyyy");
|
||||
|
||||
while (wrong_day != 1) {
|
||||
status_mesg(request_date, "");
|
||||
getstring(swin, colr, selected_day, 0, 1);
|
||||
if (strlen(selected_day) == 0) // go to today
|
||||
{
|
||||
*sel_day = day;
|
||||
*sel_month = month;
|
||||
*sel_year = year;
|
||||
break;
|
||||
} else {
|
||||
sscanf(selected_day, "%u/%u/%u", &dday, &dmonth,
|
||||
&dyear);
|
||||
//check if the entered day is correct
|
||||
if ((dday <= 0) | (dday >= 32))
|
||||
wrong_day = 1;
|
||||
if ((dmonth <= 0) | (dmonth >= 13))
|
||||
wrong_day = 1;
|
||||
if ((dyear <= 0) | (dyear >= 3000))
|
||||
wrong_day = 1;
|
||||
//go to chosen day
|
||||
if (wrong_day != 1) {
|
||||
*sel_day = dday;
|
||||
*sel_month = dmonth;
|
||||
*sel_year = dyear;
|
||||
} else {
|
||||
status_mesg(mesg_line1, mesg_line2);
|
||||
wgetch(swin);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
41
src/calendar.h
Executable file
41
src/calendar.h
Executable file
@@ -0,0 +1,41 @@
|
||||
/* $calcurse: calendar.h,v 1.1 2006/07/31 21:00:02 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_CALENDAR_H
|
||||
#define CALCURSE_CALENDAR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void update_cal_panel(WINDOW *cwin, int nl_cal,
|
||||
int nc_cal, int sel_month, int sel_year, int sel_day,
|
||||
int day, int month, int year,
|
||||
bool monday_first);
|
||||
int isBissextile(unsigned);
|
||||
long ymd_to_scalar(unsigned, unsigned, unsigned);
|
||||
void goto_day(int colr, int day, int month, int year,
|
||||
int *sel_day, int *sel_month, int *sel_year);
|
||||
|
||||
#endif /* CALCURSE_CALENDAR_H */
|
||||
178
src/custom.c
Executable file
178
src/custom.c
Executable file
@@ -0,0 +1,178 @@
|
||||
/* $calcurse: custom.c,v 1.1 2006/07/31 21:00:02 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "utils.h"
|
||||
#include "custom.h"
|
||||
#include "vars.h"
|
||||
|
||||
static struct attribute_s attr;
|
||||
|
||||
/*
|
||||
* Define window attributes (for both color and non-color terminals):
|
||||
* ATTR_HIGHEST are for window titles
|
||||
* ATTR_HIGH are for month and days names
|
||||
* ATTR_MIDDLE are for the selected day inside calendar panel
|
||||
* ATTR_LOW are for days inside calendar panel which contains an event
|
||||
* ATTR_LOWEST are for current day inside calendar panel
|
||||
*/
|
||||
void custom_init_attr(int colr)
|
||||
{
|
||||
attr.color[ATTR_HIGHEST] = COLOR_PAIR(colr);
|
||||
attr.color[ATTR_HIGH] = COLOR_PAIR(6);
|
||||
attr.color[ATTR_MIDDLE] = COLOR_PAIR(1);
|
||||
attr.color[ATTR_LOW] = COLOR_PAIR(4);
|
||||
attr.color[ATTR_LOWEST] = COLOR_PAIR(5);
|
||||
attr.color[ATTR_TRUE] = COLOR_PAIR(2);
|
||||
attr.color[ATTR_FALSE] = COLOR_PAIR(1);
|
||||
|
||||
attr.nocolor[ATTR_HIGHEST] = A_BOLD;
|
||||
attr.nocolor[ATTR_HIGH] = A_REVERSE;
|
||||
attr.nocolor[ATTR_MIDDLE] = A_REVERSE;
|
||||
attr.nocolor[ATTR_LOW] = A_UNDERLINE;
|
||||
attr.nocolor[ATTR_LOWEST] = A_BOLD;
|
||||
attr.nocolor[ATTR_TRUE] = A_BOLD;
|
||||
attr.nocolor[ATTR_FALSE] = A_DIM;
|
||||
}
|
||||
|
||||
/* Apply window attribute */
|
||||
void custom_apply_attr(WINDOW *win, int attr_num)
|
||||
{
|
||||
if (colorize)
|
||||
wattron(win, attr.color[attr_num]);
|
||||
else
|
||||
wattron(win, attr.nocolor[attr_num]);
|
||||
}
|
||||
|
||||
/* Remove window attribute */
|
||||
void custom_remove_attr(WINDOW *win, int attr_num)
|
||||
{
|
||||
if (colorize)
|
||||
wattroff(win, attr.color[attr_num]);
|
||||
else
|
||||
wattroff(win, attr.nocolor[attr_num]);
|
||||
}
|
||||
|
||||
/* Draws the configuration bar */
|
||||
void config_bar()
|
||||
{
|
||||
int smlspc, spc;
|
||||
|
||||
smlspc = 2;
|
||||
spc = 15;
|
||||
|
||||
custom_apply_attr(swin, ATTR_HIGHEST);
|
||||
mvwprintw(swin, 0, 2, "Q");
|
||||
mvwprintw(swin, 1, 2, "G");
|
||||
mvwprintw(swin, 0, 2 + spc, "L");
|
||||
mvwprintw(swin, 1, 2 + spc, "C");
|
||||
custom_remove_attr(swin, ATTR_HIGHEST);
|
||||
|
||||
mvwprintw(swin, 0, 2 + smlspc, _("Exit"));
|
||||
mvwprintw(swin, 1, 2 + smlspc, _("General"));
|
||||
mvwprintw(swin, 0, 2 + spc + smlspc, _("Layout"));
|
||||
mvwprintw(swin, 1, 2 + spc + smlspc, _("Color"));
|
||||
|
||||
wnoutrefresh(swin);
|
||||
wmove(swin, 0, 0);
|
||||
doupdate();
|
||||
}
|
||||
|
||||
/* Choose the layout */
|
||||
int layout_config(int layout, int colr)
|
||||
{
|
||||
int ch, old_layout;
|
||||
char *layout_mesg = _("Pick the desired layout on next screen [press ENTER]");
|
||||
char *choice_mesg = _("('A'= Appointment panel, 'c'= calendar panel, 't'= todo panel)");
|
||||
char *layout_up_mesg = _(" |Ac| |At| |cA| |tA|");
|
||||
char *layout_down_mesg = _("[1]|At| [2]|Ac| [3]|tA| [4]|cA|");
|
||||
|
||||
old_layout = layout;
|
||||
status_mesg(layout_mesg, choice_mesg);
|
||||
wgetch(swin);
|
||||
status_mesg(layout_up_mesg, layout_down_mesg);
|
||||
wnoutrefresh(swin);
|
||||
doupdate();
|
||||
while ((ch = wgetch(swin)) != 'q') {
|
||||
switch (ch) {
|
||||
case '1':
|
||||
layout = 1;
|
||||
return layout;
|
||||
case '2':
|
||||
layout = 2;
|
||||
return layout;
|
||||
case '3':
|
||||
layout = 3;
|
||||
return layout;
|
||||
case '4':
|
||||
layout = 4;
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
layout = old_layout;
|
||||
return layout;
|
||||
}
|
||||
|
||||
/* Choose the color theme */
|
||||
int color_config(int colr)
|
||||
{
|
||||
int ascii2dec = 48;
|
||||
int i, ch, old_colr;
|
||||
int max_colors = 9;
|
||||
int spc = 6;
|
||||
char *choose_color = _("Pick the number corresponding to the color scheme "
|
||||
"(Q to exit) :");
|
||||
|
||||
old_colr = colr;
|
||||
erase_window_part(swin, 0, 0, col, 2);
|
||||
for (i = 1; i < max_colors; i++) {
|
||||
wattron(swin, COLOR_PAIR(i));
|
||||
mvwprintw(swin, 1, (i - 1) * spc, "[>%d<]", i);
|
||||
wattroff(swin, COLOR_PAIR(i));
|
||||
}
|
||||
mvwprintw(swin, 1, 50, _("([>0<] for black & white)"));
|
||||
custom_apply_attr(swin, ATTR_HIGHEST);
|
||||
mvwprintw(swin, 0, 0, choose_color);
|
||||
custom_remove_attr(swin, ATTR_HIGHEST);
|
||||
wnoutrefresh(swin);
|
||||
doupdate();
|
||||
while ((ch = wgetch(swin)) != 'q') {
|
||||
ch = ch - ascii2dec;
|
||||
if ( (ch > 0) && (ch <= max_colors) ) {
|
||||
colorize = true;
|
||||
return ch;
|
||||
} else if (ch == 0) {
|
||||
colorize = false;
|
||||
return 0;
|
||||
} else {
|
||||
colr = old_colr;
|
||||
}
|
||||
}
|
||||
if (colr == 0) colorize = false;
|
||||
return colr;
|
||||
}
|
||||
42
src/custom.h
Executable file
42
src/custom.h
Executable file
@@ -0,0 +1,42 @@
|
||||
/* $calcurse: custom.h,v 1.1 2006/07/31 21:00:02 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_CUSTOM_H
|
||||
#define CALCURSE_CUSTOM_H
|
||||
|
||||
struct attribute_s {
|
||||
int color[7];
|
||||
int nocolor[7];
|
||||
};
|
||||
|
||||
void custom_init_attr(int colr);
|
||||
void custom_apply_attr(WINDOW *win, int attr_num);
|
||||
void custom_remove_attr(WINDOW *win, int attr_num);
|
||||
void config_bar();
|
||||
int layout_config(int layout, int colr);
|
||||
int color_config(int colr);
|
||||
|
||||
#endif /* CALCURSE_CUSTOM_H */
|
||||
362
src/day.c
Executable file
362
src/day.c
Executable file
@@ -0,0 +1,362 @@
|
||||
/* $calcurse: day.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "utils.h"
|
||||
#include "apoint.h"
|
||||
#include "event.h"
|
||||
#include "recur.h"
|
||||
#include "day.h"
|
||||
#include "vars.h"
|
||||
|
||||
static struct day_item_s *day_items_ptr;
|
||||
static struct day_saved_item_s *day_saved_item = NULL;
|
||||
|
||||
/*
|
||||
* Store all of the items to be displayed for the selected day.
|
||||
* Items are of four types: recursive events, normal events,
|
||||
* recursive appointments and normal appointments.
|
||||
* The items are stored in the linked list pointed by *day_items_ptr
|
||||
* and the length of the new pad to write is returned.
|
||||
* The number of events and appointments in the current day are also updated.
|
||||
*/
|
||||
int day_store_items(long date, int *pnb_events, int *pnb_apoints)
|
||||
{
|
||||
int pad_length;
|
||||
int nb_events, nb_recur_events;
|
||||
int nb_apoints, nb_recur_apoints;
|
||||
|
||||
pad_length = nb_events = nb_apoints = 0;
|
||||
nb_recur_events = nb_recur_apoints = 0;
|
||||
|
||||
if (day_items_ptr != 0)
|
||||
day_free_list();
|
||||
nb_recur_events = day_store_recur_events(date);
|
||||
nb_events = day_store_events(date);
|
||||
*pnb_events = nb_events;
|
||||
nb_recur_apoints = day_store_recur_apoints(date);
|
||||
nb_apoints = day_store_apoints(date);
|
||||
*pnb_apoints = nb_apoints;
|
||||
pad_length = nb_recur_events + nb_events + 1 +
|
||||
3*(nb_recur_apoints + nb_apoints);
|
||||
*pnb_apoints += nb_recur_apoints;
|
||||
*pnb_events += nb_recur_events;
|
||||
|
||||
return pad_length;
|
||||
}
|
||||
|
||||
/* Free the current day linked list containing the events and appointments. */
|
||||
void day_free_list(void)
|
||||
{
|
||||
struct day_item_s *p, *q;
|
||||
|
||||
for (p = day_items_ptr; p != 0; p = q) {
|
||||
q = p->next;
|
||||
free(p->mesg);
|
||||
free(p);
|
||||
}
|
||||
day_items_ptr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the recurrent events for the selected day in structure pointed
|
||||
* by day_items_ptr. This is done by copying the recurrent events
|
||||
* from the general structure pointed by recur_elist to the structure
|
||||
* dedicated to the selected day.
|
||||
* Returns the number of recurrent events for the selected day.
|
||||
*/
|
||||
int day_store_recur_events(long date)
|
||||
{
|
||||
struct recur_event_s *j;
|
||||
struct day_item_s *ptr;
|
||||
int e_nb = 0;
|
||||
|
||||
for (j = recur_elist; j != 0; j = j->next) {
|
||||
if (recur_item_inday(j->day, j->rpt->type, j->rpt->freq,
|
||||
j->rpt->until, date)) {
|
||||
e_nb++;
|
||||
ptr = day_add_event(RECUR_EVNT, j->mesg, j->day, j->id);
|
||||
}
|
||||
}
|
||||
|
||||
return e_nb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the events for the selected day in structure pointed
|
||||
* by day_items_ptr. This is done by copying the events
|
||||
* from the general structure pointed by eventlist to the structure
|
||||
* dedicated to the selected day.
|
||||
* Returns the number of events for the selected day.
|
||||
*/
|
||||
int day_store_events(long date)
|
||||
{
|
||||
struct event_s *j;
|
||||
struct day_item_s *ptr;
|
||||
int e_nb = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return e_nb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the recurrent apoints for the selected day in structure pointed
|
||||
* by day_items_ptr. This is done by copying the appointments
|
||||
* from the general structure pointed by recur_alist to the structure
|
||||
* dedicated to the selected day.
|
||||
* Returns the number of recurrent appointments for the selected day.
|
||||
*/
|
||||
int day_store_recur_apoints(long date)
|
||||
{
|
||||
struct recur_apoint_s *j;
|
||||
struct day_item_s *ptr;
|
||||
int a_nb = 0;
|
||||
|
||||
for (j = recur_alist; j != 0; j = j->next) {
|
||||
if (recur_item_inday(j->start, j->rpt->type, j->rpt->freq,
|
||||
j->rpt->until, date)) {
|
||||
a_nb++;
|
||||
ptr = day_add_apoint(RECUR_APPT, j->mesg, j->start, j->dur);
|
||||
}
|
||||
}
|
||||
|
||||
return a_nb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the apoints for the selected day in structure pointed
|
||||
* by day_items_ptr. This is done by copying the appointments
|
||||
* from the general structure pointed by apointlist to the structure
|
||||
* dedicated to the selected day.
|
||||
* Returns the number of appointments for the selected day.
|
||||
*/
|
||||
int day_store_apoints(long date)
|
||||
{
|
||||
struct apoint_s *j;
|
||||
struct day_item_s *ptr;
|
||||
int a_nb = 0;
|
||||
|
||||
for (j = apointlist; j != 0; j = j->next) {
|
||||
if (apoint_inday(j, date)) {
|
||||
a_nb++;
|
||||
ptr = day_add_apoint(APPT, j->mesg, j->start, j->dur);
|
||||
}
|
||||
}
|
||||
|
||||
return a_nb;
|
||||
}
|
||||
|
||||
/* Add an event in the current day list */
|
||||
struct day_item_s *day_add_event(int type, char *mesg, 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);
|
||||
strcpy(o->mesg, mesg);
|
||||
o->type = type;
|
||||
o->appt_dur = 0;
|
||||
o->start = day;
|
||||
o->evnt_id = id;
|
||||
i = &day_items_ptr;
|
||||
for (;;) {
|
||||
if (*i == 0 || (*i)->start > day) {
|
||||
o->next = *i;
|
||||
*i = o;
|
||||
break;
|
||||
}
|
||||
i = &(*i)->next;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/* Add an appointment in the current day list. */
|
||||
struct day_item_s *day_add_apoint(int type, char *mesg, long start, long dur)
|
||||
{
|
||||
struct day_item_s *o, **i;
|
||||
o = (struct day_item_s *) malloc(sizeof(struct day_item_s));
|
||||
o->mesg = (char *) malloc(strlen(mesg) + 1);
|
||||
strcpy(o->mesg, mesg);
|
||||
o->start = start;
|
||||
o->appt_dur = dur;
|
||||
o->type = type;
|
||||
o->evnt_id = 0;
|
||||
i = &day_items_ptr;
|
||||
for (;;) {
|
||||
if (*i == 0 || (*i)->start > start) {
|
||||
o->next = *i;
|
||||
*i = o;
|
||||
break;
|
||||
}
|
||||
i = &(*i)->next;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the appointments and events for the selected day in a pad.
|
||||
* An horizontal line is drawn between events and appointments, and the
|
||||
* item selected by user is highlighted. This item is also saved inside
|
||||
* structure (pointed by day_saved_item), to be later displayed in a
|
||||
* popup window if requested.
|
||||
*/
|
||||
void day_write_pad(long date, int width, int length, int incolor, int colr)
|
||||
{
|
||||
struct day_item_s *p;
|
||||
int line, item_number, max_pos;
|
||||
const int x_pos = 0;
|
||||
bool draw_line = true;
|
||||
|
||||
line = item_number = 0;
|
||||
max_pos = length;
|
||||
|
||||
/* Initialize the structure used to store highlited item. */
|
||||
if (day_saved_item == NULL) {
|
||||
day_saved_item = (struct day_saved_item_s *)
|
||||
malloc(sizeof(struct day_saved_item_s));
|
||||
day_saved_item->mesg = (char *) malloc(1);
|
||||
}
|
||||
|
||||
for (p = day_items_ptr; p != 0; p = p->next) {
|
||||
|
||||
/* First print the events for current day. */
|
||||
if (p->type < RECUR_APPT) {
|
||||
item_number++;
|
||||
if (item_number - incolor == 0) {
|
||||
day_saved_item->type = p->type;
|
||||
day_saved_item->mesg = (char *)
|
||||
realloc(day_saved_item->mesg,
|
||||
strlen(p->mesg) + 1);
|
||||
day_saved_item->mesg = p->mesg;
|
||||
}
|
||||
display_item(apad->ptrwin, item_number - incolor, p->mesg,
|
||||
width - 4, line, x_pos);
|
||||
line++;
|
||||
} else {
|
||||
/* Draw a line between events and appointments. */
|
||||
if (line > 0 && draw_line){
|
||||
wmove(apad->ptrwin, line, x_pos);
|
||||
whline(apad->ptrwin, 0, width);
|
||||
draw_line = false;
|
||||
}
|
||||
|
||||
/* Last print the appointments for current day. */
|
||||
item_number++;
|
||||
if (item_number - incolor == 0) {
|
||||
day_saved_item->type = p->type;
|
||||
day_saved_item->mesg = (char *)
|
||||
realloc(day_saved_item->mesg,
|
||||
strlen(p->mesg) + 1);
|
||||
day_saved_item->mesg = p->mesg;
|
||||
apoint_sec2str(day_item_s2apoint_s(p),
|
||||
p->type, date,
|
||||
day_saved_item->start,
|
||||
day_saved_item->end);
|
||||
}
|
||||
display_item_date(apad->ptrwin, item_number - incolor,
|
||||
day_item_s2apoint_s(p), p->type, date,
|
||||
line + 1, x_pos);
|
||||
display_item(apad->ptrwin, item_number - incolor, p->mesg,
|
||||
width - 6, line + 2, x_pos + 2);
|
||||
line = line + 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a structure of type apoint_s given a structure of type day_item_s */
|
||||
struct apoint_s *day_item_s2apoint_s(struct day_item_s *p)
|
||||
{
|
||||
struct apoint_s *a;
|
||||
|
||||
a = (struct apoint_s *) malloc(sizeof(struct apoint_s));
|
||||
a->mesg = (char *) malloc(strlen(p->mesg) + 1);
|
||||
a->start = p->start;
|
||||
a->dur = p->appt_dur;
|
||||
a->mesg = p->mesg;
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Display an item inside a popup window. */
|
||||
void day_popup_item(void)
|
||||
{
|
||||
char *error =
|
||||
_("FATAL ERROR in day_popup_item: unknown item type\n");
|
||||
|
||||
if (day_saved_item->type == EVNT || day_saved_item->type == RECUR_EVNT)
|
||||
item_in_popup(NULL, NULL, day_saved_item->mesg, _("Event :"));
|
||||
else if (day_saved_item->type == APPT ||
|
||||
day_saved_item->type == RECUR_APPT)
|
||||
item_in_popup(day_saved_item->start, day_saved_item->end,
|
||||
day_saved_item->mesg, _("Appointment :"));
|
||||
else { /* NOT REACHED */
|
||||
fputs(error, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(int year, int month, int day) {
|
||||
struct recur_event_s *re;
|
||||
struct recur_apoint_s *ra;
|
||||
struct event_s *e;
|
||||
struct apoint_s *a;
|
||||
const long date = date2sec(year, month, day, 0, 0);
|
||||
|
||||
for (re = recur_elist; re != 0; re = re->next)
|
||||
if (recur_item_inday(re->day, re->rpt->type, re->rpt->freq,
|
||||
re->rpt->until, date))
|
||||
return 1;
|
||||
|
||||
for (ra = recur_alist; ra != 0; ra = ra->next)
|
||||
if (recur_item_inday(ra->start, ra->rpt->type, ra->rpt->freq,
|
||||
ra->rpt->until, date))
|
||||
return 1;
|
||||
|
||||
for (e = eventlist; e != 0; e = e->next)
|
||||
if (event_inday(e, date))
|
||||
return 1;
|
||||
|
||||
for (a = apointlist; a != 0; a = a->next)
|
||||
if (apoint_inday(a, date))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
66
src/day.h
Executable file
66
src/day.h
Executable file
@@ -0,0 +1,66 @@
|
||||
/* $calcurse: day.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_DAY_H
|
||||
#define CALCURSE_DAY_H
|
||||
|
||||
#include "apoint.h"
|
||||
|
||||
#define RECUR_EVNT 1
|
||||
#define EVNT 2
|
||||
#define RECUR_APPT 3
|
||||
#define APPT 4
|
||||
|
||||
struct day_item_s {
|
||||
struct day_item_s *next;
|
||||
int type; /* (recursive or normal) event or appointment */
|
||||
long start; /* seconds since 1 jan 1970 */
|
||||
char *mesg; /* item description */
|
||||
int evnt_id; /* event identifier */
|
||||
long appt_dur; /* appointment duration in seconds */
|
||||
};
|
||||
|
||||
struct day_saved_item_s {
|
||||
int type ;
|
||||
char *mesg;
|
||||
char start[100];
|
||||
char end[100];
|
||||
};
|
||||
|
||||
int day_store_items(long date, int *pnb_events, int *pnb_apoints);
|
||||
void day_free_list(void);
|
||||
int day_store_recur_events(long date);
|
||||
int day_store_events(long date);
|
||||
int day_store_recur_apoints(long date);
|
||||
int day_store_apoints(long date);
|
||||
struct day_item_s *day_add_event(int type, char *mesg, long day, int id);
|
||||
struct day_item_s *day_add_apoint(int type, char *mesg, long start, long dur);
|
||||
void day_write_pad(long date, int width, int length, int incolor, int colr);
|
||||
struct apoint_s *day_item_s2apoint_s(struct day_item_s *p);
|
||||
void day_popup_item(void);
|
||||
int day_check_if_item(int year, int month, int day);
|
||||
|
||||
#endif /* CALCURSE_DAY_H */
|
||||
135
src/event.c
Executable file
135
src/event.c
Executable file
@@ -0,0 +1,135 @@
|
||||
/* $calcurse: event.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "event.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct event_s *eventlist;
|
||||
|
||||
/* Create a new event */
|
||||
struct event_s *event_new(char *mesg, long day, int id)
|
||||
{
|
||||
struct event_s *o, **i;
|
||||
o = (struct event_s *) malloc(sizeof(struct event_s));
|
||||
o->mesg = (char *) malloc(strlen(mesg) + 1);
|
||||
strcpy(o->mesg, mesg);
|
||||
o->day = day;
|
||||
o->id = id;
|
||||
i = &eventlist;
|
||||
for (;;) {
|
||||
if (*i == 0 || (*i)->day > day) {
|
||||
o->next = *i;
|
||||
*i = o;
|
||||
break;
|
||||
}
|
||||
i = &(*i)->next;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/* Check if the event belongs to the selected day */
|
||||
unsigned event_inday(struct event_s *i, long start)
|
||||
{
|
||||
if (i->day <= start + 3600 * 24 && i->day > start) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write to file the event in user-friendly format */
|
||||
void event_write(struct event_s *o, FILE * f)
|
||||
{
|
||||
struct tm *lt;
|
||||
time_t t;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* Load the events from file */
|
||||
struct event_s *event_scan(FILE * f, struct tm start, int id)
|
||||
{
|
||||
struct tm *lt;
|
||||
char buf[MESG_MAXSIZE], *nl;
|
||||
time_t tstart, t;
|
||||
|
||||
t = time(NULL);
|
||||
lt = localtime(&t);
|
||||
|
||||
/* Read the event description */
|
||||
fgets(buf, MESG_MAXSIZE, f);
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl) {
|
||||
*nl = '\0';
|
||||
}
|
||||
start.tm_hour = 12;
|
||||
start.tm_min = 0;
|
||||
start.tm_sec = 0;
|
||||
start.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
|
||||
tstart = mktime(&start);
|
||||
if (tstart == -1) {
|
||||
fputs(_("FATAL ERROR in event_scan: date error in the event\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return event_new(buf, tstart, id);
|
||||
}
|
||||
|
||||
/* Delete an event from the list */
|
||||
void event_delete_bynum(long start, unsigned num)
|
||||
{
|
||||
unsigned n;
|
||||
struct event_s *i, **iptr;
|
||||
|
||||
n = 0;
|
||||
iptr = &eventlist;
|
||||
for (i = eventlist; i != 0; i = i->next) {
|
||||
if (event_inday(i, start)) {
|
||||
if (n == num) {
|
||||
*iptr = i->next;
|
||||
free(i->mesg);
|
||||
free(i);
|
||||
return;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
iptr = &i->next;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
fputs(_("FATAL ERROR in event_delete_bynum: no such event\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
48
src/event.h
Executable file
48
src/event.h
Executable file
@@ -0,0 +1,48 @@
|
||||
/* $calcurse: event.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_EVENT_H
|
||||
#define CALCURSE_EVENT_H
|
||||
|
||||
#define HRMIN_SIZE 6
|
||||
#define MESG_MAXSIZE 256
|
||||
|
||||
struct event_s {
|
||||
struct event_s *next;
|
||||
int id; /* event identifier */
|
||||
long day; /* seconds since 1 jan 1970 */
|
||||
char *mesg;
|
||||
};
|
||||
|
||||
extern struct event_s *eventlist;
|
||||
|
||||
struct event_s *event_new(char *, long, int);
|
||||
unsigned event_inday(struct event_s *o, long start);
|
||||
void event_write(struct event_s *o, FILE * f);
|
||||
struct event_s *event_scan(FILE * f, struct tm start, int id);
|
||||
void event_delete_bynum(long start, unsigned num);
|
||||
|
||||
#endif /* CALCURSE_EVENT_H */
|
||||
375
src/help.c
Executable file
375
src/help.c
Executable file
@@ -0,0 +1,375 @@
|
||||
/* $calcurse: help.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "help.h"
|
||||
#include "custom.h"
|
||||
#include "vars.h"
|
||||
#include "utils.h"
|
||||
|
||||
/*
|
||||
* Write the desired help text inside the help pad, and return the number
|
||||
* of lines that were written.
|
||||
* */
|
||||
int write_help_pad(WINDOW *win, char *title, char *text, int pad_width)
|
||||
{
|
||||
int nl_title = 0;
|
||||
int nl_text = 0;
|
||||
|
||||
nl_text = get_help_lines(text);
|
||||
nl_title = get_help_lines(title);
|
||||
erase_window_part(win, 0, 0, MAX_LENGTH, pad_width);
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
mvwprintw(win, 0, 0, "%s", title);
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
mvwprintw(win, nl_title, 0, "%s", text);
|
||||
return nl_text + nl_title;
|
||||
}
|
||||
|
||||
int get_help_lines(char *text)
|
||||
{
|
||||
int i;
|
||||
int nl = 0;
|
||||
|
||||
for (i = 0; text[i]; i++) {
|
||||
if (text[i] == '\n') nl++;
|
||||
}
|
||||
return nl + 1;
|
||||
}
|
||||
|
||||
/* Draws the help screen */
|
||||
void help_screen(int which_pan, int colr)
|
||||
{
|
||||
WINDOW *help_win = NULL;
|
||||
WINDOW *help_pad = NULL;
|
||||
char label[80];
|
||||
int ch = '?';
|
||||
int help_row = row - 2; //size of the help window
|
||||
int help_col = col;
|
||||
int title_lines = 3;
|
||||
int pad_offset = 4;
|
||||
int text_lines = help_row - (pad_offset + 1);
|
||||
int pad_width = help_col - 2*pad_offset + 1;
|
||||
int first_line = 0, nl = 0;
|
||||
|
||||
help_page_t help_main;
|
||||
help_page_t help_redraw;
|
||||
help_page_t help_save;
|
||||
help_page_t help_displacement;
|
||||
help_page_t help_view;
|
||||
help_page_t help_tab;
|
||||
help_page_t help_goto;
|
||||
help_page_t help_delete;
|
||||
help_page_t help_add;
|
||||
help_page_t help_config;
|
||||
help_page_t help_credits;
|
||||
|
||||
help_main.title =
|
||||
_(" Welcome to Calcurse. This is the main help screen.\n");
|
||||
help_main.text =
|
||||
_(" Moving around: Press CTRL-P or CTRL-N to scroll text upward or\n"
|
||||
" downward inside help screens, if necessary.\n\n"
|
||||
" Exit help: When finished, press 'Q' to exit help and go back\n"
|
||||
" to the main Calcurse screen.\n\n"
|
||||
" Help topic: At the bottom of this screen you can see a panel\n"
|
||||
" with different fields, represented by a letter and\n"
|
||||
" a short title. This panel contains all the available\n"
|
||||
" actions you can perform when using Calcurse.\n"
|
||||
" By pressing one of the letters appearing in this\n"
|
||||
" panel, you will be shown a short description of the\n"
|
||||
" corresponding action.\n\n"
|
||||
" Credits: Press '@' for credits.");
|
||||
|
||||
help_redraw.title = _("Redraw:\n");
|
||||
help_redraw.text =
|
||||
_("Pressing 'R' redraws the Calcurse panels.\n\n"
|
||||
"You might want to use this function when you resize your terminal\n"
|
||||
"screen for example, and you want Calcurse to take into account the new\n"
|
||||
"size of the terminal.\n\n"
|
||||
"This function can also be useful when garbage appears in the display,\n"
|
||||
"and you want to clean it.");
|
||||
|
||||
help_save.title = _("Save:\n");
|
||||
help_save.text =
|
||||
_("Pressing 'S' saves the Calcurse data.\n\n"
|
||||
"The data is splitted into three different files which contains :"
|
||||
"\n\n"
|
||||
" / ~/.calcurse/conf -> the user configuration\n"
|
||||
" | (layout, color, general options)\n"
|
||||
" | ~/.calcurse/apts -> the data related to the appointments\n"
|
||||
" \\ ~/.calcurse/todo -> the data related to the todo list\n"
|
||||
"\nIn the config menu, you can choose to save the Calcurse data\n"
|
||||
"automatically before quitting.");
|
||||
|
||||
help_displacement.title = _("Displacement keys:\n");
|
||||
help_displacement.text =
|
||||
_("You can use either 'H','J','K','L' or the arrow keys '<','v','^','>'\n"
|
||||
"to move into the calendar.\n\n"
|
||||
"The following scheme explains how :\n\n"
|
||||
" move to previous week\n"
|
||||
" K ^ \n"
|
||||
" move to previous day H < > L move to next day\n"
|
||||
" J v \n"
|
||||
" move to next week\n"
|
||||
"\nWhen the Appointment or ToDo panel is selected, the up and down keys\n"
|
||||
"(respectively K or up arrow, and J or down arrow) allows you to select\n"
|
||||
"an item from those lists.");
|
||||
|
||||
help_view.title = _("View:\n");
|
||||
help_view.text =
|
||||
_("Pressing 'V' allows you to view the item you select in either the ToDo\n"
|
||||
"or Appointment panel.\n"
|
||||
"\nThis is usefull when an event description is longer than the available\n"
|
||||
"space to display it. If that is the case, the description will be\n"
|
||||
"shortened and its end replaced by '...'. To be able to read the entire\n"
|
||||
"description, just press 'V' and a popup window will appear, containing\n"
|
||||
"the whole event.\n"
|
||||
"\nPress any key to close the popup window and go back to the main\n"
|
||||
"Calcurse screen.");
|
||||
|
||||
help_tab.title = _("Tab:\n");
|
||||
help_tab.text =
|
||||
_("Pressing 'Tab' allows you to switch between panels.\n"
|
||||
"The panel currently in use has its border colorized.\n"
|
||||
"\nSome actions are possible only if the right panel is selected.\n"
|
||||
"For example, if you want to add a task in the TODO list, you need first\n"
|
||||
"to press the 'Tab' key to get the TODO panel selected. Then you can\n"
|
||||
"press 'A' to add your item.\n"
|
||||
"\nNotice that at the bottom of the screen the list of possible actions\n"
|
||||
"change while pressing 'Tab', so you always know what action can be\n"
|
||||
"performed on the selected panel.");
|
||||
|
||||
help_goto.title = _("Goto:\n");
|
||||
help_goto.text =
|
||||
_("Pressing 'G' allows you to jump to a specific day in the calendar.\n"
|
||||
"\nUsing this command, you do not need to travel to that day using\n"
|
||||
"the displacement keys inside the calendar panel.\n"
|
||||
"If you hit [ENTER] without specifying any date, Calcurse checks the\n"
|
||||
"system current date and you will be taken to that date.");
|
||||
|
||||
help_delete.title = _("Delete:\n");
|
||||
help_delete.text =
|
||||
_("Pressing 'D' deletes an element in the ToDo or Appointment list.\n"
|
||||
"\nDepending on which panel is selected when you press the delete key,\n"
|
||||
"the hilighted item of either the ToDo or Appointment list will be \n"
|
||||
"removed from this list.\n"
|
||||
"\nIf the general option 'confirm_delete' is set to 'YES', then you will\n"
|
||||
"be asked for confirmation before deleting the selected event.\n"
|
||||
"Do not forget to save the calendar data to retrieve the modifications\n"
|
||||
"next time you launch Calcurse.");
|
||||
|
||||
help_add.title = _("Add:\n");
|
||||
help_add.text =
|
||||
_("Pressing 'A' allows you to add an item in either the ToDo or Appointment\n"
|
||||
"list, depending on which panel is selected when you press 'A'.\n"
|
||||
"\nTo enter a new item in the TODO list, you only need to enter the\n"
|
||||
"description of this new item.\n"
|
||||
"\nIf the APPOINTMENT panel is selected while pressing 'A', you will be\n"
|
||||
"able to enter either a new appointment or a new all-day long event.\n"
|
||||
"To enter a new event, press [ENTER] instead of the item start time, and\n"
|
||||
"just fill in the event description.\n"
|
||||
"To enter a new appointment to be added in the APPOINTMENT list, you\n"
|
||||
"will need to enter successively the time at which the appointment\n"
|
||||
"begins, the appointment length (either by specifying the duration in\n"
|
||||
"minutes, or the end time in [hh:mm] or [h:mm] format), and the\n"
|
||||
"description of the event.\n"
|
||||
"\nThe day at which occurs the event or appointment is the day currently\n"
|
||||
"selected in the calendar, so you need to move to the desired day before\n"
|
||||
"pressing 'A'.\n"
|
||||
"\nNotes:\n"
|
||||
" o if an appointment lasts for such a long time that it continues\n"
|
||||
" on the next days, this event will be indicated on all the\n"
|
||||
" corresponding days, and the beginning or ending hour will be\n"
|
||||
" replaced by '..' if the event does not begin or end on the day.\n"
|
||||
" o if you only press [ENTER] at the APPOINTMENT or TODO event\n"
|
||||
" description prompt, without any description, no item will be\n"
|
||||
" added.\n"
|
||||
" o do not forget to save the calendar data to retrieve the new\n"
|
||||
" event next time you launch Calcurse.");
|
||||
|
||||
help_config.title = _("Config:\n");
|
||||
help_config.text =
|
||||
_("Pressing 'C' leads to the configuration submenu, from which you can\n"
|
||||
"select between color, layout, and general options.\n"
|
||||
"\nThe color submenu lets you choose the color theme.\n"
|
||||
"\nThe layout submenu lets you choose the Calcurse screen layout, in other\n"
|
||||
"words where to place the three different panels on the screen.\n"
|
||||
"\nThe general options submenu brings a screen with the different options\n"
|
||||
"which modifies the way Calcurse interacts with the user.\n"
|
||||
"\nDo not forget to save the calendar data to retrieve your configuration\n"
|
||||
"next time you launch Calcurse.");
|
||||
|
||||
help_credits.title = _("Calcurse - text-based organizer");
|
||||
help_credits.text =
|
||||
_("Copyright (c) 2004-2006 Frederic Culot\n"
|
||||
"\n"
|
||||
"This program is free software; you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation; either version 2 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\nThis program is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n\n"
|
||||
"Send your feedback or comments to : calcurse@culot.org\n"
|
||||
"Calcurse home page : http://culot.org/calcurse");
|
||||
|
||||
/*
|
||||
* Create the help window and panel. The panel is used to make
|
||||
* the scrolling faster.
|
||||
*/
|
||||
help_win = newwin(help_row, help_col, 0, 0);
|
||||
help_pad = newpad(MAX_LENGTH, pad_width);
|
||||
box(help_win, 0, 0);
|
||||
sprintf(label, _("CalCurse %s | help"), VERSION);
|
||||
win_show(help_win, label);
|
||||
|
||||
/* Display the main help screen. */
|
||||
/* nl = write_help_pad(help_pad, help_main.title, help_main.text, pad_width);
|
||||
status_bar(which_pan, colr, col, 2);
|
||||
wmove(swin, 0, 0);
|
||||
wnoutrefresh(help_win);
|
||||
pnoutrefresh(help_pad, first_line, 0, pad_offset, pad_offset,
|
||||
help_row - 2, help_col - pad_offset);
|
||||
doupdate();
|
||||
*/
|
||||
|
||||
/* Display the help screen related to user input. */
|
||||
while ( ch != 'q' ) {
|
||||
erase_window_part(help_win, 1, title_lines,
|
||||
help_col - 2, help_row - 2);
|
||||
|
||||
switch (ch) {
|
||||
|
||||
case CTRL('N') :
|
||||
if (nl > first_line + text_lines) first_line++;
|
||||
break;
|
||||
|
||||
case CTRL('P') :
|
||||
if (first_line > 0) first_line--;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_main.title,
|
||||
help_main.text, pad_width);
|
||||
break;
|
||||
case 'r':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_redraw.title,
|
||||
help_redraw.text, pad_width);
|
||||
break;
|
||||
case 's':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_save.title,
|
||||
help_save.text, pad_width);
|
||||
break;
|
||||
case 'h':
|
||||
case 'l':
|
||||
case 'j':
|
||||
case 'k':
|
||||
case 259:
|
||||
case 258:
|
||||
case 260:
|
||||
case 261:
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_displacement.title,
|
||||
help_displacement.text, pad_width);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_add.title,
|
||||
help_add.text, pad_width);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_goto.title,
|
||||
help_goto.text, pad_width);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_delete.title,
|
||||
help_delete.text, pad_width);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_config.title,
|
||||
help_config.text, pad_width);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_view.title,
|
||||
help_view.text, pad_width);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_tab.title,
|
||||
help_tab.text, pad_width);
|
||||
break;
|
||||
|
||||
case '@':
|
||||
first_line = 0;
|
||||
nl = write_help_pad(help_pad, help_credits.title,
|
||||
help_credits.text, pad_width);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Draw the scrollbar if necessary. */
|
||||
if (nl > text_lines){
|
||||
float ratio = ((float) text_lines + 1) / ((float) nl);
|
||||
int sbar_length = (int) (ratio * text_lines);
|
||||
int highend = (int) (ratio * first_line);
|
||||
int sbar_top = highend + title_lines + 1;
|
||||
|
||||
draw_scrollbar(help_win, sbar_top, help_col - 2,
|
||||
sbar_length, title_lines + 1,
|
||||
help_row - 1, true);
|
||||
}
|
||||
|
||||
wmove(swin, 0, 0);
|
||||
wnoutrefresh(help_win);
|
||||
pnoutrefresh(help_pad, first_line, 0,
|
||||
pad_offset, pad_offset,
|
||||
help_row - 2, help_col - pad_offset);
|
||||
doupdate();
|
||||
ch = wgetch(swin);
|
||||
}
|
||||
delwin(help_pad);
|
||||
delwin(help_win);
|
||||
}
|
||||
41
src/help.h
Executable file
41
src/help.h
Executable file
@@ -0,0 +1,41 @@
|
||||
/* $calcurse: help.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_HELP_H
|
||||
#define CALCURSE_HELP_H
|
||||
|
||||
#include <ncurses.h>
|
||||
|
||||
typedef struct {
|
||||
char *title;
|
||||
char *text;
|
||||
} help_page_t;
|
||||
|
||||
int write_help_pad(WINDOW *win, char *title, char *text, int pad_width);
|
||||
int get_help_lines(char *text);
|
||||
void help_screen(int which_pan, int colr);
|
||||
|
||||
#endif /* CALCURSE_HELP_H */
|
||||
54
src/i18n.h
Executable file
54
src/i18n.h
Executable file
@@ -0,0 +1,54 @@
|
||||
/* $calcurse: i18n.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_I18N_H
|
||||
#define CALCURSE_I18N_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#if ENABLE_NLS
|
||||
#include <libintl.h>
|
||||
#undef _
|
||||
#define _(String) gettext(String)
|
||||
#ifdef gettext_noop
|
||||
#define N_(String) gettext_noop(String)
|
||||
#else
|
||||
#define N_(String) (String)
|
||||
#endif
|
||||
#else /* NLS disabled */
|
||||
#define _(String) (String)
|
||||
#define N_(String) (String)
|
||||
#define textdomain(String) (String)
|
||||
#define gettext(String) (String)
|
||||
#define dgettext(String) (String)
|
||||
#define dcgettext(String) (String)
|
||||
#define bindtextdomain(String) (String)
|
||||
#define bind_textdomain_codeset(Domain,Codeset) (Codeset)
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#endif /* CALCURSE_I18N_H */
|
||||
484
src/io.c
Executable file
484
src/io.c
Executable file
@@ -0,0 +1,484 @@
|
||||
/* $calcurse: io.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "utils.h"
|
||||
#include "custom.h"
|
||||
#include "todo.h"
|
||||
#include "event.h"
|
||||
#include "apoint.h"
|
||||
#include "recur.h"
|
||||
#include "io.h"
|
||||
#include "vars.h"
|
||||
|
||||
/*
|
||||
* Initialization of data paths. The argument cfile is the variable
|
||||
* which contains the calendar file. If none is given, then the default
|
||||
* one (~/.calcurse/apts) is taken. If the one given does not exist, it
|
||||
* is created.
|
||||
*/
|
||||
void
|
||||
io_init(char *cfile)
|
||||
{
|
||||
FILE *data_file;
|
||||
char *home;
|
||||
char apts_file[MAX_LENGTH] = "";
|
||||
int ch;
|
||||
|
||||
home = getenv("HOME");
|
||||
if (home == NULL) {
|
||||
home = ".";
|
||||
}
|
||||
snprintf(path_dir, MAX_LENGTH, "%s/" DIR_NAME, home);
|
||||
snprintf(path_todo, MAX_LENGTH, "%s/" TODO_PATH, home);
|
||||
snprintf(path_conf, MAX_LENGTH, "%s/" CONF_PATH, home);
|
||||
if (cfile == NULL) {
|
||||
snprintf(path_apts, MAX_LENGTH, "%s/" APTS_PATH, home);
|
||||
} else {
|
||||
snprintf(apts_file, MAX_LENGTH, "%s", cfile);
|
||||
strncpy(path_apts, apts_file, MAX_LENGTH);
|
||||
/* check if the file exists, otherwise create it */
|
||||
data_file = fopen(path_apts, "r");
|
||||
if (data_file == NULL) {
|
||||
printf(_("%s does not exist, create it now [y or n] ? "), path_apts);
|
||||
ch = getchar();
|
||||
switch (ch) {
|
||||
case 'N':
|
||||
case 'n':
|
||||
printf(_("aborting...\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
case 'y':
|
||||
data_file = fopen(path_apts, "w");
|
||||
if (data_file == NULL) {
|
||||
perror(path_apts);
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
printf(_("%s successfully created\n"),path_apts);
|
||||
printf(_("starting interactive mode...\n"));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf(_("aborting...\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(data_file);
|
||||
}
|
||||
}
|
||||
|
||||
/* get data from file */
|
||||
void extract_data(char *dst_data, const char *org, int len)
|
||||
{
|
||||
for (;;) {
|
||||
if (*org == '\n' || *org == '\0')
|
||||
break;
|
||||
*dst_data++ = *org++;
|
||||
}
|
||||
*dst_data = '\0';
|
||||
}
|
||||
|
||||
/* Save the calendar data */
|
||||
void
|
||||
save_cal(bool auto_save, bool confirm_quit,
|
||||
bool confirm_delete, bool skip_system_dialogs,
|
||||
bool skip_progress_bar, bool week_begins_on_monday,
|
||||
int colr, int layout)
|
||||
{
|
||||
FILE *data_file;
|
||||
struct event_s *k;
|
||||
struct apoint_s *j;
|
||||
struct todo_s *i;
|
||||
char *access_pb = _("Problems accessing data file ...");
|
||||
char *config_txt =
|
||||
"#\n# Calcurse configuration file\n#\n# This file sets the configuration options used by Calcurse. These\n# options are usually set from within Calcurse. A line beginning with \n# a space or tab is considered to be a continuation of the previous line.\n# For a variable to be unset its value must be blank.\n# To set a variable to the empty string its value should be \"\".\n# Lines beginning with \"#\" are comments, and ignored by Calcurse.\n";
|
||||
char *save_success = _("The data files were successfully saved");
|
||||
char *enter = _("Press [ENTER] to continue");
|
||||
bool save = true, show_bar = false;
|
||||
|
||||
if (!skip_progress_bar) show_bar = true;
|
||||
|
||||
/* Save the user configuration. */
|
||||
|
||||
if (show_bar) progress_bar(save, 1);
|
||||
data_file = fopen(path_conf, "w");
|
||||
if (data_file == (FILE *) 0)
|
||||
status_mesg(access_pb, "");
|
||||
else {
|
||||
fprintf(data_file, "%s\n", config_txt);
|
||||
|
||||
fprintf(data_file,
|
||||
"# If this option is set to yes, automatic save is done when quitting\n");
|
||||
fprintf(data_file, "auto_save=\n");
|
||||
fprintf(data_file, "%s\n",
|
||||
(auto_save) ? "yes" : "no");
|
||||
|
||||
fprintf(data_file,
|
||||
"\n# If this option is set to yes, confirmation is required before quitting\n");
|
||||
fprintf(data_file, "confirm_quit=\n");
|
||||
fprintf(data_file, "%s\n",
|
||||
(confirm_quit) ? "yes" : "no");
|
||||
|
||||
fprintf(data_file,
|
||||
"\n# If this option is set to yes, confirmation is required before deleting an event\n");
|
||||
fprintf(data_file, "confirm_delete=\n");
|
||||
fprintf(data_file, "%s\n",
|
||||
(confirm_delete) ? "yes" : "no");
|
||||
|
||||
fprintf(data_file,
|
||||
"\n# If this option is set to yes, messages about loaded and saved data will not be displayed\n");
|
||||
fprintf(data_file, "skip_system_dialogs=\n");
|
||||
fprintf(data_file, "%s\n",
|
||||
(skip_system_dialogs) ? "yes" : "no");
|
||||
|
||||
fprintf(data_file,
|
||||
"\n# If this option is set to yes, progress bar appearing when saving data will not be displayed\n");
|
||||
fprintf(data_file, "skip_progress_bar=\n");
|
||||
fprintf(data_file, "%s\n",
|
||||
(skip_progress_bar) ? "yes" : "no");
|
||||
|
||||
fprintf(data_file,
|
||||
"\n# If this option is set to yes, monday is the first day of the week, else it is sunday\n");
|
||||
fprintf(data_file, "week_begins_on_monday=\n");
|
||||
fprintf(data_file, "%s\n",
|
||||
(week_begins_on_monday) ? "yes" : "no");
|
||||
|
||||
fprintf(data_file,
|
||||
"\n# This is the color theme used for menus (1 to 8) :\n");
|
||||
fprintf(data_file, "color-theme=\n");
|
||||
fprintf(data_file, "%d\n", colr);
|
||||
|
||||
fprintf(data_file,
|
||||
"\n# This is the layout of the calendar (1 to 4) :\n");
|
||||
fprintf(data_file, "layout=\n");
|
||||
fprintf(data_file, "%d\n", layout);
|
||||
fclose(data_file);
|
||||
}
|
||||
|
||||
/* Save the todo data file. */
|
||||
if (show_bar) progress_bar(save, 2);
|
||||
data_file = fopen(path_todo, "w");
|
||||
if (data_file == (FILE *) 0)
|
||||
status_mesg(access_pb, "");
|
||||
else {
|
||||
for (i = todolist; i != 0; i = i->next)
|
||||
fprintf(data_file, "%s\n", i->mesg);
|
||||
fclose(data_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the apts data file, which contains the
|
||||
* appointments first, and then the events.
|
||||
* Recursive items are written first.
|
||||
*/
|
||||
if (show_bar) progress_bar(save, 3);
|
||||
data_file = fopen(path_apts, "w");
|
||||
if (data_file == (FILE *) 0)
|
||||
status_mesg(access_pb, "");
|
||||
else {
|
||||
recur_save_data(data_file);
|
||||
for (j = apointlist; j != 0; j = j->next)
|
||||
apoint_write(j, data_file);
|
||||
for (k = eventlist; k != 0; k = k->next)
|
||||
event_write(k, data_file);
|
||||
fclose(data_file);
|
||||
}
|
||||
|
||||
|
||||
/* Print a message telling data were saved */
|
||||
if (!skip_system_dialogs){
|
||||
status_mesg(save_success, enter);
|
||||
wgetch(swin);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check what type of data is written in the appointment file,
|
||||
* and then load either: a new appointment, a new event, or a new
|
||||
* recursive item (which can also be either an event or an appointment).
|
||||
*/
|
||||
void load_app()
|
||||
{
|
||||
FILE *data_file;
|
||||
int c, is_appointment, is_event, is_recursive;
|
||||
struct tm start, end, until, *lt;
|
||||
time_t t;
|
||||
int id = 0;
|
||||
int freq;
|
||||
char type;
|
||||
char *error =
|
||||
_("FATAL ERROR in load_app: wrong format in the appointment or event\n");
|
||||
|
||||
t = time(NULL);
|
||||
lt = localtime(&t);
|
||||
start = end = until = *lt;
|
||||
|
||||
data_file = fopen(path_apts, "r");
|
||||
for (;;) {
|
||||
is_appointment = is_event = is_recursive = 0;
|
||||
c = getc(data_file);
|
||||
if (c == EOF)
|
||||
break;
|
||||
ungetc(c, data_file);
|
||||
|
||||
/* Read the date first: it is common to both events
|
||||
* and appointments.
|
||||
*/
|
||||
if (fscanf(data_file, "%u / %u / %u ",
|
||||
&start.tm_mon, &start.tm_mday, &start.tm_year) != 3) {
|
||||
fputs(_("FATAL ERROR in load_app: "
|
||||
"syntax error in the item date\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Read the next character : if it is an '@' then we have
|
||||
* an appointment, else if it is an '[' we have en event.
|
||||
*/
|
||||
c = getc(data_file);
|
||||
|
||||
if (c == '@')
|
||||
is_appointment = 1;
|
||||
else if (c == '[')
|
||||
is_event = 1;
|
||||
else {
|
||||
fputs(_("FATAL ERROR in load_app: "
|
||||
"no event nor appointment found\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
ungetc(c, data_file);
|
||||
|
||||
/* Read the remaining informations. */
|
||||
if (is_appointment) {
|
||||
fscanf(data_file, "@ %u : %u -> %u / %u / %u @ %u : %u ",
|
||||
&start.tm_hour, &start.tm_min,
|
||||
&end.tm_mon, &end.tm_mday, &end.tm_year,
|
||||
&end.tm_hour, &end.tm_min);
|
||||
} else if (is_event) {
|
||||
fscanf(data_file, "[%d] ", &id);
|
||||
} else { /* NOT REACHED */
|
||||
fputs(error, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Check if we have a recursive item. */
|
||||
c = getc(data_file);
|
||||
|
||||
if (c == '{') {
|
||||
ungetc(c, data_file);
|
||||
is_recursive = 1;
|
||||
fscanf(data_file, "{ %d%c ", &freq, &type);
|
||||
/* Check if we have an endless recurrent item. */
|
||||
c = getc(data_file);
|
||||
if (c == '}') {
|
||||
ungetc(c, data_file);
|
||||
fscanf(data_file, "} ");
|
||||
until.tm_year = 0;
|
||||
if (is_appointment)
|
||||
c = getc(data_file); // useless '|'
|
||||
} else if (c == '-') {
|
||||
ungetc(c, data_file);
|
||||
fscanf(data_file, " -> %u / %u / %u } ",
|
||||
&until.tm_mon, &until.tm_mday,
|
||||
&until.tm_year);
|
||||
if (is_appointment)
|
||||
c = getc(data_file); // useless '|'
|
||||
} else { /* NOT REACHED */
|
||||
fputs(error, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
if (is_event) // if appointment we have a useless '|'
|
||||
ungetc(c, data_file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Last: read the item description and load it into its
|
||||
* corresponding linked list, depending on the item type.
|
||||
*/
|
||||
if (is_appointment) {
|
||||
if (is_recursive) {
|
||||
recur_apoint_scan(data_file, start, end,
|
||||
type, freq, until);
|
||||
} else {
|
||||
apoint_scan(data_file, start, end);
|
||||
}
|
||||
} else if (is_event) {
|
||||
if (is_recursive) {
|
||||
recur_event_scan(data_file, start, id,
|
||||
type, freq, until);
|
||||
} else {
|
||||
event_scan(data_file, start, id);
|
||||
}
|
||||
} else { /* NOT REACHED */
|
||||
fputs(error, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
fclose(data_file);
|
||||
}
|
||||
|
||||
/* Load the todo data */
|
||||
int
|
||||
load_todo(int colr)
|
||||
{
|
||||
FILE *data_file;
|
||||
char *mesg_line1 = _("Failed to open todo file");
|
||||
char *mesg_line2 = _("Press [ENTER] to continue");
|
||||
int nb_tod = 0;
|
||||
char buf[100], e_todo[100];
|
||||
|
||||
data_file = fopen(path_todo, "r");
|
||||
if (data_file == NULL) {
|
||||
status_mesg(mesg_line1, mesg_line2);
|
||||
wgetch(swin);
|
||||
}
|
||||
for (;;) {
|
||||
if (fgets(buf, 99, data_file) == NULL) {
|
||||
break;
|
||||
}
|
||||
extract_data(e_todo, buf, strlen(buf));
|
||||
todo_add(e_todo);
|
||||
++nb_tod;
|
||||
}
|
||||
fclose(data_file);
|
||||
return nb_tod;
|
||||
}
|
||||
|
||||
/* Checks if data files exist. If not, create them */
|
||||
int check_data_files()
|
||||
{
|
||||
FILE *data_file;
|
||||
int no_data_file;
|
||||
|
||||
no_data_file = 0;
|
||||
/* Create the calcurse repertory if not present. */
|
||||
mkdir(path_dir, 0700);
|
||||
|
||||
data_file = fopen(path_todo, "r");
|
||||
if (data_file == NULL) {
|
||||
no_data_file++;
|
||||
data_file = fopen(path_todo, "w");
|
||||
if (data_file == NULL) {
|
||||
perror(path_todo);
|
||||
return no_data_file;
|
||||
}
|
||||
}
|
||||
fclose(data_file);
|
||||
|
||||
data_file = fopen(path_apts, "r");
|
||||
if (data_file == NULL) {
|
||||
no_data_file++;
|
||||
data_file = fopen(path_apts, "w");
|
||||
if (data_file == NULL) {
|
||||
perror(path_apts);
|
||||
return no_data_file;
|
||||
}
|
||||
}
|
||||
fclose(data_file);
|
||||
|
||||
data_file = fopen(path_conf, "r");
|
||||
if (data_file == NULL) {
|
||||
no_data_file++;
|
||||
data_file = fopen(path_conf, "w");
|
||||
if (data_file == NULL) {
|
||||
perror(path_conf);
|
||||
return no_data_file;
|
||||
}
|
||||
}
|
||||
fclose(data_file);
|
||||
return no_data_file;
|
||||
}
|
||||
|
||||
/* Draw the startup screen */
|
||||
void startup_screen(bool skip_dialogs, int no_data_file, int colr)
|
||||
{
|
||||
char *welcome_mesg = _("Welcome to Calcurse. Missing data files were created.");
|
||||
char *data_mesg = _("Data files found. Data will be loaded now.");
|
||||
char *enter = _("Press [ENTER] to continue");
|
||||
|
||||
if (no_data_file != 0) {
|
||||
status_mesg(welcome_mesg, enter);
|
||||
wgetch(swin);
|
||||
} else if (!skip_dialogs){
|
||||
status_mesg(data_mesg, enter);
|
||||
wgetch(swin);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw a progress bar while saving or loading data. */
|
||||
void progress_bar(bool save, int progress)
|
||||
{
|
||||
int i, nbd = 4;
|
||||
char *mesg_sav = _("Saving...");
|
||||
char *mesg_load = _("Loading...");
|
||||
char *barchar = "|";
|
||||
char *data[4] = {
|
||||
"[ ]",
|
||||
"[ conf ]",
|
||||
"[ todo ]",
|
||||
"[ apts ]"};
|
||||
int ipos = strlen(data[1]) + 2;
|
||||
int epos[4];
|
||||
int sleep_time = 125000;
|
||||
|
||||
/* progress bar length init. */
|
||||
epos[0] = floor(col / nbd);
|
||||
epos[1] = 2*epos[0];
|
||||
epos[2] = 3*epos[0];
|
||||
epos[3] = col - 2;
|
||||
|
||||
/* Display which data is being saved. */
|
||||
if (save)
|
||||
status_mesg(mesg_sav, data[progress]);
|
||||
else
|
||||
status_mesg(mesg_load, data[progress]);
|
||||
|
||||
/* Draw the progress bar. */
|
||||
mvwprintw(swin, 1, ipos, barchar);
|
||||
mvwprintw(swin, 1, epos[nbd - 1], barchar);
|
||||
custom_apply_attr(swin, ATTR_HIGHEST);
|
||||
for (i = ipos + 1; i < epos[progress]; i++)
|
||||
mvwaddch(swin, 1, i, ' ' | A_REVERSE);
|
||||
custom_remove_attr(swin, ATTR_HIGHEST);
|
||||
wmove(swin, 0, 0);
|
||||
wrefresh(swin);
|
||||
usleep(sleep_time);
|
||||
}
|
||||
42
src/io.h
Executable file
42
src/io.h
Executable file
@@ -0,0 +1,42 @@
|
||||
/* $calcurse: io.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_IO_H
|
||||
#define CALCURSE_IO_H
|
||||
|
||||
void io_init(char *cfile);
|
||||
void extract_data(char *dst_data, const char *org, int len);
|
||||
void save_cal(bool auto_save, bool confirm_quit,
|
||||
bool confirm_delete, bool skip_system_dialogs,
|
||||
bool skip_progress_bar, bool week_begins_on_monday,
|
||||
int colr, int layout);
|
||||
void load_app();
|
||||
int load_todo(int colr);
|
||||
int check_data_files();
|
||||
void startup_screen(bool skip_dialogs, int no_data_file, int colr);
|
||||
void progress_bar(bool save, int progress);
|
||||
|
||||
#endif /* CALCURSE_IO_H */
|
||||
355
src/recur.c
Executable file
355
src/recur.c
Executable file
@@ -0,0 +1,355 @@
|
||||
/* $calcurse: recur.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "utils.h"
|
||||
#include "apoint.h"
|
||||
#include "event.h"
|
||||
#include "recur.h"
|
||||
|
||||
struct recur_apoint_s *recur_alist;
|
||||
struct recur_event_s *recur_elist;
|
||||
|
||||
/* Insert a new recursive appointment in the general linked list */
|
||||
struct recur_apoint_s *recur_apoint_new(char *mesg, long start, long dur,
|
||||
int type, int freq, long until)
|
||||
{
|
||||
struct recur_apoint_s *o, **i;
|
||||
o = (struct recur_apoint_s *) malloc(sizeof(struct recur_apoint_s));
|
||||
o->rpt = (struct rpt_s *) malloc(sizeof(struct rpt_s));
|
||||
o->exc = (struct days_s *) malloc(sizeof(struct days_s));
|
||||
o->mesg = (char *) malloc(strlen(mesg) + 1);
|
||||
strcpy(o->mesg, mesg);
|
||||
o->start = start;
|
||||
o->dur = dur;
|
||||
o->rpt->type = type;
|
||||
o->rpt->freq = freq;
|
||||
o->rpt->until = until;
|
||||
i = &recur_alist;
|
||||
for (;;) {
|
||||
if (*i == 0 || (*i)->start > start) {
|
||||
o->next = *i;
|
||||
*i = o;
|
||||
break;
|
||||
}
|
||||
i = &(*i)->next;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 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 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->exc = (struct days_s *) malloc(sizeof(struct days_s));
|
||||
o->mesg = (char *) malloc(strlen(mesg) + 1);
|
||||
strcpy(o->mesg, mesg);
|
||||
o->day = day;
|
||||
o->id = id;
|
||||
o->rpt->type = type;
|
||||
o->rpt->freq = freq;
|
||||
o->rpt->until = until;
|
||||
i = &recur_elist;
|
||||
for (;;) {
|
||||
if (*i == 0 || (*i)->day > day) {
|
||||
o->next = *i;
|
||||
*i = o;
|
||||
break;
|
||||
}
|
||||
i = &(*i)->next;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/*
|
||||
* Correspondance between the defines on recursive type,
|
||||
* and the letter to be written in file.
|
||||
*/
|
||||
char recur_def2char(int define){
|
||||
char recur_char;
|
||||
|
||||
switch (define) {
|
||||
case 1:
|
||||
recur_char = 'D';
|
||||
break;
|
||||
case 2:
|
||||
recur_char = 'W';
|
||||
break;
|
||||
case 3:
|
||||
recur_char = 'M';
|
||||
break;
|
||||
case 4:
|
||||
recur_char = 'Y';
|
||||
break;
|
||||
}
|
||||
return recur_char;
|
||||
}
|
||||
|
||||
/*
|
||||
* Correspondance between the letters written in file and the defines
|
||||
* concerning the recursive type.
|
||||
*/
|
||||
int recur_char2def(char type){
|
||||
int recur_def;
|
||||
|
||||
switch (type) {
|
||||
case 'D':
|
||||
recur_def = RECUR_DAILY;
|
||||
break;
|
||||
case 'W':
|
||||
recur_def = RECUR_WEEKLY;
|
||||
break;
|
||||
case 'M':
|
||||
recur_def = RECUR_MONTHLY;
|
||||
break;
|
||||
case 'Y':
|
||||
recur_def = RECUR_YEARLY;
|
||||
break;
|
||||
}
|
||||
return recur_def;
|
||||
}
|
||||
|
||||
/* Writting of a recursive appointment into file. */
|
||||
void recur_apoint_write(struct recur_apoint_s *o, FILE *f)
|
||||
{
|
||||
struct tm *lt;
|
||||
time_t t;
|
||||
|
||||
t = o->start;
|
||||
lt = localtime(&t);
|
||||
fprintf(f, "%02u/%02u/%04u @ %02u:%02u",
|
||||
lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year,
|
||||
lt->tm_hour, lt->tm_min);
|
||||
|
||||
t = o->start + o->dur;
|
||||
lt = localtime(&t);
|
||||
fprintf(f, " -> %02u/%02u/%04u @ %02u:%02u",
|
||||
lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year,
|
||||
lt->tm_hour, lt->tm_min);
|
||||
|
||||
t = o->rpt->until;
|
||||
if (t == 0) { /* We have an endless recurrent appointment. */
|
||||
fprintf(f, " {%d%c} |%s\n", o->rpt->freq,
|
||||
recur_def2char(o->rpt->type), o->mesg);
|
||||
} else {
|
||||
lt = localtime(&t);
|
||||
fprintf(f, " {%d%c -> %02u/%02u/%04u} |%s\n",
|
||||
o->rpt->freq, recur_def2char(o->rpt->type),
|
||||
lt->tm_mon + 1, lt->tm_mday, 1900 + lt->tm_year,
|
||||
o->mesg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Writting of a recursive event into file. */
|
||||
void recur_event_write(struct recur_event_s *o, FILE *f)
|
||||
{
|
||||
struct tm *lt;
|
||||
time_t t;
|
||||
int st_mon, st_day, st_year;
|
||||
int end_mon, end_day, end_year;
|
||||
|
||||
t = o->day;
|
||||
lt = localtime(&t);
|
||||
st_mon = lt->tm_mon + 1;
|
||||
st_day = lt->tm_mday;
|
||||
st_year = lt->tm_year + 1900;
|
||||
t = o->rpt->until;
|
||||
if (t == 0) { /* We have an endless recurrent event. */
|
||||
fprintf(f, "%02u/%02u/%04u [%d] {%d%c} %s\n",
|
||||
st_mon, st_day, st_year, o->id, o->rpt->freq,
|
||||
recur_def2char(o->rpt->type), o->mesg);
|
||||
} else {
|
||||
lt = localtime(&t);
|
||||
end_mon = lt->tm_mon + 1;
|
||||
end_day = lt->tm_mday;
|
||||
end_year = lt->tm_year + 1900;
|
||||
fprintf(f, "%02u/%02u/%04u [%d] {%d%c -> %02u/%02u/%04u} %s\n",
|
||||
st_mon, st_day, st_year, o->id,
|
||||
o->rpt->freq, recur_def2char(o->rpt->type),
|
||||
end_mon, end_day, end_year, o->mesg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Load the recursive appointment description */
|
||||
struct recur_apoint_s *recur_apoint_scan(FILE * f, struct tm start,
|
||||
struct tm end, char type, int freq, struct tm until)
|
||||
{
|
||||
struct tm *lt;
|
||||
char buf[MESG_MAXSIZE], *nl;
|
||||
time_t tstart, tend, t, tuntil;
|
||||
|
||||
t = time(NULL);
|
||||
lt = localtime(&t);
|
||||
|
||||
/* Read the appointment description */
|
||||
fgets(buf, MESG_MAXSIZE, f);
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl) {
|
||||
*nl = '\0';
|
||||
}
|
||||
|
||||
start.tm_sec = end.tm_sec = 0;
|
||||
start.tm_isdst = end.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
end.tm_year -= 1900;
|
||||
end.tm_mon--;
|
||||
tstart = mktime(&start);
|
||||
tend = mktime(&end);
|
||||
|
||||
if (until.tm_year != 0) {
|
||||
until.tm_hour = 12;
|
||||
until.tm_min = 0;
|
||||
until.tm_sec = 0;
|
||||
until.tm_isdst = -1;
|
||||
until.tm_year -= 1900;
|
||||
until.tm_mon--;
|
||||
tuntil = mktime(&until);
|
||||
} else {
|
||||
tuntil = 0;
|
||||
}
|
||||
|
||||
if (tstart == -1 || tend == -1 || tstart > tend || tuntil == -1) {
|
||||
fputs(_("FATAL ERROR in apoint_scan: date error in the appointment\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return recur_apoint_new(buf, tstart, tend - tstart,
|
||||
recur_char2def(type), freq, tuntil);
|
||||
}
|
||||
|
||||
/* 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 tm *lt;
|
||||
char buf[MESG_MAXSIZE], *nl;
|
||||
time_t tstart, t, tuntil;
|
||||
|
||||
t = time(NULL);
|
||||
lt = localtime(&t);
|
||||
|
||||
/* Read the event description */
|
||||
fgets(buf, MESG_MAXSIZE, f);
|
||||
nl = strchr(buf, '\n');
|
||||
if (nl) {
|
||||
*nl = '\0';
|
||||
}
|
||||
|
||||
start.tm_hour = until.tm_hour = 12;
|
||||
start.tm_min = until.tm_min = 0;
|
||||
start.tm_sec = until.tm_sec = 0;
|
||||
start.tm_isdst = until.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
if (until.tm_year != 0) {
|
||||
until.tm_year -= 1900;
|
||||
until.tm_mon--;
|
||||
tuntil = mktime(&until);
|
||||
} else {
|
||||
tuntil = 0;
|
||||
}
|
||||
tstart = mktime(&start);
|
||||
if ( (tstart == -1) || (tuntil == -1) ) {
|
||||
fputs(_("FATAL ERROR in recur_event_scan: date error in the event\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return recur_event_new(buf, tstart, id, recur_char2def(type), freq, tuntil);
|
||||
}
|
||||
|
||||
/* Write recursive items to file. */
|
||||
void recur_save_data(FILE *f)
|
||||
{
|
||||
struct recur_event_s *re;
|
||||
struct recur_apoint_s *ra;
|
||||
|
||||
for (re = recur_elist; re != 0; re = re->next)
|
||||
recur_event_write(re, f);
|
||||
for (ra = recur_alist; ra != 0; ra = ra->next)
|
||||
recur_apoint_write(ra, f);
|
||||
}
|
||||
|
||||
/* Check if the recurrent item belongs to the selected day. */
|
||||
unsigned recur_item_inday(long item_start, int rpt_type, int rpt_freq,
|
||||
long rpt_until, long day_start)
|
||||
{
|
||||
const int DAYINSEC = 86400;
|
||||
long day_end = day_start + DAYINSEC;
|
||||
int inday = 0;
|
||||
struct tm *lt;
|
||||
time_t t;
|
||||
char *error =
|
||||
_("FATAL ERROR in recur_item_inday: unknown item type\n");
|
||||
|
||||
if (rpt_until == 0) /* we have an endless recurrent item */
|
||||
rpt_until = day_end;
|
||||
while (item_start <= day_end && item_start <= rpt_until) {
|
||||
if (item_start < day_end && item_start >= day_start) {
|
||||
inday = 1;
|
||||
break;
|
||||
}
|
||||
t = item_start;
|
||||
lt = localtime(&t);
|
||||
if (rpt_type == RECUR_DAILY) {
|
||||
lt->tm_mday += rpt_freq;
|
||||
} else if (rpt_type == RECUR_WEEKLY) {
|
||||
lt->tm_mday += rpt_freq * 7;
|
||||
} else if (rpt_type == RECUR_MONTHLY) {
|
||||
lt->tm_mon += rpt_freq;
|
||||
} else if (rpt_type == RECUR_YEARLY) {
|
||||
lt->tm_year += rpt_freq;
|
||||
} else { /* NOT REACHED */
|
||||
fputs(error, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
item_start = date2sec(lt->tm_year + 1900, lt->tm_mon + 1,
|
||||
lt->tm_mday, 0, 0);
|
||||
}
|
||||
return inday;
|
||||
}
|
||||
|
||||
/* Returns a structure of type apoint_s given a structure of type recur_apoint_s */
|
||||
struct apoint_s *recur_apoint_s2apoint_s(struct recur_apoint_s *p)
|
||||
{
|
||||
struct apoint_s *a;
|
||||
|
||||
a = (struct apoint_s *) malloc(sizeof(struct apoint_s));
|
||||
a->mesg = (char *) malloc(strlen(p->mesg) + 1);
|
||||
a->start = p->start;
|
||||
a->dur = p->dur;
|
||||
a->mesg = p->mesg;
|
||||
return a;
|
||||
}
|
||||
87
src/recur.h
Executable file
87
src/recur.h
Executable file
@@ -0,0 +1,87 @@
|
||||
/* $calcurse: recur.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_RECUR_H
|
||||
#define CALCURSE_RECUR_H
|
||||
|
||||
#include "apoint.h"
|
||||
|
||||
#define RECUR_NO 0
|
||||
#define RECUR_DAILY 1
|
||||
#define RECUR_WEEKLY 2
|
||||
#define RECUR_MONTHLY 3
|
||||
#define RECUR_YEARLY 4
|
||||
|
||||
struct days_s {
|
||||
struct days_s *next;
|
||||
long st; /* beggining of the considered day, in seconds */
|
||||
};
|
||||
|
||||
struct rpt_s {
|
||||
int type; /* repetition type, see RECUR_* defines */
|
||||
int freq; /* repetition frequence */
|
||||
long until; /* ending date for repeated event */
|
||||
};
|
||||
|
||||
struct recur_apoint_s {
|
||||
struct recur_apoint_s *next;
|
||||
struct rpt_s *rpt; /* information about repetition */
|
||||
struct days_s *exc; /* days when the item should not be repeated */
|
||||
long start; /* beggining of the appointment */
|
||||
long dur; /* duration of the appointment */
|
||||
char *mesg; /* appointment description */
|
||||
};
|
||||
|
||||
struct recur_event_s {
|
||||
struct recur_event_s *next;
|
||||
struct rpt_s *rpt; /* information about repetition */
|
||||
struct days_s *exc; /* days when the item should not be repeated */
|
||||
int id; /* event type */
|
||||
long day; /* day at which event occurs */
|
||||
char *mesg; /* event description */
|
||||
};
|
||||
|
||||
extern struct recur_apoint_s *recur_alist;
|
||||
extern struct recur_event_s *recur_elist;
|
||||
|
||||
struct recur_apoint_s *recur_apoint_new(char *mesg, long start, long duration,
|
||||
int type, int freq, long until);
|
||||
struct recur_event_s *recur_event_new(char *mesg, long day, int id,
|
||||
int type, int freq, long until);
|
||||
char recur_def2char(int define);
|
||||
int recur_char2def(char type);
|
||||
void recur_apoint_write(struct recur_apoint_s *o, FILE * f);
|
||||
void recur_event_write(struct recur_event_s *o, FILE * f);
|
||||
struct recur_apoint_s *recur_apoint_scan(FILE * f, struct tm start,
|
||||
struct tm end, char type, int freq, struct tm until);
|
||||
struct recur_event_s *recur_event_scan(FILE * f, struct tm start, int id,
|
||||
char type, int freq, struct tm until);
|
||||
void recur_save_data(FILE *f);
|
||||
unsigned recur_item_inday(long item_start, int rpt_type, int rpt_freq,
|
||||
long rpt_until, long day_start);
|
||||
struct apoint_s *recur_apoint_s2apoint_s(struct recur_apoint_s *p);
|
||||
|
||||
#endif /* CALCURSE_RECUR_H */
|
||||
80
src/todo.c
Executable file
80
src/todo.c
Executable file
@@ -0,0 +1,80 @@
|
||||
/* $calcurse: todo.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "todo.h"
|
||||
|
||||
struct todo_s *todolist;
|
||||
|
||||
struct todo_s *todo_insert(char *mesg)
|
||||
{
|
||||
struct todo_s *o;
|
||||
o = (struct todo_s *) malloc(sizeof(struct todo_s));
|
||||
o->mesg = (char *) malloc(strlen(mesg) + 1);
|
||||
strcpy(o->mesg, mesg);
|
||||
o->next = todolist;
|
||||
todolist = o;
|
||||
return o;
|
||||
}
|
||||
|
||||
struct todo_s *todo_add(char *mesg)
|
||||
{
|
||||
struct todo_s *o, **i;
|
||||
o = (struct todo_s *) malloc(sizeof(struct todo_s));
|
||||
o->mesg = (char *) malloc(strlen(mesg) + 1);
|
||||
strcpy(o->mesg, mesg);
|
||||
for (i = &todolist; *i != 0; i = &(*i)->next) {
|
||||
}
|
||||
o->next = *i;
|
||||
*i = o;
|
||||
return o;
|
||||
}
|
||||
|
||||
void todo_delete_bynum(unsigned num)
|
||||
{
|
||||
unsigned n;
|
||||
struct todo_s *i, **iptr;
|
||||
|
||||
n = 0;
|
||||
iptr = &todolist;
|
||||
for (i = todolist; i != 0; i = i->next) {
|
||||
if (n == num) {
|
||||
*iptr = i->next;
|
||||
free(i->mesg);
|
||||
free(i);
|
||||
return;
|
||||
}
|
||||
iptr = &i->next;
|
||||
n++;
|
||||
}
|
||||
/* not reached */
|
||||
fputs(_("FATAL ERROR in todo_delete_bynum: no such todo\n"), stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
41
src/todo.h
Executable file
41
src/todo.h
Executable file
@@ -0,0 +1,41 @@
|
||||
/* $calcurse: todo.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_TODO_H
|
||||
#define CALCURSE_TODO_H
|
||||
|
||||
struct todo_s {
|
||||
struct todo_s *next;
|
||||
char *mesg;
|
||||
};
|
||||
|
||||
extern struct todo_s *todolist;
|
||||
|
||||
struct todo_s *todo_insert(char *mesg);
|
||||
struct todo_s *todo_add(char *mesg);
|
||||
void todo_delete_bynum(unsigned num);
|
||||
|
||||
#endif /* CALCURSE_TODO_H */
|
||||
614
src/utils.c
Executable file
614
src/utils.c
Executable file
@@ -0,0 +1,614 @@
|
||||
/* $calcurse: utils.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "i18n.h"
|
||||
#include "utils.h"
|
||||
#include "custom.h"
|
||||
#include "vars.h"
|
||||
|
||||
|
||||
/*
|
||||
* Print a message in the status bar.
|
||||
* Message texts for first line and second line are to be provided.
|
||||
*/
|
||||
|
||||
void status_mesg(char *mesg_line1, char *mesg_line2)
|
||||
{
|
||||
erase_window_part(swin, 0, 0, col, 2);
|
||||
custom_apply_attr(swin, ATTR_HIGHEST);
|
||||
mvwprintw(swin, 0, 0, mesg_line1);
|
||||
mvwprintw(swin, 1, 0, mesg_line2);
|
||||
custom_remove_attr(swin, ATTR_HIGHEST);
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase part of a window
|
||||
*/
|
||||
void erase_window_part(WINDOW *win, int first_col, int first_row,
|
||||
int last_col, int last_row)
|
||||
{
|
||||
int c, r;
|
||||
|
||||
for (r = first_row; r <= last_row; r++){
|
||||
for (c = first_col; c <= last_col; c++){
|
||||
mvwprintw(win, r, c, " ");
|
||||
}
|
||||
}
|
||||
wnoutrefresh(win);
|
||||
}
|
||||
|
||||
/* draws a popup window */
|
||||
WINDOW * popup(int pop_row, int pop_col,
|
||||
int pop_y, int pop_x, char *pop_lab)
|
||||
{
|
||||
char *txt_pop = _("Press any key to continue...");
|
||||
char label[80];
|
||||
WINDOW *popup_win;
|
||||
|
||||
popup_win = newwin(pop_row, pop_col, pop_y, pop_x);
|
||||
custom_apply_attr(popup_win, ATTR_HIGHEST);
|
||||
box(popup_win, 0, 0);
|
||||
sprintf(label, "%s", pop_lab);
|
||||
win_show(popup_win, label);
|
||||
mvwprintw(popup_win, pop_row - 2, pop_col - (strlen(txt_pop) + 1), "%s",
|
||||
txt_pop);
|
||||
custom_remove_attr(popup_win, ATTR_HIGHEST);
|
||||
wnoutrefresh(popup_win);
|
||||
doupdate();
|
||||
return popup_win;
|
||||
}
|
||||
|
||||
/* prints in middle of a panel */
|
||||
void
|
||||
print_in_middle(WINDOW * win, int starty, int startx, int width, char *string)
|
||||
{
|
||||
int length, x, y;
|
||||
float temp;
|
||||
|
||||
if (win == NULL)
|
||||
win = stdscr;
|
||||
getyx(win, y, x);
|
||||
if (startx != 0)
|
||||
x = startx;
|
||||
if (starty != 0)
|
||||
y = starty;
|
||||
if (width == 0)
|
||||
width = 80;
|
||||
|
||||
length = strlen(string);
|
||||
temp = (width - length) / 2;
|
||||
x = startx + (int) temp;
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
mvwprintw(win, y, x, "%s", string);
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
}
|
||||
|
||||
/*
|
||||
* Getstring allows to get user input and to print it on a window,
|
||||
* even if noecho() is on.
|
||||
*/
|
||||
void getstring(win, colr, string, start_x, start_y)
|
||||
WINDOW *win;
|
||||
int colr;
|
||||
char *string;
|
||||
int start_x, start_y;
|
||||
{
|
||||
int ch;
|
||||
int charcount = 0;
|
||||
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
if (start_x != -1)
|
||||
wmove(win, start_y, start_x);
|
||||
|
||||
while ((ch = wgetch(win)) != '\n') {
|
||||
if ((ch == KEY_BACKSPACE) ||
|
||||
(ch == 330) ||
|
||||
(ch == 263) ||
|
||||
(ch == 127) ||
|
||||
(ch == CTRL('H')) ) {
|
||||
if (charcount > 0) {
|
||||
string--;
|
||||
charcount--;
|
||||
wmove(win, start_y, start_x + charcount);
|
||||
waddch(win, ' ');
|
||||
wmove(win, start_y, start_x + charcount);
|
||||
}
|
||||
} else {
|
||||
*string++ = ch;
|
||||
charcount++;
|
||||
waddch(win, ch);
|
||||
}
|
||||
doupdate();
|
||||
}
|
||||
*string = 0;
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
return;
|
||||
}
|
||||
|
||||
/* checks if a string is only made of digits */
|
||||
int is_all_digit(char *string)
|
||||
{
|
||||
int digit, i;
|
||||
int all_digit;
|
||||
|
||||
digit = 0;
|
||||
all_digit = 0;
|
||||
|
||||
for (i = 0; i <= strlen(string); i++)
|
||||
if (isdigit(string[i]) != 0)
|
||||
digit++;
|
||||
if (digit == strlen(string))
|
||||
all_digit = 1;
|
||||
return all_digit;
|
||||
}
|
||||
|
||||
/* draw panel border in color */
|
||||
void border_color(WINDOW * window, int bcolr)
|
||||
{
|
||||
int color_attr = A_BOLD;
|
||||
int no_color_attr = A_BOLD;
|
||||
|
||||
if (colorize) {
|
||||
wattron(window, color_attr | COLOR_PAIR(bcolr));
|
||||
box(window, 0, 0);
|
||||
} else {
|
||||
wattron(window, no_color_attr);
|
||||
box(window, 0, 0);
|
||||
}
|
||||
|
||||
if (colorize) {
|
||||
wattroff(window, color_attr | COLOR_PAIR(bcolr));
|
||||
} else {
|
||||
wattroff(window, no_color_attr);
|
||||
}
|
||||
|
||||
wnoutrefresh(window);
|
||||
}
|
||||
|
||||
/* draw panel border without any color */
|
||||
void border_nocolor(WINDOW * window)
|
||||
{
|
||||
int colr = 9;
|
||||
int color_attr = A_BOLD;
|
||||
int no_color_attr = A_DIM;
|
||||
|
||||
if (colorize) {
|
||||
wattron(window, color_attr | COLOR_PAIR(colr));
|
||||
} else {
|
||||
wattron(window, no_color_attr);
|
||||
}
|
||||
|
||||
box(window, 0, 0);
|
||||
|
||||
if (colorize) {
|
||||
wattroff(window, color_attr | COLOR_PAIR(colr));
|
||||
} else {
|
||||
wattroff(window, no_color_attr);
|
||||
}
|
||||
|
||||
wnoutrefresh(window);
|
||||
}
|
||||
|
||||
/* prints and scroll text in a window */
|
||||
void scroller(WINDOW *win, char *mesg, int x, int y, int nb_row, int nb_col)
|
||||
{
|
||||
int x_offset = 3;
|
||||
int y_offset = 3;
|
||||
int text_len = nb_col - 2 * x_offset;
|
||||
int text_max_row = nb_row - 3;
|
||||
int nlin, i, j, k;
|
||||
int last_blank_i, last_blank_j;
|
||||
char buf[] = " ";
|
||||
char *next_mesg = _("-- Press 'N' for next page --");
|
||||
char *prev_mesg = _("-- Press 'P' for previous page --");
|
||||
int ch;
|
||||
int which_page; //first page : 0, second page : 1
|
||||
|
||||
i = 0; //position in the message
|
||||
j = 0; //x position on the current line
|
||||
nlin = 1; //line number
|
||||
last_blank_j = 0;
|
||||
last_blank_i = 0;
|
||||
which_page = 0;
|
||||
|
||||
while (i <= strlen(mesg)) {
|
||||
if ((i == strlen(mesg)) & (which_page == 1)) {
|
||||
// we have finished writing text and we are on second page
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
mvwprintw(win, nb_row - 2,
|
||||
nb_col - (strlen(prev_mesg) + 2), "%s",
|
||||
prev_mesg);
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
wmove(swin, 0, 0);
|
||||
wnoutrefresh(win);
|
||||
wnoutrefresh(swin);
|
||||
doupdate();
|
||||
ch = wgetch(win);
|
||||
if ( (ch == 'P') | (ch == 'p') ) {
|
||||
erase_window_part(win, y + 1, x + 3, nb_col - 2, nb_row - 2);
|
||||
nlin = 1;
|
||||
j = 0;
|
||||
i = 0;
|
||||
which_page = 0;
|
||||
} else { //erase last line and exit next-prev page mode
|
||||
for (k = 1; k < nb_col - 2; k++)
|
||||
mvwprintw(win, nb_row - 2, k, " ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nlin == text_max_row - 2) { // we reach the last line
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
mvwprintw(win, nb_row - 2,
|
||||
nb_col - (strlen(next_mesg) + 2), "%s",
|
||||
next_mesg);
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
wmove(swin, 0, 0);
|
||||
wnoutrefresh(win);
|
||||
wnoutrefresh(swin);
|
||||
doupdate();
|
||||
ch = wgetch(win);
|
||||
if ( (ch == 'N') | (ch == 'n') ) {
|
||||
erase_window_part(win, y + 1, x + 3, nb_col - 2, nb_row - 2);
|
||||
nlin = 1;
|
||||
j = 0;
|
||||
which_page = 1;
|
||||
} else {
|
||||
for (k = 1; k < nb_col - 2; k++)
|
||||
mvwprintw(win, nb_row - 2, k, " ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
//write text
|
||||
strncpy(buf, mesg + i, 1);
|
||||
i++;
|
||||
j++;
|
||||
if ((strncmp(buf, "<EFBFBD>", 1) == 0)) { //<2F> is the character for a new line
|
||||
buf[0] = '\0';
|
||||
mvwprintw(win, x + x_offset + nlin, y + y_offset + j,
|
||||
"%s", buf);
|
||||
nlin++;
|
||||
j = 0;
|
||||
} else {
|
||||
if (j == text_len - 1) { // if we reach the terminal border
|
||||
for (k = last_blank_j; k <= text_len - 1;
|
||||
k++)
|
||||
mvwprintw(win, x + x_offset + nlin,
|
||||
y + y_offset + k, " ");
|
||||
nlin++;
|
||||
i = last_blank_i;
|
||||
j = 0;
|
||||
} else {
|
||||
if ((strncmp(buf, " ", 1) == 0)) //space between words
|
||||
{
|
||||
last_blank_j = j; //save position
|
||||
last_blank_i = i;
|
||||
}
|
||||
mvwprintw(win, x + x_offset + nlin,
|
||||
y + y_offset + j, "%s", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
wmove(swin, 0, 0);
|
||||
wnoutrefresh(win);
|
||||
wnoutrefresh(swin);
|
||||
}
|
||||
|
||||
/* Draws the status bar */
|
||||
void status_bar(int which_pan, int colr, int nc_bar, int nl_bar)
|
||||
{
|
||||
int nb_item_cal, nb_item_oth;
|
||||
int len_let, len_des, spc_lad;
|
||||
int spc_bet_cal_itm, spc_bet_oth_itm;
|
||||
int len_cal_itm, len_oth_itm;
|
||||
|
||||
nb_item_cal = 10; /* max item number to display in status bar */
|
||||
nb_item_cal = ceil(nb_item_cal / 2); /* two lines to display items */
|
||||
nb_item_oth = 12;
|
||||
nb_item_oth = ceil(nb_item_oth / 2);
|
||||
len_let = 3;
|
||||
len_des = 8;
|
||||
spc_lad = 1;
|
||||
|
||||
spc_bet_cal_itm =
|
||||
floor((col -
|
||||
nb_item_cal * (len_let + len_des +
|
||||
spc_lad)) / nb_item_cal);
|
||||
spc_bet_oth_itm =
|
||||
floor((col -
|
||||
nb_item_oth * (len_let + len_des +
|
||||
spc_lad)) / nb_item_oth);
|
||||
len_cal_itm = len_let + spc_lad + len_des + spc_bet_cal_itm;
|
||||
len_oth_itm = len_let + spc_lad + len_des + spc_bet_oth_itm;
|
||||
|
||||
erase_window_part(swin, 0, 0, nc_bar, nl_bar);
|
||||
if (which_pan == 0) {
|
||||
custom_apply_attr(swin, ATTR_HIGHEST);
|
||||
mvwprintw(swin, 0, 0, " ?");
|
||||
mvwprintw(swin, 1, 0, " Q");
|
||||
mvwprintw(swin, 0, len_cal_itm, " R");
|
||||
mvwprintw(swin, 1, len_cal_itm, " S");
|
||||
mvwprintw(swin, 0, 2 * len_cal_itm, "H/L");
|
||||
mvwprintw(swin, 1, 2 * len_cal_itm, "J/K");
|
||||
mvwprintw(swin, 0, 3 * len_cal_itm, " G");
|
||||
mvwprintw(swin, 1, 3 * len_cal_itm, "Tab");
|
||||
mvwprintw(swin, 0, 4 * len_cal_itm, " C");
|
||||
custom_remove_attr(swin, ATTR_HIGHEST);
|
||||
wnoutrefresh(swin);
|
||||
|
||||
mvwprintw(swin, 0, len_let + spc_lad, _("Help"));
|
||||
mvwprintw(swin, 1, len_let + spc_lad, _("Quit"));
|
||||
mvwprintw(swin, 0, len_cal_itm + len_let + spc_lad,
|
||||
_("Redraw"));
|
||||
mvwprintw(swin, 1, len_cal_itm + len_let + spc_lad, _("Save"));
|
||||
mvwprintw(swin, 0, 2 * len_cal_itm + len_let + spc_lad,
|
||||
_("-/+1 Day"));
|
||||
mvwprintw(swin, 1, 2 * len_cal_itm + len_let + spc_lad,
|
||||
_("-/+1 Week"));
|
||||
mvwprintw(swin, 0, 3 * len_cal_itm + len_let + spc_lad,
|
||||
_("GoTo"));
|
||||
mvwprintw(swin, 1, 3 * len_cal_itm + len_let + spc_lad,
|
||||
_("Chg View"));
|
||||
mvwprintw(swin, 0, 4 * len_cal_itm + len_let + spc_lad,
|
||||
_("Config"));
|
||||
} else {
|
||||
custom_apply_attr(swin, ATTR_HIGHEST);
|
||||
mvwprintw(swin, 0, 0, " ?");
|
||||
mvwprintw(swin, 1, 0, " Q");
|
||||
mvwprintw(swin, 0, len_oth_itm, " R");
|
||||
mvwprintw(swin, 1, len_oth_itm, " S");
|
||||
mvwprintw(swin, 0, 2 * len_oth_itm, "J/K");
|
||||
mvwprintw(swin, 1, 2 * len_oth_itm, "Tab");
|
||||
mvwprintw(swin, 0, 3 * len_oth_itm, " A");
|
||||
mvwprintw(swin, 1, 3 * len_oth_itm, " D");
|
||||
mvwprintw(swin, 0, 4 * len_oth_itm, " G");
|
||||
mvwprintw(swin, 1, 4 * len_oth_itm, " V");
|
||||
mvwprintw(swin, 0, 5 * len_oth_itm, " C");
|
||||
custom_remove_attr(swin, ATTR_HIGHEST);
|
||||
wnoutrefresh(swin);
|
||||
|
||||
mvwprintw(swin, 0, len_let + spc_lad, _("Help"));
|
||||
mvwprintw(swin, 1, len_let + spc_lad, _("Quit"));
|
||||
mvwprintw(swin, 0, len_oth_itm + len_let + spc_lad,
|
||||
_("Redraw"));
|
||||
mvwprintw(swin, 1, len_oth_itm + len_let + spc_lad, _("Save"));
|
||||
mvwprintw(swin, 0, 2 * len_oth_itm + len_let + spc_lad,
|
||||
_("Up/Down"));
|
||||
mvwprintw(swin, 1, 2 * len_oth_itm + len_let + spc_lad,
|
||||
_("Chg View"));
|
||||
mvwprintw(swin, 0, 3 * len_oth_itm + len_let + spc_lad,
|
||||
_("Add Item"));
|
||||
mvwprintw(swin, 1, 3 * len_oth_itm + len_let + spc_lad,
|
||||
_("Del Item"));
|
||||
mvwprintw(swin, 0, 4 * len_oth_itm + len_let + spc_lad,
|
||||
_( "GoTo"));
|
||||
mvwprintw(swin, 1, 4 * len_oth_itm + len_let + spc_lad,
|
||||
_("View"));
|
||||
mvwprintw(swin, 0, 5 * len_oth_itm + len_let + spc_lad,
|
||||
_("Config"));
|
||||
}
|
||||
wnoutrefresh(swin);
|
||||
}
|
||||
|
||||
long date2sec(unsigned year, unsigned month, unsigned day, unsigned hour,
|
||||
unsigned min)
|
||||
{
|
||||
struct tm start, *lt;
|
||||
time_t tstart, t;
|
||||
|
||||
t = time(NULL);
|
||||
lt = localtime(&t);
|
||||
start = *lt;
|
||||
|
||||
start.tm_mon = month;
|
||||
start.tm_mday = day;
|
||||
start.tm_year = year;
|
||||
start.tm_hour = hour;
|
||||
start.tm_min = min;
|
||||
start.tm_sec = 0;
|
||||
start.tm_isdst = -1;
|
||||
start.tm_year -= 1900;
|
||||
start.tm_mon--;
|
||||
tstart = mktime(&start);
|
||||
if (tstart == -1) {
|
||||
fputs(_("FATAL ERROR in date2sec: failure in mktime\n"), stderr);
|
||||
fprintf(stderr, "%u %u %u %u %u\n", year, month, day, hour, min);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return tstart;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the date in seconds from year 1900.
|
||||
* If no date is entered, current date is chosen.
|
||||
*/
|
||||
long
|
||||
get_sec_date(int year, int month, int day)
|
||||
{
|
||||
struct tm *ptrtime;
|
||||
time_t timer;
|
||||
long long_date;
|
||||
char current_day[3], current_month[3] ,current_year[5];
|
||||
|
||||
if (year == 0 && month == 0 && day == 0) {
|
||||
timer = time(NULL);
|
||||
ptrtime = localtime(&timer);
|
||||
strftime(current_day, 3, "%d", ptrtime);
|
||||
strftime(current_month, 3, "%m", ptrtime);
|
||||
strftime(current_year, 5, "%Y", ptrtime);
|
||||
month = atoi(current_month);
|
||||
day = atoi(current_day);
|
||||
year = atoi(current_year);
|
||||
|
||||
}
|
||||
long_date = date2sec(year, month, day, 0, 0);
|
||||
return long_date;
|
||||
}
|
||||
|
||||
long min2sec(unsigned minutes)
|
||||
{
|
||||
return minutes * 60;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if a time has a good format.
|
||||
* The format could be either HH:MM or H:MM or MM, and we should have:
|
||||
* 0 <= HH <= 24 and 0 <= MM < 999.
|
||||
* This function returns 1 if the entered time is correct and in
|
||||
* [h:mm] or [hh:mm] format, and 2 if the entered time is correct and entered
|
||||
* in [mm] format.
|
||||
*/
|
||||
int check_time(char *string)
|
||||
{
|
||||
int ok = 0;
|
||||
char hour[] = " ";
|
||||
char minutes[] = " ";
|
||||
|
||||
if ( // format test [MM]
|
||||
((strlen(string) == 2) || (strlen(string) == 3)) &
|
||||
(isdigit(string[0]) != 0) &
|
||||
(isdigit(string[1]) != 0)
|
||||
) { // check if we have a valid time
|
||||
strncpy(minutes, string, 2);
|
||||
if ( atoi(minutes) >= 0)
|
||||
ok = 2;
|
||||
}
|
||||
|
||||
else if ( // format test [H:MM]
|
||||
(strlen(string) == 4) &
|
||||
(isdigit(string[0]) != 0) &
|
||||
(isdigit(string[2]) != 0) &
|
||||
(isdigit(string[3]) != 0) & (string[1] == ':')
|
||||
) { // check if we have a valid time
|
||||
strncpy(hour, string, 1);
|
||||
strncpy(minutes, string + 2, 2);
|
||||
if ((atoi(hour) <= 24) & (atoi(hour) >=
|
||||
0) & (atoi(minutes) <
|
||||
60) & (atoi(minutes) >= 0))
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
else if ( //format test [HH:MM]
|
||||
(strlen(string) == 5) &
|
||||
(isdigit(string[0]) != 0) &
|
||||
(isdigit(string[1]) != 0) &
|
||||
(isdigit(string[3]) != 0) &
|
||||
(isdigit(string[4]) != 0) & (string[2] == ':')
|
||||
) { // check if we have a valid time
|
||||
strncpy(hour, string, 2);
|
||||
strncpy(minutes, string + 3, 2);
|
||||
if ((atoi(hour) <= 24) & (atoi(hour) >=
|
||||
0) & (atoi(minutes) <
|
||||
60) & (atoi(minutes) >= 0))
|
||||
ok = 1;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display a scroll bar when there are so many items that they
|
||||
* can not be displayed inside the corresponding panel.
|
||||
*/
|
||||
void draw_scrollbar(WINDOW *win, int y, int x, int length,
|
||||
int bar_top, int bar_bottom, bool hilt)
|
||||
{
|
||||
mvwvline(win, bar_top, x, ACS_VLINE, bar_bottom - bar_top);
|
||||
if (hilt)
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
wattron(win, A_REVERSE);
|
||||
mvwvline(win, y, x, ' ', length);
|
||||
wattroff(win, A_REVERSE);
|
||||
if (hilt)
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print an item (either an appointment, event, or todo) in a
|
||||
* popup window. This is useful if an item description is too
|
||||
* long to fit in its corresponding panel window.
|
||||
*/
|
||||
void item_in_popup(char *saved_a_start, char *saved_a_end, char *msg,
|
||||
char *pop_title)
|
||||
{
|
||||
WINDOW *popup_win;
|
||||
|
||||
popup_win = popup(row - 4, col - 2, 1, 1, pop_title);
|
||||
if (strncmp(pop_title, _("Appointment"), 11) == 0) {
|
||||
mvwprintw(popup_win, 4, 4, " - %s -> %s",
|
||||
saved_a_start, saved_a_end);
|
||||
}
|
||||
scroller(popup_win, msg, 1, 1, row - 4, col - 2);
|
||||
wmove(swin, 0, 0);
|
||||
doupdate();
|
||||
wgetch(popup_win);
|
||||
delwin(popup_win);
|
||||
}
|
||||
|
||||
/* Show the window with a border and a label */
|
||||
void win_show(WINDOW * win, char *label)
|
||||
{
|
||||
int startx, starty, height, width;
|
||||
|
||||
getbegyx(win, starty, startx);
|
||||
getmaxyx(win, height, width);
|
||||
|
||||
box(win, 0, 0);
|
||||
mvwaddch(win, 2, 0, ACS_LTEE);
|
||||
mvwhline(win, 2, 1, ACS_HLINE, width - 2);
|
||||
mvwaddch(win, 2, width - 1, ACS_RTEE);
|
||||
|
||||
print_in_middle(win, 1, 0, width, label);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print an item description in the corresponding panel window.
|
||||
*/
|
||||
void display_item(WINDOW *win, int incolor, char *msg, int len,
|
||||
int y, int x)
|
||||
{
|
||||
char buf[len];
|
||||
|
||||
if (incolor == 0)
|
||||
custom_apply_attr(win, ATTR_HIGHEST);
|
||||
if (strlen(msg) < len) {
|
||||
mvwprintw(win, y, x, "%s", msg);
|
||||
} else {
|
||||
strncpy(buf, msg, len - 1);
|
||||
buf[len - 1] = '\0';
|
||||
mvwprintw(win, y, x, "%s...", buf);
|
||||
}
|
||||
if (incolor == 0)
|
||||
custom_remove_attr(win, ATTR_HIGHEST);
|
||||
}
|
||||
55
src/utils.h
Executable file
55
src/utils.h
Executable file
@@ -0,0 +1,55 @@
|
||||
/* $calcurse: utils.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_UTILS_H
|
||||
#define CALCURSE_UTILS_H
|
||||
|
||||
void status_mesg(char *mesg_line1, char *mesg_line2);
|
||||
void erase_window_part(WINDOW *win, int first_col, int first_row,
|
||||
int last_col, int last_row);
|
||||
WINDOW *popup(int pop_row, int pop_col,
|
||||
int pop_y, int pop_x, char *pop_lab);
|
||||
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string);
|
||||
void getstring(WINDOW *win, int colr, char *string, int start_x, int start_y);
|
||||
int is_all_digit(char *string);
|
||||
void border_color(WINDOW *window, int bcolr);
|
||||
void border_nocolor(WINDOW *window);
|
||||
void scroller(WINDOW *win, char *, int x, int y, int nb_row, int nb_col);
|
||||
void status_bar(int which_pan, int colr, int nc_bar, int nl_bar);
|
||||
long date2sec(unsigned year, unsigned month, unsigned day, unsigned hour,
|
||||
unsigned min);
|
||||
long get_sec_date(int year, int month, int day);
|
||||
long min2sec(unsigned minutes);
|
||||
int check_time(char *string);
|
||||
void draw_scrollbar(WINDOW *win, int y, int x, int length,
|
||||
int bar_top, int bar_bottom, bool hilt);
|
||||
void item_in_popup(char *saved_a_start, char *saved_a_end, char *msg,
|
||||
char *pop_title);
|
||||
void win_show(WINDOW * win, char *label);
|
||||
void display_item(WINDOW *win, int incolor, char *msg,
|
||||
int len, int y, int x);
|
||||
|
||||
#endif /* CALCURSE_UTILS_H */
|
||||
85
src/vars.c
Executable file
85
src/vars.c
Executable file
@@ -0,0 +1,85 @@
|
||||
/* $calcurse: vars.c,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#include "i18n.h"
|
||||
#include "vars.h"
|
||||
|
||||
/*
|
||||
* variables to store window size
|
||||
*/
|
||||
int col = 0, row = 0;
|
||||
|
||||
/* variable to tell if the terminal supports color */
|
||||
bool colorize = false;
|
||||
|
||||
/*
|
||||
* variables to store calendar names
|
||||
*/
|
||||
int days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
char *monthnames[12] =
|
||||
{ N_("January"),
|
||||
N_("February"),
|
||||
N_("March"),
|
||||
N_("April"),
|
||||
N_("May"),
|
||||
N_("June"),
|
||||
N_("July"),
|
||||
N_("August"),
|
||||
N_("September"),
|
||||
N_("October"),
|
||||
N_("November"),
|
||||
N_("December") };
|
||||
|
||||
char *daynames[8] =
|
||||
{ N_("Sun"),
|
||||
N_("Mon"),
|
||||
N_("Tue"),
|
||||
N_("Wed"),
|
||||
N_("Thu"),
|
||||
N_("Fri"),
|
||||
N_("Sat"),
|
||||
N_("Sun") };
|
||||
|
||||
/*
|
||||
* variables to store data path names, which are initialized in
|
||||
* io_init()
|
||||
*/
|
||||
char path_dir[] = "";
|
||||
char path_todo[] = "";
|
||||
char path_apts[] = "";
|
||||
char path_conf[] = "";
|
||||
|
||||
/*
|
||||
* Variables to handle calcurse windows:
|
||||
* cwin = calendar window
|
||||
* awin = appointment window
|
||||
* twin = todo window
|
||||
* swin = status bar window
|
||||
*/
|
||||
WINDOW *awin = NULL, *cwin = NULL, *twin = NULL, *swin = NULL;
|
||||
|
||||
/* Variable to handle pads. */
|
||||
struct pad_s *apad;
|
||||
69
src/vars.h
Executable file
69
src/vars.h
Executable file
@@ -0,0 +1,69 @@
|
||||
/* $calcurse: vars.h,v 1.1 2006/07/31 21:00:03 culot Exp $ */
|
||||
|
||||
/*
|
||||
* Calcurse - text-based organizer
|
||||
* Copyright (c) 2004-2006 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Send your feedback or comments to : calcurse@culot.org
|
||||
* Calcurse home page : http://culot.org/calcurse
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CALCURSE_VARS_H
|
||||
#define CALCURSE_VARS_H
|
||||
|
||||
#include <ncurses.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DIR_NAME ".calcurse"
|
||||
#define TODO_PATH ".calcurse/todo"
|
||||
#define APTS_PATH ".calcurse/apts"
|
||||
#define CONF_PATH ".calcurse/conf"
|
||||
|
||||
#define MAX_LENGTH 512
|
||||
|
||||
#define CTRL(x) ((x) & 0x1f)
|
||||
|
||||
#define ATTR_FALSE 0
|
||||
#define ATTR_TRUE 1
|
||||
#define ATTR_LOWEST 2
|
||||
#define ATTR_LOW 3
|
||||
#define ATTR_MIDDLE 4
|
||||
#define ATTR_HIGH 5
|
||||
#define ATTR_HIGHEST 6
|
||||
|
||||
struct pad_s {
|
||||
int width;
|
||||
int length;
|
||||
int first_onscreen; /* first line to be displayed inside window */
|
||||
WINDOW *ptrwin; /* pointer to the pad window */
|
||||
};
|
||||
|
||||
extern int col, row;
|
||||
extern bool colorize;
|
||||
extern int days[12];
|
||||
extern char *monthnames[12];
|
||||
extern char *daynames[8];
|
||||
extern char path_dir[MAX_LENGTH];
|
||||
extern char path_todo[MAX_LENGTH];
|
||||
extern char path_apts[MAX_LENGTH];
|
||||
extern char path_conf[MAX_LENGTH];
|
||||
extern WINDOW *awin, *cwin, *twin, *swin;
|
||||
extern struct pad_s *apad;
|
||||
|
||||
#endif /* CALCURSE_VARS_H */
|
||||
Reference in New Issue
Block a user