poe

Уређивач .po фајлова
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување a2f93483f125d6c56488f899ce83f64bb2e0b521
родитељ c1731af897460e365b375e058501b9a2aa9d1038
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Sat, 25 Sep 2021 17:35:24 +0200

Ask before potentially dangerous operations (cancel dirty edit box, copy msgid or paste paste buffer if msgstr nonempty)

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
MTODO | 6+++---
Mdraw.c | 34++++++++++++++++++----------------
Mpoe.c | 156++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
измењених датотека: 3, додавања: 139(+), брисања: 57(-)

diff --git a/TODO b/TODO @@ -1,9 +1,9 @@ TODO ==== - [ ] Ask before: - [ ] canceling dirty edit box - [ ] copying msgid to msgstr if msgstr nonempty + [x] Ask before: + [x] canceling dirty edit box + [x] copying msgid to msgstr if msgstr nonempty < > Sort by flag/column? diff --git a/draw.c b/draw.c @@ -33,22 +33,24 @@ static const char* help[] = {"", "See the manual (man poe) for full help."}; static const char* editbox_title = "Edit translation"; const char* errors[] = { - [ERR_UNKNOWN_KEY] = "Unknown key (press H for help)", - [ERR_EXIT_KEY] = "Press q or C-Q to quit", - [ERR_DLG_OPEN] = "Press Esc to close dialog or q/C-Q to quit", - [ERR_DLG_OPEN_QUIT] = "Press Esc to close dialog", - [ERR_EMPTY_FILE] = "No msgids to edit", - [ERR_CANT_ALLOC] = "Memory allocation failed", - [ERR_CANT_SAVE] = "File is not writeable", - [ERR_CANT_MOVE] = "Cannot move temporary file", - [ERR_ILLEGAL_ON_FIRST] = "Not allowed on first entry"}; -const char* flag_strings[] = { - [FL_C_FORMAT] = "c-format", - [FL_NO_C_FORMAT] = "no-c-format", - [FL_FUZZY] = "fuzzy"}; -const char* first_entry_msgid = "*** SPECIAL: file info ***"; -const char* program_name = "poe"; -const char* prompt_dirty = "File changed, save [y/n/ESC]?"; + [ERR_UNKNOWN_KEY] = "Unknown key (press H for help)", + [ERR_EXIT_KEY] = "Press q or C-Q to quit", + [ERR_DLG_OPEN] = "Press Esc to close dialog or q/C-Q to quit", + [ERR_DLG_OPEN_QUIT] = "Press Esc to close dialog", + [ERR_EMPTY_FILE] = "No msgids to edit", + [ERR_CANT_ALLOC] = "Memory allocation failed", + [ERR_CANT_SAVE] = "File is not writeable", + [ERR_CANT_MOVE] = "Cannot move temporary file", + [ERR_ILLEGAL_ON_FIRST] = "Not allowed on first entry"}; +const char* flag_strings[] = { + [FL_C_FORMAT] = "c-format", + [FL_NO_C_FORMAT] = "no-c-format", + [FL_FUZZY] = "fuzzy"}; +const char* first_entry_msgid = "*** SPECIAL: file info ***"; +const char* program_name = "poe"; +const char* prompt_dirty = "File changed, save [y/n/ESC]?"; +const char* prompt_cancel_dirty = "Entry changed, save [y/n/ESC]?"; +const char* prompt_overwrite = "Not empty, overwrite? [y/n/ESC]?"; void init_bufferline(struct BufferLine* bl) diff --git a/poe.c b/poe.c @@ -19,6 +19,8 @@ extern const char* errors[]; extern const char* prompt_dirty; +extern const char* prompt_cancel_dirty; +extern const char* prompt_overwrite; extern const char* program_name; int print_error(const int code, const char* msg, ...); @@ -123,7 +125,8 @@ format_filename(char* result, size_t result_size, const char* format, if (!result) return; snprintf(result, result_size, format, u8_basename(state->filename), - state->dirty ? "*" : ""); + state->show_edit ? (state->dirty_before_edit ? "*" : "") + : (state->dirty ? "*" : "")); } void @@ -141,31 +144,65 @@ format_msgs(char* result, size_t result_size, const char* format, } void +overwrite_copy_msgid_callback(struct DrawState* state, struct tb_event* ev) +{ + if (!state) + return; + + if (ev->ch == 'y') + copy_msgid_to_input(state); + state->prompt_callback = NULL; +} + +void +overwrite_paste_callback(struct DrawState* state, struct tb_event* ev) +{ + if (!state) + return; + + if (ev->ch == 'y') + paste_paste_buffer_to_input(state); + state->prompt_callback = NULL; +} + +void +cancel_callback(struct DrawState* state, struct tb_event* ev) +{ + if (!state) + return; + + if (ev->ch == 'y') + save_msgstr(state); + else + cancel_msgstr(state); + state->prompt_callback = NULL; +} + +void quit_callback(struct DrawState* state, struct tb_event* ev) { - if (state) + if (!state) + return; + + if (ev->ch == 'y') { - if (ev->ch == 'y') + int result = save_file(state->entries, state->real_msgid_count, + state->filename, state->nplurals); + switch (result) { - int result = save_file(state->entries, - state->real_msgid_count, state->filename, - state->nplurals); - switch (result) - { - case SAVE_ERR_CANT_ALLOC: - strcpy(state->error, errors[ERR_CANT_ALLOC]); - break; - case SAVE_ERR_CANT_OPEN_FILE: - strcpy(state->error, errors[ERR_CANT_SAVE]); - break; - default: - state->error[0] = 0; - } + case SAVE_ERR_CANT_ALLOC: + strcpy(state->error, errors[ERR_CANT_ALLOC]); + break; + case SAVE_ERR_CANT_OPEN_FILE: + strcpy(state->error, errors[ERR_CANT_SAVE]); + break; + default: + state->error[0] = 0; } - state->dirty = 0; - state->prompt_callback = NULL; - state->running = 0; } + state->dirty = 0; + state->prompt_callback = NULL; + state->running = 0; } struct BufferLine* @@ -479,6 +516,14 @@ save_msgstr(struct DrawState* state) void cancel_msgstr(struct DrawState* state) { + if (!state->in_prompt && state->dirty) + { + state->in_prompt = 1; + strcpy(state->prompt, prompt_cancel_dirty); + state->prompt_callback = cancel_callback; + return; + } + state->show_edit = 0; state->edit_info_focused = 0; @@ -797,6 +842,15 @@ copy_msgid_to_input(struct DrawState* state) if (state->edit_info_focused) return state; + if (!state->in_prompt && state->input_rows_count > 1 + && *state->input_buffer->text) + { + state->in_prompt = 1; + strcpy(state->prompt, prompt_overwrite); + state->prompt_callback = overwrite_copy_msgid_callback; + return state; + } + if (state->msgid_number == 1) { strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]); @@ -940,6 +994,15 @@ paste_paste_buffer_to_input(struct DrawState* state) if (state->edit_info_focused) return state; + if (!state->in_prompt && state->input_rows_count > 1 + && *state->input_buffer->text) + { + state->in_prompt = 1; + strcpy(state->prompt, prompt_overwrite); + state->prompt_callback = overwrite_paste_callback; + return state; + } + if (state->msgid_number == 1) { strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]); @@ -1152,25 +1215,25 @@ next_fuzzy(struct DrawState* state) void show_edit(struct DrawState* state) { - if (load_msgstr(state) && load_info(state)) - { - state->dirty_before_edit = state->dirty; - state->fuzzy_before_edit = state->fuzzy_count; - state->input_changed_fuzzy = UNCHANGED; - state->show_edit = 1; - state->input_row = 0; - state->input_first_shown_row = 0; - state->input_first_shown_column = 0; - state->info_first_shown_row = 0; - state->info_first_shown_column = 0; - move_start(state); - state->error[0] = 0; - } - else + if (!load_msgstr(state) || !load_info(state)) { strcpy(state->error, errors[ERR_CANT_ALLOC]); state->running = 0; + return; } + + state->dirty_before_edit = state->dirty; + state->dirty = 0; + state->fuzzy_before_edit = state->fuzzy_count; + state->input_changed_fuzzy = UNCHANGED; + state->show_edit = 1; + state->input_row = 0; + state->input_first_shown_row = 0; + state->input_first_shown_column = 0; + state->info_first_shown_row = 0; + state->info_first_shown_column = 0; + move_start(state); + *state->error = 0; } void @@ -1826,8 +1889,25 @@ handle_editbox_key_event(struct tb_event* ev, struct DrawState* state) if (state->msgid_count < 1) return; - if (state->error[0]) - state->error[0] = 0; + if (state->in_prompt) + { + if (ev->ch == 'y' || ev->ch == 'n') + { + if (state->prompt_callback) + state->prompt_callback(state, ev); + state->in_prompt = 0; + *state->prompt = 0; + } + else if (ev->key == TB_KEY_ESC) + { + state->in_prompt = 0; + *state->prompt = 0; + } + return; + } + + if (*state->error) + *state->error = 0; if (ev->key != TB_KEY_ARROW_DOWN && ev->key != TB_KEY_ARROW_UP) state->saved_column = -1; @@ -1933,7 +2013,7 @@ handle_key_event(struct tb_event* ev, struct DrawState* state) if (state->prompt_callback) state->prompt_callback(state, ev); state->in_prompt = 0; - state->prompt[0] = 0; + *state->prompt = 0; } else if (state->in_prompt) return;