diff options
Diffstat (limited to 'extra/config/lxdialog')
-rw-r--r-- | extra/config/lxdialog/check-lxdialog.sh | 15 | ||||
-rw-r--r-- | extra/config/lxdialog/checklist.c | 24 | ||||
-rw-r--r-- | extra/config/lxdialog/dialog.h | 34 | ||||
-rw-r--r-- | extra/config/lxdialog/inputbox.c | 136 | ||||
-rw-r--r-- | extra/config/lxdialog/menubox.c | 56 | ||||
-rw-r--r-- | extra/config/lxdialog/textbox.c | 186 | ||||
-rw-r--r-- | extra/config/lxdialog/util.c | 97 | ||||
-rw-r--r-- | extra/config/lxdialog/yesno.c | 11 |
8 files changed, 371 insertions, 188 deletions
diff --git a/extra/config/lxdialog/check-lxdialog.sh b/extra/config/lxdialog/check-lxdialog.sh index d34dfd46d..9d2a4c585 100644 --- a/extra/config/lxdialog/check-lxdialog.sh +++ b/extra/config/lxdialog/check-lxdialog.sh @@ -4,7 +4,9 @@ # What library to link ldflags() { - for ext in so a dylib ; do + pkg-config --libs ncursesw 2>/dev/null && exit + pkg-config --libs ncurses 2>/dev/null && exit + for ext in so a dll.a dylib ; do for lib in ncursesw ncurses curses ; do $cc -print-file-name=lib${lib}.${ext} | grep -q / if [ $? -eq 0 ]; then @@ -19,14 +21,13 @@ ldflags() # Where is ncurses.h? ccflags() { - if [ -f /usr/include/ncursesw/ncurses.h ]; then - echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncurses.h>"' - elif [ -f /usr/include/ncursesw/curses.h ]; then - echo '-I/usr/include/ncursesw -DCURSES_LOC="<ncursesw/curses.h>"' + if [ -f /usr/include/ncursesw/curses.h ]; then + echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"' + echo ' -DNCURSES_WIDECHAR=1' elif [ -f /usr/include/ncurses/ncurses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"' elif [ -f /usr/include/ncurses/curses.h ]; then - echo '-I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>"' + echo '-I/usr/include/ncurses -DCURSES_LOC="<curses.h>"' elif [ -f /usr/include/ncurses.h ]; then echo '-DCURSES_LOC="<ncurses.h>"' else @@ -40,7 +41,7 @@ trap "rm -f $tmp" 0 1 2 3 15 # Check if we can link to ncurses check() { - $cc -xc - -o $tmp 2>/dev/null <<'EOF' + $cc -x c - -o $tmp 2>/dev/null <<'EOF' #include CURSES_LOC main() {} EOF diff --git a/extra/config/lxdialog/checklist.c b/extra/config/lxdialog/checklist.c index 53aa3099b..3b15c08ec 100644 --- a/extra/config/lxdialog/checklist.c +++ b/extra/config/lxdialog/checklist.c @@ -17,7 +17,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dialog.h" @@ -30,6 +31,10 @@ static int list_width, check_x, item_x; static void print_item(WINDOW * win, int choice, int selected) { int i; + char *list_item = malloc(list_width + 1); + + strncpy(list_item, item_str(), list_width - item_x); + list_item[list_width - item_x] = '\0'; /* Clear 'residue' of last item */ wattrset(win, dlg.menubox.atr); @@ -40,16 +45,18 @@ static void print_item(WINDOW * win, int choice, int selected) wmove(win, choice, check_x); wattrset(win, selected ? dlg.check_selected.atr : dlg.check.atr); - wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); + if (!item_is_tag(':')) + wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' '); wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr); - mvwaddch(win, choice, item_x, item_str()[0]); + mvwaddch(win, choice, item_x, list_item[0]); wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr); - waddstr(win, (char *)item_str() + 1); + waddstr(win, list_item + 1); if (selected) { wmove(win, choice, check_x + 1); wrefresh(win); } + free(list_item); } /* @@ -125,16 +132,16 @@ int dialog_checklist(const char *title, const char *prompt, int height, } do_resize: - if (getmaxy(stdscr) < (height + 6)) + if (getmaxy(stdscr) < (height + CHECKLIST_HEIGTH_MIN)) return -ERRDISPLAYTOOSMALL; - if (getmaxx(stdscr) < (width + 6)) + if (getmaxx(stdscr) < (width + CHECKLIST_WIDTH_MIN)) return -ERRDISPLAYTOOSMALL; max_choice = MIN(list_height, item_count()); /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; + x = (getmaxx(stdscr) - width) / 2; + y = (getmaxy(stdscr) - height) / 2; draw_shadow(stdscr, y, x, height, width); @@ -173,6 +180,7 @@ do_resize: check_x = 0; item_foreach() check_x = MAX(check_x, strlen(item_str()) + 4); + check_x = MIN(check_x, list_width); check_x = (list_width - check_x) / 2; item_x = check_x + 4; diff --git a/extra/config/lxdialog/dialog.h b/extra/config/lxdialog/dialog.h index f6e33df26..b4343d384 100644 --- a/extra/config/lxdialog/dialog.h +++ b/extra/config/lxdialog/dialog.h @@ -14,7 +14,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <sys/types.h> @@ -105,8 +106,14 @@ struct dialog_color { int hl; /* highlight this item */ }; +struct subtitle_list { + struct subtitle_list *next; + const char *text; +}; + struct dialog_info { const char *backtitle; + struct subtitle_list *subtitles; struct dialog_color screen; struct dialog_color shadow; struct dialog_color dialog; @@ -143,6 +150,7 @@ struct dialog_info { */ extern struct dialog_info dlg; extern char dialog_input_result[]; +extern int saved_x, saved_y; /* Needed in signal handler in mconf.c */ /* * Function prototypes @@ -192,8 +200,23 @@ int item_is_tag(char tag); int on_key_esc(WINDOW *win); int on_key_resize(void); +/* minimum (re)size values */ +#define CHECKLIST_HEIGTH_MIN 6 /* For dialog_checklist() */ +#define CHECKLIST_WIDTH_MIN 6 +#define INPUTBOX_HEIGTH_MIN 2 /* For dialog_inputbox() */ +#define INPUTBOX_WIDTH_MIN 2 +#define MENUBOX_HEIGTH_MIN 15 /* For dialog_menu() */ +#define MENUBOX_WIDTH_MIN 65 +#define TEXTBOX_HEIGTH_MIN 8 /* For dialog_textbox() */ +#define TEXTBOX_WIDTH_MIN 8 +#define YESNO_HEIGTH_MIN 4 /* For dialog_yesno() */ +#define YESNO_WIDTH_MIN 4 +#define WINDOW_HEIGTH_MIN 19 /* For init_dialog() */ +#define WINDOW_WIDTH_MIN 80 + int init_dialog(const char *backtitle); void set_dialog_backtitle(const char *backtitle); +void set_dialog_subtitles(struct subtitle_list *subtitles); void end_dialog(int x, int y); void attr_clear(WINDOW * win, int height, int width, chtype attr); void dialog_clear(void); @@ -208,12 +231,17 @@ int first_alpha(const char *string, const char *exempt); int dialog_yesno(const char *title, const char *prompt, int height, int width); int dialog_msgbox(const char *title, const char *prompt, int height, int width, int pause); -int dialog_textbox(const char *title, const char *file, int height, int width); + + +typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void + *_data); +int dialog_textbox(const char *title, char *tbuf, int initial_height, + int initial_width, int *keys, int *_vscroll, int *_hscroll, + update_text_fn update_text, void *data); int dialog_menu(const char *title, const char *prompt, const void *selected, int *s_scroll); int dialog_checklist(const char *title, const char *prompt, int height, int width, int list_height); -extern char dialog_input_result[]; int dialog_inputbox(const char *title, const char *prompt, int height, int width, const char *init); diff --git a/extra/config/lxdialog/inputbox.c b/extra/config/lxdialog/inputbox.c index cecc9e8ff..447a58219 100644 --- a/extra/config/lxdialog/inputbox.c +++ b/extra/config/lxdialog/inputbox.c @@ -15,7 +15,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dialog.h" @@ -44,7 +45,8 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width const char *init) { int i, x, y, box_y, box_x, box_width; - int input_x = 0, scroll = 0, key = 0, button = -1; + int input_x = 0, key = 0, button = -1; + int show_x, len, pos; char *instr = dialog_input_result; WINDOW *dialog; @@ -54,14 +56,14 @@ int dialog_inputbox(const char *title, const char *prompt, int height, int width strcpy(instr, init); do_resize: - if (getmaxy(stdscr) <= (height - 2)) + if (getmaxy(stdscr) <= (height - INPUTBOX_HEIGTH_MIN)) return -ERRDISPLAYTOOSMALL; - if (getmaxx(stdscr) <= (width - 2)) + if (getmaxx(stdscr) <= (width - INPUTBOX_WIDTH_MIN)) return -ERRDISPLAYTOOSMALL; /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; + x = (getmaxx(stdscr) - width) / 2; + y = (getmaxy(stdscr) - height) / 2; draw_shadow(stdscr, y, x, height, width); @@ -96,14 +98,17 @@ do_resize: wmove(dialog, box_y, box_x); wattrset(dialog, dlg.inputbox.atr); - input_x = strlen(instr); + len = strlen(instr); + pos = len; - if (input_x >= box_width) { - scroll = input_x - box_width + 1; + if (len >= box_width) { + show_x = len - box_width + 1; input_x = box_width - 1; for (i = 0; i < box_width - 1; i++) - waddch(dialog, instr[scroll + i]); + waddch(dialog, instr[show_x + i]); } else { + show_x = 0; + input_x = len; waddstr(dialog, instr); } @@ -120,45 +125,104 @@ do_resize: case KEY_UP: case KEY_DOWN: break; - case KEY_LEFT: - continue; - case KEY_RIGHT: - continue; case KEY_BACKSPACE: case 127: - if (input_x || scroll) { + if (pos) { wattrset(dialog, dlg.inputbox.atr); - if (!input_x) { - scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1); - wmove(dialog, box_y, box_x); - for (i = 0; i < box_width; i++) - waddch(dialog, - instr[scroll + input_x + i] ? - instr[scroll + input_x + i] : ' '); - input_x = strlen(instr) - scroll; + if (input_x == 0) { + show_x--; } else input_x--; - instr[scroll + input_x] = '\0'; - mvwaddch(dialog, box_y, input_x + box_x, ' '); + + if (pos < len) { + for (i = pos - 1; i < len; i++) { + instr[i] = instr[i+1]; + } + } + + pos--; + len--; + instr[len] = '\0'; + wmove(dialog, box_y, box_x); + for (i = 0; i < box_width; i++) { + if (!instr[show_x + i]) { + waddch(dialog, ' '); + break; + } + waddch(dialog, instr[show_x + i]); + } wmove(dialog, box_y, input_x + box_x); wrefresh(dialog); } continue; + case KEY_LEFT: + if (pos > 0) { + if (input_x > 0) { + wmove(dialog, box_y, --input_x + box_x); + } else if (input_x == 0) { + show_x--; + wmove(dialog, box_y, box_x); + for (i = 0; i < box_width; i++) { + if (!instr[show_x + i]) { + waddch(dialog, ' '); + break; + } + waddch(dialog, instr[show_x + i]); + } + wmove(dialog, box_y, box_x); + } + pos--; + } + continue; + case KEY_RIGHT: + if (pos < len) { + if (input_x < box_width - 1) { + wmove(dialog, box_y, ++input_x + box_x); + } else if (input_x == box_width - 1) { + show_x++; + wmove(dialog, box_y, box_x); + for (i = 0; i < box_width; i++) { + if (!instr[show_x + i]) { + waddch(dialog, ' '); + break; + } + waddch(dialog, instr[show_x + i]); + } + wmove(dialog, box_y, input_x + box_x); + } + pos++; + } + continue; default: if (key < 0x100 && isprint(key)) { - if (scroll + input_x < MAX_LEN) { + if (len < MAX_LEN) { wattrset(dialog, dlg.inputbox.atr); - instr[scroll + input_x] = key; - instr[scroll + input_x + 1] = '\0'; + if (pos < len) { + for (i = len; i > pos; i--) + instr[i] = instr[i-1]; + instr[pos] = key; + } else { + instr[len] = key; + } + pos++; + len++; + instr[len] = '\0'; + if (input_x == box_width - 1) { - scroll++; - wmove(dialog, box_y, box_x); - for (i = 0; i < box_width - 1; i++) - waddch(dialog, instr [scroll + i]); + show_x++; } else { - wmove(dialog, box_y, input_x++ + box_x); - waddch(dialog, key); + input_x++; + } + + wmove(dialog, box_y, box_x); + for (i = 0; i < box_width; i++) { + if (!instr[show_x + i]) { + waddch(dialog, ' '); + break; + } + waddch(dialog, instr[show_x + i]); } + wmove(dialog, box_y, input_x + box_x); wrefresh(dialog); } else flash(); /* Alarm user about overflow */ @@ -179,7 +243,7 @@ do_resize: case KEY_LEFT: switch (button) { case -1: - button = 1; /* Indicates "Cancel" button is selected */ + button = 1; /* Indicates "Help" button is selected */ print_buttons(dialog, height, width, 1); break; case 0: @@ -203,7 +267,7 @@ do_resize: print_buttons(dialog, height, width, 0); break; case 0: - button = 1; /* Indicates "Cancel" button is selected */ + button = 1; /* Indicates "Help" button is selected */ print_buttons(dialog, height, width, 1); break; case 1: diff --git a/extra/config/lxdialog/menubox.c b/extra/config/lxdialog/menubox.c index 4203b864b..c93de0b2f 100644 --- a/extra/config/lxdialog/menubox.c +++ b/extra/config/lxdialog/menubox.c @@ -15,7 +15,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -153,12 +154,14 @@ static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x, */ static void print_buttons(WINDOW * win, int height, int width, int selected) { - int x = width / 2 - 16; + int x = width / 2 - 28; int y = height - 2; print_button(win, gettext("Select"), y, x, selected == 0); print_button(win, gettext(" Exit "), y, x + 12, selected == 1); print_button(win, gettext(" Help "), y, x + 24, selected == 2); + print_button(win, gettext(" Save "), y, x + 36, selected == 3); + print_button(win, gettext(" Load "), y, x + 48, selected == 4); wmove(win, y, x + 1 + 12 * selected); wrefresh(win); @@ -190,7 +193,7 @@ int dialog_menu(const char *title, const char *prompt, do_resize: height = getmaxy(stdscr); width = getmaxx(stdscr); - if (height < 15 || width < 65) + if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN) return -ERRDISPLAYTOOSMALL; height -= 4; @@ -200,8 +203,8 @@ do_resize: max_choice = MIN(menu_height, item_count()); /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; + x = (getmaxx(stdscr) - width) / 2; + y = (getmaxy(stdscr) - height) / 2; draw_shadow(stdscr, y, x, height, width); @@ -300,10 +303,11 @@ do_resize: } } - if (i < max_choice || - key == KEY_UP || key == KEY_DOWN || - key == '-' || key == '+' || - key == KEY_PPAGE || key == KEY_NPAGE) { + if (item_count() != 0 && + (i < max_choice || + key == KEY_UP || key == KEY_DOWN || + key == '-' || key == '+' || + key == KEY_PPAGE || key == KEY_NPAGE)) { /* Remove highligt of current item */ print_item(scroll + choice, choice, FALSE); @@ -371,7 +375,7 @@ do_resize: case TAB: case KEY_RIGHT: button = ((key == KEY_LEFT ? --button : ++button) < 0) - ? 2 : (button > 2 ? 0 : button); + ? 4 : (button > 4 ? 0 : button); print_buttons(dialog, height, width, button); wrefresh(menu); @@ -382,6 +386,10 @@ do_resize: case 'n': case 'm': case '/': + case 'h': + case '?': + case 'z': + case '\n': /* save scroll info */ *s_scroll = scroll; delwin(menu); @@ -389,30 +397,26 @@ do_resize: item_set(scroll + choice); item_set_selected(1); switch (key) { + case 'h': + case '?': + return 2; case 's': - return 3; case 'y': - return 3; + return 5; case 'n': - return 4; + return 6; case 'm': - return 5; + return 7; case ' ': - return 6; + return 8; case '/': - return 7; + return 9; + case 'z': + return 10; + case '\n': + return button; } return 0; - case 'h': - case '?': - button = 2; - case '\n': - *s_scroll = scroll; - delwin(menu); - delwin(dialog); - item_set(scroll + choice); - item_set_selected(1); - return button; case 'e': case 'x': key = KEY_ESC; diff --git a/extra/config/lxdialog/textbox.c b/extra/config/lxdialog/textbox.c index 4ca8fe158..1773319b9 100644 --- a/extra/config/lxdialog/textbox.c +++ b/extra/config/lxdialog/textbox.c @@ -15,29 +15,32 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dialog.h" static void back_lines(int n); -static void print_page(WINDOW * win, int height, int width); -static void print_line(WINDOW * win, int row, int width); +static void print_page(WINDOW *win, int height, int width, update_text_fn + update_text, void *data); +static void print_line(WINDOW *win, int row, int width); static char *get_line(void); static void print_position(WINDOW * win); static int hscroll; static int begin_reached, end_reached, page_length; -static const char *buf; -static const char *page; +static char *buf; +static char *page; /* * refresh window content */ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, - int cur_y, int cur_x) + int cur_y, int cur_x, update_text_fn update_text, + void *data) { - print_page(box, boxh, boxw); + print_page(box, boxh, boxw, update_text, data); print_position(dialog); wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); @@ -46,14 +49,18 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, /* * Display text from a file in a dialog box. + * + * keys is a null-terminated array + * update_text() may not add or remove any '\n' or '\0' in tbuf */ -int dialog_textbox(const char *title, const char *tbuf, - int initial_height, int initial_width) +int dialog_textbox(const char *title, char *tbuf, int initial_height, + int initial_width, int *keys, int *_vscroll, int *_hscroll, + update_text_fn update_text, void *data) { int i, x, y, cur_x, cur_y, key = 0; int height, width, boxh, boxw; - int passed_end; WINDOW *dialog, *box; + bool done = false; begin_reached = 1; end_reached = 0; @@ -62,9 +69,18 @@ int dialog_textbox(const char *title, const char *tbuf, buf = tbuf; page = buf; /* page is pointer to start of page to be displayed */ + if (_vscroll && *_vscroll) { + begin_reached = 0; + + for (i = 0; i < *_vscroll; i++) + get_line(); + } + if (_hscroll) + hscroll = *_hscroll; + do_resize: getmaxyx(stdscr, height, width); - if (height < 8 || width < 8) + if (height < TEXTBOX_HEIGTH_MIN || width < TEXTBOX_WIDTH_MIN) return -ERRDISPLAYTOOSMALL; if (initial_height != 0) height = initial_height; @@ -82,8 +98,8 @@ do_resize: width = 0; /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; + x = (getmaxx(stdscr) - width) / 2; + y = (getmaxy(stdscr) - height) / 2; draw_shadow(stdscr, y, x, height, width); @@ -119,25 +135,28 @@ do_resize: /* Print first page of text */ attr_clear(box, boxh, boxw, dlg.dialog.atr); - refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); + refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text, + data); - while ((key != KEY_ESC) && (key != '\n')) { + while (!done) { key = wgetch(dialog); switch (key) { case 'E': /* Exit */ case 'e': case 'X': case 'x': - delwin(box); - delwin(dialog); - return 0; + case 'q': + case '\n': + done = true; + break; case 'g': /* First page */ case KEY_HOME: if (!begin_reached) { begin_reached = 1; page = buf; refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); + cur_y, cur_x, update_text, + data); } break; case 'G': /* Last page */ @@ -147,78 +166,48 @@ do_resize: /* point to last char in buf */ page = buf + strlen(buf); back_lines(boxh); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); + refresh_text_box(dialog, box, boxh, boxw, cur_y, + cur_x, update_text, data); break; case 'K': /* Previous line */ case 'k': case KEY_UP: - if (!begin_reached) { - back_lines(page_length + 1); - - /* We don't call print_page() here but use - * scrolling to ensure faster screen update. - * However, 'end_reached' and 'page_length' - * should still be updated, and 'page' should - * point to start of next page. This is done - * by calling get_line() in the following - * 'for' loop. */ - scrollok(box, TRUE); - wscrl(box, -1); /* Scroll box region down one line */ - scrollok(box, FALSE); - page_length = 0; - passed_end = 0; - for (i = 0; i < boxh; i++) { - if (!i) { - /* print first line of page */ - print_line(box, 0, boxw); - wnoutrefresh(box); - } else - /* Called to update 'end_reached' and 'page' */ - get_line(); - if (!passed_end) - page_length++; - if (end_reached && !passed_end) - passed_end = 1; - } + if (begin_reached) + break; - print_position(dialog); - wmove(dialog, cur_y, cur_x); /* Restore cursor position */ - wrefresh(dialog); - } + back_lines(page_length + 1); + refresh_text_box(dialog, box, boxh, boxw, cur_y, + cur_x, update_text, data); break; case 'B': /* Previous page */ case 'b': + case 'u': case KEY_PPAGE: if (begin_reached) break; back_lines(page_length + boxh); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); + refresh_text_box(dialog, box, boxh, boxw, cur_y, + cur_x, update_text, data); break; case 'J': /* Next line */ case 'j': case KEY_DOWN: - if (!end_reached) { - begin_reached = 0; - scrollok(box, TRUE); - scroll(box); /* Scroll box region up one line */ - scrollok(box, FALSE); - print_line(box, boxh - 1, boxw); - wnoutrefresh(box); - print_position(dialog); - wmove(dialog, cur_y, cur_x); /* Restore cursor position */ - wrefresh(dialog); - } + if (end_reached) + break; + + back_lines(page_length - 1); + refresh_text_box(dialog, box, boxh, boxw, cur_y, + cur_x, update_text, data); break; case KEY_NPAGE: /* Next page */ case ' ': + case 'd': if (end_reached) break; begin_reached = 0; - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); + refresh_text_box(dialog, box, boxh, boxw, cur_y, + cur_x, update_text, data); break; case '0': /* Beginning of line */ case 'H': /* Scroll left */ @@ -233,8 +222,8 @@ do_resize: hscroll--; /* Reprint current page to scroll horizontally */ back_lines(page_length); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); + refresh_text_box(dialog, box, boxh, boxw, cur_y, + cur_x, update_text, data); break; case 'L': /* Scroll right */ case 'l': @@ -244,11 +233,12 @@ do_resize: hscroll++; /* Reprint current page to scroll horizontally */ back_lines(page_length); - refresh_text_box(dialog, box, boxh, boxw, - cur_y, cur_x); + refresh_text_box(dialog, box, boxh, boxw, cur_y, + cur_x, update_text, data); break; case KEY_ESC: - key = on_key_esc(dialog); + if (on_key_esc(dialog) == KEY_ESC) + done = true; break; case KEY_RESIZE: back_lines(height); @@ -256,11 +246,31 @@ do_resize: delwin(dialog); on_key_resize(); goto do_resize; + default: + for (i = 0; keys[i]; i++) { + if (key == keys[i]) { + done = true; + break; + } + } } } delwin(box); delwin(dialog); - return key; /* ESC pressed */ + if (_vscroll) { + const char *s; + + s = buf; + *_vscroll = 0; + back_lines(page_length); + while (s < page && (s = strchr(s, '\n'))) { + (*_vscroll)++; + s++; + } + } + if (_hscroll) + *_hscroll = hscroll; + return key; } /* @@ -297,12 +307,23 @@ static void back_lines(int n) } /* - * Print a new page of text. Called by dialog_textbox(). + * Print a new page of text. */ -static void print_page(WINDOW * win, int height, int width) +static void print_page(WINDOW *win, int height, int width, update_text_fn + update_text, void *data) { int i, passed_end = 0; + if (update_text) { + char *end; + + for (i = 0; i < height; i++) + get_line(); + end = page; + back_lines(height); + update_text(buf, page - buf, end - buf, data); + } + page_length = 0; for (i = 0; i < height; i++) { print_line(win, i, width); @@ -315,11 +336,10 @@ static void print_page(WINDOW * win, int height, int width) } /* - * Print a new line of text. Called by dialog_textbox() and print_page(). + * Print a new line of text. */ static void print_line(WINDOW * win, int row, int width) { - int y, x; char *line; line = get_line(); @@ -328,10 +348,10 @@ static void print_line(WINDOW * win, int row, int width) waddch(win, ' '); waddnstr(win, line, MIN(strlen(line), width - 2)); - getyx(win, y, x); /* Clear 'residue' of previous line */ #if OLD_NCURSES { + int x = getcurx(win); int i; for (i = 0; i < width - x; i++) waddch(win, ' '); @@ -354,10 +374,8 @@ static char *get_line(void) end_reached = 0; while (*page != '\n') { if (*page == '\0') { - if (!end_reached) { - end_reached = 1; - break; - } + end_reached = 1; + break; } else if (i < MAX_LEN) line[i++] = *(page++); else { @@ -370,7 +388,7 @@ static char *get_line(void) if (i <= MAX_LEN) line[i] = '\0'; if (!end_reached) - page++; /* move pass '\n' */ + page++; /* move past '\n' */ return line; } diff --git a/extra/config/lxdialog/util.c b/extra/config/lxdialog/util.c index 4f14cb01f..58a8289dd 100644 --- a/extra/config/lxdialog/util.c +++ b/extra/config/lxdialog/util.c @@ -15,11 +15,17 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <stdarg.h> + #include "dialog.h" +/* Needed in signal handler in mconf.c */ +int saved_x, saved_y; + struct dialog_info dlg; static void set_mono_theme(void) @@ -248,15 +254,56 @@ void attr_clear(WINDOW * win, int height, int width, chtype attr) void dialog_clear(void) { - attr_clear(stdscr, LINES, COLS, dlg.screen.atr); + int lines, columns; + + lines = getmaxy(stdscr); + columns = getmaxx(stdscr); + + attr_clear(stdscr, lines, columns, dlg.screen.atr); /* Display background title if it exists ... - SLH */ if (dlg.backtitle != NULL) { - int i; + int i, len = 0, skip = 0; + struct subtitle_list *pos; wattrset(stdscr, dlg.screen.atr); mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle); + + for (pos = dlg.subtitles; pos != NULL; pos = pos->next) { + /* 3 is for the arrow and spaces */ + len += strlen(pos->text) + 3; + } + wmove(stdscr, 1, 1); - for (i = 1; i < COLS - 1; i++) + if (len > columns - 2) { + const char *ellipsis = "[...] "; + waddstr(stdscr, ellipsis); + skip = len - (columns - 2 - strlen(ellipsis)); + } + + for (pos = dlg.subtitles; pos != NULL; pos = pos->next) { + if (skip == 0) + waddch(stdscr, ACS_RARROW); + else + skip--; + + if (skip == 0) + waddch(stdscr, ' '); + else + skip--; + + if (skip < strlen(pos->text)) { + waddstr(stdscr, pos->text + skip); + skip = 0; + } else + skip -= strlen(pos->text); + + if (skip == 0) + waddch(stdscr, ' '); + else + skip--; + } + + for (i = len + 1; i < columns - 1; i++) waddch(stdscr, ACS_HLINE); } wnoutrefresh(stdscr); @@ -270,8 +317,12 @@ int init_dialog(const char *backtitle) int height, width; initscr(); /* Init curses */ + + /* Get current cursor position for signal handler in mconf.c */ + getyx(stdscr, saved_y, saved_x); + getmaxyx(stdscr, height, width); - if (height < 19 || width < 80) { + if (height < WINDOW_HEIGTH_MIN || width < WINDOW_WIDTH_MIN) { endwin(); return -ERRDISPLAYTOOSMALL; } @@ -292,6 +343,11 @@ void set_dialog_backtitle(const char *backtitle) dlg.backtitle = backtitle; } +void set_dialog_subtitles(struct subtitle_list *subtitles) +{ + dlg.subtitles = subtitles; +} + /* * End using dialog functions. */ @@ -320,27 +376,19 @@ void print_title(WINDOW *dialog, const char *title, int width) /* * Print a string of text in a window, automatically wrap around to the * next line if the string is too long to fit on one line. Newline - * characters '\n' are replaced by spaces. We start on a new line + * characters '\n' are propperly processed. We start on a new line * if there is no room for at least 4 nonblanks following a double-space. */ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) { int newl, cur_x, cur_y; - int i, prompt_len, room, wlen; - char tempstr[MAX_LEN + 1], *word, *sp, *sp2; + int prompt_len, room, wlen; + char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0; strcpy(tempstr, prompt); prompt_len = strlen(tempstr); - /* - * Remove newlines - */ - for (i = 0; i < prompt_len; i++) { - if (tempstr[i] == '\n') - tempstr[i] = ' '; - } - if (prompt_len <= width - x * 2) { /* If prompt is short */ wmove(win, y, (width - prompt_len) / 2); waddstr(win, tempstr); @@ -350,7 +398,10 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) newl = 1; word = tempstr; while (word && *word) { - sp = strchr(word, ' '); + sp = strpbrk(word, "\n "); + if (sp && *sp == '\n') + newline_separator = sp; + if (sp) *sp++ = 0; @@ -362,7 +413,7 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) if (wlen > room || (newl && wlen < 4 && sp && wlen + 1 + strlen(sp) > room - && (!(sp2 = strchr(sp, ' ')) + && (!(sp2 = strpbrk(sp, "\n ")) || wlen + 1 + (sp2 - sp) > room))) { cur_y++; cur_x = x; @@ -370,7 +421,15 @@ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) wmove(win, cur_y, cur_x); waddstr(win, word); getyx(win, cur_y, cur_x); - cur_x++; + + /* Move to the next line if the word separator was a newline */ + if (newline_separator) { + cur_y++; + cur_x = x; + newline_separator = 0; + } else + cur_x++; + if (sp && *sp == ' ') { cur_x++; /* double space */ while (*++sp == ' ') ; diff --git a/extra/config/lxdialog/yesno.c b/extra/config/lxdialog/yesno.c index c27b1b038..676fb2f82 100644 --- a/extra/config/lxdialog/yesno.c +++ b/extra/config/lxdialog/yesno.c @@ -15,7 +15,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dialog.h" @@ -44,14 +45,14 @@ int dialog_yesno(const char *title, const char *prompt, int height, int width) WINDOW *dialog; do_resize: - if (getmaxy(stdscr) < (height + 4)) + if (getmaxy(stdscr) < (height + YESNO_HEIGTH_MIN)) return -ERRDISPLAYTOOSMALL; - if (getmaxx(stdscr) < (width + 4)) + if (getmaxx(stdscr) < (width + YESNO_WIDTH_MIN)) return -ERRDISPLAYTOOSMALL; /* center dialog box on screen */ - x = (COLS - width) / 2; - y = (LINES - height) / 2; + x = (getmaxx(stdscr) - width) / 2; + y = (getmaxy(stdscr) - height) / 2; draw_shadow(stdscr, y, x, height, width); |