diff options
Diffstat (limited to 'Build/source/utils/dialog/dialog-1.1-20080819/editbox.c')
-rw-r--r-- | Build/source/utils/dialog/dialog-1.1-20080819/editbox.c | 683 |
1 files changed, 0 insertions, 683 deletions
diff --git a/Build/source/utils/dialog/dialog-1.1-20080819/editbox.c b/Build/source/utils/dialog/dialog-1.1-20080819/editbox.c deleted file mode 100644 index f90e44d1820..00000000000 --- a/Build/source/utils/dialog/dialog-1.1-20080819/editbox.c +++ /dev/null @@ -1,683 +0,0 @@ -/* - * $Id: editbox.c,v 1.46 2008/06/21 12:07:54 tom Exp $ - * - * editbox.c -- implements the edit box - * - * Copyright 2007,2008 Thomas E. Dickey - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License, version 2.1 - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to - * Free Software Foundation, Inc. - * 51 Franklin St., Fifth Floor - * Boston, MA 02110, USA. - */ - -#include <dialog.h> -#include <dlg_keys.h> - -#include <sys/stat.h> - -#define sTEXT -1 - -static void -fail_list(void) -{ - dlg_exiterr("File too large"); -} - -static void -grow_list(char ***list, int *have, int want) -{ - if (want > *have) { - unsigned last = *have; - unsigned need = (want | 31) + 3; - *have = need; - (*list) = dlg_realloc(char *, need, *list); - if ((*list) == 0) { - fail_list(); - } - while (++last < need) { - (*list)[last] = 0; - } - } -} - -static void -load_list(const char *file, char ***list, int *rows) -{ - FILE *fp; - char *blob = 0; - struct stat sb; - unsigned n, pass; - unsigned need; - unsigned size; - - *list = 0; - *rows = 0; - - if (stat(file, &sb) < 0 || - (sb.st_mode & S_IFMT) != S_IFREG) - dlg_exiterr("Not a file: %s", file); - - size = sb.st_size; - if ((blob = dlg_malloc(char, size + 1)) == 0) - fail_list(); - blob[size] = '\0'; - - if ((fp = fopen(file, "r")) == 0) - dlg_exiterr("Cannot open: %s", file); - size = fread(blob, sizeof(char), size, fp); - fclose(fp); - - for (pass = 0; pass < 2; ++pass) { - int first = TRUE; - need = 0; - for (n = 0; n < size; ++n) { - if (first && pass) { - (*list)[need] = blob + n; - first = FALSE; - } - if (blob[n] == '\n') { - first = TRUE; - ++need; - if (pass) - blob[n] = '\0'; - } - } - if (pass) { - if (need == 0) { - (*list)[0] = dlg_strclone(""); - (*list)[1] = 0; - } else { - for (n = 0; n < need; ++n) { - (*list)[n] = dlg_strclone((*list)[n]); - } - (*list)[need] = 0; - } - } else { - grow_list(list, rows, need + 1); - } - } - free(blob); -} - -static void -free_list(char ***list, int *rows) -{ - if (*list != 0) { - int n; - for (n = 0; n < (*rows); ++n) { - if ((*list)[n] != 0) - free((*list)[n]); - } - free(*list); - *list = 0; - } - *rows = 0; -} - -/* - * Display a single row in the editing window: - * thisrow is the actual row number that's being displayed. - * show_row is the row number that's highlighted for edit. - * base_row is the first row number in the window - */ -static bool -display_one(WINDOW *win, - char *text, - int thisrow, - int show_row, - int base_row, - int chr_offset) -{ - bool result; - - if (text != 0) { - dlg_show_string(win, - text, - chr_offset, - ((thisrow == show_row) - ? form_active_text_attr - : form_text_attr), - thisrow - base_row, - 0, - getmaxx(win), - FALSE, - FALSE); - result = TRUE; - } else { - result = FALSE; - } - return result; -} - -static void -display_all(WINDOW *win, - char **list, - int show_row, - int firstrow, - int lastrow, - int chr_offset) -{ - int limit = getmaxy(win); - int row; - - dlg_attr_clear(win, getmaxy(win), getmaxx(win), dialog_attr); - if (lastrow - firstrow >= limit) - lastrow = firstrow + limit; - for (row = firstrow; row < lastrow; ++row) { - if (!display_one(win, list[row], - row, show_row, firstrow, - (row == show_row) ? chr_offset : 0)) - break; - } -} - -static int -size_list(char **list) -{ - int result = 0; - - if (list != 0) { - while (*list++ != 0) { - ++result; - } - } - return result; -} - -static bool -scroll_to(int pagesize, int rows, int *base_row, int *this_row, int target) -{ - bool result = FALSE; - - if (target < *base_row) { - if (target < 0) { - if (*base_row == 0 && *this_row == 0) { - beep(); - } else { - *this_row = 0; - *base_row = 0; - result = TRUE; - } - } else { - *this_row = target; - *base_row = target; - result = TRUE; - } - } else if (target >= rows) { - if (*this_row < rows - 1) { - *this_row = rows - 1; - *base_row = rows - 1; - result = TRUE; - } else { - beep(); - } - } else if (target >= *base_row + pagesize) { - *this_row = target; - *base_row = target; - result = TRUE; - } else { - *this_row = target; - result = FALSE; - } - if (pagesize < rows) { - if (*base_row + pagesize >= rows) { - *base_row = rows - pagesize; - } - } else { - *base_row = 0; - } - return result; -} - -static int -col_to_chr_offset(const char *text, int col) -{ - const int *cols = dlg_index_columns(text); - const int *indx = dlg_index_wchars(text); - bool found = FALSE; - int result = 0; - unsigned n; - unsigned len = dlg_count_wchars(text); - - for (n = 0; n < len; ++n) { - if (cols[n] <= col && cols[n + 1] > col) { - result = indx[n]; - found = TRUE; - break; - } - } - if (!found && len && cols[len] == col) { - result = indx[len]; - } - return result; -} - -#define SCROLL_TO(target) show_all = scroll_to(pagesize, listsize, &base_row, &thisrow, target) - -#define PREV_ROW (*list)[thisrow - 1] -#define THIS_ROW (*list)[thisrow] -#define NEXT_ROW (*list)[thisrow + 1] - -#define UPDATE_COL(input) col_offset = dlg_edit_offset(input, chr_offset, box_width) - -/* - * Display a dialog box for editing a copy of a file - */ -int -dlg_editbox(const char *title, - char ***list, - int *rows, - int height, - int width) -{ - /* *INDENT-OFF* */ - static DLG_KEYS_BINDING binding[] = { - INPUTSTR_BINDINGS, - ENTERKEY_BINDINGS, - DLG_KEYS_DATA( DLGK_GRID_DOWN, KEY_DOWN ), - DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHT ), - DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFT ), - DLG_KEYS_DATA( DLGK_GRID_UP, KEY_UP ), - DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), - DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), - DLG_KEYS_DATA( DLGK_PAGE_FIRST, KEY_HOME ), - DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ), - DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ), - DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), - DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ), - DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ), - DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ), - END_KEYS_BINDING - }; - /* *INDENT-ON* */ - -#ifdef KEY_RESIZE - int old_height = height; - int old_width = width; -#endif - int x, y, box_y, box_x, box_height, box_width; - int show_buttons; - int thisrow, base_row, lastrow; - int goal_col = -1; - int col_offset = 0; - int chr_offset = 0; - int key, fkey, code; - int pagesize; - int listsize = size_list(*list); - int result = DLG_EXIT_UNKNOWN; - int state; - int max_len = dlg_max_input(MAX_LEN); - char *input, *buffer; - bool show_all, show_one, was_mouse; - WINDOW *dialog; - WINDOW *editing; - DIALOG_VARS save_vars; - const char **buttons = dlg_ok_labels(); - - dlg_save_vars(&save_vars); - dialog_vars.separate_output = TRUE; - - dlg_does_output(); - - buffer = dlg_malloc(char, max_len); - assert_ptr(buffer, "dlg_editbox"); - - thisrow = base_row = lastrow = 0; - -#ifdef KEY_RESIZE - retry: -#endif - show_buttons = TRUE; - state = dialog_vars.defaultno ? dlg_defaultno_button() : sTEXT; - key = fkey = 0; - - dlg_auto_size(title, "", &height, &width, 3 * LINES / 4, 3 * COLS / 4); - dlg_print_size(height, width); - dlg_ctl_size(height, width); - - x = dlg_box_x_ordinate(width); - y = dlg_box_y_ordinate(height); - - dialog = dlg_new_window(height, width, y, x); - dlg_register_window(dialog, "editbox", binding); - dlg_register_buttons(dialog, "editbox", buttons); - - dlg_mouse_setbase(x, y); - - dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); - dlg_draw_bottom_box(dialog); - dlg_draw_title(dialog, title); - - wattrset(dialog, dialog_attr); - - /* Draw the editing field in a box */ - box_y = MARGIN + 0; - box_x = MARGIN + 1; - box_width = width - 2 - (2 * MARGIN); - box_height = height - (4 * MARGIN); - - dlg_draw_box(dialog, - box_y, - box_x, - box_height, - box_width, - border_attr, dialog_attr); - dlg_mouse_mkbigregion(box_y + MARGIN, - box_x + MARGIN, - box_height - (2 * MARGIN), - box_width - (2 * MARGIN), - KEY_MAX, 1, 1, 3); - editing = dlg_sub_window(dialog, - box_height - (2 * MARGIN), - box_width - (2 * MARGIN), - getbegy(dialog) + box_y + 1, - getbegx(dialog) + box_x + 1); - dlg_register_window(editing, "editbox", binding); - - show_all = TRUE; - show_one = FALSE; - pagesize = getmaxy(editing); - - while (result == DLG_EXIT_UNKNOWN) { - int edit = 0; - - if (show_all) { - display_all(editing, *list, thisrow, base_row, listsize, chr_offset); - display_one(editing, THIS_ROW, - thisrow, thisrow, base_row, chr_offset); - show_all = FALSE; - show_one = TRUE; - } else { - if (thisrow != lastrow) { - display_one(editing, (*list)[lastrow], - lastrow, thisrow, base_row, 0); - show_one = TRUE; - } - } - if (show_one) { - display_one(editing, THIS_ROW, - thisrow, thisrow, base_row, chr_offset); - getyx(editing, y, x); - dlg_draw_arrows2(dialog, - base_row != 0, - base_row + pagesize < listsize, - box_x + ARROWS_COL, - box_y + 0, - box_y + getmaxy(editing) + 1, - dialog_attr, - border_attr); - wmove(editing, y, x); - show_one = FALSE; - } - lastrow = thisrow; - input = THIS_ROW; - - /* - * The last field drawn determines where the cursor is shown: - */ - if (show_buttons) { - show_buttons = FALSE; - UPDATE_COL(input); - if (state != sTEXT) { - display_one(editing, input, thisrow, - -1, base_row, 0); - wrefresh(editing); - } - dlg_draw_buttons(dialog, - height - 2, - 0, - buttons, - (state != sTEXT) ? state : 99, - FALSE, - width); - if (state == sTEXT) { - display_one(editing, input, thisrow, - thisrow, base_row, chr_offset); - } - } - - key = dlg_mouse_wgetch((state == sTEXT) ? editing : dialog, &fkey); - if (state != sTEXT) { - if (dlg_result_key(key, fkey, &result)) - break; - } - - was_mouse = (fkey && is_DLGK_MOUSE(key)); - if (was_mouse) - key -= M_EVENT; - - /* - * Handle mouse clicks first, since we want to know if this is a - * button, or something that dlg_edit_string() should handle. - */ - if (fkey - && was_mouse - && (code = dlg_ok_buttoncode(key)) >= 0) { - result = code; - continue; - } - - if (was_mouse - && (key >= KEY_MAX)) { - int wide = getmaxx(editing); - int cell = key - KEY_MAX; - thisrow = (cell / wide) + base_row; - col_offset = (cell % wide); - chr_offset = col_to_chr_offset(THIS_ROW, col_offset); - show_one = TRUE; - if (state != sTEXT) { - state = sTEXT; - show_buttons = TRUE; - } - continue; - } else if (was_mouse && key >= KEY_MIN) { - key = dlg_lookup_key(dialog, key, &fkey); - } - - if (state == sTEXT) { /* editing box selected */ - /* - * Intercept scrolling keys that dlg_edit_string() does not - * understand. - */ - if (fkey) { - bool moved = TRUE; - - switch (key) { - case DLGK_GRID_UP: - SCROLL_TO(thisrow - 1); - break; - case DLGK_GRID_DOWN: - SCROLL_TO(thisrow + 1); - break; - case DLGK_PAGE_FIRST: - SCROLL_TO(0); - break; - case DLGK_PAGE_LAST: - SCROLL_TO(listsize); - break; - case DLGK_PAGE_NEXT: - SCROLL_TO(base_row + pagesize); - break; - case DLGK_PAGE_PREV: - if (thisrow > base_row) { - SCROLL_TO(base_row); - } else { - SCROLL_TO(base_row - pagesize); - } - break; - case DLGK_DELETE_LEFT: - if (chr_offset == 0) { - if (thisrow == 0) { - beep(); - } else { - int len = strlen(THIS_ROW) + strlen(PREV_ROW) + 1; - char *tmp = dlg_malloc(char, len); - - assert_ptr(tmp, "dlg_editbox"); - - chr_offset = dlg_count_wchars(PREV_ROW); - UPDATE_COL(PREV_ROW); - goal_col = col_offset; - - sprintf(tmp, "%s%s", PREV_ROW, THIS_ROW); - if (len > max_len) - tmp[max_len] = '\0'; - - free(PREV_ROW); - PREV_ROW = tmp; - for (y = thisrow; y < listsize; ++y) { - (*list)[y] = (*list)[y + 1]; - } - --listsize; - --thisrow; - SCROLL_TO(thisrow); - - show_all = TRUE; - } - } else { - /* dlg_edit_string() can handle this case */ - moved = FALSE; - } - break; - default: - moved = FALSE; - break; - } - if (moved) { - if (thisrow != lastrow) { - if (goal_col < 0) - goal_col = col_offset; - chr_offset = col_to_chr_offset(THIS_ROW, goal_col); - } else { - UPDATE_COL(THIS_ROW); - } - continue; - } - } - strcpy(buffer, input); - edit = dlg_edit_string(buffer, &chr_offset, key, fkey, FALSE); - - if (edit) { - goal_col = UPDATE_COL(input); - if (strcmp(input, buffer)) { - free(input); - THIS_ROW = dlg_strclone(buffer); - input = THIS_ROW; - } - display_one(editing, input, thisrow, - thisrow, base_row, chr_offset); - continue; - } - } - - /* handle non-functionkeys */ - if (!fkey && (code = dlg_char_to_button(key, buttons)) >= 0) { - dlg_del_window(dialog); - result = dlg_ok_buttoncode(code); - continue; - } - - /* handle functionkeys */ - if (fkey) { - switch (key) { - case DLGK_FIELD_PREV: - show_buttons = TRUE; - state = dlg_prev_ok_buttonindex(state, sTEXT); - break; - case DLGK_FIELD_NEXT: - show_buttons = TRUE; - state = dlg_next_ok_buttonindex(state, sTEXT); - break; - case DLGK_ENTER: - if (state == sTEXT) { - const int *indx = dlg_index_wchars(THIS_ROW); - int split = indx[chr_offset]; - char *tmp = dlg_strclone(THIS_ROW + split); - - assert_ptr(tmp, "dlg_editbox"); - grow_list(list, rows, listsize + 1); - ++listsize; - for (y = listsize; y > thisrow; --y) { - (*list)[y] = (*list)[y - 1]; - } - THIS_ROW[split] = '\0'; - ++thisrow; - chr_offset = 0; - col_offset = 0; - THIS_ROW = tmp; - SCROLL_TO(thisrow); - show_all = TRUE; - } else { - result = dlg_ok_buttoncode(state); - } - break; -#ifdef KEY_RESIZE - case KEY_RESIZE: - /* reset data */ - height = old_height; - width = old_width; - /* repaint */ - dlg_clear(); - dlg_del_window(editing); - dlg_del_window(dialog); - refresh(); - dlg_mouse_free_regions(); - goto retry; -#endif - default: - beep(); - break; - } - } else { - if ((key == ' ') && (state != sTEXT)) { - result = dlg_ok_buttoncode(state); - } else { - beep(); - } - } - } - - dlg_unregister_window(editing); - dlg_del_window(editing); - dlg_del_window(dialog); - dlg_mouse_free_regions(); - - /* - * The caller's copy of the (*list)[] array has been updated, but for - * consistency with the other widgets, we put the "real" result in - * the output buffer. - */ - if (result == DLG_EXIT_OK) { - int n; - for (n = 0; n < listsize; ++n) { - dlg_add_result((*list)[n]); - dlg_add_separator(); - } - } - free(buffer); - dlg_restore_vars(&save_vars); - return result; -} - -int -dialog_editbox(const char *title, const char *file, int height, int width) -{ - int result; - char **list; - int rows; - - load_list(file, &list, &rows); - result = dlg_editbox(title, &list, &rows, height, width); - free_list(&list, &rows); - return result; -} |