diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-23 09:13:17 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-23 09:13:17 +0200 |
| commit | 53071bb69f5d21b35b8a61c2b1dd18832ce781d4 (patch) | |
| tree | fa76c13cef78925d1b9650e92f64d5115dcdb6e7 /clients/vlist.c | |
| parent | 2ca284619125af0d5c12e9210ff1bfc8f9122739 (diff) | |
| download | bokf-53071bb69f5d21b35b8a61c2b1dd18832ce781d4.tar.gz bokf-53071bb69f5d21b35b8a61c2b1dd18832ce781d4.zip | |
tui: aligned voucher detail, up/down between vouchers, list sorting
The detail pads every column by display width, blanks zero amounts and
shows row texts and a Summa line. Up/Down step to the previous/next
voucher in the list order; 's' cycles the list sort (number or date,
ascending or descending, saved in tui.conf). The list fetches all pages
of voucher.list instead of stopping at 200.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'clients/vlist.c')
| -rw-r--r-- | clients/vlist.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/clients/vlist.c b/clients/vlist.c new file mode 100644 index 0000000..933b704 --- /dev/null +++ b/clients/vlist.c @@ -0,0 +1,84 @@ +#include <stdlib.h> +#include <string.h> + +#include "vlist.h" + +static const char *const SORT_NAMES[VSORT_COUNT] = { + "number", "number-desc", "date", "date-desc", +}; + +static const char *const SORT_LABELS[VSORT_COUNT] = { + "nummer, stigande", "nummer, fallande", "datum, stigande", + "datum, fallande", +}; + +static int cmp_i64(int64_t a, int64_t b) +{ + return a < b ? -1 : a > b; +} + +static int cmp_number(const struct vlist_item *a, const struct vlist_item *b) +{ + int c = strcmp(a->series, b->series); + if (c) + return c; + return cmp_i64(a->number, b->number); +} + +static int g_mode; /* qsort has no context argument in C11 */ + +static int cmp_items(const void *pa, const void *pb) +{ + const struct vlist_item *a = pa, *b = pb; + int desc = g_mode == VSORT_NUMBER_DESC || g_mode == VSORT_DATE_DESC; + int c = 0; + if (g_mode == VSORT_DATE || g_mode == VSORT_DATE_DESC) + c = strcmp(a->date, b->date); + if (!c) + c = cmp_number(a, b); + if (!c) + c = cmp_i64(a->id, b->id); + return desc ? -c : c; +} + +void vlist_sort(struct vlist_item *v, size_t n, int mode) +{ + if (!v || n < 2) + return; + g_mode = mode >= 0 && mode < VSORT_COUNT ? mode : VSORT_NUMBER; + qsort(v, n, sizeof *v, cmp_items); +} + +const char *vlist_sort_label(int mode) +{ + return SORT_LABELS[mode >= 0 && mode < VSORT_COUNT ? mode : 0]; +} + +const char *vlist_sort_name(int mode) +{ + return SORT_NAMES[mode >= 0 && mode < VSORT_COUNT ? mode : 0]; +} + +int vlist_sort_parse(const char *name) +{ + for (int i = 0; name && i < VSORT_COUNT; i++) + if (strcmp(name, SORT_NAMES[i]) == 0) + return i; + return VSORT_NUMBER; +} + +int vlist_index(const struct vlist_item *v, size_t n, int64_t id) +{ + for (size_t i = 0; i < n; i++) + if (v[i].id == id) + return (int)i; + return -1; +} + +int vlist_step(size_t n, int idx, int dir) +{ + if (idx < 0 || (size_t)idx >= n) + return -1; + int next = idx + (dir < 0 ? -1 : 1); + return next >= 0 && (size_t)next < n ? next : -1; +} |
