diff options
Diffstat (limited to 'clients')
| -rw-r--r-- | clients/bokftui.c | 10 | ||||
| -rw-r--r-- | clients/client.c | 3 | ||||
| -rw-r--r-- | clients/screens_bokslut.c | 2 | ||||
| -rw-r--r-- | clients/screens_dashboard.c | 53 | ||||
| -rw-r--r-- | clients/screens_ib.c | 2 | ||||
| -rw-r--r-- | clients/screens_invoices.c | 2 | ||||
| -rw-r--r-- | clients/screens_payroll.c | 5 | ||||
| -rw-r--r-- | clients/screens_settings.c | 97 | ||||
| -rw-r--r-- | clients/screens_templates.c | 2 | ||||
| -rw-r--r-- | clients/screens_vouchers.c | 2 | ||||
| -rw-r--r-- | clients/tui.c | 35 | ||||
| -rw-r--r-- | clients/ui.c | 19 | ||||
| -rw-r--r-- | clients/ui.h | 3 |
13 files changed, 145 insertions, 90 deletions
diff --git a/clients/bokftui.c b/clients/bokftui.c index a047ef5..69d6690 100644 --- a/clients/bokftui.c +++ b/clients/bokftui.c @@ -45,7 +45,7 @@ static const struct scene SCENES[] = { { "audit", audit_screen }, { "company", company_screen }, { "settings", company_screen }, /* ^R/--screen compatibility */ - { "system", system_settings_screen }, + { "system", system_screen }, { "bokslut", bokslut_screen }, { "yearinfo", bokslut_screen }, /* ^R compatibility */ }; @@ -146,11 +146,14 @@ static void config_load(struct app *a) snprintf(a->socket, sizeof a->socket, "%s", val); else if (strcmp(line, "user") == 0 && !a->username[0]) snprintf(a->username, sizeof a->username, "%s", val); + else if (strcmp(line, "attachment_dir") == 0 && + !a->attachment_dir[0]) + snprintf(a->attachment_dir, sizeof a->attachment_dir, "%s", val); } fclose(f); } -static void config_save(const struct app *a) +void config_save(struct app *a) { char path[512]; config_path(path, sizeof path); @@ -161,6 +164,8 @@ static void config_save(const struct app *a) fprintf(f, "server=%s\n", a->socket); if (a->username[0]) fprintf(f, "user=%s\n", a->username); + if (a->attachment_dir[0]) + fprintf(f, "attachment_dir=%s\n", a->attachment_dir); fclose(f); chmod(path, 0600); } @@ -341,6 +346,7 @@ static void usage(FILE *f) static void reset_modify_keys(void) { + putp("\033[<u"); putp("\033[>4m"); fflush(stdout); } diff --git a/clients/client.c b/clients/client.c index fd119f1..30f2a67 100644 --- a/clients/client.c +++ b/clients/client.c @@ -1,4 +1,5 @@ #include "client.h" +#include "tls_ca.h" #include <arpa/inet.h> #include <errno.h> @@ -126,7 +127,7 @@ static int tls_connect_addr(const char *addrport, struct client_conn *out) } SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); - SSL_CTX_set_default_verify_paths(ctx); + tls_load_default_cas(ctx); const char *ca = getenv("BOKFD_TLS_CA"); if (ca && *ca && SSL_CTX_load_verify_locations(ctx, ca, NULL) != 1) { set_tls_error("TLS CA file"); diff --git a/clients/screens_bokslut.c b/clients/screens_bokslut.c index df47196..3f69982 100644 --- a/clients/screens_bokslut.c +++ b/clients/screens_bokslut.c @@ -242,7 +242,7 @@ void bokslut_screen(struct app *a) ff[7].cap = sizeof rate; ff[7].kind = TUI_F_TEXT; tui_form_hint("upp/ned/Tab = flytta Enter = ändra/utför F5 = visa" - " bokslutsplan ^Enter = bokför planen (frågar" + " bokslutsplan ^Enter/F9 = bokför planen (frågar" " först) Esc/q = tillbaka ^C = avsluta"); int r = tui_form_run_actions("Bokslut", ff, nf + 2, can_edit, acts, 5, NULL, &sel); diff --git a/clients/screens_dashboard.c b/clients/screens_dashboard.c index a386dae..83b4f6a 100644 --- a/clients/screens_dashboard.c +++ b/clients/screens_dashboard.c @@ -268,19 +268,11 @@ static void select_fiscal_year(struct app *a) } } static const char *const MAIN_ITEMS[] = { - MK_SECTION "Bokföring", "Verifikat", "Underlag (inkorg)", "Bankavstämning", "Mallar", - MK_SECTION "Fakturering", "Fakturor", - MK_SECTION "Lön", "Lönekörningar", - MK_SECTION "Rapporter & bokslut", "Rapporter", "Bokslut", - MK_SECTION "Företag", - "Anställda", "Kunder", "Bolaget", "Momsregler", - MK_SECTION "System", - "Skattetabeller", "Revision", "Systeminställningar", - MK_SECTION "Räkenskapsår", + "Bolaget", "System", "Ingående balans", "Räkenskapsår", "Logga ut / avsluta", }; @@ -306,61 +298,46 @@ void dashboard(struct app *a) if (sel < 0) continue; /* Esc/back at the top level never exits */ switch (sel) { - case 1: + case 0: open_scene(a, "vouchers"); break; - case 2: + case 1: open_scene(a, "inbox"); break; - case 3: + case 2: open_scene(a, "bank"); break; - case 4: + case 3: open_scene(a, "templates"); break; - case 6: + case 4: open_scene(a, "invoices"); break; - case 8: + case 5: open_scene(a, "payroll"); break; - case 10: + case 6: open_scene(a, "reports"); break; - case 11: + case 7: open_scene(a, "bokslut"); break; - case 13: - open_scene(a, "employees"); - break; - case 14: - open_scene(a, "customers"); - break; - case 15: + case 8: open_scene(a, "company"); break; - case 16: - open_scene(a, "rules"); - break; - case 18: - open_scene(a, "tax_tables"); - break; - case 19: - open_scene(a, "audit"); - break; - case 20: + case 9: open_scene(a, "system"); break; - case 22: + case 10: open_scene(a, "ib"); break; - case 23: + case 11: select_fiscal_year(a); break; - case 24: + case 12: return; default: - break; /* section header */ + break; } } } diff --git a/clients/screens_ib.c b/clients/screens_ib.c index ca35562..8950667 100644 --- a/clients/screens_ib.c +++ b/clients/screens_ib.c @@ -272,7 +272,7 @@ static int ib_form(struct app *a, char **old_acc, int64_t *old_amt, int nold) for (;;) { int rr = tui_rt_run("Ingående balans", &ib.rt, "Tab = byta fält F5 = validera ^X = rensa rad" - " ^Enter = spara Esc = avbryt"); + " ^Enter/F9 = spara Esc = avbryt"); if (rr == -1) return 0; char msg[256]; diff --git a/clients/screens_invoices.c b/clients/screens_invoices.c index b8cc8dd..ca59eef 100644 --- a/clients/screens_invoices.c +++ b/clients/screens_invoices.c @@ -1092,7 +1092,7 @@ static int64_t invoices_new(struct app *a) tui_rt_set_fields(&f.rt, ff, 7); const char *hint = "Enter = välj/ändra Tab = byta fält F5 = förhandsvisa" - " ^Enter = utfärda Esc = avbryt"; + " ^Enter/F9 = utfärda Esc = avbryt"; int64_t out = 0; for (;;) { int rr = tui_rt_run("Ny faktura", &f.rt, hint); diff --git a/clients/screens_payroll.c b/clients/screens_payroll.c index 9bfaf38..23d765f 100644 --- a/clients/screens_payroll.c +++ b/clients/screens_payroll.c @@ -1101,7 +1101,8 @@ static int64_t payroll_run_screen(struct app *a, int64_t id) { status, -1, NULL }, { totals, -1, NULL }, { "Förhandsvisa (F5)", 1, NULL }, - { "Bokför körning (^Enter)", post_reason ? 0 : 1, post_reason }, + { "Bokför körning (^Enter/F9)", post_reason ? 0 : 1, + post_reason }, { "Lönebesked (PDF)", payslip_reason ? 0 : 1, payslip_reason }, { "AGI-underlag", agi_reason ? 0 : 1, agi_reason }, { "Betala skatt & avgifter", pay_reason ? 0 : 1, pay_reason }, @@ -1123,7 +1124,7 @@ static int64_t payroll_run_screen(struct app *a, int64_t id) snprintf(title, sizeof title, "Ny lönekörning"); int editable = can_write && !posted; tui_form_hint("upp/ned/Tab = flytta Enter = ändra/utför" - " F5 = förhandsvisa ^Enter = bokför" + " F5 = förhandsvisa ^Enter/F9 = bokför" " Esc/q = tillbaka ^C = avsluta"); int ret = tui_form_run_actions(title, ff, 2, editable, acts, 7, NULL, &focus); diff --git a/clients/screens_settings.c b/clients/screens_settings.c index c6a46c5..8a31620 100644 --- a/clients/screens_settings.c +++ b/clients/screens_settings.c @@ -321,10 +321,6 @@ static const struct setting_field SMTP_SETTINGS[] = { { "smtp_password", "SMTP-lösenord", NULL, 0, 1 }, }; -static const struct setting_field SYSTEM_SETTINGS[] = { - { "attachment_dir", "Bilagornas mapp", NULL, 0, 0 }, -}; - static int settings_can_write(struct app *a) { return a->role[0] && (strcmp(a->role, "owner") == 0 || @@ -347,27 +343,40 @@ static void smtp_settings_screen(struct app *a) settings_can_write(a), 1, &sel); } -void system_settings_screen(struct app *a) +static const char *const SYSTEM_ITEMS[] = { + "Skattetabeller", + "Revision", +}; + +void system_screen(struct app *a) { static int sel = 0; - settings_form(a, "Systeminställningar", SYSTEM_SETTINGS, - (int)(sizeof SYSTEM_SETTINGS / sizeof SYSTEM_SETTINGS[0]), - settings_can_write(a), 0, &sel); + for (;;) { + if (g_quit) + return; + int r = tui_menu("System", SYSTEM_ITEMS, + (int)(sizeof SYSTEM_ITEMS / sizeof SYSTEM_ITEMS[0]), + 0, &sel); + if (r < 0) + return; + if (r == 0) + payroll_tax_tables_screen(a); + else if (r == 1) + audit_screen(a); + } } -void company_screen(struct app *a) +static void company_data_screen(struct app *a) { static int sel = 0; const int nf = (int)(sizeof COMPANY_FIELDS / sizeof COMPANY_FIELDS[0]); int owner = a->role[0] && strcmp(a->role, "owner") == 0; - int writer = settings_can_write(a); - const char *settings_reason = writer ? NULL : "du har inte behörighet"; for (;;) { if (g_quit) return; char *resp = client_rpc(&a->conn, "org.get", a->session, a->org, "{}"); if (!resp || !client_ok(resp)) { - show_error("Bolaget", resp); + show_error("Företagsuppgifter", resp); free(resp); return; } @@ -392,15 +401,7 @@ void company_screen(struct app *a) ff[i].kind = TUI_F_TEXT; } free(resp); - struct tui_form_action acts[3] = { - { "Fakturauppgifter…", writer ? 1 : 0, settings_reason }, - { "E-post (SMTP)…", writer ? 1 : 0, settings_reason }, - { "Styrelseledamöter", 1, NULL }, - }; - tui_form_hint("upp/ned/Tab = flytta Enter = ändra/utför" - " F5 = uppdatera Esc/q = tillbaka ^C = avsluta"); - int r = tui_form_run_actions("Bolaget", ff, nf, owner, acts, 3, NULL, - &sel); + int r = tui_form_run("Företagsuppgifter", ff, nf, owner, &sel); if (r >= 0 && r < nf) { if (!company_field_valid(&COMPANY_FIELDS[r], vals[r])) { tui_message("Ogiltigt värde", "%s", COMPANY_FIELDS[r].label); @@ -426,14 +427,58 @@ void company_screen(struct app *a) } for (int i = 0; i < nf; i++) free(vals[i]); - if (r == TUI_FORM_ACTION + 0) + if (r == TUI_FORM_BACK) + return; + } +} + +static const char *const COMPANY_ITEMS[] = { + "Företagsuppgifter", + "Fakturauppgifter", + "E-post (SMTP)", + "Styrelseledamöter", + MK_SECTION "Register", + "Anställda", + "Kunder", + "Momsregler", +}; + +void company_screen(struct app *a) +{ + static int sel = 0; + for (;;) { + if (g_quit) + return; + int r = tui_menu("Bolaget", COMPANY_ITEMS, + (int)(sizeof COMPANY_ITEMS / sizeof COMPANY_ITEMS[0]), + 0, &sel); + if (r < 0) + return; + switch (r) { + case 0: + company_data_screen(a); + break; + case 1: invoice_settings_screen(a); - else if (r == TUI_FORM_ACTION + 1) + break; + case 2: smtp_settings_screen(a); - else if (r == TUI_FORM_ACTION + 2) + break; + case 3: board_screen(a); - else if (r == TUI_FORM_BACK) - return; + break; + case 5: + employees_screen(a); + break; + case 6: + customers_screen(a); + break; + case 7: + rules_screen(a); + break; + default: + break; + } } } diff --git a/clients/screens_templates.c b/clients/screens_templates.c index b2cd7ab..5777742 100644 --- a/clients/screens_templates.c +++ b/clients/screens_templates.c @@ -234,7 +234,7 @@ static int template_form(struct app *a, const char *load_name) tui_rt_set_fields(&tf.rt, ff, 3); const char *title = load_name ? "Redigera mall" : "Ny mall"; const char *hint = "Enter = ändra fält Tab = byta fält F5 = validera" - " ^X = rensa rad ^Enter = spara Esc = avbryt"; + " ^X = rensa rad ^Enter/F9 = spara Esc = avbryt"; for (;;) { int rr = tui_rt_run(title, &tf.rt, hint); if (rr == -1) diff --git a/clients/screens_vouchers.c b/clients/screens_vouchers.c index fedffe9..5e1b006 100644 --- a/clients/screens_vouchers.c +++ b/clients/screens_vouchers.c @@ -836,7 +836,7 @@ int64_t vouchers_new_prefill(struct app *a, const struct voucher_prefill *p) tui_rt_normalize(&vf.rt); const char *hint = "Enter = ändra fält Tab = byta fält F4 = mall" " ^F = bifoga fil F5 = validera ^X = rensa rad" - " ^Enter = bokför Esc = avbryt"; + " ^Enter/F9 = bokför Esc = avbryt"; for (;;) { int rr = tui_rt_run("Nytt verifikat", &vf.rt, hint); if (rr == -1) diff --git a/clients/tui.c b/clients/tui.c index 031fad0..30761a8 100644 --- a/clients/tui.c +++ b/clients/tui.c @@ -159,9 +159,34 @@ int tui_sticky_split(char **lines, int n, char **head, int *nhead) void tui_keys_setup(void) { - /* ^Enter has no control code; enable xterm modifyOtherKeys and bind the - sequence it produces. Terminals without it ignore the request. */ + /* ^Enter has no control code; enable xterm modifyOtherKeys level 2 (level + 1 leaves control+Enter alone) and the Kitty keyboard protocol, then bind + the sequences they produce. Terminals with neither keep F9 working. */ + putp("\033[>4;2m"); + putp("\033[>1u"); + fflush(stdout); define_key("\033[27;5;13~", TUI_KEY_CTRL_ENTER); + define_key("\033[13;5u", TUI_KEY_CTRL_ENTER); + define_key("\033[27;2;9~", KEY_BTAB); + define_key("\033[9;2u", KEY_BTAB); + define_key("\033[27u", 27); + define_key("\033[27;1u", 27); + define_key("\033[27;5;97~", 1); + define_key("\033[97;5u", 1); + define_key("\033[27;5;99~", 3); + define_key("\033[99;5u", 3); + define_key("\033[27;5;101~", 5); + define_key("\033[101;5u", 5); + define_key("\033[27;5;102~", 6); + define_key("\033[102;5u", 6); + define_key("\033[27;5;110~", 14); + define_key("\033[110;5u", 14); + define_key("\033[27;5;114~", 18); + define_key("\033[114;5u", 18); + define_key("\033[27;5;117~", 21); + define_key("\033[117;5u", 21); + define_key("\033[27;5;120~", 24); + define_key("\033[120;5u", 24); /* Home/End arrive as CSI or SS3 depending on the terminal */ define_key("\033[1~", KEY_HOME); define_key("\033OH", KEY_HOME); @@ -184,8 +209,6 @@ void tui_keys_setup(void) init_pair(TUI_CP_RULE, COLOR_BLUE, -1); init_pair(TUI_CP_STATUS, COLOR_CYAN, -1); } - putp("\033[>4;1m"); - fflush(stdout); } @@ -1592,7 +1615,7 @@ static int form_run(const char *title, struct tui_form_field *f, int nf, h = na > 0 ? (can_edit ? "upp/ned/Tab = flytta Enter = ändra/utför" - " F5 = uppdatera ^Enter = spara" + " F5 = uppdatera ^Enter/F9 = spara" " Esc/q = tillbaka ^C = avsluta" : "upp/ned/Tab = flytta Enter = utför" " F5 = uppdatera Esc/q = tillbaka" @@ -1600,7 +1623,7 @@ static int form_run(const char *title, struct tui_form_field *f, int nf, " (endast behöriga kan ändra)") : (can_edit ? "upp/ned/Home/End Enter = ändra" - " F5 = uppdatera ^Enter = spara" + " F5 = uppdatera ^Enter/F9 = spara" " Esc/q = tillbaka ^C = avsluta" : "upp/ned/Home/End F5 = uppdatera" " Esc/q = tillbaka ^C = avsluta" diff --git a/clients/ui.c b/clients/ui.c index a95ce44..ca6906f 100644 --- a/clients/ui.c +++ b/clients/ui.c @@ -217,17 +217,12 @@ void app_refresh_context(struct app *a) free(resp); snprintf(a->default_series, sizeof a->default_series, "%s", "A"); - a->attachment_dir[0] = '\0'; resp = client_rpc(&a->conn, "settings.get", a->session, a->org, "{}"); if (resp && client_ok(resp)) { char *ser = jstr_dup(resp, "result.default_series"); if (ser && *ser) snprintf(a->default_series, sizeof a->default_series, "%s", ser); free(ser); - char *dir = jstr_dup(resp, "result.attachment_dir"); - if (dir && *dir) - snprintf(a->attachment_dir, sizeof a->attachment_dir, "%s", dir); - free(dir); } free(resp); @@ -332,14 +327,18 @@ static void expand_path(const char *in, char *out, size_t n) Returns a malloc'd path, or NULL on cancel. */ char *file_browser(struct app *a, const char *start_dir) { - (void)a; if (g_quit) return NULL; char dir[1024]; - const char *start = (start_dir && *start_dir) ? start_dir : getenv("HOME"); + const char *home = getenv("HOME"); + const char *start = (start_dir && *start_dir) ? start_dir : home; expand_path(start, dir, sizeof dir); - if (!dir[0]) - snprintf(dir, sizeof dir, "."); + struct stat sb; + if (!dir[0] || stat(dir, &sb) != 0 || !S_ISDIR(sb.st_mode)) { + expand_path(home && *home ? home : ".", dir, sizeof dir); + if (!dir[0]) + snprintf(dir, sizeof dir, "."); + } for (;;) { DIR *d = opendir(dir); if (!d) { @@ -408,6 +407,8 @@ char *file_browser(struct app *a, const char *start_dir) continue; } free(ents); + snprintf(a->attachment_dir, sizeof a->attachment_dir, "%.255s", dir); + config_save(a); return xstrdup(full); } } diff --git a/clients/ui.h b/clients/ui.h index 2b93106..b37eb4f 100644 --- a/clients/ui.h +++ b/clients/ui.h @@ -102,6 +102,7 @@ extern const struct is_group IS_GROUPS[IS_GROUPS_N]; /* defined in bokftui.c, used by screens */ void open_scene(struct app *a, const char *name); void config_mkdirs(const char *path); +void config_save(struct app *a); /* Optional prefill for the new-voucher form (bank reconciliation). */ struct voucher_prefill { @@ -130,12 +131,12 @@ void audit_screen(struct app *a); void templates_screen(struct app *a); void ib_screen(struct app *a); void company_screen(struct app *a); -void system_settings_screen(struct app *a); void invoices_screen(struct app *a); void customers_screen(struct app *a); void bokslut_screen(struct app *a); void employees_screen(struct app *a); void payroll_screen(struct app *a); void payroll_tax_tables_screen(struct app *a); +void system_screen(struct app *a); #endif |
