чување 0cfd22f6599c25287aa248f21e2912bbf71df67d
родитељ 127f482c975b16843dbc1d0d9b6eda79571e3c5e
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Sun, 27 Feb 2022 19:19:59 +0100
poe.c: Sort functions
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | config.def.h | | | 4 | ++-- |
| M | config.h | | | 4 | ++-- |
| M | poe.c | | | 2612 | ++++++++++++++++++++++++++++++++++++++++---------------------------------------- |
измењених датотека: 3, додавања: 1310(+), брисања: 1310(-)
diff --git a/config.def.h b/config.def.h
@@ -71,16 +71,16 @@ int cancel_close(struct DrawState* state);
int cancel_msgstr(struct DrawState* state);
int cancel_search(struct DrawState* state);
int copy_msgid_to_input(struct DrawState* state);
-int edit_page_up(struct DrawState* state);
int edit_page_down(struct DrawState* state);
+int edit_page_up(struct DrawState* state);
int erase_backwards(struct DrawState* state);
int erase_forward(struct DrawState* state);
int erase_prev_word(struct DrawState* state);
int erase_search_backwards(struct DrawState* state);
int erase_search_forward(struct DrawState* state);
int erase_search_prev_word(struct DrawState* state);
-int erase_search_to_start(struct DrawState* state);
int erase_search_to_end(struct DrawState* state);
+int erase_search_to_start(struct DrawState* state);
int erase_to_end(struct DrawState* state);
int erase_to_start(struct DrawState* state);
int exit_program(struct DrawState* state);
diff --git a/config.h b/config.h
@@ -71,16 +71,16 @@ int cancel_close(struct DrawState* state);
int cancel_msgstr(struct DrawState* state);
int cancel_search(struct DrawState* state);
int copy_msgid_to_input(struct DrawState* state);
-int edit_page_up(struct DrawState* state);
int edit_page_down(struct DrawState* state);
+int edit_page_up(struct DrawState* state);
int erase_backwards(struct DrawState* state);
int erase_forward(struct DrawState* state);
int erase_prev_word(struct DrawState* state);
int erase_search_backwards(struct DrawState* state);
int erase_search_forward(struct DrawState* state);
int erase_search_prev_word(struct DrawState* state);
-int erase_search_to_start(struct DrawState* state);
int erase_search_to_end(struct DrawState* state);
+int erase_search_to_start(struct DrawState* state);
int erase_to_end(struct DrawState* state);
int erase_to_start(struct DrawState* state);
int exit_program(struct DrawState* state);
diff --git a/poe.c b/poe.c
@@ -46,60 +46,6 @@ void overwrite_paste_callback(struct DrawState* state, struct tb_event* ev);
int print_error(const int code, const char* msg, ...);
void quit_callback(struct DrawState* state, struct tb_event* ev);
-int
-print_error(const int code, const char* msg, ...)
-{
- char buf[MAXBUFLINE];
- va_list args;
- va_start(args, msg);
- vsnprintf(buf, sizeof(buf), msg, args);
- va_end(args);
- fprintf(stderr, "%s: %s\n", program_name, buf);
- return code;
-}
-
-int
-write_file(struct DrawState* state)
-{
- 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]);
- state->running = 0;
- break;
- case SAVE_ERR_CANT_OPEN_FILE:
- strcpy(state->error, errors[ERR_CANT_SAVE]);
- state->running = 0;
- break;
- case SAVE_ERR_CANT_MOVE_FILE:
- strcpy(state->error, strerror(errno));
- state->running = 0;
- break;
- default:
- *state->error = 0;
- state->dirty = 0;
- }
- return 0;
-}
-
-void
-overwrite_copy_msgid_callback(struct DrawState* state, struct tb_event* ev)
-{
- 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 (ev->ch == 'y')
- paste_paste_buffer_to_input(state);
- state->prompt_callback = NULL;
-}
-
void
cancel_callback(struct DrawState* state, struct tb_event* ev)
{
@@ -111,151 +57,318 @@ cancel_callback(struct DrawState* state, struct tb_event* ev)
}
void
-quit_callback(struct DrawState* state, struct tb_event* ev)
+goto_msgid(struct DrawState* state, const size_t msgid_number)
{
- if (ev->ch == 'y')
- write_file(state);
- state->prompt_callback = NULL;
- state->running = 0;
+ state->msgid_number = msgid_number;
+ if (state->msgid_number < (state->maxy - 1) / 2)
+ state->first_shown_msgid = state->msgid_count > 0 ? 1 : 0;
+ else if (state->msgid_count - state->msgid_number
+ < (state->maxy - 1) / 2)
+ state->first_shown_msgid
+ = MAX(1, state->msgid_count - (state->maxy - 2));
+ else
+ state->first_shown_msgid
+ = MAX(1, state->msgid_number - (state->maxy - 1) / 2);
}
-int
-cancel_close(struct DrawState* state)
+void
+handle_key_event(struct tb_event* ev, struct DrawState* state)
{
- *state->error = 0;
+ const struct Key* current = NULL;
+
if (state->in_prompt)
{
- state->in_prompt = 0;
- *state->prompt = 0;
+ 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)
+ cancel_close(state);
+ return;
}
- else if (state->show_help)
- state->show_help = 0;
- else if (state->show_edit)
- cancel_msgstr(state);
- else if (state->show_search)
- cancel_search(state);
- else
- strcpy(state->error, errors[ERR_EXIT_KEY]);
- return 0;
-}
+ /* Remember to also edit the following condition if you reassign motion
+ * keys */
+ if (ev->key != TB_KEY_ARROW_DOWN && ev->key != TB_KEY_ARROW_UP
+ && state->show_edit)
+ state->saved_column = -1;
-int
-exit_program(struct DrawState* state)
-{
- if (state->show_edit)
- {
- strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
- return 0;
- }
- if (state->dirty)
+ for (int key = 0; key < LEN(top_level_keys); key++)
{
- state->in_prompt = 1;
- strcpy(state->prompt, prompt_dirty);
- state->prompt_callback = quit_callback;
+ current = top_level_keys + key;
+ if (((current->ev.key == ev->key) && !ev->ch)
+ || (current->ev.ch && (current->ev.ch == ev->ch)))
+ if (current->callback && !current->callback(state))
+ return;
}
- else
- state->running = 0;
- *state->error = 0;
- return 0;
-}
-
-struct BufferLine*
-load_info(struct DrawState* state)
-{
- struct PoEntry* first = &state->entries[0];
- struct PoEntry* current = &state->entries[state->msgid_number - 1];
- size_t msgid_num_lines = u32_lines_in_string(current->msgid, 0, 0);
- size_t msgid_plural_num_lines
- = u32_lines_in_string(current->msgid_plural, 0, 0);
- size_t num_lines = 0;
- struct BufferLine* newbuf = NULL;
- struct BufferLine* pnewbuf = NULL;
-
- for (size_t i = 0; i < state->info_rows_count; i++)
- free_bufferline(state->info_buffer + i);
- free(state->info_buffer);
-
- state->info_rows_maxlen = 0;
- if (current->msgid)
- num_lines += msgid_num_lines + 1;
- if (current->msgid_plural)
+ if (state->show_help)
{
- num_lines += msgid_plural_num_lines + 1;
- if (first->plural_forms)
- num_lines += 3;
+ strcpy(state->error, errors[ERR_DLG_OPEN]);
+ return;
}
- if (current->comments)
- num_lines += current->comment_lines + 1;
- if (current->trans_comments)
- num_lines += current->trans_comment_lines + 1;
- if (current->ref_comments)
- num_lines += current->ref_comment_lines + 1;
- newbuf = calloc(num_lines, sizeof(struct BufferLine));
- if (!newbuf)
- return NULL;
-
- pnewbuf = newbuf;
- for (size_t i = 0; i < num_lines; i++)
+ else if (state->show_edit)
{
- init_bufferline(pnewbuf);
- uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
- if (!newtext)
- return NULL;
- pnewbuf->text = newtext;
- pnewbuf++;
+ for (int key = 0; key < LEN(edit_keys); key++)
+ {
+ current = edit_keys + key;
+ if (((current->ev.key == ev->key) && !ev->ch)
+ || (current->ev.ch
+ && (current->ev.ch == ev->ch)))
+ if (current->callback
+ && !current->callback(state))
+ return;
+ }
+ if (ev->ch)
+ {
+ insert_char(state, ev->ch);
+ return;
+ }
}
-
- state->info_rows_count = num_lines;
-
- pnewbuf = newbuf;
- size_t newlen = 0;
- const uint32_t* pumsgid = NULL;
- if (current->msgid)
+ else if (state->show_search)
{
- pumsgid = current->msgid;
- newlen = u32_u8_strncpy(pnewbuf->text, "msgid:", MAXBUFLINE);
- pnewbuf->length = newlen;
- if (newlen > state->info_rows_maxlen)
- state->info_rows_maxlen = newlen;
- pnewbuf->fg = EDIT_MSGID_HEADING_FG;
- pnewbuf->bg = EDIT_MSGID_HEADING_BG;
- pnewbuf++;
- while (*pumsgid)
+ for (int key = 0; key < LEN(search_keys); key++)
{
- size_t len = 0;
- const uint32_t* old_pumsgid = pumsgid;
-
- len = u32_next_line(current->msgid, &pumsgid, 0, 0);
- u32_strncpy(pnewbuf->text, old_pumsgid,
- MIN(len + 1, MAXBUFLINE));
- newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE);
- pnewbuf->length = newlen;
- if (newlen > state->info_rows_maxlen)
- state->info_rows_maxlen = newlen;
- pnewbuf++;
+ current = search_keys + key;
+ if (((current->ev.key == ev->key) && !ev->ch)
+ || (current->ev.ch
+ && (current->ev.ch == ev->ch)))
+ if (current->callback
+ && !current->callback(state))
+ return;
+ }
+ if (ev->ch)
+ {
+ insert_search_char(state, ev->ch);
+ return;
}
}
- if (current->msgid_plural)
+ else
{
- newlen = u32_u8_strncpy(pnewbuf->text,
- "msgid_plural:", MAXBUFLINE);
- pnewbuf->length = newlen;
- if (newlen > state->info_rows_maxlen)
- state->info_rows_maxlen = newlen;
- pnewbuf->fg = EDIT_MSGID_HEADING_FG;
- pnewbuf->bg = EDIT_MSGID_HEADING_BG;
- pnewbuf++;
- pumsgid = current->msgid_plural;
- while (*pumsgid)
+ for (int key = 0; key < LEN(main_keys); key++)
{
- size_t len = 0;
- const uint32_t* old_pumsgid = pumsgid;
+ current = main_keys + key;
+ if (((current->ev.key == ev->key) && !ev->ch)
+ || (current->ev.ch
+ && (current->ev.ch == ev->ch)))
+ if (current->callback
+ && !current->callback(state))
+ return;
+ }
+ }
- len = u32_next_line(current->msgid_plural, &pumsgid, 0,
- 0);
- u32_strncpy(pnewbuf->text, old_pumsgid,
+ strcpy(state->error, errors[ERR_UNKNOWN_KEY]);
+}
+
+void
+insert_char(struct DrawState* state, uint32_t ch)
+{
+ if (state->edit_info_focused)
+ return;
+ struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ size_t len = buffer_line->length;
+ if (state->input_column < MAXBUFLINE - 1)
+ {
+ size_t i = len + 1;
+ int add_null = buffer_line->text[state->input_column] == 0;
+ while (i < MAXBUFLINE - 2 && i > state->input_column)
+ {
+ buffer_line->text[i] = buffer_line->text[i - 1];
+ i--;
+ }
+ buffer_line->text[state->input_column++] = ch;
+ buffer_line->length++;
+ if (state->input_column == MAXBUFLINE)
+ state->input_column = MAXBUFLINE - 1;
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
+ if (state->input_display_column - state->input_first_shown_column
+ > state->edit_width - 4)
+ {
+ state->input_first_shown_column
+ = state->input_display_column
+ - state->edit_width + 4;
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
+ }
+ if (add_null)
+ buffer_line->text[state->input_column] = 0;
+ }
+ state->dirty = 1;
+}
+
+void
+insert_search_char(struct DrawState* state, uint32_t ch)
+{
+ size_t len = u32_strlen(state->search);
+ if (state->search_column < MAXSEARCH - 1)
+ {
+ size_t i = len + 1;
+ int add_null = state->search[state->search_column] == 0;
+ while (i < MAXSEARCH - 2 && i > state->search_column)
+ {
+ state->search[i] = state->search[i - 1];
+ i--;
+ }
+ state->search[state->search_column++] = ch;
+ if (state->search_column == MAXSEARCH)
+ state->search_column = MAXSEARCH - 1;
+ state->search_display_column = display_length(state,
+ state->search, state->search_column);
+ if (state->search_display_column
+ - state->search_first_shown_column
+ > state->search_width - 4)
+ {
+ state->search_first_shown_column
+ = state->search_display_column
+ - state->search_width + 4;
+ state->search_display_column = display_length(state,
+ state->search, state->search_column);
+ }
+ if (add_null)
+ state->search[state->search_column] = 0;
+
+ next_match(state);
+ }
+}
+
+struct DrawState*
+join_lines(struct DrawState* state, size_t first_line, int forward)
+{
+ state->input_column = state->input_buffer[first_line].length;
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
+ u32_strncat(state->input_buffer[first_line].text,
+ state->input_buffer[first_line + 1].text, MAXBUFLINE);
+ state->input_buffer[first_line].length
+ = u32_strlen(state->input_buffer[first_line].text);
+ if (!forward)
+ {
+ state->input_row--;
+ if (state->input_row < 0)
+ state->input_row = 0;
+ }
+ for (size_t i = first_line + 1; i < state->input_rows_count - 1; i++)
+ {
+ u32_strncpy(state->input_buffer[i].text,
+ state->input_buffer[i + 1].text, MAXBUFLINE);
+ state->input_buffer[i].length
+ = state->input_buffer[i + 1].length;
+ }
+ free_bufferline(state->input_buffer + state->input_rows_count - 1);
+ state->input_rows_count--;
+ struct BufferLine* newbuf = realloc(state->input_buffer,
+ state->input_rows_count * sizeof(struct BufferLine));
+ if (!newbuf)
+ return NULL;
+ state->input_buffer = newbuf;
+ state->dirty = 1;
+
+ return state;
+}
+
+struct BufferLine*
+load_info(struct DrawState* state)
+{
+ struct PoEntry* first = &state->entries[0];
+ struct PoEntry* current = &state->entries[state->msgid_number - 1];
+ size_t msgid_num_lines = u32_lines_in_string(current->msgid, 0, 0);
+ size_t msgid_plural_num_lines
+ = u32_lines_in_string(current->msgid_plural, 0, 0);
+ size_t num_lines = 0;
+ struct BufferLine* newbuf = NULL;
+ struct BufferLine* pnewbuf = NULL;
+
+ for (size_t i = 0; i < state->info_rows_count; i++)
+ free_bufferline(state->info_buffer + i);
+ free(state->info_buffer);
+
+ state->info_rows_maxlen = 0;
+
+ if (current->msgid)
+ num_lines += msgid_num_lines + 1;
+ if (current->msgid_plural)
+ {
+ num_lines += msgid_plural_num_lines + 1;
+ if (first->plural_forms)
+ num_lines += 3;
+ }
+ if (current->comments)
+ num_lines += current->comment_lines + 1;
+ if (current->trans_comments)
+ num_lines += current->trans_comment_lines + 1;
+ if (current->ref_comments)
+ num_lines += current->ref_comment_lines + 1;
+ newbuf = calloc(num_lines, sizeof(struct BufferLine));
+ if (!newbuf)
+ return NULL;
+
+ pnewbuf = newbuf;
+ for (size_t i = 0; i < num_lines; i++)
+ {
+ init_bufferline(pnewbuf);
+ uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
+ if (!newtext)
+ return NULL;
+ pnewbuf->text = newtext;
+ pnewbuf++;
+ }
+
+ state->info_rows_count = num_lines;
+
+ pnewbuf = newbuf;
+ size_t newlen = 0;
+ const uint32_t* pumsgid = NULL;
+ if (current->msgid)
+ {
+ pumsgid = current->msgid;
+ newlen = u32_u8_strncpy(pnewbuf->text, "msgid:", MAXBUFLINE);
+ pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf->fg = EDIT_MSGID_HEADING_FG;
+ pnewbuf->bg = EDIT_MSGID_HEADING_BG;
+ pnewbuf++;
+ while (*pumsgid)
+ {
+ size_t len = 0;
+ const uint32_t* old_pumsgid = pumsgid;
+
+ len = u32_next_line(current->msgid, &pumsgid, 0, 0);
+ u32_strncpy(pnewbuf->text, old_pumsgid,
+ MIN(len + 1, MAXBUFLINE));
+ newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE);
+ pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf++;
+ }
+ }
+ if (current->msgid_plural)
+ {
+ newlen = u32_u8_strncpy(pnewbuf->text,
+ "msgid_plural:", MAXBUFLINE);
+ pnewbuf->length = newlen;
+ if (newlen > state->info_rows_maxlen)
+ state->info_rows_maxlen = newlen;
+ pnewbuf->fg = EDIT_MSGID_HEADING_FG;
+ pnewbuf->bg = EDIT_MSGID_HEADING_BG;
+ pnewbuf++;
+ pumsgid = current->msgid_plural;
+ while (*pumsgid)
+ {
+ size_t len = 0;
+ const uint32_t* old_pumsgid = pumsgid;
+
+ len = u32_next_line(current->msgid_plural, &pumsgid, 0,
+ 0);
+ u32_strncpy(pnewbuf->text, old_pumsgid,
MIN(len + 1, MAXBUFLINE));
newlen = u32_decode_tabs(pnewbuf->text, MAXBUFLINE);
pnewbuf->length = newlen;
@@ -416,61 +529,61 @@ load_msgstr(struct DrawState* state)
return state->input_buffer;
}
+void
+overwrite_copy_msgid_callback(struct DrawState* state, struct tb_event* ev)
+{
+ 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 (ev->ch == 'y')
+ paste_paste_buffer_to_input(state);
+ state->prompt_callback = NULL;
+}
+
int
-save_msgstr(struct DrawState* state)
+print_error(const int code, const char* msg, ...)
{
- uint32_t* to_save = NULL;
- size_t to_save_size = 0;
- struct PoEntry* current = NULL;
+ char buf[MAXBUFLINE];
+ va_list args;
+ va_start(args, msg);
+ vsnprintf(buf, sizeof(buf), msg, args);
+ va_end(args);
+ fprintf(stderr, "%s: %s\n", program_name, buf);
+ return code;
+}
- state->show_edit = 0;
- state->edit_info_focused = 0;
+void
+quit_callback(struct DrawState* state, struct tb_event* ev)
+{
+ if (ev->ch == 'y')
+ write_file(state);
+ state->prompt_callback = NULL;
+ state->running = 0;
+}
- if (state->input_buffer)
+int
+cancel_close(struct DrawState* state)
+{
+ *state->error = 0;
+ if (state->in_prompt)
{
- to_save_size = state->input_rows_count * MAXMSGLINE;
- to_save = calloc(to_save_size, sizeof(uint32_t));
- if (!to_save)
- {
- strcpy(state->error, errors[ERR_CANT_ALLOC]);
- return 0;
- }
- struct BufferLine* pinput_buffer = NULL;
- for (size_t i = 0; i < state->input_rows_count; i++)
- {
- pinput_buffer = state->input_buffer + i;
- if (i == 0)
- u32_strncpy(to_save, pinput_buffer->text,
- to_save_size * sizeof(uint32_t));
- else
- {
- u32_strncat(to_save, (uint32_t*)L"\\n",
- to_save_size * sizeof(uint32_t));
- u32_strncat(to_save, pinput_buffer->text,
- to_save_size * sizeof(uint32_t));
- }
- free_bufferline(pinput_buffer);
- }
+ state->in_prompt = 0;
+ *state->prompt = 0;
}
- free(state->input_buffer);
- state->input_buffer = NULL;
- state->input_rows_count = 0;
- for (size_t i = 0; i < state->info_rows_count; i++)
- free_bufferline(state->info_buffer + i);
- free(state->info_buffer);
- state->dirty = (state->dirty_before_edit || state->dirty);
- state->info_rows_count = 0;
- state->info_buffer = NULL;
- u32_encode_tabs(to_save, to_save_size * sizeof(uint32_t));
- current = &state->entries[state->msgid_number - 1];
- u32_match_msgid_ending(current->msgid, to_save,
- to_save_size * sizeof(uint32_t));
- u32_set_msgstr(current, to_save, state->msgstr_index, 0, state);
- update_warning(current->msgid, to_save, ¤t->warning);
- state->input_changed_fuzzy = UNCHANGED;
+ else if (state->show_help)
+ state->show_help = 0;
+ else if (state->show_edit)
+ cancel_msgstr(state);
+ else if (state->show_search)
+ cancel_search(state);
+ else
+ strcpy(state->error, errors[ERR_EXIT_KEY]);
- tb_hide_cursor();
- free(to_save);
return 0;
}
@@ -517,37 +630,6 @@ cancel_msgstr(struct DrawState* state)
}
int
-show_help(struct DrawState* state)
-{
- state->show_help = 1;
- *state->error = 0;
- return 0;
-}
-
-int
-show_search(struct DrawState* state)
-{
- state->show_search = 1;
- state->search_column = 0;
- state->search_display_column = 0;
- state->search_first_shown_column = 0;
- if (!state->search)
- state->search = calloc(MAXSEARCH, sizeof(uint32_t));
- *state->search = 0;
- tb_set_cursor((state->maxx - state->search_width + 2) / 2,
- state->maxy - 1 - SEARCH_HEIGHT + 1);
- return 0;
-}
-
-int
-hide_search(struct DrawState* state)
-{
- state->show_search = 0;
- tb_hide_cursor();
- return 0;
-}
-
-int
cancel_search(struct DrawState* state)
{
state->show_search = 0;
@@ -557,180 +639,203 @@ cancel_search(struct DrawState* state)
}
int
-move_search_start(struct DrawState* state)
+copy_msgid_to_input(struct DrawState* state)
{
- state->search_column = 0;
- state->search_display_column = 0;
- state->search_first_shown_column = 0;
- return 0;
-}
+ if (state->edit_info_focused)
+ return 0;
-int
-move_search_left(struct DrawState* state)
-{
- if (state->search_column == 0)
+ if (!state->in_prompt && *state->input_buffer->text)
+ {
+ state->in_prompt = 1;
+ strcpy(state->prompt, prompt_overwrite);
+ state->prompt_callback = overwrite_copy_msgid_callback;
return 0;
+ }
- if (state->search[state->search_column - 1] == '\t')
- state->search_display_column = display_length(state,
- state->search, state->search_column - 1);
- else
- state->search_display_column--;
- state->search_column--;
+ if (state->msgid_number == 1)
+ {
+ strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]);
+ return 0;
+ }
- if (state->search_display_column < state->search_first_shown_column)
- state->search_first_shown_column = state->search_display_column;
- return 0;
-}
+ struct PoEntry* current = &state->entries[state->msgid_number - 1];
+ size_t msgid_num_lines = u32_lines_in_string(current->msgid, 0, 0);
+ size_t lines_to_init = state->input_rows_count < msgid_num_lines
+ ? msgid_num_lines - state->input_rows_count
+ : 0;
+ size_t lines_to_free = state->input_rows_count > msgid_num_lines
+ ? state->input_rows_count - msgid_num_lines
+ : 0;
+ for (size_t i = 0; i < lines_to_free; i++)
+ free_bufferline(
+ state->input_buffer + state->input_rows_count - i - 1);
+ struct BufferLine* newbuf = realloc(state->input_buffer,
+ msgid_num_lines * sizeof(struct BufferLine));
+ const uint32_t* pmsgid = current->msgid;
-int
-move_search_right(struct DrawState* state)
-{
- size_t len = u32_strlen(state->search);
- if (state->search_column == len)
+ if (!newbuf)
return 0;
- if (state->search[state->search_column] == '\t')
- state->search_display_column = display_length(state,
- state->search, state->search_column + 1);
- else
- state->search_display_column++;
- state->search_column++;
+ struct BufferLine* pbuffer = NULL;
+ for (size_t i = 0; i < lines_to_init; i++)
+ {
+ pbuffer = newbuf + msgid_num_lines - 1 - i;
+ init_bufferline(pbuffer);
+ uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
+ if (!newtext)
+ return 0;
+ pbuffer->text = newtext;
+ }
+
+ pbuffer = newbuf;
+ while (pmsgid && *pmsgid)
+ {
+ size_t len = 0;
+ size_t newlen = 0;
+ const uint32_t* old_pmsgid = pmsgid;
+ len = u32_next_line(current->msgid, &pmsgid, 0, 0);
+ u32_strncpy(pbuffer->text, old_pmsgid, MIN(len + 1, MAXBUFLINE));
+ newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE);
+ pbuffer->length = newlen;
+ pbuffer++;
+ }
+
+ state->input_rows_count = msgid_num_lines;
+ state->input_buffer = newbuf;
+ state->dirty = 1;
- if (state->search_display_column - state->search_first_shown_column
- > state->search_width - 4)
- state->search_first_shown_column = state->search_display_column
- - state->search_width + 4;
return 0;
}
int
-move_search_end(struct DrawState* state)
+edit_page_down(struct DrawState* state)
{
- size_t len = u32_strlen(state->search);
- state->search_column = len;
- size_t dlen
- = display_length(state, state->search, state->search_column);
- state->search_display_column = dlen;
- if (dlen > state->search_width - 4)
- state->search_first_shown_column
- = dlen - state->search_width + 4;
- else
- state->search_first_shown_column = 0;
- return 0;
+ if (state->edit_info_focused)
+ {
+ if (state->info_first_shown_row + (EDIT_HEIGHT - 3) / 2
+ < state->info_rows_count - 1)
+ state->info_first_shown_row += (EDIT_HEIGHT - 3) / 2;
+ return 0;
+ }
+
+ if (state->dirty)
+ save_msgstr(state);
+ else /* No need to call cancel_msgstr */
+ state->dirty = state->dirty_before_edit;
+ move_list_down(state);
+ state->msgstr_index = 0;
+ return show_edit(state);
}
-void
-insert_search_char(struct DrawState* state, uint32_t ch)
+int
+edit_page_up(struct DrawState* state)
{
- size_t len = u32_strlen(state->search);
- if (state->search_column < MAXSEARCH - 1)
+ if (state->edit_info_focused)
{
- size_t i = len + 1;
- int add_null = state->search[state->search_column] == 0;
- while (i < MAXSEARCH - 2 && i > state->search_column)
- {
- state->search[i] = state->search[i - 1];
- i--;
- }
- state->search[state->search_column++] = ch;
- if (state->search_column == MAXSEARCH)
- state->search_column = MAXSEARCH - 1;
- state->search_display_column = display_length(state,
- state->search, state->search_column);
- if (state->search_display_column
- - state->search_first_shown_column
- > state->search_width - 4)
- {
- state->search_first_shown_column
- = state->search_display_column
- - state->search_width + 4;
- state->search_display_column = display_length(state,
- state->search, state->search_column);
- }
- if (add_null)
- state->search[state->search_column] = 0;
-
- next_match(state);
+ if (state->info_first_shown_row > (EDIT_HEIGHT - 3) / 2)
+ state->info_first_shown_row -= (EDIT_HEIGHT - 3) / 2;
+ else
+ move_start(state);
+ return 0;
}
+
+ if (state->dirty)
+ save_msgstr(state);
+ else /* No need to call cancel_msgstr */
+ state->dirty = state->dirty_before_edit;
+ move_list_up(state);
+ state->msgstr_index = 0;
+ return show_edit(state);
}
int
-erase_search_backwards(struct DrawState* state)
+erase_backwards(struct DrawState* state)
{
- if (state->search_column > 0)
+ struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ if (state->edit_info_focused)
+ return 0;
+
+ if (state->input_column > 0)
{
- size_t i = state->search_column;
+ size_t i = state->input_column;
do
{
- state->search[i - 1] = state->search[i];
+ buffer_line->text[i - 1] = buffer_line->text[i];
i++;
- } while (state->search[i]);
- state->search[i - 1] = 0;
- state->search_column--;
- if (state->search_column < state->search_first_shown_column)
+ } while (buffer_line->text[i]);
+ buffer_line->text[i - 1] = 0;
+ buffer_line->length--;
+ state->input_column--;
+ if (state->input_first_shown_column > 0)
{
- if (state->search_column > state->search_width - 4)
- state->search_first_shown_column
- = state->search_column
- - state->search_width + 4;
- else
- state->search_first_shown_column = 0;
+ const struct BufferLine* current_line
+ = &state->input_buffer[state->input_row];
+ if (display_length(state, current_line->text,
+ current_line->length)
+ >= state->edit_width - 4)
+ state->input_first_shown_column--;
}
- state->search_display_column = display_length(state,
- state->search, state->search_column);
-
- return next_match(state);
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
+ if (state->input_display_column
+ < state->input_first_shown_column)
+ state->input_first_shown_column
+ = state->input_display_column;
+ state->dirty = 1;
+ }
+ else if (state->input_row > 0)
+ {
+ move_up(state);
+ move_end(state);
+ erase_forward(state);
}
return 0;
}
int
-erase_search_forward(struct DrawState* state)
+erase_forward(struct DrawState* state)
{
- if (state->search[state->search_column])
+ struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ if (state->edit_info_focused)
+ return 0;
+
+ if (buffer_line->text[state->input_column])
{
- size_t i = state->search_column;
- while (i < MAXSEARCH - 2 && state->search[i + 1])
+ size_t i = state->input_column;
+ while (i < MAXBUFLINE - 2 && buffer_line->text[i + 1])
{
- state->search[i] = state->search[i + 1];
+ buffer_line->text[i] = buffer_line->text[i + 1];
i++;
}
- state->search[i] = 0;
-
- return next_match(state);
+ buffer_line->text[i] = 0;
+ buffer_line->length--;
+ state->dirty = 1;
+ }
+ else if (state->input_row < state->input_rows_count - 1)
+ {
+ if (!join_lines(state, state->input_row, 1))
+ {
+ strcpy(state->error, errors[ERR_CANT_ALLOC]);
+ state->running = 0;
+ }
}
return 0;
}
int
-erase_search_to_start(struct DrawState* state)
+erase_prev_word(struct DrawState* state)
{
- size_t i = state->search_column;
- size_t len = u32_strlen(state->search);
- do
+ if (state->edit_info_focused)
{
- state->search[i - state->search_column] = state->search[i];
- i++;
- } while (state->search[i]);
- state->search[len - state->search_column] = 0;
- move_search_start(state);
- return next_match(state);
-}
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
+ return 0;
+ }
-int
-erase_search_to_end(struct DrawState* state)
-{
- state->search[state->search_column] = 0;
- move_search_end(state);
- return next_match(state);
-}
+ int i = state->input_column;
+ size_t len = state->input_buffer[state->input_row].length;
-int
-move_search_prev_word(struct DrawState* state)
-{
- int i = state->search_column;
- uint32_t* pline = state->search;
+ uint32_t* pline = state->input_buffer[state->input_row].text;
if (i > 0 && u32_is_word_boundary(pline[i - 1], 0))
i--;
@@ -740,45 +845,66 @@ move_search_prev_word(struct DrawState* state)
&& !u32_is_word_boundary(pline[i - 1], 0))
i--;
- state->search_column = i;
- state->search_display_column
- = display_length(state, state->search, state->search_column);
+ int d = state->input_column - i;
- if (state->search_column < state->search_first_shown_column)
- {
- if (state->search_column > state->search_width - 4)
- state->search_first_shown_column = state->search_column
- - state->search_width + 4;
- else
- state->search_first_shown_column = 0;
- }
- state->search_display_column
- = display_length(state, state->search, state->search_column);
+ for (int j = i; j < len - d; j++)
+ pline[j] = pline[j + d];
+
+ len -= d;
+ state->input_buffer[state->input_row].length = len;
+ pline[len] = 0;
+ state->input_column = i;
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
+ state->dirty = 1;
return 0;
}
int
-move_search_next_word(struct DrawState* state)
+erase_search_backwards(struct DrawState* state)
{
- int i = state->search_column;
- uint32_t* pline = state->search;
- size_t len = u32_strlen(state->search);
-
- while (i < len && !u32_is_word_boundary(pline[i], 0))
- i++;
- while (i < len && u32_is_word_boundary(pline[i], 0))
- i++;
- state->search_column = i;
- state->search_display_column
- = display_length(state, state->search, state->search_column);
-
- if (state->search_display_column - state->search_first_shown_column
- > state->search_width - 4)
+ if (state->search_column > 0)
{
- state->search_first_shown_column = state->search_display_column
- - state->search_width + 4;
+ size_t i = state->search_column;
+ do
+ {
+ state->search[i - 1] = state->search[i];
+ i++;
+ } while (state->search[i]);
+ state->search[i - 1] = 0;
+ state->search_column--;
+ if (state->search_column < state->search_first_shown_column)
+ {
+ if (state->search_column > state->search_width - 4)
+ state->search_first_shown_column
+ = state->search_column
+ - state->search_width + 4;
+ else
+ state->search_first_shown_column = 0;
+ }
state->search_display_column = display_length(state,
state->search, state->search_column);
+
+ return next_match(state);
+ }
+ return 0;
+}
+
+int
+erase_search_forward(struct DrawState* state)
+{
+ if (state->search[state->search_column])
+ {
+ size_t i = state->search_column;
+ while (i < MAXSEARCH - 2 && state->search[i + 1])
+ {
+ state->search[i] = state->search[i + 1];
+ i++;
+ }
+ state->search[i] = 0;
+
+ return next_match(state);
}
return 0;
}
@@ -825,569 +951,399 @@ erase_search_prev_word(struct DrawState* state)
}
int
-copy_msgid_to_input(struct DrawState* state)
+erase_search_to_end(struct DrawState* state)
+{
+ state->search[state->search_column] = 0;
+ move_search_end(state);
+ return next_match(state);
+}
+
+int
+erase_search_to_start(struct DrawState* state)
+{
+ size_t i = state->search_column;
+ size_t len = u32_strlen(state->search);
+ do
+ {
+ state->search[i - state->search_column] = state->search[i];
+ i++;
+ } while (state->search[i]);
+ state->search[len - state->search_column] = 0;
+ move_search_start(state);
+ return next_match(state);
+}
+
+int
+erase_to_end(struct DrawState* state)
{
if (state->edit_info_focused)
return 0;
+ struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ buffer_line->text[state->input_column] = 0;
+ buffer_line->length = state->input_column;
+ move_end(state);
+ state->dirty = 1;
+ return 0;
+}
- if (!state->in_prompt && *state->input_buffer->text)
+int
+erase_to_start(struct DrawState* state)
+{
+ if (state->edit_info_focused)
{
- state->in_prompt = 1;
- strcpy(state->prompt, prompt_overwrite);
- state->prompt_callback = overwrite_copy_msgid_callback;
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
return 0;
}
- if (state->msgid_number == 1)
+ size_t i = state->input_column;
+ struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
+ size_t len = buffer_line->length;
+ do
{
- strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]);
+ buffer_line->text[i - state->input_column]
+ = buffer_line->text[i];
+ i++;
+ } while (buffer_line->text[i]);
+ buffer_line->text[len - state->input_column] = 0;
+ buffer_line->length = len - state->input_column;
+ move_start(state);
+ state->dirty = 1;
+ return 0;
+}
+
+int
+exit_program(struct DrawState* state)
+{
+ if (state->show_edit)
+ {
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
return 0;
}
+ if (state->dirty)
+ {
+ state->in_prompt = 1;
+ strcpy(state->prompt, prompt_dirty);
+ state->prompt_callback = quit_callback;
+ }
+ else
+ state->running = 0;
+ *state->error = 0;
+ return 0;
+}
- struct PoEntry* current = &state->entries[state->msgid_number - 1];
- size_t msgid_num_lines = u32_lines_in_string(current->msgid, 0, 0);
- size_t lines_to_init = state->input_rows_count < msgid_num_lines
- ? msgid_num_lines - state->input_rows_count
- : 0;
- size_t lines_to_free = state->input_rows_count > msgid_num_lines
- ? state->input_rows_count - msgid_num_lines
- : 0;
- for (size_t i = 0; i < lines_to_free; i++)
- free_bufferline(
- state->input_buffer + state->input_rows_count - i - 1);
- struct BufferLine* newbuf = realloc(state->input_buffer,
- msgid_num_lines * sizeof(struct BufferLine));
- const uint32_t* pmsgid = current->msgid;
+int
+hide_search(struct DrawState* state)
+{
+ state->show_search = 0;
+ tb_hide_cursor();
+ return 0;
+}
+int
+insert_line(struct DrawState* state)
+{
+ if (state->edit_info_focused)
+ return 0;
+ state->input_rows_count++;
+ struct BufferLine* newbuf = realloc(state->input_buffer,
+ state->input_rows_count * sizeof(struct BufferLine));
if (!newbuf)
+ {
+ strcpy(state->error, errors[ERR_CANT_ALLOC]);
+ state->running = 0;
return 0;
+ }
- struct BufferLine* pbuffer = NULL;
- for (size_t i = 0; i < lines_to_init; i++)
+ state->input_buffer = newbuf;
+ init_bufferline(&state->input_buffer[state->input_rows_count - 1]);
+ uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
+ if (!newtext)
{
- pbuffer = newbuf + msgid_num_lines - 1 - i;
- init_bufferline(pbuffer);
- uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
- if (!newtext)
- return 0;
- pbuffer->text = newtext;
+ strcpy(state->error, errors[ERR_CANT_ALLOC]);
+ state->running = 0;
+ return 0;
}
-
- pbuffer = newbuf;
- while (pmsgid && *pmsgid)
+ state->input_buffer[state->input_rows_count - 1].text = newtext;
+ for (size_t i = state->input_rows_count - 1; i > state->input_row + 1;
+ i--)
{
- size_t len = 0;
- size_t newlen = 0;
- const uint32_t* old_pmsgid = pmsgid;
- len = u32_next_line(current->msgid, &pmsgid, 0, 0);
- u32_strncpy(pbuffer->text, old_pmsgid, MIN(len + 1, MAXBUFLINE));
- newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE);
- pbuffer->length = newlen;
- pbuffer++;
+ u32_strncpy(state->input_buffer[i].text,
+ state->input_buffer[i - 1].text, MAXBUFLINE);
+ state->input_buffer[i].length
+ = state->input_buffer[i - 1].length;
}
+ u32_strncpy(state->input_buffer[state->input_row + 1].text,
+ state->input_buffer[state->input_row].text + state->input_column,
+ MAXBUFLINE);
+ state->input_buffer[state->input_row + 1].length
+ = u32_strlen(state->input_buffer[state->input_row + 1].text);
+ state->input_buffer[state->input_row].text[state->input_column] = 0;
+ state->input_buffer[state->input_row].length
+ = u32_strlen(state->input_buffer[state->input_row].text);
- state->input_rows_count = msgid_num_lines;
- state->input_buffer = newbuf;
- state->dirty = 1;
+ state->input_row++;
+ if (state->input_row
+ > state->input_first_shown_row + (EDIT_HEIGHT - 3) / 2)
+ state->input_first_shown_row
+ = state->input_row - (EDIT_HEIGHT - 3) / 2;
+ move_start(state);
+ state->dirty = 1;
return 0;
}
int
-yank_msgstr_to_paste_buffer(struct DrawState* state)
+insert_search_space(struct DrawState* state)
{
- if (state->edit_info_focused)
- return 0;
+ insert_search_char(state, (uint32_t)L' ');
+ return 0;
+}
- if (state->msgid_number == 1)
- {
- strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]);
- return 0;
- }
+int
+insert_search_tab(struct DrawState* state)
+{
+ insert_search_char(state, (uint32_t)L'\t');
+ return 0;
+}
- struct PoEntry* current = &state->entries[state->msgid_number - 1];
- size_t msgstr_num_lines = 0;
- size_t lines_to_init = 0;
- size_t lines_to_free = 0;
- struct BufferLine* newbuf = NULL;
- const uint32_t* pmsgstr = NULL;
- struct BufferLine* pbuffer = NULL;
+int
+insert_space(struct DrawState* state)
+{
+ insert_char(state, (uint32_t)L' ');
+ return 0;
+}
- if (!current->msgstr || !*(current->msgstr + state->msgstr_index))
+int
+insert_tab(struct DrawState* state)
+{
+ insert_char(state, (uint32_t)L'\t');
+ return 0;
+}
+
+int
+move_end(struct DrawState* state)
+{
+ if (state->edit_info_focused)
{
- for (size_t i = 0; i < state->paste_rows_count; i++)
- free_bufferline(state->paste_buffer + i);
- free(state->paste_buffer);
- state->paste_buffer = NULL;
- state->paste_rows_count = 0;
+ if (state->info_rows_count > (EDIT_HEIGHT - 3) / 2)
+ state->info_first_shown_row = state->info_rows_count
+ - (EDIT_HEIGHT - 3) / 2;
+ state->info_first_shown_column = 0;
return 0;
}
- msgstr_num_lines
- = u32_lines_in_string(*(current->msgstr + state->msgstr_index),
- 0, 0);
- lines_to_init = state->paste_rows_count < msgstr_num_lines
- ? msgstr_num_lines - state->paste_rows_count
- : 0;
- lines_to_free = state->paste_rows_count > msgstr_num_lines
- ? state->paste_rows_count - msgstr_num_lines
- : 0;
-
- for (size_t i = 0; i < lines_to_free; i++)
- free_bufferline(
- state->paste_buffer + state->paste_rows_count - i - 1);
- if (!state->paste_buffer)
- newbuf = calloc(msgstr_num_lines, sizeof(struct BufferLine));
+ size_t len = state->input_buffer[state->input_row].length;
+ state->input_column = len;
+ size_t dlen = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
+ state->input_display_column = dlen;
+ if (dlen > state->edit_width - 4)
+ state->input_first_shown_column = dlen - state->edit_width + 4;
else
- newbuf = realloc(state->paste_buffer,
- msgstr_num_lines * sizeof(struct BufferLine));
- pmsgstr = *(current->msgstr + state->msgstr_index);
-
- if (!newbuf)
- return 0;
-
- for (size_t i = 0; i < lines_to_init; i++)
- {
- pbuffer = newbuf + msgstr_num_lines - 1 - i;
- init_bufferline(pbuffer);
- uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
- if (!newtext)
- return 0;
- pbuffer->text = newtext;
- }
+ state->input_first_shown_column = 0;
+ return 0;
+}
- pbuffer = newbuf;
- while (*pmsgstr)
+int
+move_down(struct DrawState* state)
+{
+ if (state->edit_info_focused)
{
- size_t len = 0;
- size_t newlen = 0;
- const uint32_t* old_pmsgstr = pmsgstr;
-
- len = u32_next_line(*(current->msgstr + state->msgstr_index),
- &pmsgstr, 0, 0);
- u32_strncpy(pbuffer->text, old_pmsgstr,
- MIN(len + 1, MAXBUFLINE));
- newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE);
- pbuffer->length = newlen;
- pbuffer++;
+ if (state->info_first_shown_row + (EDIT_HEIGHT - 3) / 2
+ < state->info_rows_count)
+ state->info_first_shown_row++;
+ return 0;
}
- state->paste_rows_count = msgstr_num_lines;
- state->paste_buffer = newbuf;
-
+ if (state->input_row < state->input_rows_count - 1)
+ state->input_row++;
+ if (state->input_first_shown_row + (EDIT_HEIGHT - 3) / 2
+ < state->input_row)
+ state->input_first_shown_row
+ = state->input_row - (EDIT_HEIGHT - 3) / 2;
+ if (state->saved_column == -1)
+ state->saved_column = state->input_display_column;
+ size_t dlen = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_buffer[state->input_row].length);
+ if (dlen < state->saved_column)
+ state->input_display_column = dlen;
+ else
+ state->input_display_column = state->saved_column;
+ state->input_column = input_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_display_column);
+ if (state->input_first_shown_column > state->input_display_column)
+ state->input_first_shown_column = state->input_display_column;
+ if (state->input_first_shown_column + state->edit_width - 4
+ < state->input_display_column)
+ state->input_first_shown_column
+ = state->input_display_column - state->edit_width + 4;
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
return 0;
}
int
-paste_paste_buffer_to_input(struct DrawState* state)
+move_left(struct DrawState* state)
{
if (state->edit_info_focused)
- return 0;
-
- if (!state->in_prompt && *state->input_buffer->text)
{
- state->in_prompt = 1;
- strcpy(state->prompt, prompt_overwrite);
- state->prompt_callback = overwrite_paste_callback;
+ if (state->info_first_shown_column > 0)
+ state->info_first_shown_column--;
return 0;
}
- if (state->msgid_number == 1)
- {
- strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]);
+ if (state->input_column == 0)
return 0;
- }
- size_t lines_to_init = 0;
- size_t lines_to_free = 0;
- struct BufferLine* pinput = NULL;
- struct BufferLine* newbuf = NULL;
- struct BufferLine* ppaste = NULL;
+ if (state->input_buffer[state->input_row].text[state->input_column - 1]
+ == '\t')
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column - 1);
+ else
+ state->input_display_column--;
+ state->input_column--;
- if (!state->paste_buffer || !(*state->paste_buffer).text
- || !*(*state->paste_buffer).text)
- {
- /* leave one row */
- for (size_t i = 1; i < state->input_rows_count; i++)
- free_bufferline(state->input_buffer + i);
- state->input_buffer = realloc(state->input_buffer,
- sizeof(struct BufferLine));
- *(state->input_buffer->text) = 0;
- state->input_column = 0;
- state->input_display_column = 0;
- state->input_first_shown_column = 0;
- state->input_first_shown_row = 0;
- state->input_row = 0;
- state->input_rows_count = 1;
- state->dirty = 1;
- return 0;
- }
-
- lines_to_init = state->input_rows_count < state->paste_rows_count
- ? state->paste_rows_count - state->input_rows_count
- : 0;
- lines_to_free = state->input_rows_count > state->paste_rows_count
- ? state->input_rows_count - state->paste_rows_count
- : 0;
-
- for (size_t i = 0; i < lines_to_free; i++)
- free_bufferline(
- state->input_buffer + state->input_rows_count - i - 1);
- newbuf = realloc(state->input_buffer,
- state->paste_rows_count * sizeof(struct BufferLine));
- ppaste = state->paste_buffer;
-
- if (!newbuf)
- return 0;
+ if (state->input_display_column < state->input_first_shown_column)
+ state->input_first_shown_column = state->input_display_column;
+ return 0;
+}
- for (size_t i = 0; i < lines_to_init; i++)
+int
+move_list_down(struct DrawState* state)
+{
+ if (state->msgid_number < state->msgid_count)
{
- pinput = newbuf + state->paste_rows_count - 1 - i;
- init_bufferline(pinput);
- uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
- if (!newtext)
- return 0;
- pinput->text = newtext;
+ *state->error = 0;
+ state->msgid_number++;
+ if (state->msgid_number - state->first_shown_msgid
+ > state->maxy - 2)
+ state->first_shown_msgid++;
}
-
- if (ppaste)
- for (size_t i = 0; i < state->paste_rows_count; i++)
- {
- pinput = newbuf + i;
- u32_strncpy(pinput->text, ppaste->text,
- MIN(ppaste->length + 1, MAXBUFLINE));
- pinput->length = ppaste->length;
- ppaste++;
- }
-
- state->input_rows_count = state->paste_rows_count;
- state->input_buffer = newbuf;
- state->dirty = 1;
-
return 0;
}
-void
-goto_msgid(struct DrawState* state, const size_t msgid_number)
+int
+move_list_end(struct DrawState* state)
{
- state->msgid_number = msgid_number;
- if (state->msgid_number < (state->maxy - 1) / 2)
- state->first_shown_msgid = state->msgid_count > 0 ? 1 : 0;
- else if (state->msgid_count - state->msgid_number
- < (state->maxy - 1) / 2)
- state->first_shown_msgid
- = MAX(1, state->msgid_count - (state->maxy - 2));
- else
- state->first_shown_msgid
- = MAX(1, state->msgid_number - (state->maxy - 1) / 2);
+ *state->error = 0;
+ state->msgid_number = state->msgid_count;
+ state->first_shown_msgid = state->msgid_count > 0
+ ? MAX(1, state->msgid_number - (state->maxy - 2))
+ : 0;
+ return 0;
}
int
-next_match(struct DrawState* state)
+move_list_page_down(struct DrawState* state)
{
- if (state->msgid_count == 0 || !state->search || !*state->search)
- return 0;
-
- *state->error = 0;
- struct PoEntry* current = NULL;
- for (size_t e = state->msgid_number; e < state->msgid_count; e++)
+ *state->error = 0;
+ if (state->msgid_number < state->msgid_count - state->maxy - 2)
{
- current = state->entries + e;
- if ((current->msgid && *current->msgid
- && u32_strstr(current->msgid, state->search))
- || (current->msgstr && *current->msgstr
- && **current->msgstr
- && u32_strstr(*current->msgstr, state->search)))
- {
- goto_msgid(state, e + 1);
- return 0;
- }
+ state->msgid_number += state->maxy - 2;
+ if (state->msgid_number - state->first_shown_msgid
+ > state->maxy - 2)
+ state->first_shown_msgid
+ = state->msgid_number - (state->maxy - 2);
}
+ else
+ return move_list_end(state);
return 0;
}
int
-prev_match(struct DrawState* state)
+move_list_page_up(struct DrawState* state)
{
- if (state->msgid_count == 0 || !state->search || !*state->search)
- return 0;
-
- *state->error = 0;
- struct PoEntry* current = NULL;
- for (size_t e = state->msgid_number - 1; e > 0; e--)
+ *state->error = 0;
+ if (state->msgid_number > state->maxy - 2)
{
- current = state->entries + e - 1;
- if ((current->msgid && *current->msgid
- && u32_strstr(current->msgid, state->search))
- || (current->msgstr && *current->msgstr
- && **current->msgstr
- && u32_strstr(*current->msgstr, state->search)))
- {
- goto_msgid(state, e);
- return 0;
- }
+ state->msgid_number -= state->maxy - 2;
+ if (state->msgid_number < state->first_shown_msgid)
+ state->first_shown_msgid = state->msgid_number;
}
+ else
+ return move_list_start(state);
return 0;
}
int
-next_untranslated(struct DrawState* state)
+move_list_start(struct DrawState* state)
{
- if (state->msgid_count == 0)
- return 0;
-
- *state->error = 0;
-
- struct PoEntry* current = NULL;
- for (size_t e = state->msgid_number; e < state->msgid_count; e++)
- {
- current = state->entries + e;
- if (!current->msgstr || !*current->msgstr
- || u32_strlen(*current->msgstr) == 0)
- {
- int saved_show_edit = state->show_edit;
- if (saved_show_edit)
- {
- if (state->dirty)
- save_msgstr(state);
- else /* No need to call cancel_msgstr */
- state->dirty = state->dirty_before_edit;
- }
-
- goto_msgid(state, e + 1);
-
- if (saved_show_edit)
- {
- state->msgstr_index = 0;
- show_edit(state);
- }
-
- return 0;
- }
- }
+ *state->error = 0;
+ state->msgid_number = state->msgid_count > 0 ? 1 : 0;
+ state->first_shown_msgid = state->msgid_number;
return 0;
}
int
-next_fuzzy(struct DrawState* state)
+move_list_up(struct DrawState* state)
{
- if (state->msgid_count == 0)
- return 0;
-
- *state->error = 0;
-
- struct PoEntry* current = NULL;
- for (size_t e = state->msgid_number; e < state->msgid_count; e++)
+ if (state->msgid_number > 1)
{
- current = state->entries + e;
- if (current->flags & FL_FUZZY)
- {
- int saved_show_edit = state->show_edit;
- if (saved_show_edit)
- {
- if (state->dirty)
- save_msgstr(state);
- else /* No need to call cancel_msgstr */
- state->dirty = state->dirty_before_edit;
- }
-
- goto_msgid(state, e + 1);
-
- if (saved_show_edit)
- {
- state->msgstr_index = 0;
- show_edit(state);
- }
-
- return 0;
- }
+ *state->error = 0;
+ state->msgid_number--;
+ if (state->msgid_number < state->first_shown_msgid)
+ state->first_shown_msgid--;
}
return 0;
}
int
-show_edit(struct DrawState* state)
+move_next_word(struct DrawState* state)
{
- if (!load_msgstr(state) || !load_info(state))
+ if (state->edit_info_focused)
{
- strcpy(state->error, errors[ERR_CANT_ALLOC]);
- state->running = 0;
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
return 0;
}
- 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;
+ int i = state->input_column;
+ uint32_t* pline = state->input_buffer[state->input_row].text;
+ size_t len = state->input_buffer[state->input_row].length;
+
+ while (i < len && !u32_is_word_boundary(pline[i], 0))
+ i++;
+ while (i < len && u32_is_word_boundary(pline[i], 0))
+ i++;
+ state->input_column = i;
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
+ if (state->input_display_column - state->input_first_shown_column
+ > state->edit_width - 4)
+ state->input_first_shown_column
+ = state->input_display_column - state->edit_width + 4;
return 0;
}
int
-move_up(struct DrawState* state)
+move_prev_word(struct DrawState* state)
{
if (state->edit_info_focused)
{
- if (state->info_first_shown_row > 0)
- state->info_first_shown_row--;
+ strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
return 0;
}
- if (state->input_row > 0)
- state->input_row--;
- if (state->input_first_shown_row > state->input_row)
- state->input_first_shown_row = state->input_row;
- if (state->saved_column == -1)
- state->saved_column = state->input_display_column;
- size_t dlen = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_buffer[state->input_row].length);
- if (dlen < state->saved_column)
- state->input_display_column = dlen;
- else
- state->input_display_column = state->saved_column;
- state->input_column = input_length(state,
- state->input_buffer[state->input_row].text,
- state->input_display_column);
- if (state->input_first_shown_column > state->input_display_column)
- state->input_first_shown_column = state->input_display_column;
- if (state->input_first_shown_column + state->edit_width - 4
- < state->input_display_column)
- state->input_first_shown_column
- = state->input_display_column - state->edit_width + 4;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- return 0;
-}
+ int i = state->input_column;
+ uint32_t* pline = state->input_buffer[state->input_row].text;
-int
-move_down(struct DrawState* state)
-{
- if (state->edit_info_focused)
- {
- if (state->info_first_shown_row + (EDIT_HEIGHT - 3) / 2
- < state->info_rows_count)
- state->info_first_shown_row++;
- return 0;
- }
+ if (i > 0 && u32_is_word_boundary(pline[i - 1], 0))
+ i--;
+ while (i > 0 && u32_is_word_boundary(pline[i], 0))
+ i--;
+ while (i > 0 && !u32_is_word_boundary(pline[i], 0)
+ && !u32_is_word_boundary(pline[i - 1], 0))
+ i--;
- if (state->input_row < state->input_rows_count - 1)
- state->input_row++;
- if (state->input_first_shown_row + (EDIT_HEIGHT - 3) / 2
- < state->input_row)
- state->input_first_shown_row
- = state->input_row - (EDIT_HEIGHT - 3) / 2;
- if (state->saved_column == -1)
- state->saved_column = state->input_display_column;
- size_t dlen = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_buffer[state->input_row].length);
- if (dlen < state->saved_column)
- state->input_display_column = dlen;
- else
- state->input_display_column = state->saved_column;
- state->input_column = input_length(state,
- state->input_buffer[state->input_row].text,
- state->input_display_column);
- if (state->input_first_shown_column > state->input_display_column)
- state->input_first_shown_column = state->input_display_column;
- if (state->input_first_shown_column + state->edit_width - 4
- < state->input_display_column)
- state->input_first_shown_column
- = state->input_display_column - state->edit_width + 4;
+ state->input_column = i;
state->input_display_column = display_length(state,
state->input_buffer[state->input_row].text,
state->input_column);
- return 0;
-}
-
-int
-edit_page_up(struct DrawState* state)
-{
- if (state->edit_info_focused)
- {
- if (state->info_first_shown_row > (EDIT_HEIGHT - 3) / 2)
- state->info_first_shown_row -= (EDIT_HEIGHT - 3) / 2;
- else
- move_start(state);
- return 0;
- }
-
- if (state->dirty)
- save_msgstr(state);
- else /* No need to call cancel_msgstr */
- state->dirty = state->dirty_before_edit;
- move_list_up(state);
- state->msgstr_index = 0;
- return show_edit(state);
-}
-
-int
-edit_page_down(struct DrawState* state)
-{
- if (state->edit_info_focused)
- {
- if (state->info_first_shown_row + (EDIT_HEIGHT - 3) / 2
- < state->info_rows_count - 1)
- state->info_first_shown_row += (EDIT_HEIGHT - 3) / 2;
- return 0;
- }
-
- if (state->dirty)
- save_msgstr(state);
- else /* No need to call cancel_msgstr */
- state->dirty = state->dirty_before_edit;
- move_list_down(state);
- state->msgstr_index = 0;
- return show_edit(state);
-}
-
-int
-move_start(struct DrawState* state)
-{
- if (state->edit_info_focused)
- {
- state->info_first_shown_row = 0;
- state->info_first_shown_column = 0;
- return 0;
- }
-
- state->input_column = 0;
- state->input_display_column = 0;
- state->input_first_shown_column = 0;
- return 0;
-}
-
-int
-move_left(struct DrawState* state)
-{
- if (state->edit_info_focused)
- {
- if (state->info_first_shown_column > 0)
- state->info_first_shown_column--;
- return 0;
- }
-
- if (state->input_column == 0)
- return 0;
-
- if (state->input_buffer[state->input_row].text[state->input_column - 1]
- == '\t')
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column - 1);
- else
- state->input_display_column--;
- state->input_column--;
-
if (state->input_display_column < state->input_first_shown_column)
state->input_first_shown_column = state->input_display_column;
return 0;
@@ -1425,75 +1381,70 @@ move_right(struct DrawState* state)
}
int
-move_prev_word(struct DrawState* state)
+move_search_end(struct DrawState* state)
{
- if (state->edit_info_focused)
- {
- strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
- return 0;
- }
+ size_t len = u32_strlen(state->search);
+ state->search_column = len;
+ size_t dlen
+ = display_length(state, state->search, state->search_column);
+ state->search_display_column = dlen;
+ if (dlen > state->search_width - 4)
+ state->search_first_shown_column
+ = dlen - state->search_width + 4;
+ else
+ state->search_first_shown_column = 0;
+ return 0;
+}
- int i = state->input_column;
- uint32_t* pline = state->input_buffer[state->input_row].text;
+int
+move_search_left(struct DrawState* state)
+{
+ if (state->search_column == 0)
+ return 0;
- if (i > 0 && u32_is_word_boundary(pline[i - 1], 0))
- i--;
- while (i > 0 && u32_is_word_boundary(pline[i], 0))
- i--;
- while (i > 0 && !u32_is_word_boundary(pline[i], 0)
- && !u32_is_word_boundary(pline[i - 1], 0))
- i--;
+ if (state->search[state->search_column - 1] == '\t')
+ state->search_display_column = display_length(state,
+ state->search, state->search_column - 1);
+ else
+ state->search_display_column--;
+ state->search_column--;
- state->input_column = i;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- if (state->input_display_column < state->input_first_shown_column)
- state->input_first_shown_column = state->input_display_column;
+ if (state->search_display_column < state->search_first_shown_column)
+ state->search_first_shown_column = state->search_display_column;
return 0;
}
int
-move_next_word(struct DrawState* state)
+move_search_next_word(struct DrawState* state)
{
- if (state->edit_info_focused)
- {
- strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
- return 0;
- }
-
- int i = state->input_column;
- uint32_t* pline = state->input_buffer[state->input_row].text;
- size_t len = state->input_buffer[state->input_row].length;
+ int i = state->search_column;
+ uint32_t* pline = state->search;
+ size_t len = u32_strlen(state->search);
while (i < len && !u32_is_word_boundary(pline[i], 0))
i++;
while (i < len && u32_is_word_boundary(pline[i], 0))
i++;
- state->input_column = i;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- if (state->input_display_column - state->input_first_shown_column
- > state->edit_width - 4)
- state->input_first_shown_column
- = state->input_display_column - state->edit_width + 4;
+ state->search_column = i;
+ state->search_display_column
+ = display_length(state, state->search, state->search_column);
+
+ if (state->search_display_column - state->search_first_shown_column
+ > state->search_width - 4)
+ {
+ state->search_first_shown_column = state->search_display_column
+ - state->search_width + 4;
+ state->search_display_column = display_length(state,
+ state->search, state->search_column);
+ }
return 0;
}
int
-erase_prev_word(struct DrawState* state)
+move_search_prev_word(struct DrawState* state)
{
- if (state->edit_info_focused)
- {
- strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
- return 0;
- }
-
- int i = state->input_column;
- size_t len = state->input_buffer[state->input_row].length;
-
- uint32_t* pline = state->input_buffer[state->input_row].text;
+ int i = state->search_column;
+ uint32_t* pline = state->search;
if (i > 0 && u32_is_word_boundary(pline[i - 1], 0))
i--;
@@ -1503,151 +1454,165 @@ erase_prev_word(struct DrawState* state)
&& !u32_is_word_boundary(pline[i - 1], 0))
i--;
- int d = state->input_column - i;
-
- for (int j = i; j < len - d; j++)
- pline[j] = pline[j + d];
+ state->search_column = i;
+ state->search_display_column
+ = display_length(state, state->search, state->search_column);
- len -= d;
- state->input_buffer[state->input_row].length = len;
- pline[len] = 0;
- state->input_column = i;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- state->dirty = 1;
+ if (state->search_column < state->search_first_shown_column)
+ {
+ if (state->search_column > state->search_width - 4)
+ state->search_first_shown_column = state->search_column
+ - state->search_width + 4;
+ else
+ state->search_first_shown_column = 0;
+ }
+ state->search_display_column
+ = display_length(state, state->search, state->search_column);
return 0;
}
int
-insert_space(struct DrawState* state)
+move_search_right(struct DrawState* state)
{
- insert_char(state, (uint32_t)L' ');
- return 0;
-}
+ size_t len = u32_strlen(state->search);
+ if (state->search_column == len)
+ return 0;
-int
-insert_tab(struct DrawState* state)
-{
- insert_char(state, (uint32_t)L'\t');
- return 0;
-}
+ if (state->search[state->search_column] == '\t')
+ state->search_display_column = display_length(state,
+ state->search, state->search_column + 1);
+ else
+ state->search_display_column++;
+ state->search_column++;
-int
-insert_search_space(struct DrawState* state)
-{
- insert_search_char(state, (uint32_t)L' ');
+ if (state->search_display_column - state->search_first_shown_column
+ > state->search_width - 4)
+ state->search_first_shown_column = state->search_display_column
+ - state->search_width + 4;
return 0;
}
int
-insert_search_tab(struct DrawState* state)
+move_search_start(struct DrawState* state)
{
- insert_search_char(state, (uint32_t)L'\t');
+ state->search_column = 0;
+ state->search_display_column = 0;
+ state->search_first_shown_column = 0;
return 0;
}
int
-move_end(struct DrawState* state)
+move_start(struct DrawState* state)
{
if (state->edit_info_focused)
{
- if (state->info_rows_count > (EDIT_HEIGHT - 3) / 2)
- state->info_first_shown_row = state->info_rows_count
- - (EDIT_HEIGHT - 3) / 2;
+ state->info_first_shown_row = 0;
state->info_first_shown_column = 0;
return 0;
}
- size_t len = state->input_buffer[state->input_row].length;
- state->input_column = len;
- size_t dlen = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- state->input_display_column = dlen;
- if (dlen > state->edit_width - 4)
- state->input_first_shown_column = dlen - state->edit_width + 4;
- else
- state->input_first_shown_column = 0;
- return 0;
-}
-
-int
-move_list_up(struct DrawState* state)
-{
- if (state->msgid_number > 1)
- {
- *state->error = 0;
- state->msgid_number--;
- if (state->msgid_number < state->first_shown_msgid)
- state->first_shown_msgid--;
- }
+ state->input_column = 0;
+ state->input_display_column = 0;
+ state->input_first_shown_column = 0;
return 0;
}
int
-move_list_down(struct DrawState* state)
+move_up(struct DrawState* state)
{
- if (state->msgid_number < state->msgid_count)
+ if (state->edit_info_focused)
{
- *state->error = 0;
- state->msgid_number++;
- if (state->msgid_number - state->first_shown_msgid
- > state->maxy - 2)
- state->first_shown_msgid++;
+ if (state->info_first_shown_row > 0)
+ state->info_first_shown_row--;
+ return 0;
}
- return 0;
-}
-int
-move_list_start(struct DrawState* state)
-{
- *state->error = 0;
- state->msgid_number = state->msgid_count > 0 ? 1 : 0;
- state->first_shown_msgid = state->msgid_number;
+ if (state->input_row > 0)
+ state->input_row--;
+ if (state->input_first_shown_row > state->input_row)
+ state->input_first_shown_row = state->input_row;
+ if (state->saved_column == -1)
+ state->saved_column = state->input_display_column;
+ size_t dlen = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_buffer[state->input_row].length);
+ if (dlen < state->saved_column)
+ state->input_display_column = dlen;
+ else
+ state->input_display_column = state->saved_column;
+ state->input_column = input_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_display_column);
+ if (state->input_first_shown_column > state->input_display_column)
+ state->input_first_shown_column = state->input_display_column;
+ if (state->input_first_shown_column + state->edit_width - 4
+ < state->input_display_column)
+ state->input_first_shown_column
+ = state->input_display_column - state->edit_width + 4;
+ state->input_display_column = display_length(state,
+ state->input_buffer[state->input_row].text,
+ state->input_column);
return 0;
}
int
-move_list_end(struct DrawState* state)
+next_fuzzy(struct DrawState* state)
{
- *state->error = 0;
- state->msgid_number = state->msgid_count;
- state->first_shown_msgid = state->msgid_count > 0
- ? MAX(1, state->msgid_number - (state->maxy - 2))
- : 0;
- return 0;
-}
+ if (state->msgid_count == 0)
+ return 0;
-int
-move_list_page_up(struct DrawState* state)
-{
*state->error = 0;
- if (state->msgid_number > state->maxy - 2)
+
+ struct PoEntry* current = NULL;
+ for (size_t e = state->msgid_number; e < state->msgid_count; e++)
{
- state->msgid_number -= state->maxy - 2;
- if (state->msgid_number < state->first_shown_msgid)
- state->first_shown_msgid = state->msgid_number;
+ current = state->entries + e;
+ if (current->flags & FL_FUZZY)
+ {
+ int saved_show_edit = state->show_edit;
+ if (saved_show_edit)
+ {
+ if (state->dirty)
+ save_msgstr(state);
+ else /* No need to call cancel_msgstr */
+ state->dirty = state->dirty_before_edit;
+ }
+
+ goto_msgid(state, e + 1);
+
+ if (saved_show_edit)
+ {
+ state->msgstr_index = 0;
+ show_edit(state);
+ }
+
+ return 0;
+ }
}
- else
- return move_list_start(state);
return 0;
}
int
-move_list_page_down(struct DrawState* state)
+next_match(struct DrawState* state)
{
- *state->error = 0;
- if (state->msgid_number < state->msgid_count - state->maxy - 2)
+ if (state->msgid_count == 0 || !state->search || !*state->search)
+ return 0;
+
+ *state->error = 0;
+ struct PoEntry* current = NULL;
+ for (size_t e = state->msgid_number; e < state->msgid_count; e++)
{
- state->msgid_number += state->maxy - 2;
- if (state->msgid_number - state->first_shown_msgid
- > state->maxy - 2)
- state->first_shown_msgid
- = state->msgid_number - (state->maxy - 2);
+ current = state->entries + e;
+ if ((current->msgid && *current->msgid
+ && u32_strstr(current->msgid, state->search))
+ || (current->msgstr && *current->msgstr
+ && **current->msgstr
+ && u32_strstr(*current->msgstr, state->search)))
+ {
+ goto_msgid(state, e + 1);
+ return 0;
+ }
}
- else
- return move_list_end(state);
return 0;
}
@@ -1665,387 +1630,422 @@ next_plural(struct DrawState* state)
}
int
-prev_plural(struct DrawState* state)
+next_untranslated(struct DrawState* state)
{
- if (state->edit_info_focused)
+ if (state->msgid_count == 0)
return 0;
- save_msgstr(state);
- if (state->msgstr_index > 0)
- state->msgstr_index--;
- show_edit(state);
+
+ *state->error = 0;
+
+ struct PoEntry* current = NULL;
+ for (size_t e = state->msgid_number; e < state->msgid_count; e++)
+ {
+ current = state->entries + e;
+ if (!current->msgstr || !*current->msgstr
+ || u32_strlen(*current->msgstr) == 0)
+ {
+ int saved_show_edit = state->show_edit;
+ if (saved_show_edit)
+ {
+ if (state->dirty)
+ save_msgstr(state);
+ else /* No need to call cancel_msgstr */
+ state->dirty = state->dirty_before_edit;
+ }
+
+ goto_msgid(state, e + 1);
+
+ if (saved_show_edit)
+ {
+ state->msgstr_index = 0;
+ show_edit(state);
+ }
+
+ return 0;
+ }
+ }
return 0;
}
int
-toggle_fuzzy(struct DrawState* state)
+paste_paste_buffer_to_input(struct DrawState* state)
{
+ if (state->edit_info_focused)
+ return 0;
+
+ if (!state->in_prompt && *state->input_buffer->text)
+ {
+ state->in_prompt = 1;
+ strcpy(state->prompt, prompt_overwrite);
+ state->prompt_callback = overwrite_paste_callback;
+ return 0;
+ }
+
if (state->msgid_number == 1)
{
strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]);
return 0;
}
- if (state->msgid_count > 0)
- {
- state->entries[state->msgid_number - 1].flags ^= FL_FUZZY;
- if (state->entries[state->msgid_number - 1].flags & FL_FUZZY)
- {
- state->fuzzy_count++;
- if (state->input_changed_fuzzy == CLEARED)
- state->input_changed_fuzzy = UNCHANGED;
- else
- state->input_changed_fuzzy = SET;
- }
- else
- {
- state->fuzzy_count--;
- if (state->input_changed_fuzzy == SET)
- state->input_changed_fuzzy = UNCHANGED;
- else
- state->input_changed_fuzzy = CLEARED;
- }
- state->dirty = 1;
+
+ size_t lines_to_init = 0;
+ size_t lines_to_free = 0;
+ struct BufferLine* pinput = NULL;
+ struct BufferLine* newbuf = NULL;
+ struct BufferLine* ppaste = NULL;
+
+ if (!state->paste_buffer || !(*state->paste_buffer).text
+ || !*(*state->paste_buffer).text)
+ {
+ /* leave one row */
+ for (size_t i = 1; i < state->input_rows_count; i++)
+ free_bufferline(state->input_buffer + i);
+ state->input_buffer = realloc(state->input_buffer,
+ sizeof(struct BufferLine));
+ *(state->input_buffer->text) = 0;
+ state->input_column = 0;
+ state->input_display_column = 0;
+ state->input_first_shown_column = 0;
+ state->input_first_shown_row = 0;
+ state->input_row = 0;
+ state->input_rows_count = 1;
+ state->dirty = 1;
+ return 0;
}
- return 0;
-}
-int
-toggle_info_focused(struct DrawState* state)
-{
- state->edit_info_focused = !state->edit_info_focused;
- return 0;
-}
+ lines_to_init = state->input_rows_count < state->paste_rows_count
+ ? state->paste_rows_count - state->input_rows_count
+ : 0;
+ lines_to_free = state->input_rows_count > state->paste_rows_count
+ ? state->input_rows_count - state->paste_rows_count
+ : 0;
-void
-insert_char(struct DrawState* state, uint32_t ch)
-{
- if (state->edit_info_focused)
- return;
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
- size_t len = buffer_line->length;
- if (state->input_column < MAXBUFLINE - 1)
+ for (size_t i = 0; i < lines_to_free; i++)
+ free_bufferline(
+ state->input_buffer + state->input_rows_count - i - 1);
+ newbuf = realloc(state->input_buffer,
+ state->paste_rows_count * sizeof(struct BufferLine));
+ ppaste = state->paste_buffer;
+
+ if (!newbuf)
+ return 0;
+
+ for (size_t i = 0; i < lines_to_init; i++)
{
- size_t i = len + 1;
- int add_null = buffer_line->text[state->input_column] == 0;
- while (i < MAXBUFLINE - 2 && i > state->input_column)
- {
- buffer_line->text[i] = buffer_line->text[i - 1];
- i--;
- }
- buffer_line->text[state->input_column++] = ch;
- buffer_line->length++;
- if (state->input_column == MAXBUFLINE)
- state->input_column = MAXBUFLINE - 1;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- if (state->input_display_column - state->input_first_shown_column
- > state->edit_width - 4)
+ pinput = newbuf + state->paste_rows_count - 1 - i;
+ init_bufferline(pinput);
+ uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
+ if (!newtext)
+ return 0;
+ pinput->text = newtext;
+ }
+
+ if (ppaste)
+ for (size_t i = 0; i < state->paste_rows_count; i++)
{
- state->input_first_shown_column
- = state->input_display_column
- - state->edit_width + 4;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
+ pinput = newbuf + i;
+ u32_strncpy(pinput->text, ppaste->text,
+ MIN(ppaste->length + 1, MAXBUFLINE));
+ pinput->length = ppaste->length;
+ ppaste++;
}
- if (add_null)
- buffer_line->text[state->input_column] = 0;
- }
- state->dirty = 1;
+
+ state->input_rows_count = state->paste_rows_count;
+ state->input_buffer = newbuf;
+ state->dirty = 1;
+
+ return 0;
}
int
-erase_backwards(struct DrawState* state)
+prev_match(struct DrawState* state)
{
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
- if (state->edit_info_focused)
+ if (state->msgid_count == 0 || !state->search || !*state->search)
return 0;
- if (state->input_column > 0)
+ *state->error = 0;
+ struct PoEntry* current = NULL;
+ for (size_t e = state->msgid_number - 1; e > 0; e--)
{
- size_t i = state->input_column;
- do
- {
- buffer_line->text[i - 1] = buffer_line->text[i];
- i++;
- } while (buffer_line->text[i]);
- buffer_line->text[i - 1] = 0;
- buffer_line->length--;
- state->input_column--;
- if (state->input_first_shown_column > 0)
+ current = state->entries + e - 1;
+ if ((current->msgid && *current->msgid
+ && u32_strstr(current->msgid, state->search))
+ || (current->msgstr && *current->msgstr
+ && **current->msgstr
+ && u32_strstr(*current->msgstr, state->search)))
{
- const struct BufferLine* current_line
- = &state->input_buffer[state->input_row];
- if (display_length(state, current_line->text,
- current_line->length)
- >= state->edit_width - 4)
- state->input_first_shown_column--;
+ goto_msgid(state, e);
+ return 0;
}
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- if (state->input_display_column
- < state->input_first_shown_column)
- state->input_first_shown_column
- = state->input_display_column;
- state->dirty = 1;
- }
- else if (state->input_row > 0)
- {
- move_up(state);
- move_end(state);
- erase_forward(state);
}
return 0;
}
int
-erase_forward(struct DrawState* state)
+prev_plural(struct DrawState* state)
{
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
if (state->edit_info_focused)
return 0;
+ save_msgstr(state);
+ if (state->msgstr_index > 0)
+ state->msgstr_index--;
+ show_edit(state);
+ return 0;
+}
- if (buffer_line->text[state->input_column])
+int
+save_msgstr(struct DrawState* state)
+{
+ uint32_t* to_save = NULL;
+ size_t to_save_size = 0;
+ struct PoEntry* current = NULL;
+
+ state->show_edit = 0;
+ state->edit_info_focused = 0;
+
+ if (state->input_buffer)
{
- size_t i = state->input_column;
- while (i < MAXBUFLINE - 2 && buffer_line->text[i + 1])
+ to_save_size = state->input_rows_count * MAXMSGLINE;
+ to_save = calloc(to_save_size, sizeof(uint32_t));
+ if (!to_save)
{
- buffer_line->text[i] = buffer_line->text[i + 1];
- i++;
+ strcpy(state->error, errors[ERR_CANT_ALLOC]);
+ return 0;
}
- buffer_line->text[i] = 0;
- buffer_line->length--;
- state->dirty = 1;
- }
- else if (state->input_row < state->input_rows_count - 1)
- {
- if (!join_lines(state, state->input_row, 1))
+ struct BufferLine* pinput_buffer = NULL;
+ for (size_t i = 0; i < state->input_rows_count; i++)
{
- strcpy(state->error, errors[ERR_CANT_ALLOC]);
- state->running = 0;
+ pinput_buffer = state->input_buffer + i;
+ if (i == 0)
+ u32_strncpy(to_save, pinput_buffer->text,
+ to_save_size * sizeof(uint32_t));
+ else
+ {
+ u32_strncat(to_save, (uint32_t*)L"\\n",
+ to_save_size * sizeof(uint32_t));
+ u32_strncat(to_save, pinput_buffer->text,
+ to_save_size * sizeof(uint32_t));
+ }
+ free_bufferline(pinput_buffer);
}
}
+ free(state->input_buffer);
+ state->input_buffer = NULL;
+ state->input_rows_count = 0;
+ for (size_t i = 0; i < state->info_rows_count; i++)
+ free_bufferline(state->info_buffer + i);
+ free(state->info_buffer);
+ state->dirty = (state->dirty_before_edit || state->dirty);
+ state->info_rows_count = 0;
+ state->info_buffer = NULL;
+ u32_encode_tabs(to_save, to_save_size * sizeof(uint32_t));
+ current = &state->entries[state->msgid_number - 1];
+ u32_match_msgid_ending(current->msgid, to_save,
+ to_save_size * sizeof(uint32_t));
+ u32_set_msgstr(current, to_save, state->msgstr_index, 0, state);
+ update_warning(current->msgid, to_save, ¤t->warning);
+ state->input_changed_fuzzy = UNCHANGED;
+
+ tb_hide_cursor();
+ free(to_save);
return 0;
}
int
-erase_to_start(struct DrawState* state)
+show_edit(struct DrawState* state)
{
- if (state->edit_info_focused)
+ if (!load_msgstr(state) || !load_info(state))
{
- strcpy(state->error, errors[ERR_DLG_OPEN_QUIT]);
+ strcpy(state->error, errors[ERR_CANT_ALLOC]);
+ state->running = 0;
return 0;
}
- size_t i = state->input_column;
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
- size_t len = buffer_line->length;
- do
- {
- buffer_line->text[i - state->input_column]
- = buffer_line->text[i];
- i++;
- } while (buffer_line->text[i]);
- buffer_line->text[len - state->input_column] = 0;
- buffer_line->length = len - state->input_column;
- move_start(state);
- state->dirty = 1;
+ 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;
return 0;
}
int
-erase_to_end(struct DrawState* state)
+show_help(struct DrawState* state)
{
- if (state->edit_info_focused)
- return 0;
- struct BufferLine* buffer_line = &state->input_buffer[state->input_row];
- buffer_line->text[state->input_column] = 0;
- buffer_line->length = state->input_column;
- move_end(state);
- state->dirty = 1;
+ state->show_help = 1;
+ *state->error = 0;
return 0;
}
int
-insert_line(struct DrawState* state)
+show_search(struct DrawState* state)
{
- if (state->edit_info_focused)
- return 0;
- state->input_rows_count++;
- struct BufferLine* newbuf = realloc(state->input_buffer,
- state->input_rows_count * sizeof(struct BufferLine));
- if (!newbuf)
- {
- strcpy(state->error, errors[ERR_CANT_ALLOC]);
- state->running = 0;
- return 0;
- }
+ state->show_search = 1;
+ state->search_column = 0;
+ state->search_display_column = 0;
+ state->search_first_shown_column = 0;
+ if (!state->search)
+ state->search = calloc(MAXSEARCH, sizeof(uint32_t));
+ *state->search = 0;
+ tb_set_cursor((state->maxx - state->search_width + 2) / 2,
+ state->maxy - 1 - SEARCH_HEIGHT + 1);
+ return 0;
+}
- state->input_buffer = newbuf;
- init_bufferline(&state->input_buffer[state->input_rows_count - 1]);
- uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
- if (!newtext)
+int
+toggle_fuzzy(struct DrawState* state)
+{
+ if (state->msgid_number == 1)
{
- strcpy(state->error, errors[ERR_CANT_ALLOC]);
- state->running = 0;
+ strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]);
return 0;
}
- state->input_buffer[state->input_rows_count - 1].text = newtext;
- for (size_t i = state->input_rows_count - 1; i > state->input_row + 1;
- i--)
+ if (state->msgid_count > 0)
{
- u32_strncpy(state->input_buffer[i].text,
- state->input_buffer[i - 1].text, MAXBUFLINE);
- state->input_buffer[i].length
- = state->input_buffer[i - 1].length;
+ state->entries[state->msgid_number - 1].flags ^= FL_FUZZY;
+ if (state->entries[state->msgid_number - 1].flags & FL_FUZZY)
+ {
+ state->fuzzy_count++;
+ if (state->input_changed_fuzzy == CLEARED)
+ state->input_changed_fuzzy = UNCHANGED;
+ else
+ state->input_changed_fuzzy = SET;
+ }
+ else
+ {
+ state->fuzzy_count--;
+ if (state->input_changed_fuzzy == SET)
+ state->input_changed_fuzzy = UNCHANGED;
+ else
+ state->input_changed_fuzzy = CLEARED;
+ }
+ state->dirty = 1;
}
- u32_strncpy(state->input_buffer[state->input_row + 1].text,
- state->input_buffer[state->input_row].text + state->input_column,
- MAXBUFLINE);
- state->input_buffer[state->input_row + 1].length
- = u32_strlen(state->input_buffer[state->input_row + 1].text);
- state->input_buffer[state->input_row].text[state->input_column] = 0;
- state->input_buffer[state->input_row].length
- = u32_strlen(state->input_buffer[state->input_row].text);
-
- state->input_row++;
- if (state->input_row
- > state->input_first_shown_row + (EDIT_HEIGHT - 3) / 2)
- state->input_first_shown_row
- = state->input_row - (EDIT_HEIGHT - 3) / 2;
- move_start(state);
- state->dirty = 1;
-
return 0;
}
-struct DrawState*
-join_lines(struct DrawState* state, size_t first_line, int forward)
+int
+toggle_info_focused(struct DrawState* state)
{
- state->input_column = state->input_buffer[first_line].length;
- state->input_display_column = display_length(state,
- state->input_buffer[state->input_row].text,
- state->input_column);
- u32_strncat(state->input_buffer[first_line].text,
- state->input_buffer[first_line + 1].text, MAXBUFLINE);
- state->input_buffer[first_line].length
- = u32_strlen(state->input_buffer[first_line].text);
- if (!forward)
- {
- state->input_row--;
- if (state->input_row < 0)
- state->input_row = 0;
- }
- for (size_t i = first_line + 1; i < state->input_rows_count - 1; i++)
- {
- u32_strncpy(state->input_buffer[i].text,
- state->input_buffer[i + 1].text, MAXBUFLINE);
- state->input_buffer[i].length
- = state->input_buffer[i + 1].length;
- }
- free_bufferline(state->input_buffer + state->input_rows_count - 1);
- state->input_rows_count--;
- struct BufferLine* newbuf = realloc(state->input_buffer,
- state->input_rows_count * sizeof(struct BufferLine));
- if (!newbuf)
- return NULL;
- state->input_buffer = newbuf;
- state->dirty = 1;
-
- return state;
+ state->edit_info_focused = !state->edit_info_focused;
+ return 0;
}
-void
-handle_key_event(struct tb_event* ev, struct DrawState* state)
+int
+yank_msgstr_to_paste_buffer(struct DrawState* state)
{
- const struct Key* current = NULL;
+ if (state->edit_info_focused)
+ return 0;
- if (state->in_prompt)
+ if (state->msgid_number == 1)
{
- 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)
- cancel_close(state);
- return;
+ strcpy(state->error, errors[ERR_ILLEGAL_ON_FIRST]);
+ return 0;
}
- /* Remember to also edit the following condition if you reassign motion
- * keys */
- if (ev->key != TB_KEY_ARROW_DOWN && ev->key != TB_KEY_ARROW_UP
- && state->show_edit)
- state->saved_column = -1;
+ struct PoEntry* current = &state->entries[state->msgid_number - 1];
+ size_t msgstr_num_lines = 0;
+ size_t lines_to_init = 0;
+ size_t lines_to_free = 0;
+ struct BufferLine* newbuf = NULL;
+ const uint32_t* pmsgstr = NULL;
+ struct BufferLine* pbuffer = NULL;
- for (int key = 0; key < LEN(top_level_keys); key++)
+ if (!current->msgstr || !*(current->msgstr + state->msgstr_index))
{
- current = top_level_keys + key;
- if (((current->ev.key == ev->key) && !ev->ch)
- || (current->ev.ch && (current->ev.ch == ev->ch)))
- if (current->callback && !current->callback(state))
- return;
+ for (size_t i = 0; i < state->paste_rows_count; i++)
+ free_bufferline(state->paste_buffer + i);
+ free(state->paste_buffer);
+ state->paste_buffer = NULL;
+ state->paste_rows_count = 0;
+ return 0;
}
- if (state->show_help)
- {
- strcpy(state->error, errors[ERR_DLG_OPEN]);
- return;
- }
- else if (state->show_edit)
+ msgstr_num_lines
+ = u32_lines_in_string(*(current->msgstr + state->msgstr_index),
+ 0, 0);
+ lines_to_init = state->paste_rows_count < msgstr_num_lines
+ ? msgstr_num_lines - state->paste_rows_count
+ : 0;
+ lines_to_free = state->paste_rows_count > msgstr_num_lines
+ ? state->paste_rows_count - msgstr_num_lines
+ : 0;
+
+ for (size_t i = 0; i < lines_to_free; i++)
+ free_bufferline(
+ state->paste_buffer + state->paste_rows_count - i - 1);
+ if (!state->paste_buffer)
+ newbuf = calloc(msgstr_num_lines, sizeof(struct BufferLine));
+ else
+ newbuf = realloc(state->paste_buffer,
+ msgstr_num_lines * sizeof(struct BufferLine));
+ pmsgstr = *(current->msgstr + state->msgstr_index);
+
+ if (!newbuf)
+ return 0;
+
+ for (size_t i = 0; i < lines_to_init; i++)
{
- for (int key = 0; key < LEN(edit_keys); key++)
- {
- current = edit_keys + key;
- if (((current->ev.key == ev->key) && !ev->ch)
- || (current->ev.ch
- && (current->ev.ch == ev->ch)))
- if (current->callback
- && !current->callback(state))
- return;
- }
- if (ev->ch)
- {
- insert_char(state, ev->ch);
- return;
- }
+ pbuffer = newbuf + msgstr_num_lines - 1 - i;
+ init_bufferline(pbuffer);
+ uint32_t* newtext = calloc(MAXBUFLINE, sizeof(uint32_t));
+ if (!newtext)
+ return 0;
+ pbuffer->text = newtext;
}
- else if (state->show_search)
+
+ pbuffer = newbuf;
+ while (*pmsgstr)
{
- for (int key = 0; key < LEN(search_keys); key++)
- {
- current = search_keys + key;
- if (((current->ev.key == ev->key) && !ev->ch)
- || (current->ev.ch
- && (current->ev.ch == ev->ch)))
- if (current->callback
- && !current->callback(state))
- return;
- }
- if (ev->ch)
- {
- insert_search_char(state, ev->ch);
- return;
- }
+ size_t len = 0;
+ size_t newlen = 0;
+ const uint32_t* old_pmsgstr = pmsgstr;
+
+ len = u32_next_line(*(current->msgstr + state->msgstr_index),
+ &pmsgstr, 0, 0);
+ u32_strncpy(pbuffer->text, old_pmsgstr,
+ MIN(len + 1, MAXBUFLINE));
+ newlen = u32_decode_tabs(pbuffer->text, MAXBUFLINE);
+ pbuffer->length = newlen;
+ pbuffer++;
}
- else
+
+ state->paste_rows_count = msgstr_num_lines;
+ state->paste_buffer = newbuf;
+
+ return 0;
+}
+
+int
+write_file(struct DrawState* state)
+{
+ int result = save_file(state->entries, state->real_msgid_count,
+ state->filename, state->nplurals);
+ switch (result)
{
- for (int key = 0; key < LEN(main_keys); key++)
- {
- current = main_keys + key;
- if (((current->ev.key == ev->key) && !ev->ch)
- || (current->ev.ch
- && (current->ev.ch == ev->ch)))
- if (current->callback
- && !current->callback(state))
- return;
- }
+ case SAVE_ERR_CANT_ALLOC:
+ strcpy(state->error, errors[ERR_CANT_ALLOC]);
+ state->running = 0;
+ break;
+ case SAVE_ERR_CANT_OPEN_FILE:
+ strcpy(state->error, errors[ERR_CANT_SAVE]);
+ state->running = 0;
+ break;
+ case SAVE_ERR_CANT_MOVE_FILE:
+ strcpy(state->error, strerror(errno));
+ state->running = 0;
+ break;
+ default:
+ *state->error = 0;
+ state->dirty = 0;
}
-
- strcpy(state->error, errors[ERR_UNKNOWN_KEY]);
+ return 0;
}
int