diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-21 22:07:58 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-21 22:07:58 +0200 |
| commit | ad8e1707374ca56bed3dbf472dc8b6bb6cb1f38b (patch) | |
| tree | 16aa7a868b4a95a8ee12c8e371f6f4e57c37b6a6 /clients | |
| parent | f2c8f68763494f64a0a2d2e48d852bd83bd6df65 (diff) | |
| download | bokf-0.1.61.tar.gz bokf-0.1.61.zip | |
tui: granska/ladda ned underlag via pagern eller skrivbordsvisarenv0.1.61
Diffstat (limited to 'clients')
| -rw-r--r-- | clients/screens_attachments.c | 2 | ||||
| -rw-r--r-- | clients/screens_invoices.c | 4 | ||||
| -rw-r--r-- | clients/screens_payroll.c | 2 | ||||
| -rw-r--r-- | clients/screens_vouchers.c | 2 | ||||
| -rw-r--r-- | clients/ui.c | 98 | ||||
| -rw-r--r-- | clients/ui.h | 6 |
6 files changed, 84 insertions, 30 deletions
diff --git a/clients/screens_attachments.c b/clients/screens_attachments.c index 3eeb9e9..c72ee67 100644 --- a/clients/screens_attachments.c +++ b/clients/screens_attachments.c @@ -158,6 +158,6 @@ void inbox_screen(struct app *a) continue; } if (sel_id) - attachment_download(a, sel_id); + attachment_view_or_download(a, sel_id); } } diff --git a/clients/screens_invoices.c b/clients/screens_invoices.c index 8fb32eb..d685e83 100644 --- a/clients/screens_invoices.c +++ b/clients/screens_invoices.c @@ -476,7 +476,7 @@ static void inv_detail_pdf(struct invctx *ctx) char fname[800]; snprintf(fname, sizeof fname, "Faktura %lld %s.pdf", (long long)ctx->number, ctx->customer); - pdf_save_and_open(b64, fname, "Faktura PDF"); + file_save_and_open(b64, fname, "Faktura PDF"); free(b64); } free(resp); @@ -967,7 +967,7 @@ static void iform_preview(struct iform *f) } char *b64 = jstr_dup(resp, "result.content_base64"); if (b64) { - pdf_save_and_open(b64, "Faktura förhandsvisning.pdf", "Faktura PDF"); + file_save_and_open(b64, "Faktura förhandsvisning.pdf", "Faktura PDF"); free(b64); } free(resp); diff --git a/clients/screens_payroll.c b/clients/screens_payroll.c index 234778c..8a27ec8 100644 --- a/clients/screens_payroll.c +++ b/clients/screens_payroll.c @@ -898,7 +898,7 @@ static void payroll_run_payslip(struct payroll_run *r) char *fname = jstr_dup(resp, "result.filename"); free(resp); if (b64 && fname) - pdf_save_and_open(b64, fname, "Lönebesked"); + file_save_and_open(b64, fname, "Lönebesked"); free(b64); free(fname); } diff --git a/clients/screens_vouchers.c b/clients/screens_vouchers.c index d884b6e..52d29da 100644 --- a/clients/screens_vouchers.c +++ b/clients/screens_vouchers.c @@ -137,7 +137,7 @@ static int vd_key(void *ud, int ch) int asel = tui_select_list("Underlag", alines, (int)ctx->natts, 0, 0, &acursor, 0, "ta bort", 0); if (asel >= 0) { - attachment_download(a, aids[asel]); + attachment_view_or_download(a, aids[asel]); } else if (asel == -6 && acursor >= 0 && (size_t)acursor < ctx->natts) { char q[320]; diff --git a/clients/ui.c b/clients/ui.c index e6f6e07..cda0883 100644 --- a/clients/ui.c +++ b/clients/ui.c @@ -472,26 +472,9 @@ static void safe_fname(const char *in, char *out, size_t n) out[o] = '\0'; } -static int write_pdf_b64(const char *b64, const char *path) -{ - unsigned char *data = NULL; - size_t len = 0; - if (!b64 || util_b64_decode(b64, strlen(b64), &data, &len) != 0) - return -1; - FILE *fp = fopen(path, "wb"); - if (!fp) { - free(data); - return -1; - } - size_t wrote = fwrite(data, 1, len, fp); - fclose(fp); - free(data); - return wrote == len ? 0 : -1; -} - -/* Open a saved PDF with xdg-open when a desktop session is present; +/* Open a saved file with xdg-open when a desktop session is present; otherwise (or on fork failure) show where it was saved. */ -static void open_pdf(const char *path, const char *title) +static void open_saved(const char *path, const char *title) { const char *display = getenv("DISPLAY"); const char *wayland = getenv("WAYLAND_DISPLAY"); @@ -515,8 +498,8 @@ static void open_pdf(const char *path, const char *title) tui_message(title, "Sparad: %s", path); } -void pdf_save_and_open(const char *b64, const char *filename, - const char *title) +static void save_cache_and_open(const unsigned char *data, size_t n, + const char *filename, const char *title) { char dir[512], path[700], safe[600]; pdf_cache_dir(dir, sizeof dir); @@ -526,11 +509,80 @@ void pdf_save_and_open(const char *b64, const char *filename, return; } config_mkdirs(path); - if (write_pdf_b64(b64, path) != 0) { + FILE *fp = fopen(path, "wb"); + if (!fp || (n > 0 && fwrite(data, 1, n, fp) != n)) { + if (fp) + fclose(fp); tui_message(title, "Kunde inte spara %s", path); return; } - open_pdf(path, title); + fclose(fp); + open_saved(path, title); +} + +void file_save_and_open(const char *b64, const char *filename, + const char *title) +{ + unsigned char *data = NULL; + size_t n = 0; + if (!b64 || util_b64_decode(b64, strlen(b64), &data, &n) != 0) { + tui_message(title, "Kunde inte avkoda innehållet."); + return; + } + save_cache_and_open(data, n, filename, title); + free(data); +} + +/* Show one attachment: text inline in a pager, anything else through the + desktop viewer (or a message with the saved path). */ +void attachment_open(struct app *a, int64_t att_id) +{ + char args[64]; + snprintf(args, sizeof args, "{\"id\":%lld}", (long long)att_id); + char *resp = + client_rpc(&a->conn, "attachment.get", a->session, a->org, args); + if (!resp || !client_ok(resp)) { + show_error("Kunde inte hämta underlaget", resp); + free(resp); + return; + } + char *fn = jstr_dup(resp, "result.filename"); + char *mime = jstr_dup(resp, "result.mime"); + char *b64 = jstr_dup(resp, "result.content_base64"); + unsigned char *data = NULL; + size_t n = 0; + if (!b64 || util_b64_decode(b64, strlen(b64), &data, &n) != 0) { + tui_message("Underlag", "Kunde inte avkoda innehållet."); + goto done; + } + int is_text = (mime && strncmp(mime, "text/", 5) == 0) || + (n > 0 && bytes_look_text(data, n)); + if (is_text && n <= 256 * 1024) { + char *copy = xmalloc(n + 1); + memcpy(copy, data, n); + copy[n] = '\0'; + tui_pager("Underlag", copy, NULL); + free(copy); + } else { + save_cache_and_open(data, n, fn && *fn ? fn : "underlag", "Underlag"); + } +done: + free(data); + free(b64); + free(mime); + free(fn); + free(resp); +} + +/* Enter on an attachment row: granska or ladda ned. */ +void attachment_view_or_download(struct app *a, int64_t att_id) +{ + static const char *const opts[] = { "Granska", "Ladda ned…" }; + int c = tui_choice_prompt("Underlag: ", opts, 2, 0); + if (c == 0) + attachment_open(a, att_id); + else if (c == 1) + attachment_download(a, att_id); } /* Fetch one attachment, save it to a prompted path and verify its hash. diff --git a/clients/ui.h b/clients/ui.h index b4ce5f5..393d5ff 100644 --- a/clients/ui.h +++ b/clients/ui.h @@ -79,9 +79,11 @@ char *rpc_dry(struct app *a, const char *cmd, const char *args); char *read_file_b64(const char *path); char *file_browser(struct app *a, const char *start_dir); void attachment_download(struct app *a, int64_t att_id); +void attachment_open(struct app *a, int64_t att_id); +void attachment_view_or_download(struct app *a, int64_t att_id); int64_t pick_voucher(struct app *a); -void pdf_save_and_open(const char *b64, const char *filename, - const char *title); +void file_save_and_open(const char *b64, const char *filename, + const char *title); /* generated-document helpers (reports, bokslut) */ void buf_line(struct buf *b, const char *fmt, ...) |
