1971864966
break mixed form dialogs in conjunction with the FreeBSD termcap, making the bsdinstall partition editor Add dialog, among other things, completely nonfunctional. This restores dialog 20110707.
722 lines
16 KiB
C
722 lines
16 KiB
C
/*
|
|
* $Id: editbox.c,v 1.55 2011/06/21 00:10:46 tom Exp $
|
|
*
|
|
* editbox.c -- implements the edit box
|
|
*
|
|
* Copyright 2007-2010,2011 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) {
|
|
size_t last = (size_t) *have;
|
|
size_t need = (size_t) (want | 31) + 3;
|
|
*have = (int) 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;
|
|
size_t 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 = (size_t) 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, (int) 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 = (unsigned) 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)
|
|
|
|
static int
|
|
widest_line(char **list)
|
|
{
|
|
int result = MAX_LEN;
|
|
char *value;
|
|
|
|
if (list != 0) {
|
|
while ((value = *list++) != 0) {
|
|
int check = (int) strlen(value);
|
|
if (check > result)
|
|
result = check;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#define NAVIGATE_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) )
|
|
/*
|
|
* 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[] = {
|
|
HELPKEY_BINDINGS,
|
|
ENTERKEY_BINDINGS,
|
|
NAVIGATE_BINDINGS,
|
|
END_KEYS_BINDING
|
|
};
|
|
static DLG_KEYS_BINDING binding2[] = {
|
|
INPUTSTR_BINDINGS,
|
|
HELPKEY_BINDINGS,
|
|
ENTERKEY_BINDINGS,
|
|
NAVIGATE_BINDINGS,
|
|
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;
|
|
size_t max_len = (size_t) dlg_max_input(widest_line(*list));
|
|
char *input, *buffer;
|
|
bool show_all, show_one, was_mouse;
|
|
WINDOW *dialog;
|
|
WINDOW *editing;
|
|
DIALOG_VARS save_vars;
|
|
const char **buttons = dlg_ok_labels();
|
|
int mincols = (3 * COLS / 4);
|
|
|
|
dlg_save_vars(&save_vars);
|
|
dialog_vars.separate_output = TRUE;
|
|
|
|
dlg_does_output();
|
|
|
|
buffer = dlg_malloc(char, max_len + 1);
|
|
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_button_layout(buttons, &mincols);
|
|
dlg_auto_size(title, "", &height, &width, 3 * LINES / 4, mincols);
|
|
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", binding2);
|
|
|
|
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_scrollbar(dialog,
|
|
base_row,
|
|
base_row,
|
|
base_row + pagesize,
|
|
listsize,
|
|
box_x,
|
|
box_x + getmaxx(editing),
|
|
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 (key == ERR) {
|
|
result = DLG_EXIT_ERROR;
|
|
break;
|
|
} else if (key == ESC) {
|
|
result = DLG_EXIT_ESC;
|
|
break;
|
|
}
|
|
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 {
|
|
size_t 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;
|
|
}
|
|
}
|
|
strncpy(buffer, input, max_len - 1)[max_len - 1] = '\0';
|
|
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;
|
|
}
|