From 524b09511d3647444ac2efe4572a8755068a69a9 Mon Sep 17 00:00:00 2001 From: Felicity Tarnell Date: Fri, 7 Mar 2014 23:47:31 +0000 Subject: [PATCH] Code cleanups; no functional changes. --- Makefile.in | 3 +- bindings.c | 151 ++++++++++++++ functions.c | 15 ++ style.c | 128 ++++++++++++ style.h | 3 + tts.c | 569 +--------------------------------------------------- ui.c | 292 +++++++++++++++++++++++++++ 7 files changed, 593 insertions(+), 568 deletions(-) create mode 100644 style.c diff --git a/Makefile.in b/Makefile.in index 77c9e0e..d582022 100644 --- a/Makefile.in +++ b/Makefile.in @@ -20,7 +20,8 @@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ INSTALL = @INSTALL@ -OBJS = tts.o wide.o entry.o ui.o functions.o commands.o bindings.o str.o +OBJS = tts.o wide.o entry.o ui.o functions.o commands.o bindings.o \ + str.o style.o prefix = @prefix@ exec_prefix = @exec_prefix@ diff --git a/bindings.c b/bindings.c index dfcb5d1..9115989 100644 --- a/bindings.c +++ b/bindings.c @@ -8,6 +8,157 @@ * warranty. */ +#include + #include "bindings.h" +#include "wide.h" +#include "ui.h" binding_list_t bindings = TTS_TAILQ_HEAD_INITIALIZER(bindings); + +static tkey_t keys[] = { + { KEY_BREAK, WIDE("") }, + { KEY_DOWN, WIDE("") }, + { KEY_UP, WIDE("") }, + { KEY_LEFT, WIDE("") }, + { KEY_RIGHT, WIDE("") }, + { KEY_HOME, WIDE("") }, + { KEY_BACKSPACE, WIDE("") }, + { 0x7F, WIDE("") }, /* DEL */ + { KEY_F(0), WIDE("") }, + { KEY_F(1), WIDE("") }, + { KEY_F(2), WIDE("") }, + { KEY_F(3), WIDE("") }, + { KEY_F(4), WIDE("") }, + { KEY_F(5), WIDE("") }, + { KEY_F(6), WIDE("") }, + { KEY_F(7), WIDE("") }, + { KEY_F(8), WIDE("") }, + { KEY_F(9), WIDE("") }, + { KEY_F(10), WIDE("") }, + { KEY_F(11), WIDE("") }, + { KEY_F(12), WIDE("") }, + { KEY_F(13), WIDE("") }, + { KEY_F(14), WIDE("") }, + { KEY_F(15), WIDE("") }, + { KEY_F(16), WIDE("") }, + { KEY_F(17), WIDE("") }, + { KEY_F(18), WIDE("") }, + { KEY_F(19), WIDE("") }, + { KEY_F(20), WIDE("") }, + { KEY_F(21), WIDE("") }, + { KEY_F(22), WIDE("") }, + { KEY_F(23), WIDE("") }, + { KEY_F(24), WIDE("") }, + { KEY_NPAGE, WIDE("") }, + { KEY_PPAGE, WIDE("") }, + { '\001', WIDE("") }, + { '\002', WIDE("") }, + { '\003', WIDE("") }, + { '\004', WIDE("") }, + { '\005', WIDE("") }, + { '\006', WIDE("") }, + { '\007', WIDE("") }, + { '\010', WIDE("") }, + { '\011', WIDE("") }, + { '\011', WIDE("") }, + { '\012', WIDE("") }, + { '\013', WIDE("") }, + { '\014', WIDE("") }, + { '\015', WIDE("") }, + { '\016', WIDE("") }, + { '\017', WIDE("") }, + { '\020', WIDE("") }, + { '\021', WIDE("") }, + { '\022', WIDE("") }, + { '\023', WIDE("") }, + { '\024', WIDE("") }, + { '\025', WIDE("") }, + { '\026', WIDE("") }, + { '\027', WIDE("") }, + { '\030', WIDE("") }, + { '\031', WIDE("") }, + { ' ', WIDE("") }, + { KEY_ENTER, WIDE("") }, + { KEY_BACKSPACE, WIDE("") }, + { KEY_DC, WIDE("") } +}; + +/* + * Bind .keyname to run the function .funcname. If a binding for .keyname + * already exists, overwrite it. + * + * If .keyname is a single character, e.g. 'a', it is used as a key name + * directly, rather than being looked up in the key table. + */ +void +bind_key(keyname, funcname, is_macro) + const WCHAR *keyname, *funcname; +{ +tkey_t *key = NULL; +function_t *func; +binding_t *binding; +INT code; + + /* Find the key and the function */ + if (STRLEN(keyname) > 1) { + if ((key = find_key(keyname)) == NULL) { + errbox(WIDE("Unknown key \"%"FMT_L"s\""), keyname); + return; + } + code = key->ky_code; + } else + code = *keyname; + + if (!is_macro) { + if ((func = find_func(funcname)) == NULL) { + errbox(WIDE("Unknown function \"%"FMT_L"s\""), funcname); + return; + } + } + + /* Do we already have a binding for this key? */ + TTS_TAILQ_FOREACH(binding, &bindings, bi_entries) { + if (binding->bi_code == code) { + if (is_macro) { + binding->bi_func = NULL; + binding->bi_macro = STRDUP(funcname); + } else { + free(binding->bi_macro); + binding->bi_func = func; + } + return; + } + } + + /* No, add a new one */ + if ((binding = calloc(1, sizeof(*binding))) == NULL) + return; + + binding->bi_key = key; + binding->bi_code = code; + + if (is_macro) + binding->bi_macro = STRDUP(funcname); + else + binding->bi_func = func; + + TTS_TAILQ_INSERT_TAIL(&bindings, binding, bi_entries); +} + +/* + * Return the tkey_t for the key called .name, or NULL if such a key doesn't + * exist. + */ +tkey_t * +find_key(name) + const WCHAR *name; +{ +size_t i; + + for (i = 0; i < sizeof(keys) / sizeof(*keys); i++) + if (STRCMP(name, keys[i].ky_name) == 0) + return &keys[i]; + return NULL; +} + diff --git a/functions.c b/functions.c index c1ed4c6..62acfd0 100644 --- a/functions.c +++ b/functions.c @@ -804,3 +804,18 @@ size_t nargs; tokfree(&args); } +/* + * Return the function_t for the function called .name, or NULL if such a + * function doesn't exist. + */ +function_t * +find_func(name) + const WCHAR *name; +{ +function_t *f; + for (f = funcs; f->fn_name; f++) + if (STRCMP(name, f->fn_name) == 0) + return f; + return NULL; +} + diff --git a/style.c b/style.c new file mode 100644 index 0000000..bca75a7 --- /dev/null +++ b/style.c @@ -0,0 +1,128 @@ +/* + * TTS - track your time. + * Copyright (c) 2012-2014 Felicity Tarnell. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely. This software is provided 'as-is', without any express or implied + * warranty. + */ + +#include "style.h" +#include "ui.h" +#include "wide.h" + +short default_fg, default_bg; + +style_t sy_header = { 1, 0 }, + sy_status = { 2, 0 }, + sy_entry = { 3, 0 }, + sy_running = { 4, 0 }, + sy_selected = { 5, 0 }, + sy_date = { 6, 0 }; + +static attrname_t attrnames[] = { + { WIDE("normal"), WA_NORMAL }, + { WIDE("bold"), WA_BOLD }, + { WIDE("reverse"), WA_REVERSE }, + { WIDE("blink"), WA_BLINK }, + { WIDE("dim"), WA_DIM }, + { WIDE("underline"), WA_UNDERLINE }, + { WIDE("standout"), WA_STANDOUT } +}; + +static colour_t colours[] = { + { WIDE("black"), COLOR_BLACK }, + { WIDE("red"), COLOR_RED }, + { WIDE("green"), COLOR_GREEN }, + { WIDE("yellow"), COLOR_YELLOW }, + { WIDE("blue"), COLOR_BLUE }, + { WIDE("magenta"), COLOR_MAGENTA }, + { WIDE("cyan"), COLOR_CYAN }, + { WIDE("white"), COLOR_WHITE } +}; + +int +attr_find(name, result) + const WCHAR *name; + attr_t *result; +{ +size_t i; + for (i = 0; i < sizeof(attrnames) / sizeof(*attrnames); i++) { + if (STRCMP(attrnames[i].an_name, name) == 0) { + *result = attrnames[i].an_value; + return 0; + } + } + + return -1; +} + +int +colour_find(name, result) + const WCHAR *name; + short *result; +{ +size_t i; + for (i = 0; i < sizeof(colours) / sizeof(*colours); i++) { + if (STRCMP(colours[i].co_name, name) == 0) { + *result = colours[i].co_value; + return 0; + } + } + + return -1; +} + +void +style_clear(sy) + style_t *sy; +{ + init_pair(sy->sy_pair, default_fg, default_bg); + sy->sy_attrs = WA_NORMAL; +} + +int +style_set(sy, fg, bg) + style_t *sy; + const WCHAR *fg, *bg; +{ + sy->sy_attrs = WA_NORMAL; + init_pair(sy->sy_pair, default_fg, default_bg); + return style_add(sy, fg, bg); +} + +int +style_add(sy, fg, bg) + style_t *sy; + const WCHAR *fg, *bg; +{ +attr_t at; +short colfg, colbg = default_bg; + + if (colour_find(fg, &colfg) == 0) { + if (bg && (colour_find(bg, &colbg) == -1)) + return -1; + + init_pair(sy->sy_pair, colfg, colbg); + return 0; + } + + if (attr_find(fg, &at) == -1) + return -1; + sy->sy_attrs |= at; + return 0; +} + +void +apply_styles() +{ + wbkgd(statwin, style_bg(sy_status)); + wattr_on(statwin, style_fg(sy_status), NULL); + drawstatus(WIDE("")); + + wbkgd(titwin, style_bg(sy_header)); + wattr_on(titwin, style_fg(sy_header), NULL); + drawheader(); +} + diff --git a/style.h b/style.h index 9afac1b..7bc0879 100644 --- a/style.h +++ b/style.h @@ -12,6 +12,7 @@ #define TTS_STYLE_H #include "tts_curses.h" +#include "wide.h" typedef struct style { short sy_pair; @@ -38,6 +39,8 @@ extern style_t sy_header, sy_selected, sy_date; +extern short default_fg, default_bg; + int attr_find(const WCHAR *name, attr_t *result); int colour_find(const WCHAR *name, short *result); diff --git a/tts.c b/tts.c index dc74e9d..9ae691f 100644 --- a/tts.c +++ b/tts.c @@ -77,74 +77,6 @@ static char statfile[PATH_MAX + 1]; static int load_file(const char *); -static tkey_t keys[] = { - { KEY_BREAK, WIDE("") }, - { KEY_DOWN, WIDE("") }, - { KEY_UP, WIDE("") }, - { KEY_LEFT, WIDE("") }, - { KEY_RIGHT, WIDE("") }, - { KEY_HOME, WIDE("") }, - { KEY_BACKSPACE, WIDE("") }, - { 0x7F, WIDE("") }, /* DEL */ - { KEY_F(0), WIDE("") }, - { KEY_F(1), WIDE("") }, - { KEY_F(2), WIDE("") }, - { KEY_F(3), WIDE("") }, - { KEY_F(4), WIDE("") }, - { KEY_F(5), WIDE("") }, - { KEY_F(6), WIDE("") }, - { KEY_F(7), WIDE("") }, - { KEY_F(8), WIDE("") }, - { KEY_F(9), WIDE("") }, - { KEY_F(10), WIDE("") }, - { KEY_F(11), WIDE("") }, - { KEY_F(12), WIDE("") }, - { KEY_F(13), WIDE("") }, - { KEY_F(14), WIDE("") }, - { KEY_F(15), WIDE("") }, - { KEY_F(16), WIDE("") }, - { KEY_F(17), WIDE("") }, - { KEY_F(18), WIDE("") }, - { KEY_F(19), WIDE("") }, - { KEY_F(20), WIDE("") }, - { KEY_F(21), WIDE("") }, - { KEY_F(22), WIDE("") }, - { KEY_F(23), WIDE("") }, - { KEY_F(24), WIDE("") }, - { KEY_NPAGE, WIDE("") }, - { KEY_PPAGE, WIDE("") }, - { '\001', WIDE("") }, - { '\002', WIDE("") }, - { '\003', WIDE("") }, - { '\004', WIDE("") }, - { '\005', WIDE("") }, - { '\006', WIDE("") }, - { '\007', WIDE("") }, - { '\010', WIDE("") }, - { '\011', WIDE("") }, - { '\011', WIDE("") }, - { '\012', WIDE("") }, - { '\013', WIDE("") }, - { '\014', WIDE("") }, - { '\015', WIDE("") }, - { '\016', WIDE("") }, - { '\017', WIDE("") }, - { '\020', WIDE("") }, - { '\021', WIDE("") }, - { '\022', WIDE("") }, - { '\023', WIDE("") }, - { '\024', WIDE("") }, - { '\025', WIDE("") }, - { '\026', WIDE("") }, - { '\027', WIDE("") }, - { '\030', WIDE("") }, - { '\031', WIDE("") }, - { ' ', WIDE("") }, - { KEY_ENTER, WIDE("") }, - { KEY_BACKSPACE, WIDE("") }, - { KEY_DC, WIDE("") } -}; - int pagestart; entry_t *curent; @@ -152,36 +84,6 @@ int showinv = 0; static WCHAR *macro_text, *macro_pos; -static attrname_t attrnames[] = { - { WIDE("normal"), WA_NORMAL }, - { WIDE("bold"), WA_BOLD }, - { WIDE("reverse"), WA_REVERSE }, - { WIDE("blink"), WA_BLINK }, - { WIDE("dim"), WA_DIM }, - { WIDE("underline"), WA_UNDERLINE }, - { WIDE("standout"), WA_STANDOUT } -}; - -static colour_t colours[] = { - { WIDE("black"), COLOR_BLACK }, - { WIDE("red"), COLOR_RED }, - { WIDE("green"), COLOR_GREEN }, - { WIDE("yellow"), COLOR_YELLOW }, - { WIDE("blue"), COLOR_BLUE }, - { WIDE("magenta"), COLOR_MAGENTA }, - { WIDE("cyan"), COLOR_CYAN }, - { WIDE("white"), COLOR_WHITE } -}; - -static short default_fg, default_bg; - -style_t sy_header = { 1, 0 }, - sy_status = { 2, 0 }, - sy_entry = { 3, 0 }, - sy_running = { 4, 0 }, - sy_selected = { 5, 0 }, - sy_date = { 6, 0 }; - time_t itime = 0; int show_billable = 0; @@ -537,198 +439,6 @@ struct kevent evs[2], rev; return 0; } -void -drawentries() -{ -int i, nlines; -int cline = 0; -time_t lastday = 0; -entry_t *en; -chtype oldbg; - - getmaxyx(listwin, nlines, i); - - TTS_TAILQ_FOREACH(en, &entries, en_entries) - en->en_flags.efl_visible = 0; - - en = TTS_TAILQ_FIRST(&entries); - for (i = 0; i < pagestart; i++) - if ((en = TTS_TAILQ_NEXT(en, en_entries)) == NULL) - return; - - for (; en; en = TTS_TAILQ_NEXT(en, en_entries)) { - time_t n; - int h, s, m; - WCHAR flags[10], stime[16], *p; - attr_t attrs = WA_NORMAL; - - if (!showinv && en->en_flags.efl_invoiced) - continue; - - oldbg = getbkgd(listwin); - - if (lastday != entry_day(en)) { - struct tm *lt; - WCHAR lbl[128]; - time_t itime = entry_time_for_day(entry_day(en), 1, 0), - ntime = entry_time_for_day(entry_day(en), 0, 0), - btime = entry_time_for_day(entry_day(en), 2, bill_increment); - int hi, mi, si, - hn, mn, sn, - hb, mb, sb, - ht, mt, st; - WCHAR hdrtext[256]; - - time_to_hms(itime, hi, mi, si); - time_to_hms(ntime, hn, mn, sn); - time_to_hms(btime, hb, mb, sb); - time_to_hms(itime + ntime, ht, mt, st); - - oldbg = getbkgd(listwin); - wbkgdset(listwin, style_bg(sy_entry)); - wattr_on(listwin, style_fg(sy_entry), NULL); - - wmove(listwin, cline, 0); - wclrtoeol(listwin); - - wbkgdset(listwin, oldbg); - wattr_off(listwin, style_fg(sy_entry), NULL); - - if (++cline >= nlines) - break; - - lastday = entry_day(en); - lt = localtime(&lastday); - - STRFTIME(lbl, WSIZEOF(lbl), WIDE("%A, %d %B %Y"), lt); - if (show_billable) - SNPRINTF(hdrtext, WSIZEOF(hdrtext), - WIDE("%-30"FMT_L"s [I:%02d:%02d:%02d / " - "N:%02d:%02d:%02d / T:%02d:%02d:%02d / " - "B:%02d:%02d:%02d]"), - lbl, hi, mi, si, hn, mn, sn, ht, mt, st, - hb, mb, sb); - else - SNPRINTF(hdrtext, WSIZEOF(hdrtext), - WIDE("%-30"FMT_L"s [I:%02d:%02d:%02d / " - "N:%02d:%02d:%02d / T:%02d:%02d:%02d]"), - lbl, hi, mi, si, hn, mn, sn, ht, mt, st); - - wattr_on(listwin, style_fg(sy_date), NULL); - wbkgdset(listwin, style_bg(sy_date)); - wmove(listwin, cline, 0); - WADDSTR(listwin, hdrtext); - wclrtoeol(listwin); - wattr_off(listwin, style_fg(sy_date), NULL); - wbkgdset(listwin, oldbg); - - if (++cline >= nlines) { - wbkgdset(listwin, oldbg); - wattr_off(listwin, style_fg(sy_date), NULL); - break; - } - - oldbg = getbkgd(listwin); - wbkgdset(listwin, style_bg(sy_entry)); - wattr_on(listwin, style_fg(sy_entry), NULL); - - wmove(listwin, cline, 0); - wclrtoeol(listwin); - - wbkgdset(listwin, oldbg); - wattr_off(listwin, style_fg(sy_entry), NULL); - - if (++cline >= nlines) - break; - } - - en->en_flags.efl_visible = 1; - wmove(listwin, cline, 0); - - attrs = style_fg(sy_entry); - - if (en->en_started && en == curent) - attrs = style_fg(sy_selected) | - (style_fg(sy_running) & ( - WA_STANDOUT | WA_UNDERLINE | - WA_REVERSE | WA_BLINK | WA_DIM | - WA_BOLD)); - else if (en->en_started) - attrs = style_fg(sy_running); - else if (en == curent) - attrs = style_fg(sy_selected); - - wbkgdset(listwin, ' ' | (attrs & ~WA_UNDERLINE)); - wattr_on(listwin, attrs, NULL); - - if (en == curent) { - WADDSTR(listwin, WIDE(" -> ")); - } else - WADDSTR(listwin, WIDE(" ")); - - n = en->en_secs; - if (en->en_started) - n += time(NULL) - en->en_started; - h = n / (60 * 60); - n %= (60 * 60); - m = n / 60; - n %= 60; - s = n; - - SNPRINTF(stime, WSIZEOF(stime), WIDE("%02d:%02d:%02d%c "), - h, m, s, (itime && (en == running)) ? '*' : ' '); - WADDSTR(listwin, stime); - - memset(flags, 0, sizeof(flags)); - p = flags; - - if (en->en_flags.efl_marked) - *p++ = 'M'; - else - *p++ = ' '; - - if (en->en_flags.efl_invoiced) - *p++ = 'I'; - else - *p++ = ' '; - - if (!en->en_flags.efl_nonbillable) - *p++ = 'B'; - else - *p++ = ' '; - - if (en->en_flags.efl_deleted) - *p++ = 'D'; - else - *p++ = ' '; - - if (*flags) { - WCHAR s[10]; - SNPRINTF(s, WSIZEOF(s), WIDE("%-5"FMT_L"s "), flags); - WADDSTR(listwin, s); - } else - WADDSTR(listwin, WIDE(" ")); - - WADDSTR(listwin, en->en_desc); - wclrtoeol(listwin); - wbkgdset(listwin, oldbg); - wattr_off(listwin, attrs, NULL); - - if (++cline >= nlines) - return; - } - - oldbg = getbkgd(listwin); - wattr_on(listwin, style_fg(sy_entry), NULL); - wbkgdset(listwin, style_bg(sy_entry)); - for (; cline < nlines; cline++) { - wmove(listwin, cline, 0); - wclrtoeol(listwin); - } - wattr_off(listwin, style_fg(sy_entry), NULL); - wbkgdset(listwin, oldbg); -} - int load() { @@ -902,59 +612,6 @@ entry_t *en; return 0; } -void -errbox(const WCHAR *msg, ...) -{ -va_list ap; - va_start(ap, msg); - verrbox(msg, ap); - va_end(ap); -} - -void -verrbox(msg, ap) - const WCHAR *msg; - va_list ap; -{ -WCHAR text[4096]; -WINDOW *ewin; - -#define ETITLE WIDE(" Error ") -#define ECONT WIDE(" ") -int width; -INT c; - - VSNPRINTF(text, WSIZEOF(text), msg, ap); - width = STRLEN(text); - - ewin = newwin(6, width + 4, - (LINES / 2) - ((1 + 2)/ 2), - (COLS / 2) - ((width + 2) / 2)); - leaveok(ewin, TRUE); - wborder(ewin, 0, 0, 0, 0, 0, 0, 0, 0); - - wattron(ewin, A_REVERSE | A_BOLD); - wmove(ewin, 0, (width / 2) - (WSIZEOF(ETITLE) - 1)/2); - WADDSTR(ewin, ETITLE); - wattroff(ewin, A_REVERSE | A_BOLD); - - wmove(ewin, 2, 2); - WADDSTR(ewin, text); - wattron(ewin, A_REVERSE | A_BOLD); - wmove(ewin, 4, (width / 2) - ((WSIZEOF(ECONT) - 1) / 2)); - WADDSTR(ewin, ECONT); - wattroff(ewin, A_REVERSE | A_BOLD); - - for (;;) { - if (WGETCH(ewin, &c) == ERR) - continue; - if (c == '\r') - break; - } - - delwin(ewin); -} - history_t * hist_new() { @@ -965,7 +622,8 @@ history_t *hi; return hi; } -void hist_add(hi, text) +void +hist_add(hi, text) history_t *hi; const WCHAR *text; { @@ -990,99 +648,6 @@ histent_t *hent; ++hi->hi_nents; } -/* - * Return the tkey_t for the key called .name, or NULL if such a key doesn't - * exist. - */ -tkey_t * -find_key(name) - const WCHAR *name; -{ -size_t i; - - for (i = 0; i < sizeof(keys) / sizeof(*keys); i++) - if (STRCMP(name, keys[i].ky_name) == 0) - return &keys[i]; - return NULL; -} - -/* - * Return the function_t for the function called .name, or NULL if such a - * function doesn't exist. - */ -function_t * -find_func(name) - const WCHAR *name; -{ -function_t *f; - for (f = funcs; f->fn_name; f++) - if (STRCMP(name, f->fn_name) == 0) - return f; - return NULL; -} - -/* - * Bind .keyname to run the function .funcname. If a binding for .keyname - * already exists, overwrite it. - * - * If .keyname is a single character, e.g. 'a', it is used as a key name - * directly, rather than being looked up in the key table. - */ -void -bind_key(keyname, funcname, is_macro) - const WCHAR *keyname, *funcname; -{ -tkey_t *key = NULL; -function_t *func; -binding_t *binding; -INT code; - - /* Find the key and the function */ - if (STRLEN(keyname) > 1) { - if ((key = find_key(keyname)) == NULL) { - errbox(WIDE("Unknown key \"%"FMT_L"s\""), keyname); - return; - } - code = key->ky_code; - } else - code = *keyname; - - if (!is_macro) { - if ((func = find_func(funcname)) == NULL) { - errbox(WIDE("Unknown function \"%"FMT_L"s\""), funcname); - return; - } - } - - /* Do we already have a binding for this key? */ - TTS_TAILQ_FOREACH(binding, &bindings, bi_entries) { - if (binding->bi_code == code) { - if (is_macro) { - binding->bi_func = NULL; - binding->bi_macro = STRDUP(funcname); - } else { - free(binding->bi_macro); - binding->bi_func = func; - } - return; - } - } - - /* No, add a new one */ - if ((binding = calloc(1, sizeof(*binding))) == NULL) - return; - - binding->bi_key = key; - binding->bi_code = code; - - if (is_macro) - binding->bi_macro = STRDUP(funcname); - else - binding->bi_func = func; - - TTS_TAILQ_INSERT_TAIL(&bindings, binding, bi_entries); -} - variable_t * find_variable(name) WCHAR const *name; @@ -1094,90 +659,6 @@ variable_t *v; return NULL; } -int -attr_find(name, result) - const WCHAR *name; - attr_t *result; -{ -size_t i; - for (i = 0; i < sizeof(attrnames) / sizeof(*attrnames); i++) { - if (STRCMP(attrnames[i].an_name, name) == 0) { - *result = attrnames[i].an_value; - return 0; - } - } - - return -1; -} - -int -colour_find(name, result) - const WCHAR *name; - short *result; -{ -size_t i; - for (i = 0; i < sizeof(colours) / sizeof(*colours); i++) { - if (STRCMP(colours[i].co_name, name) == 0) { - *result = colours[i].co_value; - return 0; - } - } - - return -1; -} - -void -style_clear(sy) - style_t *sy; -{ - init_pair(sy->sy_pair, default_fg, default_bg); - sy->sy_attrs = WA_NORMAL; -} - -int -style_set(sy, fg, bg) - style_t *sy; - const WCHAR *fg, *bg; -{ - sy->sy_attrs = WA_NORMAL; - init_pair(sy->sy_pair, default_fg, default_bg); - return style_add(sy, fg, bg); -} - -int -style_add(sy, fg, bg) - style_t *sy; - const WCHAR *fg, *bg; -{ -attr_t at; -short colfg, colbg = default_bg; - - if (colour_find(fg, &colfg) == 0) { - if (bg && (colour_find(bg, &colbg) == -1)) - return -1; - - init_pair(sy->sy_pair, colfg, colbg); - return 0; - } - - if (attr_find(fg, &at) == -1) - return -1; - sy->sy_attrs |= at; - return 0; -} - -void -apply_styles() -{ - wbkgd(statwin, style_bg(sy_status)); - wattr_on(statwin, style_fg(sy_status), NULL); - drawstatus(WIDE("")); - - wbkgd(titwin, style_bg(sy_header)); - wattr_on(titwin, style_fg(sy_header), NULL); - drawheader(); -} - static char *curfile; static int lineno, nerr; @@ -1282,52 +763,6 @@ char input[1024]; return 0; } -int -prduration(pr, hh, mm, ss) - WCHAR *pr; - int *hh, *mm, *ss; -{ -WCHAR *tstr; -int h, m, s; - if ((tstr = prompt(pr, WIDE("00:00:00"), NULL)) == NULL) - return -1; - - if (!*tstr) { - drawstatus(WIDE("No duration entered")); - free(tstr); - return -1; - } - - if (SSCANF(tstr, WIDE("%d:%d:%d"), &h, &m, &s) != 3) { - h = 0; - if (SSCANF(tstr, WIDE("%d:%d"), &m, &s) != 2) { - m = 0; - if (SSCANF(tstr, WIDE("%d"), &s) != 1) { - free(tstr); - drawstatus(WIDE("Invalid time format.")); - return -1; - } - } - } - - free(tstr); - - if (m >= 60) { - drawstatus(WIDE("Minutes cannot be more than 59.")); - return -1; - } - - if (s >= 60) { - drawstatus(WIDE("Seconds cannot be more than 59.")); - return -1; - } - - *hh = h; - *mm = m; - *ss = s; - return 0; -} - #ifdef USE_DARWIN_POWER static void prompt_sleep() diff --git a/ui.c b/ui.c index c9e44ec..1ea29fe 100644 --- a/ui.c +++ b/ui.c @@ -9,6 +9,7 @@ */ #include +#include #include "ui.h" #include "tts.h" @@ -315,3 +316,294 @@ end: ; return STRDUP(input); } +void +errbox(const WCHAR *msg, ...) +{ +va_list ap; + va_start(ap, msg); + verrbox(msg, ap); + va_end(ap); +} + +void +verrbox(msg, ap) + const WCHAR *msg; + va_list ap; +{ +WCHAR text[4096]; +WINDOW *ewin; + +#define ETITLE WIDE(" Error ") +#define ECONT WIDE(" ") +int width; +INT c; + + VSNPRINTF(text, WSIZEOF(text), msg, ap); + width = STRLEN(text); + + ewin = newwin(6, width + 4, + (LINES / 2) - ((1 + 2)/ 2), + (COLS / 2) - ((width + 2) / 2)); + leaveok(ewin, TRUE); + wborder(ewin, 0, 0, 0, 0, 0, 0, 0, 0); + + wattron(ewin, A_REVERSE | A_BOLD); + wmove(ewin, 0, (width / 2) - (WSIZEOF(ETITLE) - 1)/2); + WADDSTR(ewin, ETITLE); + wattroff(ewin, A_REVERSE | A_BOLD); + + wmove(ewin, 2, 2); + WADDSTR(ewin, text); + wattron(ewin, A_REVERSE | A_BOLD); + wmove(ewin, 4, (width / 2) - ((WSIZEOF(ECONT) - 1) / 2)); + WADDSTR(ewin, ECONT); + wattroff(ewin, A_REVERSE | A_BOLD); + + for (;;) { + if (WGETCH(ewin, &c) == ERR) + continue; + if (c == '\r') + break; + } + + delwin(ewin); +} + +void +drawentries() +{ +int i, nlines; +int cline = 0; +time_t lastday = 0; +entry_t *en; +chtype oldbg; + + getmaxyx(listwin, nlines, i); + + TTS_TAILQ_FOREACH(en, &entries, en_entries) + en->en_flags.efl_visible = 0; + + en = TTS_TAILQ_FIRST(&entries); + for (i = 0; i < pagestart; i++) + if ((en = TTS_TAILQ_NEXT(en, en_entries)) == NULL) + return; + + for (; en; en = TTS_TAILQ_NEXT(en, en_entries)) { + time_t n; + int h, s, m; + WCHAR flags[10], stime[16], *p; + attr_t attrs = WA_NORMAL; + + if (!showinv && en->en_flags.efl_invoiced) + continue; + + oldbg = getbkgd(listwin); + + if (lastday != entry_day(en)) { + struct tm *lt; + WCHAR lbl[128]; + time_t itime = entry_time_for_day(entry_day(en), 1, 0), + ntime = entry_time_for_day(entry_day(en), 0, 0), + btime = entry_time_for_day(entry_day(en), 2, bill_increment); + int hi, mi, si, + hn, mn, sn, + hb, mb, sb, + ht, mt, st; + WCHAR hdrtext[256]; + + time_to_hms(itime, hi, mi, si); + time_to_hms(ntime, hn, mn, sn); + time_to_hms(btime, hb, mb, sb); + time_to_hms(itime + ntime, ht, mt, st); + + oldbg = getbkgd(listwin); + wbkgdset(listwin, style_bg(sy_entry)); + wattr_on(listwin, style_fg(sy_entry), NULL); + + wmove(listwin, cline, 0); + wclrtoeol(listwin); + + wbkgdset(listwin, oldbg); + wattr_off(listwin, style_fg(sy_entry), NULL); + + if (++cline >= nlines) + break; + + lastday = entry_day(en); + lt = localtime(&lastday); + + STRFTIME(lbl, WSIZEOF(lbl), WIDE("%A, %d %B %Y"), lt); + if (show_billable) + SNPRINTF(hdrtext, WSIZEOF(hdrtext), + WIDE("%-30"FMT_L"s [I:%02d:%02d:%02d / " + "N:%02d:%02d:%02d / T:%02d:%02d:%02d / " + "B:%02d:%02d:%02d]"), + lbl, hi, mi, si, hn, mn, sn, ht, mt, st, + hb, mb, sb); + else + SNPRINTF(hdrtext, WSIZEOF(hdrtext), + WIDE("%-30"FMT_L"s [I:%02d:%02d:%02d / " + "N:%02d:%02d:%02d / T:%02d:%02d:%02d]"), + lbl, hi, mi, si, hn, mn, sn, ht, mt, st); + + wattr_on(listwin, style_fg(sy_date), NULL); + wbkgdset(listwin, style_bg(sy_date)); + wmove(listwin, cline, 0); + WADDSTR(listwin, hdrtext); + wclrtoeol(listwin); + wattr_off(listwin, style_fg(sy_date), NULL); + wbkgdset(listwin, oldbg); + + if (++cline >= nlines) { + wbkgdset(listwin, oldbg); + wattr_off(listwin, style_fg(sy_date), NULL); + break; + } + + oldbg = getbkgd(listwin); + wbkgdset(listwin, style_bg(sy_entry)); + wattr_on(listwin, style_fg(sy_entry), NULL); + + wmove(listwin, cline, 0); + wclrtoeol(listwin); + + wbkgdset(listwin, oldbg); + wattr_off(listwin, style_fg(sy_entry), NULL); + + if (++cline >= nlines) + break; + } + + en->en_flags.efl_visible = 1; + wmove(listwin, cline, 0); + + attrs = style_fg(sy_entry); + + if (en->en_started && en == curent) + attrs = style_fg(sy_selected) | + (style_fg(sy_running) & ( + WA_STANDOUT | WA_UNDERLINE | + WA_REVERSE | WA_BLINK | WA_DIM | + WA_BOLD)); + else if (en->en_started) + attrs = style_fg(sy_running); + else if (en == curent) + attrs = style_fg(sy_selected); + + wbkgdset(listwin, ' ' | (attrs & ~WA_UNDERLINE)); + wattr_on(listwin, attrs, NULL); + + if (en == curent) { + WADDSTR(listwin, WIDE(" -> ")); + } else + WADDSTR(listwin, WIDE(" ")); + + n = en->en_secs; + if (en->en_started) + n += time(NULL) - en->en_started; + h = n / (60 * 60); + n %= (60 * 60); + m = n / 60; + n %= 60; + s = n; + + SNPRINTF(stime, WSIZEOF(stime), WIDE("%02d:%02d:%02d%c "), + h, m, s, (itime && (en == running)) ? '*' : ' '); + WADDSTR(listwin, stime); + + memset(flags, 0, sizeof(flags)); + p = flags; + + if (en->en_flags.efl_marked) + *p++ = 'M'; + else + *p++ = ' '; + + if (en->en_flags.efl_invoiced) + *p++ = 'I'; + else + *p++ = ' '; + + if (!en->en_flags.efl_nonbillable) + *p++ = 'B'; + else + *p++ = ' '; + + if (en->en_flags.efl_deleted) + *p++ = 'D'; + else + *p++ = ' '; + + if (*flags) { + WCHAR s[10]; + SNPRINTF(s, WSIZEOF(s), WIDE("%-5"FMT_L"s "), flags); + WADDSTR(listwin, s); + } else + WADDSTR(listwin, WIDE(" ")); + + WADDSTR(listwin, en->en_desc); + wclrtoeol(listwin); + wbkgdset(listwin, oldbg); + wattr_off(listwin, attrs, NULL); + + if (++cline >= nlines) + return; + } + + oldbg = getbkgd(listwin); + wattr_on(listwin, style_fg(sy_entry), NULL); + wbkgdset(listwin, style_bg(sy_entry)); + for (; cline < nlines; cline++) { + wmove(listwin, cline, 0); + wclrtoeol(listwin); + } + wattr_off(listwin, style_fg(sy_entry), NULL); + wbkgdset(listwin, oldbg); +} + +int +prduration(pr, hh, mm, ss) + WCHAR *pr; + int *hh, *mm, *ss; +{ +WCHAR *tstr; +int h, m, s; + if ((tstr = prompt(pr, WIDE("00:00:00"), NULL)) == NULL) + return -1; + + if (!*tstr) { + drawstatus(WIDE("No duration entered")); + free(tstr); + return -1; + } + + if (SSCANF(tstr, WIDE("%d:%d:%d"), &h, &m, &s) != 3) { + h = 0; + if (SSCANF(tstr, WIDE("%d:%d"), &m, &s) != 2) { + m = 0; + if (SSCANF(tstr, WIDE("%d"), &s) != 1) { + free(tstr); + drawstatus(WIDE("Invalid time format.")); + return -1; + } + } + } + + free(tstr); + + if (m >= 60) { + drawstatus(WIDE("Minutes cannot be more than 59.")); + return -1; + } + + if (s >= 60) { + drawstatus(WIDE("Seconds cannot be more than 59.")); + return -1; + } + + *hh = h; + *mm = m; + *ss = s; + return 0; +} +