1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-05 09:14:03 +00:00

Import dialog 1.3-20180621

This commit is contained in:
Baptiste Daroussin 2018-10-20 20:32:57 +00:00
parent 42c10d5d7d
commit 4dccdce419
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/dialog/dist/; revision=339482
svn path=/vendor/dialog/1.3-20180621/; revision=339483; tag=vendor/dialog/1.3-20180621
92 changed files with 22580 additions and 8184 deletions

323
CHANGES
View File

@ -1,9 +1,328 @@
-- $Id: CHANGES,v 1.476 2013/09/24 00:06:47 tom Exp $
-- $Id: CHANGES,v 1.619 2018/06/21 09:19:45 tom Exp $
-- Thomas E. Dickey <dickey@invisible-island.net>
This version of dialog was originally from a Debian snapshot. I've done this
to it:
2018/06/21
+ improve file-offset computation in textbox.c (Werner Fink).
+ fix an overlooked case with real_auto_size() to maximize when
height or width is given as -1.
+ build-fixes for configure options "--disable-Xdialog2" and
"--disable-form"
+ add traces for each widget to show its parameters.
+ modify color scheme for mixedgauge to use the dialog window colors,
like the captions.
+ fix a too-small malloc in the mixedgauge widget.
+ fix a use-after-free in dlg_remove_callback().
+ improve handling of SIGWINCH for several widgets (Debian #865840).
+ menubox, the point of the Debian report was that it would be nice
to increase the window size if the terminal size increases. Did
that as a special case less problematic than decreasing the
terminal size. Added samples/menubox11 to demonstrate by
comparison with menubox10 a problem with debconf which puts extra
newlines in the caption that interfere with autowrap.
+ progressbox and derived prgbox, programbox, now handle resizing.
+ yesno, window was cleared
+ add dlg_ttysize() to support new options, allowing scripts to obtain
some text-formatting details without initializing the terminal.
+ add options --print-text-only, and --print-text-size for scripts that
adjust the widget size according to how the captions are formatted.
+ improve dialog.pl:
+ add demo.pl, to demonstrate the functions
+ quote/escape string parameters passed to dialog.
+ ensure all "integer" parameters are really integers.
+ use actual screensize for list captions rather than assuming 24
lines.
+ when trimming blanks, treat unconverted tabs the same as spaces.
+ correct parameter to test when trimming blanks from the script,
e.g., with "--trim" (report by Jarno Suni).
+ improve documentation of the various whitespace-filtering options,
to show which take precedence (Debian #867536, cf: Debian #102942).
+ modify msgbox.c, yesno.c to bind SCROLLKEY_BINDINGS before
TRAVERSE_BINDINGS so that up/down arrow will by default scroll the
message up/down rather than be aliases for tab-traversal (report by
Fredrik Kers).
+ modify dump_one_binding() to show when a binding is overridden.
+ improve format of trace-file, making comment-syntax consistent,
as well as showing argv-splitting as a series of comments.
+ modify dlg_string_to_argv() to change the quoting behavior to be
more consistent with shell behavior (patch by Denilson Sa Maia).
+ modify dlg_getc() to return ESC when a timeout expires, notifying
callers that a quit occurred rather than exiting the application
(suggested by Rodrigo Freitas).
+ modify handle_inputs() to ensure cursor-visibility is restored when
there is no input character available (report by Guillaume Vareille).
+ improve comment in manual page regarding which widgets can use the
"--help-button" (prompted by discussion with Csanyi Pal).
+ add a check for valid object pointer in tailbox's main loop since
the getc-callback may have been freed within ui_getc.c (report by
"David").
+ improved configure macros for ncurses: CF_GNU_SOURCE, CF_SHARED_OPTS,
CF_CURSES_LIBS, CF_CURSES_FUNCS, CF_NCURSES_CONFIG
+ improved configure script checks for groff vs man2html:
CF_PROG_GROFF and CF_WITH_MAN2HTML
+ build-fix from lynx for AM_WITH_NLS configure macro
+ update config.guess, config.sub
2017/12/09
+ update ftp url in test-packages.
+ modify test-packages to use recommended compiler/linker flags.
+ improved configure macros AM_WITH_NLS, CF_CC_ENV_FLAGS,
CF_CURSES_LIBS, CF_NCURSES_CONFIG, CF_SHARED_OPTS, CF_WITH_LIBTOOL,
CF__INTL_BODY.
+ update config.guess, config.sub
2017/05/09
+ improved configure macros CF_ADD_CFLAGS, CF_CC_ENV_FLAGS, and
CF_SHARED_OPTS.
+ updated hu.po and tr.po from
http://translationproject.org/latest/dialog/
+ update config.guess, config.sub
2017/01/31
+ use DLG_TRACE macro consistently to make "--disable-trace" configure
option work.
+ modify buildlist widget to support option "--reorder" for to allow
user to reorder the data based on the sequence of selections
(discussion with Paraic O'Ceallaigh).
+ fill background color on unused parts of buildlist.
+ fix a minor error in buildlist which let pageup switch columns.
+ change several calls to dlg_trace_msg to prefix with "#" to make
the trace logs more consistent for parsing.
+ add samples/run_test.sh
+ further improve performance with very long command-lines by changes
to howmany_tags().
+ modify dlg_string_to_argv() to convert escaped double-quotes to
plain double-quotes when within a double-quoted string.
+ modify makefile to apply CFLAGS to linking
+ modify dlg_string_to_argv() to ignore escaped newlines except when
quoted, fixing a problem with samples/checklist9.
+ interpret $DIALOGOPTS before expanding "--file", etc., to allow
the environment variable to turn on tracing in that process.
+ improve performance when processing very long command lines, e.g.,
using "--file" by changing dialog_opts[] to an array of pointers to
the expanded argv[] (discussion with Lars Tauber).
+ modified autoconf macros
+ CF_CC_ENV_FLAGS amend the last change to move only the
preprocessor, optimization and warning flags to CPPFLAGS and
CFLAGS, leaving the residue in CC. That happens to work for gcc's
various "model" options, but may require tuning for other compilers
+ CF_LARGEFILE workaround for clang exit-code vs warnings
+ CF_MATH_LIB quiet strict gcc warning
+ CF_WITH_LIBTOOL fix a few places in configure/build scripts where
DESTDIR and rpath were combined
+ CF_XOPEN_SOURCE add "uclinux" to list of Linux's
+ update config.guess, config.sub
2016/11/20
+ added fur.po (Friulian) from
http://translationproject.org/latest/dialog/
2016/08/28
+ improve parsing and trace for "bindkey", to convert space to/from
"\s", as well as handle octal escapes for single byte characters.
+ change explicit checks for space character used for select or toggle
to make this rebindable to "TOGGLE" (prompted by discussion with
Paul van Tilburg).
+ add default bindings for cursor left/right to formbox. The cursor
left/right cases were replaced with rebindable symbols in 2005/12/07
without providing these keys as default values (report/patch by
Miroslav Lichvar).
+ modified autoconf macros
+ CF_PROG_LINT add cpplint to programs to use; drop ad hoc tdlint and
alint.
+ CF_CC_ENV_FLAGS don't limit the check to -I, -U and -D options,
since the added options can include various compiler options before
and after preprocessor options.
+ CF_GNU_SOURCE recent glibc (Debian 2.23-4 for example) has
misordered ifdef/checks for new symbol _DEFAULT_SOURCE, producing
warning messages when only _GNU_SOURCE is defined. Add a followup
check to define _DEFAULT_SOURCE.
+ CF_XOPEN_SOURCE use _GNU_SOURCE for cygwin headers, tested with
cygwin 2.3, 2.5 (patch by Corinna Vinschen).
+ mention --no-collapse option in manual page description of
--tab-correct option.
+ update config.guess, config.sub
2016/04/24
+ fix a special case in drawing shadow on a line-drawing cell where the
alternate-character set flag was lost (report by Martin Kravec).
+ fix a regression from 2015/05/13 changes for escaping; it is
necessary to retain backslashes within quotes to make "\Z" escapes
work (report by Marcin Krol).
+ fix test package for RPMs; changes in 2015 omitted symbolic links
for the library.
+ fix typo in help message for "--buildlist" (report by Rihards Olups).
+ modified autoconf macros
+ CF_PROG_AR, CF_AR_FLAGS added to improve check for archive tool.
+ CF_LD_RPATH_OPT, change FreeBSD to use -Wl,-rpath rather than
-rpath option. According to FreeBSD #178732, either works since
FreeBSD 4.x; however scons does not accept anything except the
-Wl,-rpath form.
+ CF_WITH_NCURSES_ETC, change from ncurses to check for pthreads
dependency.
2016/02/09
+ modify editbox widget to add a trailing newline if the text has none
to ensure the last line is not ignored (report by Florent Rougon).
+ change mouse initialization to look for button-presses rather than
button-clicks, for better response.
+ modify dump_curses_key() to show mouse-coding in readable form.
+ correct mapping of mouse-clicks on the day-grid in calendar widget
when "--week-start" is used to set the start of the week (report by
Stefan Vogtner).
> integrated changes from Stefan Vogtner:
+ use Gregorian algorithm for leap year
+ use mktime if available; calendar was written just as it became
standard.
2016/01/26 - release 1.3
+ correct --infobox documentation, which said it shows an OK button.
+ fix a couple of place in test-scripts which referred to $SIG_TRAP
rather than $SIG_QUIT
+ reorganize dialog.3, to use subsections for generating navigation
pane, using man2html
+ add "--week-start" option for calendar widget (prompted by discussion
with Stefan Vogtner).
+ add a limit-check in editbox.c to ensure that mouse-clicks outside
the filled-in text area do not access past the end of the array
(report by Stefan Vogtner).
+ update configure macros from ncurses changes.
+ update config.guess, config.sub
2015/09/20
+ decrease table value for minimum number of arguments for the widgets
which use --no-items option (report by Raven Singularity).
+ update configure macros:
+ use $SHELL consistently, deprecate non-POSIX shell
+ PKG_CONFIG may simply be unset - fix
+ add option to allow changing ABI version, from ncurses6.
2015/05/28
+ fixes for two autoconf macros, CF_ADD_INCDIR and CF_NCURSES_CONFIG
from work on ncurses.
+ build-fix for NetBSD curses (patch by Matthias Scheler).
2015/05/13
+ add configure option --with-install-prefix, like ncurses.
+ add --with-screen and related configure options from ncurses-examples
to allow building with ncurses6 test-packages.
+ update configure macros for improved coding style from lynx changes.
+ updated ro.po from
http://translationproject.org/latest/dialog/
+ update config.guess, config.sub
> patches by Florent Rougon:
+ fix two bugs in the "--file" option.
+ When the number of arguments read from the included file is 0, the
code used to just skip over '--file' and its argument instead of
removing them from the argument list, causing "Error: Unknown
option --file" later on.
+ In the alternative case (at least one argument read from the file),
the previous code used to do '--j;' in order to "force rescan" of
the inserted arguments. However, control then flowed to outer
blocks where a '++j;' counteracted this measure, causing "Error:
Unknown option --msgbox" (for instance) later on.
+ modify escaping in argv.c to be more uniform, whether or not the
backslash is found within a parameter.
2015/02/25
+ modify gauge widget to keep from erasing a second gauge widget, e.g.,
via the "--and-widget" option. This is a cosmetic change to match
behavior of dialog 1.0 (report by Jason Orendorf).
+ add configure option "--with-man2html"
+ add configure options for versioned symbols, from ongoing work on
ncurses.
+ update configure macros, e.g., for shared libraries
2015/01/25
+ suppress highlighting of character which denotes an abbreviation or
shortcut for the OK/Cancel and other buttons for these widgets, which
use abbreviations for the list shown on the screen: buildlist,
checklist/radiobox, menubox, treeview (Debian #775295).
+ add grid up/left and down/right bindings in editbox.c as synonyms for
field prev and next, respectively when handling the OK/Cancel buttons
(Debian #775294).
2014/09/11
+ correct malloc-size for change to prgbox.
2014/09/10
+ fixes to make "-c" option work when passing command to shell for the
prgbox widget, for example in samples/prgbox2 (report by Korantin
Auguste).
2014/09/08
+ fix an out-of-bounds array index in buildlist widget (report by
Cade Foster).
2014/09/01
+ add configure check for groff, needed for html/ps/pdf output.
+ update configure-script macros:
+ CF_ACVERSION_CHECK - work around another gratuitous incompatibility
introduced in 2.69
+ CF_ADD_CFLAGS - workaround for ash-shell, e.g., with Minix
+ CF_ADD_LIBS - filter out duplicates
+ CF_CURSES_FUNCS - improve workaround for weak-linkage, seems to fix
tests with NetBSD 6.1
+ CF_INTEL_COMPILER - clean up the -no-gcc option which was leftover
from testing.
+ CF_LIB_SUFFIX - change suffix for AIX shared libraries to ".so".
+ CF_MAKEFLAGS - workaround for GNU make 4.0 incompatibility with
previous releases.
+ CF_XOPEN_SOURCE - add cases for Minix, UnixWare and improve the
workaround for Solaris.
+ improve comparison in compare_cache() function, in case difference
between pointers does not fit in int's.
+ updated de.po, es.po, hu.po, lv.po from
http://translationproject.org/latest/dialog/
+ update config.guess, config.sub
2014/02/19
+ cleanup of manpages prompted by Gislason's comments.
+ several changes to manpages to improve presentation (patches by
Bjarni I. Gislason, Debian #739180, Debian #739181)
+ use "\/" when transitioning from italic to normal font
+ correct an instance of "e.g,."
+ use "\e" rather than "\\" to present a literal "\"
+ improve formatting of table header
+ remove some excess space-characters
+ change a reference 0-9 to use "through" as the connector
+ use "\&" to separate "." from a space to make the space shorter
+ change a list's TP macro parameters to make the hanging text align
better with the adjacent paragraph
+ add comma in a few places before "and" in a list
+ separate units from numbers with a nonfillable space
+ replace "-" with en-dash in a few places
+ corrected argument indices after "--args" and "--file" to rescan the
argument list after removing/substituting those options.
+ fix loops for "--file" option to handle cases with zero or no tokens at
all substituted (Redhat #1066168).
+ add gd.po from
http://translationproject.org/latest/dialog/
2014/01/12
+ improve calculation for amount to scroll in programbox when an "Ok"
button might obscure part of the data (report by Florent Rougon).
+ modify program to permit --separate-output to be used with buildlist
and treeview widgets (report by Florent Rougon).
+ add list-height parameter to manpage description of --buildlist
(report by Florent Rougon).
+ minor fixes to dialog.1 manpage; the reported problem was actually
fixed in 20120703 (Debian #726233, patch by Bjarni Ingi Gislason).
+ add a "Hello World" example to dialog.3 manpage (prompted by
discussions with Dustin Oprea, Kevin Ingwersen).
+ correct comparison in dlg_lookup_key() so that using "bindkey" with
a "*" wildcard parameter works as documented (report by Stewart
Benedict).
+ updated configure macros, fixes for clang and mingw.
+ update config.guess, config.sub
2013/09/28
+ fix a regression in gauge widget from 2013/09/28 changes;
dlg_reallocate_gauge() failed when no --title option was given
(report by Tritonas Insomnia).
2013/09/23
+ fix samples/inputbox6-utf8, which had depended unnecessarily on bash.
+ improve memory caching for wide-character manipulation in gauge
@ -434,7 +753,7 @@ to it:
to display (Debian #579390).
+ add makefile rules for generating html, etc., documentation from
nroff.
> patches by Samuel Martín Moro
> patches by Samuel Martin Moro
+ reset errors in tailbox before reading new character.
+ modify dlg_draw_scrollbar(), omitting hiding percentages in boxes
when no arrows or scrollbar are needed.

View File

@ -1 +1 @@
11:1:0 1.2 20130923
15:0:0 1.3 20180621

3013
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

73
argv.c
View File

@ -1,9 +1,9 @@
/*
* $Id: argv.c,v 1.2 2012/11/30 20:28:23 tom Exp $
* $Id: argv.c,v 1.12 2018/06/12 22:47:23 tom Exp $
*
* argv - Reusable functions for argv-parsing.
*
* Copyright 2011,2012 Thomas E. Dickey
* Copyright 2011-2017,2018 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
@ -32,19 +32,42 @@
char **
dlg_string_to_argv(char *blob)
{
size_t n;
size_t n, k;
int pass;
size_t length = strlen(blob);
char **result = 0;
#ifdef HAVE_DLG_TRACE
if (dialog_state.trace_output) {
DLG_TRACE(("# dlg_string_to_argv:\n"));
DLG_TRACE(("# given:\n"));
for (n = k = 0; n < length; ++n) {
if (blob[n] == '\n') {
DLG_TRACE(("#%s\t%.*s\\n\n",
k ? "+" : "",
(int) (n - k), blob + k));
k = n + 1;
}
}
if (n > k) {
DLG_TRACE(("#%s\t%.*s\n",
k ? "+" : "",
(int) (n - k), blob + k));
}
DLG_TRACE(("# result:\n"));
}
#endif
for (pass = 0; pass < 2; ++pass) {
bool inparm = FALSE;
bool quoted = FALSE;
bool escape = FALSE;
char *param = blob;
size_t count = 0;
for (n = 0; n < length; ++n) {
if (quoted && blob[n] == '"') {
if (escape) {
;
} else if (quoted && blob[n] == '"') {
quoted = FALSE;
} else if (blob[n] == '"') {
quoted = TRUE;
@ -54,20 +77,32 @@ dlg_string_to_argv(char *blob)
++count;
inparm = TRUE;
}
} else if (blob[n] == '\\') {
if (quoted && !isspace(UCH(blob[n + 1]))) {
if (pass) {
*param++ = blob[n];
*param++ = blob[n + 1];
}
}
++n;
} else if (!quoted && isspace(UCH(blob[n]))) {
inparm = FALSE;
if (pass) {
*param++ = '\0';
if (inparm) {
if (pass) {
*param++ = '\0';
}
inparm = FALSE;
}
} else {
if (blob[n] == '\\') {
if (n + 1 == length) {
break; /* The string is terminated by a backslash */
} else if ((blob[n + 1] == '\\') ||
(blob[n + 1] == '"') ||
(!quoted && blob[n + 1] == '\n')) {
/* eat the backslash */
if (pass) {
--length;
for (k = n; k < length; ++k)
blob[k] = blob[k + 1];
blob[length] = '\0';
} else {
escape = TRUE;
continue;
}
}
}
if (!inparm) {
if (pass)
result[count] = param;
@ -78,6 +113,7 @@ dlg_string_to_argv(char *blob)
*param++ = blob[n];
}
}
escape = FALSE;
}
if (!pass) {
@ -91,6 +127,13 @@ dlg_string_to_argv(char *blob)
*param = '\0';
}
}
#ifdef HAVE_DLG_TRACE
if (result != 0) {
for (n = 0; result[n] != 0; ++n) {
DLG_TRACE(("#\targv[%d] = %s\n", (int) n, result[n]));
}
}
#endif
return result;
}

View File

@ -1,9 +1,9 @@
/*
* $Id: arrows.c,v 1.51 2013/09/02 15:10:09 tom Exp $
* $Id: arrows.c,v 1.52 2018/06/18 22:10:54 tom Exp $
*
* arrows.c -- draw arrows to indicate end-of-range for lists
*
* Copyright 2000-2012,2013 Thomas E. Dickey
* Copyright 2000-2013,2018 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
@ -125,11 +125,11 @@ dlg_draw_arrows2(WINDOW *win,
if (draw_top) {
(void) wmove(win, top, x);
if (top_arrow) {
(void) wattrset(win, merge_colors(uarrow_attr, attr));
dlg_attrset(win, merge_colors(uarrow_attr, attr));
(void) add_acs(win, ACS_UARROW);
(void) waddstr(win, "(-)");
} else {
(void) wattrset(win, attr);
dlg_attrset(win, attr);
(void) whline(win, dlg_boxchar(ACS_HLINE), ON_LEFT);
}
}
@ -137,11 +137,11 @@ dlg_draw_arrows2(WINDOW *win,
(void) wmove(win, bottom, x);
if (bottom_arrow) {
(void) wattrset(win, merge_colors(darrow_attr, borderattr));
dlg_attrset(win, merge_colors(darrow_attr, borderattr));
(void) add_acs(win, ACS_DARROW);
(void) waddstr(win, "(+)");
} else {
(void) wattrset(win, borderattr);
dlg_attrset(win, borderattr);
(void) whline(win, dlg_boxchar(ACS_HLINE), ON_LEFT);
}
mouse_mkbutton(bottom, x - 1, 6, KEY_NPAGE);
@ -149,7 +149,7 @@ dlg_draw_arrows2(WINDOW *win,
(void) wmove(win, cur_y, cur_x);
wrefresh(win);
(void) wattrset(win, save);
dlg_attrset(win, save);
}
void
@ -188,12 +188,12 @@ dlg_draw_scrollbar(WINDOW *win,
else if (percent > 100)
percent = 100;
(void) wattrset(win, position_indicator_attr);
dlg_attrset(win, position_indicator_attr);
(void) sprintf(buffer, "%d%%", percent);
(void) wmove(win, bottom, right - 7);
(void) waddstr(win, buffer);
if ((len = dlg_count_columns(buffer)) < 4) {
(void) wattrset(win, border_attr);
dlg_attrset(win, border_attr);
whline(win, dlg_boxchar(ACS_HLINE), 4 - len);
}
}
@ -220,7 +220,7 @@ dlg_draw_scrollbar(WINDOW *win,
wmove(win, top + 1, right);
(void) wattrset(win, save);
dlg_attrset(win, save);
wvline(win, ACS_VLINE | A_REVERSE, all_high);
bar_y = ORDSIZE(this_data);
@ -232,8 +232,8 @@ dlg_draw_scrollbar(WINDOW *win,
wmove(win, top + 1 + bar_y, right);
(void) wattrset(win, position_indicator_attr);
wattron(win, A_REVERSE);
dlg_attrset(win, position_indicator_attr);
dlg_attron(win, A_REVERSE);
#if defined(WACS_BLOCK) && defined(NCURSES_VERSION) && defined(USE_WIDE_CURSES)
wvline_set(win, WACS_BLOCK, bar_last - bar_y);
#else
@ -251,7 +251,7 @@ dlg_draw_scrollbar(WINDOW *win,
attr,
borderattr);
(void) wattrset(win, save);
dlg_attrset(win, save);
wmove(win, oldy, oldx);
}

View File

@ -1,9 +1,9 @@
/*
* $Id: buildlist.c,v 1.59 2013/09/02 17:01:02 tom Exp $
* $Id: buildlist.c,v 1.83 2018/06/19 22:57:01 tom Exp $
*
* buildlist.c -- implements the buildlist dialog
*
* Copyright 2012,2013 Thomas E. Dickey
* Copyright 2012-2017,2018 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
@ -31,7 +31,6 @@
#define sLEFT (-2)
#define sRIGHT (-1)
#define KEY_TOGGLE ' '
#define KEY_LEFTCOL '^'
#define KEY_RIGHTCOL '$'
@ -43,10 +42,22 @@ typedef struct {
int box_x;
int top_index;
int cur_index;
DIALOG_LISTITEM **ip; /* pointers to items in this list */
} MY_DATA;
#if 0
#define TRACE(p) dlg_trace_msg p
#else
#define TRACE(p) /* nothing */
#endif
#define okIndex(all,index) ((index) >= 0 && (index) < (all)->item_no)
#define myItem(p,n) ((p)->ip)[n]
#define mySide(n) ((n)?"right":"left")
typedef struct {
DIALOG_LISTITEM *items;
DIALOG_LISTITEM *items; /* all items in the widget */
int base_y; /* base for mouse coordinates */
int base_x;
int use_height; /* actual size of column box */
@ -57,34 +68,82 @@ typedef struct {
MY_DATA list[2];
} ALL_DATA;
/*
* Translate a choice from items[] to a row-number in an unbounded column,
* starting at zero.
*/
static int
index2row(ALL_DATA * all, int choice, int selected)
{
MY_DATA *data = all->list + selected;
int result = -1;
int row;
if (okIndex(all, choice)) {
for (row = 0; row < all->item_no; ++row) {
TRACE(("!... choice %d: %p vs row %d: %p\n",
choice, all->items + choice,
row, myItem(data, row)));
if (myItem(data, row) == all->items + choice) {
result = row;
break;
}
}
}
TRACE(("! index2row(choice %d, %s) = %d\n", choice, mySide(selected), result));
return result;
}
/*
* Convert a row-number back to an item number, i.e., index into items[].
*/
static int
row2index(ALL_DATA * all, int row, int selected)
{
MY_DATA *data = all->list + selected;
int result = -1;
int n;
for (n = 0; n < all->item_no; ++n) {
TRACE(("!... row %d: %p vs choice %d: %p\n",
row, myItem(data, row),
n, all->items + n));
if (myItem(data, row) == all->items + n) {
result = n;
break;
}
}
TRACE(("! row2index(row %d, %s) = %d\n", row, mySide(selected), result));
return result;
}
/*
* Print list item. The 'selected' parameter is true if 'choice' is the
* current item. That one is colored differently from the other items.
*/
static void
print_item(ALL_DATA * data,
print_item(ALL_DATA * all,
WINDOW *win,
DIALOG_LISTITEM * item,
int choice,
int row,
int selected)
{
chtype save = dlg_get_attrs(win);
int i;
bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
bool first = TRUE;
int climit = (data->item_x - data->check_x - 1);
int climit = (all->item_x - all->check_x - 1);
const char *show = (dialog_vars.no_items
? item->name
: item->text);
/* Clear 'residue' of last item */
(void) wattrset(win, menubox_attr);
(void) wmove(win, choice, 0);
dlg_attrset(win, menubox_attr);
(void) wmove(win, row, 0);
for (i = 0; i < getmaxx(win); i++)
(void) waddch(win, ' ');
(void) wmove(win, choice, data->check_x);
(void) wattrset(win, menubox_attr);
(void) wmove(win, row, all->check_x);
dlg_attrset(win, menubox_attr);
if (both) {
dlg_print_listitem(win, item->name, climit, first, selected);
@ -92,44 +151,54 @@ print_item(ALL_DATA * data,
first = FALSE;
}
(void) wmove(win, choice, data->item_x);
climit = (getmaxx(win) - data->item_x + 1);
(void) wmove(win, row, all->item_x);
climit = (getmaxx(win) - all->item_x + 1);
dlg_print_listitem(win, show, climit, first, selected);
if (selected) {
dlg_item_help(item->help);
}
(void) wattrset(win, save);
dlg_attrset(win, save);
}
/*
* Prints either the left (unselected) or right (selected) list.
*/
static void
print_1_list(ALL_DATA * data,
print_1_list(ALL_DATA * all,
int choice,
int selected)
{
MY_DATA *moi = data->list + selected;
WINDOW *win = moi->win;
MY_DATA *data = all->list + selected;
DIALOG_LISTITEM *target = (okIndex(all, choice)
? all->items + choice
: 0);
WINDOW *win = data->win;
int i, j;
int last = 0;
int top_row = index2row(all, data->top_index, selected);
int max_rows = getmaxy(win);
TRACE(("! print_1_list %d %s, top %d\n", choice, mySide(selected), top_row));
for (i = j = 0; j < max_rows; i++) {
int ii = i + moi->top_index;
if (ii >= data->item_no) {
break;
} else if (!(selected ^ (data->items[ii].state != 0))) {
print_item(data,
int ii = i + top_row;
if (ii < 0) {
continue;
} else if (myItem(data, ii)) {
print_item(all,
win,
&data->items[ii],
j, ii == choice);
myItem(data, ii),
j, myItem(data, ii) == target);
last = ++j;
} else {
break;
}
}
if (wmove(win, last, 0) != ERR) {
while (waddch(win, ' ') != ERR) {
;
}
}
if (wmove(win, last, 0) != ERR)
wclrtobot(win);
(void) wnoutrefresh(win);
}
@ -138,17 +207,15 @@ print_1_list(ALL_DATA * data,
* further movement is possible, return the same choice as given.
*/
static int
prev_item(ALL_DATA * data, int choice, int selected)
prev_item(ALL_DATA * all, int choice, int selected)
{
int result = choice;
int n;
for (n = choice - 1; n >= 0; --n) {
if ((data->items[n].state != 0) == selected) {
result = n;
break;
}
int row = index2row(all, choice, selected);
if (row > 0) {
row--;
result = row2index(all, row, selected);
}
TRACE(("! prev_item choice %d, %s = %d\n", choice, mySide(selected), result));
return result;
}
@ -156,9 +223,9 @@ prev_item(ALL_DATA * data, int choice, int selected)
* Return true if the given choice is on the first page in the current column.
*/
static bool
stop_prev(ALL_DATA * data, int choice, int selected)
stop_prev(ALL_DATA * all, int choice, int selected)
{
return (prev_item(data, choice, selected) == choice);
return (prev_item(all, choice, selected) == choice);
}
static bool
@ -182,37 +249,16 @@ check_hotkey(DIALOG_LISTITEM * items, int choice, int selected)
* further movement is possible, return the same choice as given.
*/
static int
next_item(ALL_DATA * data, int choice, int selected)
next_item(ALL_DATA * all, int choice, int selected)
{
MY_DATA *data = all->list + selected;
int result = choice;
int n;
for (n = choice + 1; n < data->item_no; ++n) {
if ((data->items[n].state != 0) == selected) {
result = n;
break;
}
}
dlg_trace_msg("next_item(%d) ->%d\n", choice, result);
return result;
}
/*
* Translate a choice from items[] to a row-number in an unbounded column,
* starting at zero.
*/
static int
index2row(ALL_DATA * data, int choice, int selected)
{
int result = -1;
int n;
for (n = 0; n < data->item_no; ++n) {
if ((data->items[n].state != 0) == selected) {
++result;
}
if (n == choice)
break;
int row = index2row(all, choice, selected);
TRACE(("! given item %d, testing next-item on row %d\n", choice, row + 1));
if (myItem(data, row + 1)) {
result = row2index(all, row + 1, selected);
}
TRACE(("! next_item(%d, %s) ->%d\n", choice, mySide(selected), result));
return result;
}
@ -220,17 +266,21 @@ index2row(ALL_DATA * data, int choice, int selected)
* Return the first choice from items[] for the given column.
*/
static int
first_item(ALL_DATA * data, int selected)
first_item(ALL_DATA * all, int selected)
{
MY_DATA *data = all->list + selected;
int result = -1;
int n;
for (n = 0; n < data->item_no; ++n) {
if ((data->items[n].state != 0) == selected) {
result = n;
break;
if (myItem(data, 0) != 0) {
for (n = 0; n < all->item_no; ++n) {
if (myItem(data, 0) == &all->items[n]) {
result = n;
break;
}
}
}
TRACE(("! first_item %s = %d\n", mySide(selected), result));
return result;
}
@ -238,62 +288,42 @@ first_item(ALL_DATA * data, int selected)
* Return the last choice from items[] for the given column.
*/
static int
last_item(ALL_DATA * data, int selected)
last_item(ALL_DATA * all, int selected)
{
MY_DATA *data = all->list + selected;
int result = -1;
int n;
for (n = data->item_no - 1; n >= 0; --n) {
if ((data->items[n].state != 0) == selected) {
result = n;
break;
}
for (n = 0; myItem(data, n) != 0; ++n) {
result = n;
}
return result;
}
/*
* Convert a row-number back to an item number, i.e., index into items[].
*/
static int
row2index(ALL_DATA * data, int row, int selected)
{
int result = -1;
int n;
for (n = 0; n < data->item_no; ++n) {
if ((data->items[n].state != 0) == selected) {
if (row-- <= 0) {
result = n;
break;
}
}
if (result >= 0) {
result = row2index(all, result, selected);
}
TRACE(("! last_item %s = %d\n", mySide(selected), result));
return result;
}
static int
skip_rows(ALL_DATA * data, int row, int skip, int selected)
skip_rows(ALL_DATA * all, int row, int skip, int selected)
{
int choice = row2index(data, row, selected);
MY_DATA *data = all->list + selected;
int result = row;
int n;
if (skip > 0) {
for (n = choice + 1; n < data->item_no; ++n) {
if ((data->items[n].state != 0) == selected) {
++result;
if (--skip <= 0)
break;
}
for (n = row + 1; (n < all->item_no) && (n <= row + skip); ++n) {
if (myItem(data, n) == 0)
break;
result = n;
}
} else if (skip < 0) {
for (n = choice - 1; n >= 0; --n) {
if ((data->items[n].state != 0) == selected) {
--result;
if (++skip >= 0)
break;
}
}
result -= skip;
if (result < 0)
result = 0;
}
TRACE(("! skip_rows row %d, skip %d, %s = %d\n",
row, skip, mySide(selected), result));
return result;
}
@ -301,7 +331,7 @@ skip_rows(ALL_DATA * data, int row, int skip, int selected)
* Find the closest item in the given column starting with the given choice.
*/
static int
closest_item(ALL_DATA * data, int choice, int selected)
closest_item(ALL_DATA * all, int choice, int selected)
{
int prev = choice;
int next = choice;
@ -309,13 +339,13 @@ closest_item(ALL_DATA * data, int choice, int selected)
int n;
for (n = choice; n >= 0; --n) {
if ((data->items[n].state != 0) == selected) {
if ((all->items[n].state != 0) == selected) {
prev = n;
break;
}
}
for (n = choice; n < data->item_no; ++n) {
if ((data->items[n].state != 0) == selected) {
for (n = choice; n < all->item_no; ++n) {
if ((all->items[n].state != 0) == selected) {
next = n;
break;
}
@ -330,37 +360,40 @@ closest_item(ALL_DATA * data, int choice, int selected)
} else if (next != choice) {
result = next;
}
TRACE(("! XXX closest item choice %d, %s = %d\n",
choice, mySide(selected), result));
return result;
}
static void
print_both(ALL_DATA * data,
print_both(ALL_DATA * all,
int choice)
{
int selected;
int cur_y, cur_x;
WINDOW *dialog = wgetparent(data->list[0].win);
WINDOW *dialog = wgetparent(all->list[0].win);
TRACE(("! print_both %d\n", choice));
getyx(dialog, cur_y, cur_x);
for (selected = 0; selected < 2; ++selected) {
MY_DATA *moi = data->list + selected;
WINDOW *win = moi->win;
int thumb_top = index2row(data, moi->top_index, selected);
int thumb_max = index2row(data, -1, selected);
MY_DATA *data = all->list + selected;
WINDOW *win = data->win;
int thumb_top = index2row(all, data->top_index, selected);
int thumb_max = index2row(all, -1, selected);
int thumb_end = thumb_top + getmaxy(win);
print_1_list(data, choice, selected);
print_1_list(all, choice, selected);
dlg_mouse_setcode(selected * KEY_MAX);
dlg_draw_scrollbar(dialog,
(long) (moi->top_index),
(long) (data->top_index),
(long) (thumb_top),
(long) MIN(thumb_end, thumb_max),
(long) thumb_max,
moi->box_x + data->check_x,
moi->box_x + getmaxx(win),
moi->box_y,
moi->box_y + getmaxy(win) + 1,
data->box_x + all->check_x,
data->box_x + getmaxx(win),
data->box_y,
data->box_y + getmaxy(win) + 1,
menubox_border2_attr,
menubox_border_attr);
}
@ -369,13 +402,13 @@ print_both(ALL_DATA * data,
}
static void
set_top_item(ALL_DATA * data, int value, int selected)
set_top_item(ALL_DATA * all, int choice, int selected)
{
if (value != data->list[selected].top_index) {
dlg_trace_msg("set top of %s column to %d\n",
selected ? "right" : "left",
value);
data->list[selected].top_index = value;
if (choice != all->list[selected].top_index) {
DLG_TRACE(("# set top of %s column to %d\n",
mySide(selected),
choice));
all->list[selected].top_index = choice;
}
}
@ -384,23 +417,82 @@ set_top_item(ALL_DATA * data, int value, int selected)
* visible.
*/
static void
fix_top_item(ALL_DATA * data, int cur_item, int selected)
fix_top_item(ALL_DATA * all, int cur_item, int selected)
{
int top_item = data->list[selected].top_index;
int cur_row = index2row(data, cur_item, selected);
int top_row = index2row(data, top_item, selected);
int top_item = all->list[selected].top_index;
int cur_row = index2row(all, cur_item, selected);
int top_row = index2row(all, top_item, selected);
if (cur_row < top_row) {
top_item = cur_item;
} else if ((cur_row - top_row) > data->use_height) {
top_item = row2index(data, cur_row + 1 - data->use_height, selected);
} else if ((cur_row - top_row) >= all->use_height) {
top_item = row2index(all, cur_row + 1 - all->use_height, selected);
}
if (cur_row < data->use_height) {
top_item = row2index(data, 0, selected);
if (cur_row < all->use_height) {
top_item = row2index(all, 0, selected);
}
DLG_TRACE(("# fix_top_item(cur_item %d, %s) ->top_item %d\n",
cur_item, mySide(selected), top_item));
set_top_item(all, top_item, selected);
}
static void
append_right_side(ALL_DATA * all, int choice)
{
MY_DATA *data = &all->list[1];
int j;
for (j = 0; j < all->item_no; ++j) {
if (myItem(data, j) == 0) {
myItem(data, j) = &all->items[choice];
break;
}
}
}
static void
amend_right_side(ALL_DATA * all, int choice)
{
MY_DATA *data = &all->list[1];
int j, k;
for (j = 0; j < all->item_no; ++j) {
if (myItem(data, j) == &all->items[choice]) {
for (k = j; k < all->item_no; ++k) {
if ((myItem(data, k) = myItem(data, k + 1)) == 0)
break;
}
break;
}
}
}
static void
fill_one_side(ALL_DATA * all, int selected)
{
int i, j;
MY_DATA *data = all->list + selected;
for (i = j = 0; j < all->item_no; ++j) {
myItem(data, i) = 0;
if ((all->items[j].state != 0) == selected) {
myItem(data, i) = all->items + j;
TRACE(("! %s item[%d] %p = all[%d] %p\n",
mySide(selected),
i, myItem(data, i),
j, all->items + j));
++i;
}
}
myItem(data, i) = 0;
}
static void
fill_both_sides(ALL_DATA * all)
{
int k;
for (k = 0; k < 2; ++k) {
fill_one_side(all, k);
}
dlg_trace_msg("fix_top_item(cur_item %d, selected %d) ->top_item %d\n",
cur_item, selected, top_item);
set_top_item(data, top_item, selected);
}
/*
@ -420,6 +512,7 @@ dlg_buildlist(const char *title,
int order_mode,
int *current_item)
{
#define THIS_FUNC "dlg_buildlist"
/* *INDENT-OFF* */
static DLG_KEYS_BINDING binding[] = {
HELPKEY_BINDINGS,
@ -445,6 +538,7 @@ dlg_buildlist(const char *title,
DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE+KEY_MAX) ),
DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFTCOL ),
DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHTCOL ),
TOGGLEKEY_BINDINGS,
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -466,11 +560,11 @@ dlg_buildlist(const char *title,
int num_states;
bool first = TRUE;
WINDOW *dialog;
char *prompt = dlg_strclone(cprompt);
char *prompt;
const char **buttons = dlg_ok_labels();
const char *widget_name = "buildlist";
(void) order_mode;
dialog_state.plain_buttons = TRUE;
/*
* Unlike other uses of --visit-items, we have two windows to visit.
@ -481,6 +575,10 @@ dlg_buildlist(const char *title,
memset(&all, 0, sizeof(all));
all.items = items;
all.item_no = item_no;
for (k = 0; k < 2; ++k) {
data[k].ip = dlg_calloc(DIALOG_LISTITEM *, (item_no + 2));
}
fill_both_sides(&all);
if (dialog_vars.default_item != 0) {
cur_item = dlg_default_listitem(items);
@ -493,12 +591,14 @@ dlg_buildlist(const char *title,
: dlg_default_button());
dlg_does_output();
dlg_tab_correct_str(prompt);
#ifdef KEY_RESIZE
retry:
#endif
prompt = dlg_strclone(cprompt);
dlg_tab_correct_str(prompt);
all.use_height = list_height;
all.use_width = (2 * (dlg_calc_list_width(item_no, items)
+ 4
@ -536,7 +636,7 @@ dlg_buildlist(const char *title,
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
list_width = (width - 6 * MARGIN - 2) / 2;
@ -612,11 +712,12 @@ dlg_buildlist(const char *title,
/* ensure we are scrolled to show the current choice */
j = MIN(all.use_height, item_no);
for (i = 0; i < 2; ++i) {
int top_item = 0;
if ((items[cur_item].state != 0) == i) {
top_item = cur_item - j + 1;
int top_item = cur_item - j + 1;
if (top_item < 0)
top_item = 0;
while ((items[top_item].state != 0) != i)
++top_item;
set_top_item(&all, top_item, i);
} else {
set_top_item(&all, 0, i);
@ -642,11 +743,11 @@ dlg_buildlist(const char *title,
int at_end = index2row(&all, -1, which);
int at_bot = skip_rows(&all, at_top, all.use_height, which);
dlg_trace_msg("\t** state %d:%d top %d (%d:%d:%d) %d\n",
cur_item, item_no - 1,
moi->top_index,
at_top, at_bot, at_end,
which);
DLG_TRACE(("# ** state %d:%d top %d (%d:%d:%d) %s\n",
cur_item, item_no - 1,
moi->top_index,
at_top, at_bot, at_end,
mySide(which)));
if (first) {
print_both(&all, cur_item);
@ -663,7 +764,7 @@ dlg_buildlist(const char *title,
cur_y -= at_top;
cur_x = (data[which].box_x
+ all.check_x + 1);
dlg_trace_msg("\t...visit row %d (%d,%d)\n", cur_row, cur_y, cur_x);
DLG_TRACE(("# ...visit row %d (%d,%d)\n", cur_row, cur_y, cur_x));
wmove(dialog, cur_y, cur_x);
}
@ -681,7 +782,7 @@ dlg_buildlist(const char *title,
i = (key - 2 * KEY_MAX) % (1 + all.use_height);
j = (key - 2 * KEY_MAX) / (1 + all.use_height);
k = row2index(&all, i + at_top, j);
dlg_trace_msg("MOUSE column %d, row %d ->item %d\n", j, i, k);
DLG_TRACE(("# MOUSE column %d, row %d ->item %d\n", j, i, k));
if (k >= 0 && j < 2) {
if (j != which) {
/*
@ -695,7 +796,7 @@ dlg_buildlist(const char *title,
at_bot = skip_rows(&all, at_top, all.use_height, which);
cur_item = k;
print_both(&all, cur_item);
key = KEY_TOGGLE; /* force the selected item to toggle */
key = DLGK_TOGGLE; /* force the selected item to toggle */
} else {
beep();
continue;
@ -723,18 +824,29 @@ dlg_buildlist(const char *title,
* the next available item in the same column. But if there are no
* more items in the column, move the cursor to the other column.
*/
if (key == KEY_TOGGLE) {
if (key == DLGK_TOGGLE) {
int new_choice;
int new_state = items[cur_item].state + 1;
if ((new_choice = next_item(&all, cur_item, which)) == cur_item) {
new_choice = prev_item(&all, cur_item, which);
}
dlg_trace_msg("cur_item %d, new_choice:%d\n", cur_item, new_choice);
DLG_TRACE(("# cur_item %d, new_choice:%d\n", cur_item, new_choice));
/* FIXME - how to test and handle multiple states? */
if (new_state >= num_states)
new_state = 0;
items[cur_item].state = new_state;
if (order_mode) {
fill_one_side(&all, 0);
if (new_state) {
append_right_side(&all, cur_item);
} else {
amend_right_side(&all, cur_item);
}
} else {
fill_both_sides(&all);
}
if (cur_item == moi->top_index) {
set_top_item(&all, new_choice, which);
}
@ -837,7 +949,11 @@ dlg_buildlist(const char *title,
fix_top_item(&all, i, 0);
break;
case DLGK_GRID_RIGHT:
i = closest_item(&all, cur_item, 1);
if (order_mode) {
i = last_item(&all, 1);
} else {
i = closest_item(&all, cur_item, 1);
}
fix_top_item(&all, i, 1);
break;
case DLGK_PAGE_PREV:
@ -895,11 +1011,11 @@ dlg_buildlist(const char *title,
int oops = item_no;
int old_item;
dlg_trace_msg("<--CHOICE %d\n", i);
dlg_trace_msg("<--topITM %d\n", moi->top_index);
dlg_trace_msg("<--now_at %d\n", now_at);
dlg_trace_msg("<--at_top %d\n", at_top);
dlg_trace_msg("<--at_bot %d\n", at_bot);
DLG_TRACE(("# <--CHOICE %d\n", i));
DLG_TRACE(("# <--topITM %d\n", moi->top_index));
DLG_TRACE(("# <--now_at %d\n", now_at));
DLG_TRACE(("# <--at_top %d\n", at_top));
DLG_TRACE(("# <--at_bot %d\n", at_bot));
if (now_at >= at_bot) {
while (now_at >= at_bot) {
@ -911,11 +1027,11 @@ dlg_buildlist(const char *title,
at_top = index2row(&all, moi->top_index, which);
at_bot = skip_rows(&all, at_top, all.use_height, which);
dlg_trace_msg("...at_bot %d (now %d vs %d)\n",
at_bot, now_at, at_end);
dlg_trace_msg("...topITM %d\n", moi->top_index);
dlg_trace_msg("...at_top %d (diff %d)\n", at_top,
at_bot - at_top);
DLG_TRACE(("# ...at_bot %d (now %d vs %d)\n",
at_bot, now_at, at_end));
DLG_TRACE(("# ...topITM %d\n", moi->top_index));
DLG_TRACE(("# ...at_top %d (diff %d)\n", at_top,
at_bot - at_top));
if (at_bot >= at_end) {
/*
@ -936,7 +1052,7 @@ dlg_buildlist(const char *title,
break;
}
if (--oops < 0) {
dlg_trace_msg("OOPS-forward\n");
DLG_TRACE(("# OOPS-forward\n"));
break;
}
}
@ -948,20 +1064,20 @@ dlg_buildlist(const char *title,
which);
at_top = index2row(&all, moi->top_index, which);
dlg_trace_msg("...at_top %d (now %d)\n", at_top, now_at);
dlg_trace_msg("...topITM %d\n", moi->top_index);
DLG_TRACE(("# ...at_top %d (now %d)\n", at_top, now_at));
DLG_TRACE(("# ...topITM %d\n", moi->top_index));
if (moi->top_index >= old_item)
break;
if (at_top <= now_at)
break;
if (--oops < 0) {
dlg_trace_msg("OOPS-backward\n");
DLG_TRACE(("# OOPS-backward\n"));
break;
}
}
}
dlg_trace_msg("-->now_at %d\n", now_at);
DLG_TRACE(("# -->now_at %d\n", now_at));
cur_item = i;
print_both(&all, cur_item);
}
@ -976,14 +1092,16 @@ dlg_buildlist(const char *title,
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
/* repaint */
free(prompt);
dlg_clear();
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
/* repaint */
first = TRUE;
goto retry;
#endif
default:
@ -1000,12 +1118,50 @@ dlg_buildlist(const char *title,
}
}
/*
* If told to re-order the list, update it to reflect the current display:
* a) The left-side will be at the beginning, without gaps.
* b) The right-side will follow, in display-order.
*/
if (order_mode) {
DIALOG_LISTITEM *redo;
int row;
int choice;
int new_item = cur_item;
redo = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
assert_ptr(redo, THIS_FUNC);
j = 0;
for (k = 0; k < 2; ++k) {
for (row = 0; row < item_no; ++row) {
if (myItem(all.list + k, row) == 0)
break;
choice = row2index(&all, row, k);
if (choice == cur_item)
new_item = j;
redo[j++] = items[choice];
}
}
cur_item = new_item;
memcpy(items, redo, sizeof(DIALOG_LISTITEM) * (size_t) (item_no + 1));
free(redo);
}
for (k = 0; k < 2; ++k) {
free(data[k].ip);
}
dialog_state.visit_cols = save_visit;
dlg_del_window(dialog);
dlg_mouse_free_regions();
free(prompt);
*current_item = cur_item;
return result;
#undef THIS_FUNC
}
/*
@ -1021,6 +1177,7 @@ dialog_buildlist(const char *title,
char **items,
int order_mode)
{
#define THIS_FUNC "dialog_buildlist"
int result;
int i, j;
DIALOG_LISTITEM *listitems;
@ -1029,8 +1186,18 @@ dialog_buildlist(const char *title,
int current = 0;
char *help_result;
DLG_TRACE(("# buildlist args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("lheight", list_height);
DLG_TRACE2N("llength", item_no);
/* FIXME dump the items[][] too */
DLG_TRACE2N("order", order_mode != 0);
listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
assert_ptr(listitems, "dialog_buildlist");
assert_ptr(listitems, THIS_FUNC);
for (i = j = 0; i < item_no; ++i) {
listitems[i].name = items[j++];
@ -1094,4 +1261,5 @@ dialog_buildlist(const char *title,
dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
free(listitems);
return result;
#undef THIS_FUNC
}

View File

@ -1,9 +1,9 @@
/*
* $Id: buttons.c,v 1.94 2012/12/30 20:51:01 tom Exp $
* $Id: buttons.c,v 1.99 2018/06/18 22:11:16 tom Exp $
*
* buttons.c -- draw buttons, e.g., OK/Cancel
*
* Copyright 2000-2011,2012 Thomas E. Dickey
* Copyright 2000-2017,2018 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
@ -29,6 +29,7 @@
#endif
#define MIN_BUTTON (-dialog_state.visit_cols)
#define CHR_BUTTON (!dialog_state.plain_buttons)
static void
center_label(char *buffer, int longest, const char *label)
@ -160,6 +161,12 @@ get_hotkeys(const char **labels)
return result;
}
typedef enum {
sFIND_KEY = 0
,sHAVE_KEY = 1
,sHAD_KEY = 2
} HOTKEY;
/*
* Print a button
*/
@ -167,7 +174,7 @@ static void
print_button(WINDOW *win, char *label, int hotkey, int y, int x, int selected)
{
int i;
int state = 0;
HOTKEY state = sFIND_KEY;
const int *indx = dlg_index_wchars(label);
int limit = dlg_count_wchars(label);
chtype key_attr = (selected
@ -178,18 +185,18 @@ print_button(WINDOW *win, char *label, int hotkey, int y, int x, int selected)
: button_label_inactive_attr);
(void) wmove(win, y, x);
(void) wattrset(win, selected
? button_active_attr
: button_inactive_attr);
dlg_attrset(win, selected
? button_active_attr
: button_inactive_attr);
(void) waddstr(win, "<");
(void) wattrset(win, label_attr);
dlg_attrset(win, label_attr);
for (i = 0; i < limit; ++i) {
int check;
int first = indx[i];
int last = indx[i + 1];
switch (state) {
case 0:
case sFIND_KEY:
check = UCH(label[first]);
#ifdef USE_WIDE_CURSES
if ((last - first) != 1) {
@ -198,22 +205,24 @@ print_button(WINDOW *win, char *label, int hotkey, int y, int x, int selected)
}
#endif
if (check == hotkey) {
(void) wattrset(win, key_attr);
state = 1;
dlg_attrset(win, key_attr);
state = sHAVE_KEY;
}
break;
case 1:
wattrset(win, label_attr);
state = 2;
case sHAVE_KEY:
dlg_attrset(win, label_attr);
state = sHAD_KEY;
break;
default:
break;
}
waddnstr(win, label + first, last - first);
}
(void) wattrset(win, selected
? button_active_attr
: button_inactive_attr);
dlg_attrset(win, selected
? button_active_attr
: button_inactive_attr);
(void) waddstr(win, ">");
(void) wmove(win, y, x + ((int) strspn(label, " ")) + 1);
(void) wmove(win, y, x + ((int) (strspn) (label, " ")) + 1);
}
/*
@ -374,7 +383,9 @@ dlg_draw_buttons(WINDOW *win,
for (n = 0; labels[n] != 0; n++) {
center_label(buffer, longest, labels[n]);
mouse_mkbutton(y, x, dlg_count_columns(buffer), n);
print_button(win, buffer, hotkeys[n], y, x,
print_button(win, buffer,
CHR_BUTTON ? hotkeys[n] : -1,
y, x,
(selected == n) || (n == 0 && selected < 0));
if (selected == n)
getyx(win, final_y, final_x);
@ -389,7 +400,7 @@ dlg_draw_buttons(WINDOW *win,
}
(void) wmove(win, final_y, final_x);
wrefresh(win);
(void) wattrset(win, save);
dlg_attrset(win, save);
free(buffer);
free(hotkeys);
}
@ -629,7 +640,7 @@ dlg_ok_buttoncode(int button)
} else if (dialog_vars.help_button && (button == n)) {
result = DLG_EXIT_HELP;
}
dlg_trace_msg("# dlg_ok_buttoncode(%d) = %d\n", button, result);
DLG_TRACE(("# dlg_ok_buttoncode(%d) = %d\n", button, result));
return result;
}
@ -679,7 +690,7 @@ dlg_defaultno_button(void)
while (dlg_ok_buttoncode(result) != DLG_EXIT_CANCEL)
++result;
}
dlg_trace_msg("# dlg_defaultno_button() = %d\n", result);
DLG_TRACE(("# dlg_defaultno_button() = %d\n", result));
return result;
}
@ -702,7 +713,7 @@ dlg_default_button(void)
}
}
}
dlg_trace_msg("# dlg_default_button() = %d\n", result);
DLG_TRACE(("# dlg_default_button() = %d\n", result));
return result;
}

View File

@ -1,9 +1,9 @@
/*
* $Id: calendar.c,v 1.67 2013/03/17 15:03:41 tom Exp $
* $Id: calendar.c,v 1.97 2018/06/19 22:57:01 tom Exp $
*
* calendar.c -- implements the calendar box
*
* Copyright 2001-2012,2013 Thomas E. Dickey
* Copyright 2001-2017,2018 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
@ -26,6 +26,12 @@
#include <time.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#define intptr_t long
#endif
#define ONE_DAY (60 * 60 * 24)
#define MON_WIDE 4 /* width of a month-name */
@ -35,7 +41,7 @@
#define BTN_HIGH 1 /* height of button-row excluding margin */
/* two more lines: titles for day-of-week and month/year boxes */
#define MIN_HIGH (DAY_HIGH + 2 + HDR_HIGH + BTN_HIGH + (7 * MARGIN))
#define MIN_HIGH (DAY_HIGH + 2 + HDR_HIGH + BTN_HIGH + (MAX_DAYS * MARGIN))
#define MIN_WIDE (DAY_WIDE + (4 * MARGIN))
typedef enum {
@ -56,14 +62,20 @@ typedef struct _box {
int width;
int height;
BOX_DRAW box_draw;
int week_start;
} BOX;
#define MAX_DAYS 7
#define MAX_MONTHS 12
static char *cached_days[MAX_DAYS];
static char *cached_months[MAX_MONTHS];
static const char *
nameOfDayOfWeek(int n)
{
static const char *table[7]
#ifndef ENABLE_NLS
=
static bool shown[MAX_DAYS];
static const char *posix_days[MAX_DAYS] =
{
"Sunday",
"Monday",
@ -72,35 +84,49 @@ nameOfDayOfWeek(int n)
"Thursday",
"Friday",
"Saturday"
}
#endif
;
const char *result = 0;
};
if (n >= 0 && n < 7) {
while (n < 0) {
n += MAX_DAYS;
}
n %= MAX_DAYS;
#ifdef ENABLE_NLS
if (table[n] == 0) {
nl_item items[7] =
{
ABDAY_1, ABDAY_2, ABDAY_3, ABDAY_4, ABDAY_5, ABDAY_6, ABDAY_7
};
table[n] = nl_langinfo(items[n]);
}
if (cached_days[n] == 0) {
const nl_item items[MAX_DAYS] =
{
ABDAY_1, ABDAY_2, ABDAY_3, ABDAY_4, ABDAY_5, ABDAY_6, ABDAY_7
};
cached_days[n] = dlg_strclone(nl_langinfo(items[n]));
memset(shown, 0, sizeof(shown));
}
#endif
result = table[n];
if (cached_days[n] == 0) {
size_t len, limit = MON_WIDE - 1;
char *value = dlg_strclone(posix_days[n]);
/*
* POSIX does not actually say what the length of an abbreviated name
* is. Typically it is 2, which will fit into our layout. That also
* happens to work with CJK entries as seen in glibc, which are a
* double-width cell. For now (2016/01/26), handle too-long names only
* for POSIX values.
*/
if ((len = strlen(value)) > limit)
value[limit] = '\0';
cached_days[n] = value;
}
if (result == 0) {
result = "?";
if (!shown[n]) {
DLG_TRACE(("# DAY(%d) = '%s'\n", n, cached_days[n]));
shown[n] = TRUE;
}
return result;
return cached_days[n];
}
static const char *
nameOfMonth(int n)
{
static const char *table[12]
#ifndef ENABLE_NLS
=
static bool shown[MAX_MONTHS];
static const char *posix_mons[MAX_MONTHS] =
{
"January",
"February",
@ -114,70 +140,199 @@ nameOfMonth(int n)
"October",
"November",
"December"
}
#endif
;
const char *result = 0;
};
if (n >= 0 && n < 12) {
while (n < 0) {
n += MAX_MONTHS;
}
n %= MAX_MONTHS;
#ifdef ENABLE_NLS
if (table[n] == 0) {
nl_item items[12] =
{
MON_1, MON_2, MON_3, MON_4, MON_5, MON_6,
MON_7, MON_8, MON_9, MON_10, MON_11, MON_12
};
table[n] = nl_langinfo(items[n]);
}
if (cached_months[n] == 0) {
const nl_item items[MAX_MONTHS] =
{
MON_1, MON_2, MON_3, MON_4, MON_5, MON_6,
MON_7, MON_8, MON_9, MON_10, MON_11, MON_12
};
cached_months[n] = dlg_strclone(nl_langinfo(items[n]));
memset(shown, 0, sizeof(shown));
}
#endif
result = table[n];
if (cached_months[n] == 0) {
cached_months[n] = dlg_strclone(posix_mons[n]);
}
if (result == 0) {
result = "?";
if (!shown[n]) {
DLG_TRACE(("# MON(%d) = '%s'\n", n, cached_months[n]));
shown[n] = TRUE;
}
return cached_months[n];
}
/*
* Algorithm for Gregorian calendar.
*/
static int
isleap(int y)
{
return ((y % 4 == 0) &&
((y % 100 != 0) ||
(y % 400 == 0))) ? 1 : 0;
}
static void
adjust_year_month(int *year, int *month)
{
while (*month < 0) {
*month += MAX_MONTHS;
*year -= 1;
}
while (*month >= MAX_MONTHS) {
*month -= MAX_MONTHS;
*year += 1;
}
return result;
}
static int
days_in_month(struct tm *current, int offset /* -1, 0, 1 */ )
days_per_month(int year, int month)
{
static const int nominal[] =
{
31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31
};
int year = current->tm_year;
int month = current->tm_mon + offset;
int result;
while (month < 0) {
month += 12;
year -= 1;
}
while (month >= 12) {
month -= 12;
year += 1;
}
adjust_year_month(&year, &month);
result = nominal[month];
if (month == 1)
result += ((year % 4) == 0);
result += isleap(year);
return result;
}
static int
days_in_month(struct tm *current, int offset /* -1, 0, 1 */ )
{
int year = current->tm_year + 1900;
int month = current->tm_mon + offset;
adjust_year_month(&year, &month);
return days_per_month(year, month);
}
static int
days_per_year(int year)
{
return (isleap(year) ? 366 : 365);
}
static int
days_in_year(struct tm *current, int offset /* -1, 0, 1 */ )
{
int year = current->tm_year + 1900 + offset;
return days_per_year(current->tm_year + 1900 + offset);
}
return ((year % 4) == 0) ? 366 : 365;
/*
* Adapted from C FAQ
* "17.28: How can I find the day of the week given the date?"
* implementation by Tomohiko Sakamoto.
*
* d = day (0 to whatever)
* m = month (1 through 12)
* y = year (1752 and later, for Gregorian calendar)
*/
static int
day_of_week(int y, int m, int d)
{
static int t[] =
{
0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4
};
y -= (m < 3);
return (6 + (y + (y / 4) - (y / 100) + (y / 400) + t[m - 1] + d)) % MAX_DAYS;
}
static int
day_in_year(int year, int month, int day)
{
int result = day;
while (--month >= 1)
result += days_per_month(year, month);
return result;
}
static int
iso_week(int year, int month, int day)
{
int week = 1;
int dow;
int new_year_dow;
int diy;
int new_years_eve_dow;
static const int thursday = 3;
/* add the number weeks *between* date and newyear */
diy = day_in_year(year, month, day);
week += (diy - 1) / MAX_DAYS;
/* 0 = Monday */
dow = day_of_week(year, month, day);
new_year_dow = day_of_week(year, 1, 1);
/*
* If New Year falls on Friday, Saturday or Sunday, then New Years's week
* is the last week of the preceding year. In that case subtract one week.
*/
if (new_year_dow > thursday)
--week;
/* Add one week if there is a Sunday to Monday transition. */
if (dow - new_year_dow < 0)
++week;
/* Check if we are in the last week of the preceding year. */
if (week < 1) {
week = iso_week(--year, 12, 31);
}
/*
* If we are in the same week as New Year's eve, check if New Year's eve is
* in the first week of the next year.
*/
new_years_eve_dow = (new_year_dow + 364 + isleap(year)) % MAX_DAYS;
if (365 + isleap(year) - diy < MAX_DAYS
&& new_years_eve_dow >= dow
&& new_years_eve_dow < thursday) {
++year;
week = 1;
}
return week;
}
static int *
getisoweeks(int year, int month)
{
static int result[10];
int windx = 0;
int day;
int dpm = days_per_month(year, month);
for (day = 1; day <= dpm; day += MAX_DAYS)
result[windx++] = iso_week(year, month, day);
/*
* Ensure that there is a week number associated with the last day of the
* month, e.g., in case the last day of the month falls before Thursday,
* so that we have to show the week-number for the beginning of the
* following month.
*/
result[windx] = iso_week(year, month, dpm);
return result;
}
static int
day_cell_number(struct tm *current)
{
int cell;
cell = current->tm_mday - ((6 + current->tm_mday - current->tm_wday) % 7);
if ((current->tm_mday - 1) % 7 != current->tm_wday)
cell = current->tm_mday - ((6 + current->tm_mday - current->tm_wday) % MAX_DAYS);
if ((current->tm_mday - 1) % MAX_DAYS != current->tm_wday)
cell += 6;
else
cell--;
@ -191,13 +346,13 @@ next_or_previous(int key, int two_d)
switch (key) {
case DLGK_GRID_UP:
result = two_d ? -7 : -1;
result = two_d ? -MAX_DAYS : -1;
break;
case DLGK_GRID_LEFT:
result = -1;
break;
case DLGK_GRID_DOWN:
result = two_d ? 7 : 1;
result = two_d ? MAX_DAYS : 1;
break;
case DLGK_GRID_RIGHT:
result = 1;
@ -220,7 +375,9 @@ draw_day(BOX * data, struct tm *current)
int save_y = 0, save_x = 0;
int day = current->tm_mday;
int mday;
int week;
int week = 0;
int windx = 0;
int *weeks = 0;
int last = days_in_month(current, 0);
int prev = days_in_month(current, -1);
@ -232,36 +389,43 @@ draw_day(BOX * data, struct tm *current)
menubox_border_attr,
menubox_border2_attr);
(void) wattrset(data->window, menubox_attr); /* daynames headline */
for (x = 0; x < 7; x++) {
dlg_attrset(data->window, menubox_attr); /* daynames headline */
for (x = 0; x < MAX_DAYS; x++) {
mvwprintw(data->window,
0, (x + 1) * cell_wide, "%*.*s ",
cell_wide - 1,
cell_wide - 1,
nameOfDayOfWeek(x));
nameOfDayOfWeek(x + data->week_start));
}
mday = ((6 + current->tm_mday - current->tm_wday) % 7) - 7;
if (mday <= -7)
mday += 7;
/* mday is now in the range -6 to 0. */
week = (current->tm_yday + 6 + mday - current->tm_mday) / 7;
mday = ((6 + current->tm_mday -
current->tm_wday +
data->week_start) % MAX_DAYS) - MAX_DAYS;
if (mday <= -MAX_DAYS)
mday += MAX_DAYS;
if (dialog_vars.iso_week) {
weeks = getisoweeks(current->tm_year + 1900, current->tm_mon + 1);
} else {
/* mday is now in the range -6 to 0. */
week = (current->tm_yday + 6 + mday - current->tm_mday) / MAX_DAYS;
}
for (y = 1; mday < last; y++) {
(void) wattrset(data->window, menubox_attr); /* weeknumbers headline */
dlg_attrset(data->window, menubox_attr); /* weeknumbers headline */
mvwprintw(data->window,
y, 0,
"%*d ",
cell_wide - 1,
++week);
for (x = 0; x < 7; x++) {
weeks ? weeks[windx++] : ++week);
for (x = 0; x < MAX_DAYS; x++) {
this_x = 1 + (x + 1) * cell_wide;
++mday;
if (wmove(data->window, y, this_x) == ERR)
continue;
(void) wattrset(data->window, item_attr); /* not selected days */
dlg_attrset(data->window, item_attr); /* not selected days */
if (mday == day) {
(void) wattrset(data->window, item_selected_attr); /* selected day */
dlg_attrset(data->window, item_selected_attr); /* selected day */
save_y = y;
save_x = this_x;
}
@ -296,7 +460,7 @@ draw_month(BOX * data, struct tm *current)
month = current->tm_mon + 1;
(void) wattrset(data->parent, dialog_attr); /* Headline "Month" */
dlg_attrset(data->parent, dialog_attr); /* Headline "Month" */
(void) mvwprintw(data->parent, data->y - 2, data->x - 1, _("Month"));
dlg_draw_box2(data->parent,
data->y - 1, data->x - 1,
@ -304,7 +468,7 @@ draw_month(BOX * data, struct tm *current)
menubox_attr,
menubox_border_attr,
menubox_border2_attr);
(void) wattrset(data->window, item_attr); /* color the month selection */
dlg_attrset(data->window, item_attr); /* color the month selection */
mvwprintw(data->window, 0, 0, "%s", nameOfMonth(month - 1));
wmove(data->window, 0, 0);
return 0;
@ -318,7 +482,7 @@ draw_year(BOX * data, struct tm *current)
{
int year = current->tm_year + 1900;
(void) wattrset(data->parent, dialog_attr); /* Headline "Year" */
dlg_attrset(data->parent, dialog_attr); /* Headline "Year" */
(void) mvwprintw(data->parent, data->y - 2, data->x - 1, _("Year"));
dlg_draw_box2(data->parent,
data->y - 1, data->x - 1,
@ -326,7 +490,7 @@ draw_year(BOX * data, struct tm *current)
menubox_attr,
menubox_border_attr,
menubox_border2_attr);
(void) wattrset(data->window, item_attr); /* color the year selection */
dlg_attrset(data->window, item_attr); /* color the year selection */
mvwprintw(data->window, 0, 0, "%4d", year);
wmove(data->window, 0, 0);
return 0;
@ -338,6 +502,7 @@ init_object(BOX * data,
int x, int y,
int width, int height,
BOX_DRAW box_draw,
int key_offset,
int code)
{
data->parent = parent;
@ -346,6 +511,7 @@ init_object(BOX * data,
data->width = width;
data->height = height;
data->box_draw = box_draw;
data->week_start = key_offset;
data->window = derwin(data->parent,
data->height, data->width,
@ -357,7 +523,7 @@ init_object(BOX * data,
dlg_mouse_setbase(getbegx(parent), getbegy(parent));
if (code == 'D') {
dlg_mouse_mkbigregion(y + 1, x + MON_WIDE, height - 1, width - MON_WIDE,
KEY_MAX, 1, MON_WIDE, 3);
KEY_MAX + key_offset, 1, MON_WIDE, 3);
} else {
dlg_mouse_mkregion(y, x, height, width, code);
}
@ -365,9 +531,104 @@ init_object(BOX * data,
return 0;
}
#if defined(ENABLE_NLS) && defined(HAVE_NL_LANGINFO_1STDAY)
#elif defined(HAVE_DLG_GAUGE)
static int
read_locale_setting(const char *name, int which)
{
FILE *fp;
char command[80];
int result = -1;
sprintf(command, "locale %s", name);
if ((fp = dlg_popen(command, "r")) != 0) {
int count = 0;
char buf[80];
while (fgets(buf, (int) sizeof(buf) - 1, fp) != 0) {
if (++count > which) {
char *next = 0;
long check = strtol(buf, &next, 0);
if (next != 0 &&
next != buf &&
*next == '\n') {
result = (int) check;
}
break;
}
}
pclose(fp);
}
return result;
}
#endif
static int
WeekStart(void)
{
int result = 0;
char *option = dialog_vars.week_start;
if (option != 0) {
if (option[0]) {
char *next = 0;
long check = strtol(option, &next, 0);
if (next == 0 ||
next == option ||
*next != '\0') {
if (!strcmp(option, "locale")) {
#if defined(ENABLE_NLS) && defined(HAVE_NL_LANGINFO_1STDAY)
/*
* glibc-specific.
*/
int first_day = nl_langinfo(_NL_TIME_FIRST_WEEKDAY)[0];
char *basis_ptr = nl_langinfo(_NL_TIME_WEEK_1STDAY);
int basis_day = (int) (intptr_t) basis_ptr;
#elif defined(HAVE_DLG_GAUGE)
/*
* probably Linux-specific, but harmless otherwise. When
* available, the locale program will return a single
* integer on one line.
*/
int first_day = read_locale_setting("first_weekday", 0);
int basis_day = read_locale_setting("week-1stday", 0);
#endif
#if (defined(ENABLE_NLS) && defined(HAVE_NL_LANGINFO_1STDAY)) || defined(HAVE_DLG_GAUGE)
int week_1stday = -1;
if (basis_day == 19971130)
week_1stday = 0; /* Sun */
else if (basis_day == 19971201)
week_1stday = 1; /* Mon */
if (week_1stday >= 0) {
result = first_day - week_1stday - 1;
}
#else
result = 0; /* Sun */
#endif
} else {
int day;
size_t eql = strlen(option);
for (day = 0; day < MAX_DAYS; ++day) {
if (!strncmp(nameOfDayOfWeek(day), option, eql)) {
result = day;
break;
}
}
}
} else if (check < 0) {
result = -1;
} else {
result = (int) (check % MAX_DAYS);
}
}
}
return result;
}
static int
CleanupResult(int code, WINDOW *dialog, char *prompt, DIALOG_VARS * save_vars)
{
int n;
if (dialog != 0)
dlg_del_window(dialog);
dlg_mouse_free_regions();
@ -375,9 +636,35 @@ CleanupResult(int code, WINDOW *dialog, char *prompt, DIALOG_VARS * save_vars)
free(prompt);
dlg_restore_vars(save_vars);
for (n = 0; n < MAX_DAYS; ++n) {
free(cached_days[n]);
cached_days[n] = 0;
}
for (n = 0; n < MAX_MONTHS; ++n) {
free(cached_months[n]);
cached_months[n] = 0;
}
return code;
}
static void
trace_date(struct tm *current, struct tm *old)
{
bool changed = (old == 0 ||
current->tm_mday != old->tm_mday ||
current->tm_mon != old->tm_mon ||
current->tm_year != old->tm_year);
if (changed) {
DLG_TRACE(("# current %04d/%02d/%02d\n",
current->tm_year + 1900,
current->tm_mon + 1,
current->tm_mday));
} else {
DLG_TRACE(("# current (unchanged)\n"));
}
}
#define DrawObject(data) (data)->box_draw(data, &current)
/*
@ -396,7 +683,7 @@ dialog_calendar(const char *title,
static DLG_KEYS_BINDING binding[] = {
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
DLG_KEYS_DATA( DLGK_ENTER, ' ' ),
TOGGLEKEY_BINDINGS,
DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
DLG_KEYS_DATA( DLGK_GRID_DOWN, 'j' ),
@ -433,23 +720,51 @@ dialog_calendar(const char *title,
int step;
int button;
int result = DLG_EXIT_UNKNOWN;
int week_start;
WINDOW *dialog;
time_t now_time = time((time_t *) 0);
struct tm current;
int state = dlg_default_button();
const char **buttons = dlg_ok_labels();
char *prompt = dlg_strclone(subtitle);
char *prompt;
int mincols = MIN_WIDE;
char buffer[MAX_LEN];
DIALOG_VARS save_vars;
DLG_TRACE(("# calendar args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", subtitle);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("day", day);
DLG_TRACE2N("month", month);
DLG_TRACE2N("year", year);
dlg_save_vars(&save_vars);
dialog_vars.separate_output = TRUE;
dlg_does_output();
/*
* Unless overrridden, the current time/date is our starting point.
*/
now_time = time((time_t *) 0);
current = *localtime(&now_time);
#if HAVE_MKTIME
current.tm_isdst = -1;
if (year >= 1900) {
current.tm_year = year - 1900;
}
if (month >= 1) {
current.tm_mon = month - 1;
}
if (day > 0 && day <= days_per_month(current.tm_year + 1900,
current.tm_mon + 1)) {
current.tm_mday = day;
}
now_time = mktime(&current);
#else
if (day < 0)
day = current.tm_mday;
if (month < 0)
@ -479,13 +794,17 @@ dialog_calendar(const char *title,
current = *localtime(&now_time);
}
}
#endif
dlg_button_layout(buttons, &mincols);
#ifdef KEY_RESIZE
retry:
#endif
prompt = dlg_strclone(subtitle);
dlg_auto_size(title, prompt, &height, &width, 0, mincols);
height += MIN_HIGH - 1;
dlg_print_size(height, width);
dlg_ctl_size(height, width);
@ -501,7 +820,7 @@ dialog_calendar(const char *title,
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr); /* text mainbox */
dlg_attrset(dialog, dialog_attr); /* text mainbox */
dlg_print_autowrap(dialog, prompt, height, width);
/* compute positions of day, month and year boxes */
@ -509,15 +828,18 @@ dialog_calendar(const char *title,
memset(&mn_box, 0, sizeof(mn_box));
memset(&yr_box, 0, sizeof(yr_box));
if (init_object(&dy_box,
if ((week_start = WeekStart()) < 0 ||
init_object(&dy_box,
dialog,
(width - DAY_WIDE) / 2,
1 + (height - (DAY_HIGH + BTN_HIGH + (5 * MARGIN))),
DAY_WIDE,
DAY_HIGH + 1,
draw_day,
'D') < 0
|| DrawObject(&dy_box) < 0) {
week_start,
'D') < 0 ||
((dy_box.week_start = WeekStart()) < 0) ||
DrawObject(&dy_box) < 0) {
return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars);
}
@ -528,6 +850,7 @@ dialog_calendar(const char *title,
(DAY_WIDE / 2) - MARGIN,
HDR_HIGH,
draw_month,
0,
'M') < 0
|| DrawObject(&mn_box) < 0) {
return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars);
@ -540,6 +863,7 @@ dialog_calendar(const char *title,
mn_box.width,
mn_box.height,
draw_year,
0,
'Y') < 0
|| DrawObject(&yr_box) < 0) {
return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars);
@ -560,8 +884,9 @@ dialog_calendar(const char *title,
if (dlg_result_key(key, fkey, &result))
break;
#define Mouse2Key(key) (key - M_EVENT)
if (fkey && (key >= DLGK_MOUSE(KEY_MIN) && key <= DLGK_MOUSE(KEY_MAX))) {
key = dlg_lookup_key(dialog, key - M_EVENT, &fkey);
key = dlg_lookup_key(dialog, Mouse2Key(key), &fkey);
}
if ((key2 = dlg_char_to_button(key, buttons)) >= 0) {
@ -578,6 +903,7 @@ dialog_calendar(const char *title,
case DLGK_MOUSE('Y'):
state = sYEAR;
break;
case DLGK_TOGGLE:
case DLGK_ENTER:
result = dlg_enter_buttoncode(button);
break;
@ -589,21 +915,22 @@ dialog_calendar(const char *title,
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
/* repaint */
free(prompt);
dlg_clear();
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
/* repaint */
goto retry;
#endif
default:
step = 0;
key2 = -1;
if (is_DLGK_MOUSE(key)) {
if ((key2 = dlg_ok_buttoncode(key - M_EVENT)) >= 0) {
if ((key2 = dlg_ok_buttoncode(Mouse2Key(key))) >= 0) {
result = key2;
break;
} else if (key >= DLGK_MOUSE(KEY_MAX)) {
@ -613,11 +940,13 @@ dialog_calendar(const char *title,
step = (key
- DLGK_MOUSE(KEY_MAX)
- day_cell_number(&current));
DLG_TRACE(("# mouseclick decoded %d\n", step));
}
}
if (obj != 0) {
if (key2 < 0)
if (key2 < 0) {
step = next_or_previous(key, (obj == &dy_box));
}
if (step != 0) {
struct tm old = current;
@ -642,6 +971,7 @@ dialog_calendar(const char *title,
current = *localtime(&now_time);
trace_date(&current, &old);
if (obj != &dy_box
&& (current.tm_mday != old.tm_mday
|| current.tm_mon != old.tm_mon

View File

@ -1,9 +1,9 @@
/*
* $Id: checklist.c,v 1.153 2013/09/02 17:01:02 tom Exp $
* $Id: checklist.c,v 1.160 2018/06/19 22:57:01 tom Exp $
*
* checklist.c -- implements the checklist box
*
* Copyright 2000-2012,2013 Thomas E. Dickey
* Copyright 2000-2016,2018 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
@ -70,17 +70,17 @@ print_item(ALL_DATA * data,
: item->text);
/* Clear 'residue' of last item */
(void) wattrset(win, menubox_attr);
dlg_attrset(win, menubox_attr);
(void) wmove(win, choice, 0);
for (i = 0; i < data->use_width; i++)
(void) waddch(win, ' ');
(void) wmove(win, choice, data->check_x);
(void) wattrset(win, selected ? check_selected_attr : check_attr);
dlg_attrset(win, selected ? check_selected_attr : check_attr);
(void) wprintw(win,
(data->checkflag == FLAG_CHECK) ? "[%c]" : "(%c)",
states[item->state]);
(void) wattrset(win, menubox_attr);
dlg_attrset(win, menubox_attr);
(void) waddch(win, ' ');
if (both) {
@ -94,7 +94,7 @@ print_item(ALL_DATA * data,
if (selected) {
dlg_item_help(item->help);
}
(void) wattrset(win, save);
dlg_attrset(win, save);
}
static void
@ -181,6 +181,7 @@ dlg_checklist(const char *title,
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) ),
TOGGLEKEY_BINDINGS,
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -201,16 +202,29 @@ dlg_checklist(const char *title,
int result = DLG_EXIT_UNKNOWN;
int num_states;
WINDOW *dialog;
char *prompt = dlg_strclone(cprompt);
char *prompt;
const char **buttons = dlg_ok_labels();
const char *widget_name;
DLG_TRACE(("# %s args:\n", flag ? "checklist" : "radiolist"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("lheight", list_height);
DLG_TRACE2N("llength", item_no);
/* FIXME dump the items[][] too */
DLG_TRACE2S("states", states);
DLG_TRACE2N("flag", flag);
DLG_TRACE2N("current", *current_item);
dialog_state.plain_buttons = TRUE;
memset(&all, 0, sizeof(all));
all.items = items;
all.item_no = item_no;
dlg_does_output();
dlg_tab_correct_str(prompt);
/*
* If this is a radiobutton list, ensure that no more than one item is
@ -237,6 +251,9 @@ dlg_checklist(const char *title,
retry:
#endif
prompt = dlg_strclone(cprompt);
dlg_tab_correct_str(prompt);
all.use_height = list_height;
use_width = dlg_calc_list_width(item_no, items) + 10;
use_width = MAX(26, use_width);
@ -275,7 +292,7 @@ dlg_checklist(const char *title,
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
all.use_width = width - 6;
@ -381,7 +398,7 @@ dlg_checklist(const char *title,
choice = (key - KEY_MAX);
print_list(&all, choice, scrollamt, max_choice);
key = ' '; /* force the selected item to toggle */
key = DLGK_TOGGLE; /* force the selected item to toggle */
} else {
beep();
continue;
@ -396,7 +413,7 @@ dlg_checklist(const char *title,
* (any number of items can be selected) or radio list (zero or one
* items can be selected).
*/
if (key == ' ') {
if (key == DLGK_TOGGLE) {
int current = scrollamt + choice;
int next = items[current].state + 1;
@ -555,14 +572,15 @@ dlg_checklist(const char *title,
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
/* repaint */
free(prompt);
dlg_clear();
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
/* repaint */
goto retry;
#endif
default:

856
config.guess vendored

File diff suppressed because it is too large Load Diff

1711
config.sub vendored

File diff suppressed because it is too large Load Diff

15745
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
dnl $Id: configure.in,v 1.79 2013/09/02 14:02:57 tom Exp $
dnl $Id: configure.in,v 1.92 2018/06/18 08:59:49 tom Exp $
dnl Process this file with autoconf to produce a configure script.
dnl ---------------------------------------------------------------------------
dnl Copyright 1999-2011,2012 -- Thomas E. Dickey
dnl Copyright 1999-2016,2018 -- Thomas E. Dickey
dnl
dnl Permission is hereby granted, free of charge, to any person obtaining a
dnl copy of this software and associated documentation files (the
@ -27,7 +27,7 @@ dnl holders shall not be used in advertising or otherwise to promote the
dnl sale, use or other dealings in this Software without prior written
dnl authorization.
dnl ---------------------------------------------------------------------------
AC_PREREQ(2.52.20011201)
AC_PREREQ(2.52.20170501)
AC_INIT(dialog.h)
AC_CONFIG_HEADER(dlg_config.h:config.hin)
@ -47,8 +47,11 @@ AC_PROG_INSTALL
CF_PROG_LN_S
CF_PROG_LINT
CF_PROG_GROFF
test -z "$GROFF_NOTE" && NROFF_NOTE=
dnl needed for CF_WITH_LIBTOOL
AC_CHECK_TOOL(AR, ar, ar)
CF_AR_FLAGS
CF_MAKEFLAGS
CF_MAKE_TAGS
@ -59,6 +62,7 @@ CF_LIB_PREFIX
CF_XOPEN_SOURCE
CF_LARGEFILE
CF_WITH_INSTALL_PREFIX
CF_WITH_WARNINGS
CF_PKG_CONFIG
@ -92,6 +96,8 @@ AC_ARG_ENABLE(header-subdir,
AC_MSG_RESULT($SUB_INC)
AC_SUBST(SUB_INC)
CF_WITH_MAN2HTML
dnl
dnl Checks for libraries.
dnl
@ -114,23 +120,8 @@ CF_WITH_CURSES_DIR
CF_ENABLE_RPATH
use_ncurses=no
AC_ARG_WITH(ncurses,
[ --with-ncurses compile/link with ncurses library],
[use_ncurses=ncurses])
AC_ARG_WITH(ncursesw,
[ --with-ncursesw compile/link with wide-char ncurses library],
[use_ncurses=ncursesw])
if test $use_ncurses != no ; then
cf_wide_curses=yes
if test $use_ncurses = ncursesw ; then
CF_UTF8_LIB
fi
CF_NCURSES_CONFIG($use_ncurses)
else
cf_wide_curses=no
CF_CURSES_CONFIG
fi
CF_WITH_NCURSES_ETC
CF_WIDEC_CURSES
cf_all_widgets=yes
CF_ARG_MSG_ENABLE([if you want extra dialogs],
@ -183,7 +174,7 @@ CF_ARG_MSG_ENABLE([if you want the mixedform dialog],
mixedform,
[ --disable-mixedform do not include the mixedform dialog],
[EXTRAOBJS="$EXTRAOBJS mixedform\$o"
AC_DEFINE(HAVE_DLG_MIXEDFORM,1,[Define to 1 to include the mixedform dialog])],,$cf_all_widgets)
AC_DEFINE(HAVE_DLG_MIXEDFORM,1,[Define to 1 to include the mixedform dialog])],,${enable_form:=$cf_all_widgets})
CF_ARG_MSG_ENABLE([if you want the mixedgauge dialog],
mixedgauge,
@ -194,7 +185,7 @@ CF_ARG_MSG_ENABLE([if you want the mixedgauge dialog],
CF_ARG_MSG_ENABLE([if you want the wide-curses features],
widec,
[ --enable-widec enable wide-curses features],
[AC_DEFINE(USE_WIDE_CURSES,1,[Define to 1 to enable wide-curses features])],,$cf_wide_curses)
[AC_DEFINE(USE_WIDE_CURSES,1,[Define to 1 to enable wide-curses features])],,$cf_cv_widec_curses)
AC_SUBST(EXTRAOBJS)
@ -204,7 +195,7 @@ dnl
AC_HEADER_STDC
AC_HEADER_TIME
AC_HEADER_DIRENT
AC_CHECK_HEADERS(search.h unctrl.h unistd.h)
AC_CHECK_HEADERS(search.h stdint.h unistd.h)
CF_CURSES_TERM_H
dnl
@ -226,6 +217,7 @@ wcsrtombs \
wcstombs \
wctob \
wctomb \
mktime \
)
CF_CURSES_FUNCS(\
@ -255,10 +247,12 @@ CF_CURSES_WACS_SYMBOLS
CF_CURSES_WGETPARENT
CF_FUNC_WAIT
CF_MBSTATE_T
CF_SIZECHANGE
CF_HEADERS_SH(DLG,dlg_config.h)
AC_TRY_LINK([#include <locale.h>],[setlocale(LC_ALL, "")],[AC_DEFINE(HAVE_SETLOCALE,1,[Define to 1 if locale feature can be enabled])])
CF_NL_LANGINFO_1STDAY
CF_DISABLE_RPATH_HACK

337
demo.pl Executable file
View File

@ -0,0 +1,337 @@
#!/usr/bin/env perl
# $Id: demo.pl,v 1.23 2018/06/12 21:39:44 tom Exp $
################################################################################
# Copyright 2018 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
# as published by the Free Software Foundation.
#
# 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.
################################################################################
# This demonstration is provided solely to exercise the sample Perl wrapper for
# dialog which is included in its source-code. See libui-dialog-perl for a
# more comprehensive binding.
#
# TODO: modify dialog.pl to use $DIALOG environment variable, drive from GetOpts here
# TODO: eliminate constant $scr_lines in dialog.pl
use warnings;
use strict;
use diagnostics;
use FindBin qw($Bin $Script);
use lib "$Bin";
require "dialog.pl";
dialog->import('@dialog_result');
our @dialog_result;
sub tput($$) {
my $name = shift;
my $default = shift;
my $value = `tput "$name"`;
chomp $value;
$value = $default unless ( $value =~ /^[0-9]+$/ );
return $value;
}
sub napms($) {
my $msecs = shift;
select( undef, undef, undef, $msecs * 0.001 );
}
sub show_results($$) {
my $title = shift;
my $width = shift;
&rhs_msgbox(
$title,
sprintf(
"Resulting text:\\n %s", join( '\\n ', @dialog_result )
),
$width
);
}
sub doit() {
my $status = 1;
my $RHS_CLEAR = "clear";
my $RHS_TEXTBOX = "textbox";
my $RHS_MSGBOX = "msgbox";
my $RHS_INFOBOX = "infobox";
my $RHS_YESNO = "yesno";
my $RHS_GAUGE = "gauge";
my $RHS_INPUTBOX = "inputbox";
my $RHS_MENU = "menu";
my $RHS_MENUL = "menul";
my $RHS_MENUA = "menua";
my $RHS_CHECKLIST = "checklist";
my $RHS_CHECKLISTL = "checklistl";
my $RHS_CHECKLISTA = "checklista";
my $RHS_RADIOLIST = "radiolist";
my @demo_2col = qw(
This that
is has
a this
2-column quoted
menu "tag".
);
my @demo_3col;
my @demo_tags;
my %demo_hash;
for ( my $s = 0, my $t = 0 ; $s <= $#demo_2col ; $s += 2, $t += 3 ) {
my $d = $s / 2;
my $c1 = $demo_2col[$s];
my $c2 = $demo_2col[ $s + 1 ];
$demo_3col[$t] = $c1;
$demo_3col[ $t + 1 ] = $c2;
$demo_3col[ $t + 2 ] = ( $c1 =~ /2/ ) ? 1 : 0;
$demo_tags[$d] = $c1;
$demo_tags[$d] =~ s/2/1/;
$demo_tags[ $d + ( $#demo_2col + 1 ) / 2 ] = $c2;
$demo_hash{ sprintf( "%d %s", $d, $c1 ) } = $c2;
}
while ( $status > 0 ) {
my $lines = &tput( "lines", 24 );
my $cols = &tput( "cols", 80 );
my $maxcols = $cols - 4;
my $mincols = ( $cols > 8 ) ? 8 : $cols;
my $midcols = int( ( $cols * 3 ) / 4 );
@dialog_result = ();
$status = &rhs_menu(
"My title", "My message",
0, 14,
$RHS_CLEAR, "clear and exit",
$RHS_TEXTBOX, "text-box of this script",
$RHS_MSGBOX, "informational-message, OK button",
$RHS_INFOBOX, "informational-message, no button",
$RHS_YESNO, "message with Yes/No buttons",
$RHS_GAUGE, "message with progress-gauge",
$RHS_INPUTBOX, "input-box",
$RHS_MENU, "menu, with tags and description",
$RHS_MENUL, "menu, using only tags",
$RHS_MENUA, "alphabetically sorted menu",
$RHS_CHECKLIST, "check-list with tags and description",
$RHS_CHECKLISTL, "check-list using only tags",
$RHS_CHECKLISTA, "alphabetically sorted check-list",
$RHS_RADIOLIST, "list of radio-buttons"
);
if ( $status > 0 and $#dialog_result == 0 ) {
my $testcase = $dialog_result[0];
if ( $testcase eq $RHS_CLEAR ) {
&rhs_clear;
last;
}
elsif ( $testcase eq $RHS_TEXTBOX ) {
&rhs_textbox( "This script", "$Script", 0, 0 );
}
elsif ( $testcase eq $RHS_MSGBOX ) {
my $msg =
"This is a demonstration script.\\n"
. "This should be the second line,\\n"
. "and this should be the third line,";
&rhs_msgbox( "A message", $msg,
int( ( length($msg) + 3 ) / 3 ) + 3 );
}
elsif ( $testcase eq $RHS_INFOBOX ) {
my $msg =
"This is a fairly long line of text, used to"
. " show how dialog can be used to wrap lines to fit in"
. " screens with different width. The text will start wide,"
. " then get narrower, showing a new infobox for each width"
. " before going back up to the full width of the terminal.";
my $wide = $maxcols;
while ( $wide > $mincols ) {
&rhs_infobox( "Info-box", $msg, $wide-- );
&napms(50);
}
while ( $wide < $maxcols ) {
&rhs_infobox( "Info-box", $msg, ++$wide );
&napms(50);
}
&rhs_msgbox( "Info-end", $msg, $wide );
}
elsif ( $testcase eq $RHS_YESNO ) {
if (
&rhs_yesno(
"Yes/no",
"Should \"dialog --yesno\" return \"1\" on \"yes\""
. " to simplify (some) shell scripts?",
$cols / 2
)
)
{
&rhs_msgbox(
"Explanation",
"No, a successful program exits with "
. "\"0\" (EXIT_SUCCESS)",
$cols / 2
);
}
else {
&rhs_msgbox(
"Explanation",
"Shell scripts assume that \"exit\ 0\" is successful;"
. " Perl is different.",
$cols / 2
);
}
}
elsif ( $testcase eq $RHS_GAUGE ) {
my $pct = 0;
my $sec = 10;
&rhs_gauge(
"My gauge",
"Show progress (or lack of it)",
$midcols * 3, $pct
);
while ( $pct < 100 ) {
$pct++;
&napms($sec);
$sec *= 1.04;
&rhs_update_gauge($pct);
}
$pct = 99;
&rhs_update_gauge_and_message( "This will go faster", $pct );
while ( $pct > 0 ) {
$pct--;
&napms($sec);
$sec /= 1.05;
&rhs_update_gauge($pct);
}
&napms(1000);
&rhs_stop_gauge;
}
elsif ( $testcase eq $RHS_INPUTBOX ) {
if (
&rhs_inputbox(
"My inputbox", "This demonstrates the inputbox",
$maxcols, ""
)
)
{
&show_results( "My inputbox", $midcols );
}
}
elsif ( $testcase eq $RHS_MENU ) {
if (
&rhs_menu(
(
"A menu",
"This menu uses \"tag\" values and descriptions:",
$midcols, ( $#demo_2col + 1 ) / 2
),
@demo_2col
)
)
{
&show_results( "My menu", $midcols );
}
}
elsif ( $testcase eq $RHS_MENUL ) {
if (
&rhs_menul(
(
"A menu", "This menu uses only the \"tag\" values:",
$midcols, $#demo_tags + 1
),
@demo_tags
)
)
{
&show_results( "My long-menu", $midcols );
}
}
elsif ( $testcase eq $RHS_MENUA ) {
if (
&rhs_menua(
"A menu", "This menu uses the sorted keys from a hash:",
$midcols, %demo_hash
)
)
{
&show_results( "My alpha-menu", $midcols );
}
}
elsif ( $testcase eq $RHS_CHECKLIST ) {
if (
&rhs_checklist(
(
"A checklist",
"This checklist uses \"tag\" values"
. " and descriptions:",
$midcols,
( $#demo_3col + 1 ) / 3
),
@demo_3col
)
)
{
&show_results( "My checklist", $midcols );
}
}
elsif ( $testcase eq $RHS_CHECKLISTL ) {
if (
&rhs_checklistl(
(
"A checklist",
"This checklist uses only the \"tag\" values:",
$midcols, $#demo_tags + 1
),
@demo_tags
)
)
{
&show_results( "My long-checklist", $midcols );
}
}
elsif ( $testcase eq $RHS_CHECKLISTA ) {
if (
&rhs_checklista(
"A checklist",
"This checklist uses the sorted keys from a hash:",
$midcols, %demo_hash
)
)
{
&show_results( "My alpha-checklist", $midcols );
}
}
elsif ( $testcase eq $RHS_RADIOLIST ) {
if (
&rhs_radiolist(
(
"A radiolist",
"This radiolist uses \"tag\" values"
. " and descriptions:",
$midcols,
( $#demo_3col + 1 ) / 3
),
@demo_3col
)
)
{
&show_results( "My radiolist", $midcols );
}
}
}
}
}
&doit;
1;

639
dialog.1

File diff suppressed because it is too large Load Diff

1601
dialog.3

File diff suppressed because it is too large Load Diff

502
dialog.c
View File

@ -1,9 +1,9 @@
/*
* $Id: dialog.c,v 1.231 2013/09/02 17:20:09 tom Exp $
* $Id: dialog.c,v 1.268 2018/06/21 09:16:05 tom Exp $
*
* cdialog - Display simple dialog boxes from shell scripts
*
* Copyright 2000-2012,2013 Thomas E. Dickey
* Copyright 2000-2017,2018 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
@ -109,6 +109,8 @@ typedef enum {
,o_prgbox
,o_print_maxsize
,o_print_size
,o_print_text_only
,o_print_text_size
,o_print_version
,o_programbox
,o_progressbox
@ -151,10 +153,12 @@ typedef enum {
,o_editbox
,o_fselect
,o_timebox
,o_week_start
#endif
#ifdef HAVE_XDIALOG2
,o_buildlist
,o_rangebox
,o_reorder
,o_treeview
#endif
#if defined(HAVE_XDIALOG2) || defined(HAVE_WHIPTAIL)
@ -164,6 +168,7 @@ typedef enum {
#ifdef HAVE_DLG_TRACE
,o_trace
#endif
,o_iso_week
} eOptions;
/*
@ -186,13 +191,26 @@ typedef struct {
callerFn *jumper;
} Mode;
static bool *dialog_opts;
static int known_opts = 0;
static const char **dialog_opts;
static char **dialog_argv;
static char **special_argv = 0;
static int special_argc = 0;
static bool ignore_unknown = FALSE;
static const char *program = "dialog";
#ifdef NO_LEAKS
typedef struct _all_blobs {
struct _all_blobs *next;
void *blob;
} AllBlobs;
static AllBlobs *all_blobs;
#endif
/*
* The options[] table is organized this way to make it simple to maintain
* a sorted list of options for the help-message.
@ -272,6 +290,8 @@ static const Options options[] = {
{ "prgbox", o_prgbox, 2, "<text> <command> <height> <width>" },
{ "print-maxsize", o_print_maxsize, 1, "" },
{ "print-size", o_print_size, 1, "" },
{ "print-text-only",o_print_text_only, 5, "<text> <height> <width>" },
{ "print-text-size",o_print_text_size, 5, "<text> <height> <width>" },
{ "print-version", o_print_version, 5, "" },
{ "programbox", o_programbox, 2, "<text> <height> <width>" },
{ "progressbox", o_progressbox, 2, "<text> <height> <width>" },
@ -320,12 +340,15 @@ static const Options options[] = {
{ "editbox", o_editbox, 2, "<file> <height> <width>" },
{ "fselect", o_fselect, 2, "<filepath> <height> <width>" },
{ "timebox", o_timebox, 2, "<text> <height> <width> <hour> <minute> <second>" },
{ "week-start", o_week_start, 1, "<str>" },
{ "iso-week", o_iso_week, 1, NULL },
#endif
#ifdef HAVE_XDIALOG2
{ "buildlist", o_buildlist, 2, "<text> <height> <width> <tag1> <item1> <status1>..." },
{ "buildlist", o_buildlist, 2, "<text> <height> <width> <list-height> <tag1> <item1> <status1>..." },
{ "no-items", o_no_items, 1, "" },
{ "no-tags", o_no_tags, 1, "" },
{ "rangebox", o_rangebox, 2, "<text> <height> <width> <min-value> <max-value> <default-value>" },
{ "reorder", o_reorder, 1, "" },
{ "treeview", o_treeview, 2, "<text> <height> <width> <list-height> <tag1> <item1> <status1> <depth1>..." },
#endif
#if defined(HAVE_XDIALOG2) || defined(HAVE_WHIPTAIL)
@ -338,6 +361,76 @@ static const Options options[] = {
};
/* *INDENT-ON* */
#ifdef NO_LEAKS
static void
ignore_leak(void *value)
{
AllBlobs *next = dlg_calloc(AllBlobs, (size_t) 1);
if (next != 0) {
next->blob = value;
next->next = all_blobs;
all_blobs = next;
}
}
static void
handle_leaks(void)
{
while (all_blobs != 0) {
char *blob = all_blobs->blob;
AllBlobs *next = all_blobs->next;
free(blob);
free(all_blobs);
all_blobs = next;
}
free(dialog_opts);
if (special_argv != 0) {
free(special_argv[0]);
free(special_argv);
special_argv = 0;
special_argc = 0;
}
}
#else
#define handle_leaks() /* nothing */
#define ignore_leak(n) /* nothing */
#endif
#define OptionChars "\
0123456789\
-\
abcdefghijklmnopqrstuvwxyz\
"
/*
* Check if the given string from main's argv is an option.
*/
static bool
isOption(const char *arg)
{
bool result = FALSE;
if (arg != 0) {
if (dialog_opts != 0) {
int n;
for (n = 0; dialog_opts[n] != 0; ++n) {
if (dialog_opts[n] == arg) {
result = TRUE;
break;
}
}
} else if (!strncmp(arg, "--", (size_t) 2) && isalpha(UCH(arg[2]))) {
if (strlen(arg) == (strspn) (arg, OptionChars)) {
result = TRUE;
} else {
handle_leaks();
dlg_exiterr("Invalid option \"%s\"", arg);
}
}
}
return result;
}
/*
* Make an array showing which argv[] entries are options. Use "--" as a
* special token to escape the next argument, allowing it to begin with "--".
@ -357,27 +450,51 @@ unescape_argv(int *argcp, char ***argvp)
int j, k;
int limit_includes = 20 + *argcp;
int count_includes = 0;
bool changed = FALSE;
bool doalloc = FALSE;
char *filename;
const char **my_argv = 0;
int my_argc;
dialog_opts = dlg_calloc(bool, (size_t) *argcp + 1);
assert_ptr(dialog_opts, "unescape_argv");
DLG_TRACE(("# unescape_argv\n"));
for (k = 0; k < 2; ++k) {
my_argc = 0;
if (special_argv != 0) {
for (j = 0; special_argv[j] != 0; ++j) {
if (!strcmp(special_argv[j], "--")) {
break;
} else if (isOption(special_argv[j])) {
if (k != 0)
my_argv[my_argc] = special_argv[j];
my_argc++;
}
}
}
if (k == 0) {
my_argc += (*argcp + 1);
my_argv = dlg_calloc(const char *, (size_t) my_argc);
assert_ptr(my_argv, "unescape_argv");
}
}
for (j = 1; j < *argcp; j++) {
bool escaped = FALSE;
if (!strcmp((*argvp)[j], "--")) {
escaped = TRUE;
changed = dlg_eat_argv(argcp, argvp, j, 1);
dlg_eat_argv(argcp, argvp, j, 1);
} else if (!strcmp((*argvp)[j], "--args")) {
fprintf(stderr, "Showing arguments at arg%d\n", j);
for (k = 0; k < *argcp; ++k) {
fprintf(stderr, " arg%d:%s\n", k, (*argvp)[k]);
}
changed = dlg_eat_argv(argcp, argvp, j, 1);
dlg_eat_argv(argcp, argvp, j, 1);
--j;
} else if (!strcmp((*argvp)[j], "--file")) {
if (++count_includes > limit_includes)
if (++count_includes > limit_includes) {
handle_leaks();
dlg_exiterr("Too many --file options");
}
if ((filename = (*argvp)[j + 1]) != 0) {
FILE *fp;
@ -395,6 +512,7 @@ unescape_argv(int *argcp, char ***argvp)
}
if (fp) {
DLG_TRACE(("# opened --file %s ..\n", filename));
blob = NULL;
length = 0;
do {
@ -405,50 +523,71 @@ unescape_argv(int *argcp, char ***argvp)
(size_t) BUFSIZ,
fp);
length += bytes_read;
if (ferror(fp))
if (ferror(fp)) {
handle_leaks();
dlg_exiterr("error on filehandle in unescape_argv");
}
} while (bytes_read == BUFSIZ);
fclose(fp);
blob[length] = '\0';
ignore_leak(blob);
list = dlg_string_to_argv(blob);
if ((added = dlg_count_argv(list)) != 0) {
if (added > 2) {
size_t need = (size_t) (*argcp + added + 1);
if (doalloc) {
*argvp = dlg_realloc(char *, need, *argvp);
assert_ptr(*argvp, "unescape_argv");
} else {
char **newp = dlg_malloc(char *, need);
assert_ptr(newp, "unescape_argv");
for (n = 0; n < *argcp; ++n) {
newp[n] = (*argvp)[n];
}
*argvp = newp;
doalloc = TRUE;
added = dlg_count_argv(list);
if (added > 2) {
/* *argcp arguments before the expansion of --file
- 2 for the removal of '--file <filepath>'
+ added for the arguments contained in <filepath>
+ 1 for the terminating NULL pointer */
size_t need = (size_t) (*argcp + added - 1);
if (doalloc) {
*argvp = dlg_realloc(char *, need, *argvp);
assert_ptr(*argvp, "unescape_argv");
} else {
char **newp = dlg_malloc(char *, need);
ignore_leak(newp);
assert_ptr(newp, "unescape_argv");
for (n = 0; n < *argcp; ++n) {
newp[n] = (*argvp)[n];
}
dialog_opts = dlg_realloc(bool, need, dialog_opts);
assert_ptr(dialog_opts, "unescape_argv");
/* The new array is not NULL-terminated yet. */
*argvp = newp;
doalloc = TRUE;
}
for (n = *argcp; n >= j + 2; --n) {
my_argv = dlg_realloc(const char *, need, my_argv);
assert_ptr(my_argv, "unescape_argv");
/* Shift the arguments after '--file <filepath>'
right by (added - 2) positions */
for (n = *argcp - 1; n >= j + 2; --n) {
(*argvp)[n + added - 2] = (*argvp)[n];
dialog_opts[n + added - 2] = dialog_opts[n];
}
for (n = 0; n < added; ++n) {
(*argvp)[n + j] = list[n];
dialog_opts[n + j] = FALSE;
} else if (added < 2) {
/* 0 or 1 argument read from the included file
-> shift the arguments after '--file <filepath>'
left by (2 - added) positions */
for (n = j + added; n + 2 - added < *argcp; ++n) {
(*argvp)[n] = (*argvp)[n + 2 - added];
}
*argcp += added - 2;
free(list);
}
/* Copy the inserted arguments to *argvp */
for (n = 0; n < added; ++n) {
(*argvp)[n + j] = list[n];
}
*argcp += added - 2;
(*argvp)[*argcp] = 0; /* Write the NULL terminator */
free(list); /* No-op if 'list' is NULL */
/* Force rescan starting from the first inserted argument */
--j;
DLG_TRACE(("# finished --file\n"));
continue;
} else {
handle_leaks();
dlg_exiterr("Cannot open --file %s", filename);
}
(*argvp)[*argcp] = 0;
++j;
continue;
} else {
handle_leaks();
dlg_exiterr("No value given for --file");
}
}
@ -456,54 +595,20 @@ unescape_argv(int *argcp, char ***argvp)
&& (*argvp)[j] != 0
&& !strncmp((*argvp)[j], "--", (size_t) 2)
&& isalpha(UCH((*argvp)[j][2]))) {
dialog_opts[j] = TRUE;
my_argv[my_argc++] = (*argvp)[j];
DLG_TRACE(("#\toption argv[%d]=%s\n", j, (*argvp)[j]));
}
}
/* if we didn't find any "--" tokens, there's no reason to do the table
* lookup in isOption()
*/
if (!changed) {
free(dialog_opts);
dialog_opts = 0;
}
my_argv[my_argc] = 0;
known_opts = my_argc;
dialog_opts = my_argv;
DLG_TRACE(("#\t%d options vs %d arguments\n", known_opts, *argcp));
dialog_argv = (*argvp);
}
#define OptionChars "\
0123456789\
-\
abcdefghijklmnopqrstuvwxyz\
"
/*
* Check if the given string from main's argv is an option.
*/
static bool
isOption(const char *arg)
{
bool result = FALSE;
if (arg != 0) {
if (dialog_opts != 0) {
int n;
for (n = 1; dialog_argv[n] != 0; ++n) {
if (dialog_argv[n] == arg) {
result = dialog_opts[n];
break;
}
}
} else if (!strncmp(arg, "--", (size_t) 2) && isalpha(UCH(arg[2]))) {
if (strlen(arg) == strspn(arg, OptionChars)) {
result = TRUE;
} else {
dlg_exiterr("Invalid option \"%s\"", arg);
}
}
}
return result;
}
static eOptions
lookupOption(const char *name, int pass)
{
@ -526,6 +631,7 @@ lookupOption(const char *name, int pass)
static void
Usage(const char *msg)
{
handle_leaks();
dlg_exiterr("Error: %s.\nUse --help to list options.\n\n", msg);
}
@ -553,19 +659,23 @@ howmany_tags(char *argv[], int group)
{
int result = 0;
int have;
const char *format = "Expected %d arguments, found only %d";
char temp[80];
while (argv[0] != 0) {
if (isOption(argv[0]))
break;
if ((have = arg_rest(argv)) < group) {
const char *format = _("Expected %d arguments, found only %d");
sprintf(temp, format, group, have);
Usage(temp);
} else if ((have % group) != 0) {
const char *format = _("Expected %d arguments, found extra %d");
sprintf(temp, format, group, (have % group));
Usage(temp);
}
argv += group;
result++;
argv += have;
result += (have / group);
}
return result;
@ -634,6 +744,7 @@ show_result(int ret)
if (dialog_vars.input_result != 0
&& dialog_vars.input_result[0] != '\0') {
fputs(dialog_vars.input_result, dialog_state.output);
DLG_TRACE(("# input_result:\n%s\n", dialog_vars.input_result));
either = TRUE;
}
if (either) {
@ -872,7 +983,7 @@ call_buildlist(CALLARGS)
numeric_arg(av, 3),
numeric_arg(av, 4),
tags, av + 5,
TRUE);
dialog_vars.reorder);
RestoreNoTags();
return result;
}
@ -1099,10 +1210,10 @@ static const Mode modes[] =
{o_msgbox, 4, 4, call_msgbox},
{o_infobox, 4, 4, call_infobox},
{o_textbox, 4, 4, call_textbox},
{o_menu, 7, 0, call_menu},
{o_inputmenu, 7, 0, call_inputmenu},
{o_checklist, 8, 0, call_checklist},
{o_radiolist, 8, 0, call_radiolist},
{o_menu, 6, 0, call_menu},
{o_inputmenu, 6, 0, call_inputmenu},
{o_checklist, 7, 0, call_checklist},
{o_radiolist, 7, 0, call_radiolist},
{o_inputbox, 4, 5, call_inputbox},
{o_passwordbox, 4, 5, call_passwordbox},
#ifdef HAVE_DLG_GAUGE
@ -1127,13 +1238,15 @@ static const Mode modes[] =
{o_tailboxbg, 4, 4, call_tailboxbg},
#endif
#ifdef HAVE_XDIALOG
{o_buildlist, 4, 0, call_buildlist},
{o_calendar, 4, 7, call_calendar},
{o_dselect, 4, 5, call_dselect},
{o_editbox, 4, 4, call_editbox},
{o_fselect, 4, 5, call_fselect},
{o_rangebox, 5, 7, call_rangebox},
{o_timebox, 4, 7, call_timebox},
#endif
#ifdef HAVE_XDIALOG2
{o_buildlist, 4, 0, call_buildlist},
{o_rangebox, 5, 7, call_rangebox},
{o_treeview, 4, 0, call_treeview},
#endif
};
@ -1213,6 +1326,64 @@ button_code(const char *name)
return code;
}
/*
* If this is the last option, we do not want any error messages - just our
* output. Calling end_dialog() cancels the refresh() at the end of the
* program as well.
*/
static void
IgnoreNonScreen(char **argv, int offset)
{
if (argv[offset + 1] == 0) {
ignore_unknown = TRUE;
end_dialog();
}
}
static void
PrintTextOnly(char **argv, int *offset, eOptions code)
{
/* TODO - handle two optional numeric params */
char *text;
int height = 0;
int width = 0;
int height2 = 0;
int width2 = 0;
int next = arg_rest(argv + *offset);
if (LINES <= 0 && COLS <= 0)
dlg_ttysize(fileno(dialog_state.input), &LINES, &COLS);
text = strdup(optionString(argv, offset));
IgnoreNonScreen(argv, *offset);
if (next >= 1) {
next = MIN(next, 3);
height = numeric_arg(argv, *offset + 1);
if (next >= 2)
width = numeric_arg(argv, *offset + 2);
*offset += next - 1;
}
dlg_trim_string(text);
dlg_auto_size(NULL, text, &height2, &width2, height, width);
switch (code) {
case o_print_text_only:
dialog_state.text_only = TRUE;
dlg_print_autowrap(stdscr, text, height2, width2);
dialog_state.text_only = FALSE;
break;
case o_print_text_size:
fprintf(dialog_state.output, "%d %d\n",
dialog_state.text_height,
dialog_state.text_width);
break;
default:
break;
}
}
/*
* Print parts of a message
*/
@ -1276,7 +1447,7 @@ Help(void)
static const char *const tbl_1[] =
{
"cdialog (ComeOn Dialog!) version %s",
"Copyright 2000-2012,2013 Thomas E. Dickey",
"Copyright 2000-2017,2018 Thomas E. Dickey",
"This is free software; see the source for copying conditions. There is NO",
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
"",
@ -1330,13 +1501,15 @@ Help(void)
for (j = 0; j < limit; j++) {
if ((opts[j]->pass & 2) != 0
&& opts[j]->help != 0
&& lookupMode(opts[j]->code))
&& lookupMode(opts[j]->code)) {
fprintf(dialog_state.output, " --%-12s %s\n", opts[j]->name,
opts[j]->help);
}
}
PrintList(tbl_3);
free(opts);
handle_leaks();
dlg_exit(DLG_EXIT_OK);
}
@ -1355,13 +1528,13 @@ process_trace_option(char **argv, int *offset)
if (dialog_state.trace_output == 0) {
dlg_trace(optionString(argv, offset));
} else {
dlg_trace_msg("# ignore extra --trace option\n");
DLG_TRACE(("# ignore extra --trace option\n"));
*offset += 1;
}
dlg_trace_msg("# Parameters:\n");
DLG_TRACE(("# Parameters:\n"));
for (j = 0; argv[j] != 0; ++j) {
dlg_trace_msg("# argv[%d] = %s\n", j, argv[j]);
DLG_TRACE(("#\targv[%d] = %s\n", j, argv[j]));
}
}
#endif
@ -1375,12 +1548,13 @@ static int
process_common_options(int argc, char **argv, int offset, bool output)
{
bool done = FALSE;
eOptions code;
dlg_trace_msg("# process_common_options, offset %d\n", offset);
DLG_TRACE(("# process_common_options, offset %d\n", offset));
while (offset < argc && !done) { /* Common options */
dlg_trace_msg("#\targv[%d] = %s\n", offset, argv[offset]);
switch (lookupOption(argv[offset], 1)) {
DLG_TRACE(("#\targv[%d] = %s\n", offset, argv[offset]));
switch (code = lookupOption(argv[offset], 1)) {
case o_title:
dialog_vars.title = optionString(argv, &offset);
break;
@ -1485,17 +1659,13 @@ process_common_options(int argc, char **argv, int offset, bool output)
case o_print_size:
dialog_vars.print_siz = TRUE;
break;
case o_print_text_only:
case o_print_text_size:
PrintTextOnly(argv, &offset, code);
break;
case o_print_maxsize:
if (output) {
/*
* If this is the last option, we do not want any error
* messages - just our output. Calling end_dialog() cancels
* the refresh() at the end of the program as well.
*/
if (argv[offset + 1] == 0) {
ignore_unknown = TRUE;
end_dialog();
}
IgnoreNonScreen(argv, offset);
fflush(dialog_state.output);
fprintf(dialog_state.output, "MaxSize: %d, %d\n", SLINES, SCOLS);
}
@ -1632,10 +1802,31 @@ process_common_options(int argc, char **argv, int offset, bool output)
dialog_vars.no_tags = TRUE;
break;
#endif
#ifdef HAVE_XDIALOG2
case o_reorder:
dialog_vars.reorder = TRUE;
break;
#endif
#ifdef HAVE_XDIALOG
case o_week_start:
dialog_vars.week_start = optionString(argv, &offset);
break;
#endif
case o_iso_week:
dialog_vars.iso_week = TRUE;
if (dialog_vars.week_start == 0) { /* Monday is implied */
static char default_1st[] = "1";
dialog_vars.week_start = default_1st;
}
break;
}
if (!done)
offset++;
}
if (dialog_state.aspect_ratio == 0)
dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO;
return offset;
}
@ -1647,10 +1838,8 @@ static void
init_result(char *buffer)
{
static bool first = TRUE;
static char **special_argv = 0;
static int special_argc = 0;
dlg_trace_msg("# init_result\n");
DLG_TRACE(("# init_result\n"));
/* clear everything we do not save for the next widget */
memset(&dialog_vars, 0, sizeof(dialog_vars));
@ -1675,19 +1864,8 @@ init_result(char *buffer)
first = FALSE;
}
/*
* If we are not checking memory leaks, just do the parse of the
* environment once.
*/
if (special_argv != 0) {
process_common_options(special_argc, special_argv, 0, FALSE);
#ifdef NO_LEAKS
free(special_argv[0]);
free(special_argv);
special_argv = 0;
special_argc = 0;
first = TRUE;
#endif
}
}
@ -1697,6 +1875,7 @@ main(int argc, char *argv[])
char temp[256];
bool esc_pressed = FALSE;
bool keep_tite = FALSE;
bool first_time = TRUE;
int offset = 1;
int offset_add;
int retval = DLG_EXIT_OK;
@ -1717,6 +1896,7 @@ main(int argc, char *argv[])
(void) setlocale(LC_ALL, "");
#endif
init_result(my_buffer); /* honor $DIALOGOPTS */
unescape_argv(&argc, &argv);
program = argv[0];
dialog_state.output = stderr;
@ -1742,13 +1922,17 @@ main(int argc, char *argv[])
break;
case o_input_fd:
if ((j = optionValue(argv, &offset)) < 0
|| (dialog_state.input = fdopen(j, "r")) == 0)
|| (dialog_state.input = fdopen(j, "r")) == 0) {
handle_leaks();
dlg_exiterr("Cannot open input-fd\n");
}
break;
case o_output_fd:
if ((j = optionValue(argv, &offset)) < 0
|| (dialog_state.output = fdopen(j, "w")) == 0)
|| (dialog_state.output = fdopen(j, "w")) == 0) {
handle_leaks();
dlg_exiterr("Cannot open output-fd\n");
}
break;
case o_keep_tite:
keep_tite = TRUE;
@ -1756,7 +1940,7 @@ main(int argc, char *argv[])
case o_version:
dialog_state.output = stdout;
PrintVersion(dialog_state.output);
exit(DLG_EXIT_OK);
dlg_exit(DLG_EXIT_OK);
break;
case o_help:
Help();
@ -1780,26 +1964,25 @@ main(int argc, char *argv[])
++offset;
continue;
}
dlg_trace_msg("# discarding %d parameters starting with argv[%d] (%s)\n",
1 + offset - base, base,
argv[base]);
DLG_TRACE(("# discarding %d parameters starting with argv[%d] (%s)\n",
1 + offset - base, base,
argv[base]));
for (j = base; j < argc; ++j) {
dialog_argv[j] = dialog_argv[j + 1 + (offset - base)];
if (dialog_opts != 0)
dialog_opts[j] = dialog_opts[j + 1 + (offset - base)];
}
argc -= (1 + offset - base);
offset = base;
}
offset = 1;
init_result(my_buffer);
dialog_vars.keep_tite = keep_tite; /* init_result() cleared global */
/*
* Dialog's output may be redirected (see above). Handle the special
* case of options that only report information without interaction.
*/
if (argc == 2) {
switch (lookupOption(argv[1], 7)) {
switch (code = lookupOption(argv[1], 7)) {
case o_print_maxsize:
(void) initscr();
endwin();
@ -1820,33 +2003,44 @@ main(int argc, char *argv[])
Help();
break;
}
return DLG_EXIT_OK;
}
if (argc < 2) {
dlg_exit(DLG_EXIT_OK);
} else if (argc < 2) {
Help();
}
#ifdef HAVE_RC_FILE
if (lookupOption(argv[1], 7) == o_create_rc) {
else if (lookupOption(argv[1], 7) == o_create_rc) {
if (argc != 3) {
sprintf(temp, "Expected a filename for %.50s", argv[1]);
Usage(temp);
}
if (dlg_parse_rc() == -1) /* Read the configuration file */
if (dlg_parse_rc() == -1) { /* Read the configuration file */
handle_leaks();
dlg_exiterr("dialog: dlg_parse_rc");
}
dlg_create_rc(argv[2]);
return DLG_EXIT_OK;
dlg_exit(DLG_EXIT_OK);
}
#endif
dialog_vars.keep_tite = keep_tite; /* init_result() cleared global */
else {
/*
* Handle combinations of common options including --print-text-only
* which can be done before involving curses, in case we can exit
* without initializing curses (and writing to the terminal).
*/
offset = process_common_options(argc, argv, offset, TRUE);
if (offset >= argc)
dlg_exit(DLG_EXIT_OK);
}
init_dialog(dialog_state.input, dialog_state.output);
while (offset < argc && !esc_pressed) {
init_result(my_buffer);
offset = process_common_options(argc, argv, offset, TRUE);
if (first_time) {
first_time = FALSE;
} else {
init_result(my_buffer);
offset = process_common_options(argc, argv, offset, TRUE);
}
if (argv[offset] == NULL) {
if (ignore_unknown)
@ -1854,15 +2048,22 @@ main(int argc, char *argv[])
Usage("Expected a box option");
}
if (lookupOption(argv[offset], 2) != o_checklist
&& dialog_vars.separate_output) {
sprintf(temp, "Expected --checklist, not %.20s", argv[offset]);
Usage(temp);
if (dialog_vars.separate_output) {
switch (lookupOption(argv[offset], 2)) {
#ifdef HAVE_XDIALOG2
case o_buildlist:
case o_treeview:
#endif
case o_checklist:
break;
default:
sprintf(temp,
"Unexpected widget with --separate-output %.20s",
argv[offset]);
Usage(temp);
}
}
if (dialog_state.aspect_ratio == 0)
dialog_state.aspect_ratio = DEFAULT_ASPECT_RATIO;
dlg_put_backtitle();
/* use a table to look for the requested mode, to avoid code duplication */
@ -1917,15 +2118,17 @@ main(int argc, char *argv[])
} else {
argv[j] = strdup("?");
}
ignore_leak(argv[j]);
}
break;
}
}
DLG_TRACE(("# execute %s\n", argv[offset]));
retval = show_result((*(modePtr->jumper)) (dialog_vars.title,
argv + offset,
&offset_add));
dlg_trace_msg("# widget returns %d\n", retval);
DLG_TRACE(("# widget returns %d\n", retval));
offset += offset_add;
if (dialog_vars.input_result != my_buffer) {
@ -1972,5 +2175,6 @@ main(int argc, char *argv[])
(void) refresh();
end_dialog();
}
handle_leaks();
dlg_exit(retval);
}

View File

@ -1,9 +1,9 @@
/*
* $Id: dialog.h,v 1.267 2013/09/22 19:06:36 tom Exp $
* $Id: dialog.h,v 1.283 2018/06/19 22:52:11 tom Exp $
*
* dialog.h -- common declarations for all dialog modules
*
* Copyright 2000-2012,2013 Thomas E. Dickey
* Copyright 2000-2017,2018 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
@ -127,8 +127,8 @@
#define USE_COLORS TRUE
#ifdef HAVE_COLOR
#define SCOLS (COLS - (dialog_state.use_shadow ? 2 : 0))
#define SLINES (LINES - (dialog_state.use_shadow ? 1 : 0))
#define SCOLS (COLS - (dialog_state.use_shadow ? SHADOW_COLS : 0))
#define SLINES (LINES - (dialog_state.use_shadow ? SHADOW_ROWS : 0))
#else
#define SCOLS COLS
#define SLINES LINES
@ -154,15 +154,16 @@
#define CHR_NEXT DLG_CTRL('N')
#define CHR_PREVIOUS DLG_CTRL('P')
#define CHR_TRACE DLG_CTRL('T')
#define CHR_SPACE ' '
#define ESC 27
#define TAB DLG_CTRL('I')
#define MARGIN 1
#define GUTTER 2
#define SHADOW_ROWS 1
#define SHADOW_COLS 2
#define ARROWS_COL 5
#define MARGIN 1 /* width of the line drawn around each box */
#define GUTTER 2 /* minimum columns between name/description in menu */
#define SHADOW_ROWS 1 /* rows to reserve for window's shadow */
#define SHADOW_COLS 2 /* columns to reserve for window's shadow */
#define ARROWS_COL 5 /* distance from left margin to up/down arrows */
#define MAX_LEN 2048
#define BUF_SIZE (10L*1024)
@ -388,6 +389,19 @@ extern WINDOW * dlg_wgetparent(WINDOW * /*win*/);
#define DLGK_max (KEY_MAX + 256)
/*
* Use attributes.
*/
#ifdef PDCURSES
#define dlg_attrset(w,a) (void) wattrset((w), (a))
#define dlg_attron(w,a) (void) wattron((w), (a))
#define dlg_attroff(w,a) (void) wattroff((w), (a))
#else
#define dlg_attrset(w,a) (void) wattrset((w), (int)(a))
#define dlg_attron(w,a) (void) wattron((w), (int)(a))
#define dlg_attroff(w,a) (void) wattroff((w), (int)(a))
#endif
/*
* Callbacks are used to implement the "background" tailbox.
*/
@ -447,6 +461,12 @@ typedef struct {
int visit_cols; /* option "--visit-items" */
/* 1.2-20130922 */
bool finish_string; /* caching optimization for gauge */
/* 1.2-20150125 */
bool plain_buttons; /* true to suppress button-label highlight */
/* 1.3-20180610 */
bool text_only; /* option "--print-text-only", etc. */
int text_height;
int text_width;
} DIALOG_STATE;
extern DIALOG_STATE dialog_state;
@ -526,6 +546,12 @@ typedef struct {
bool last_key; /* option "--last-key" */
/* 1.2-20130902 */
bool help_tags; /* option "--help-tags" */
/* 1.3-20160126 */
char *week_start; /* option "--week-start" */
/* 1.3-20160206 */
bool iso_week; /* option "--iso-week" */
/* 1.3-20170131 */
bool reorder; /* option "--reorder" */
} DIALOG_VARS;
#define USE_ITEM_HELP(s) (dialog_vars.item_help && (s) != 0)
@ -553,6 +579,10 @@ extern DIALOG_VARS dialog_vars;
#define chtype long
#endif
#ifndef isblank
#define isblank(c) ((c) == ' ' || (c) == TAB)
#endif
#define UCH(ch) ((unsigned char)(ch))
#define assert_ptr(ptr,msg) if ((ptr) == 0) dlg_exiterr("cannot allocate memory in " msg)
@ -711,6 +741,9 @@ extern void dlg_show_string(WINDOW * /*win*/, const char * /*string*/, int /*off
extern int dlg_dummy_menutext(DIALOG_LISTITEM * /*items*/, int /*current*/, char * /*newtext*/);
extern int dlg_renamed_menutext(DIALOG_LISTITEM * /*items*/, int /*current*/, char * /*newtext*/);
/* prgbox.c */
extern FILE * dlg_popen(const char * /*command */, const char * /*type */);
/* rc.c */
#ifdef HAVE_RC_FILE
extern int dlg_parse_rc(void);
@ -720,6 +753,9 @@ extern void dlg_create_rc(const char * /*filename*/);
/* treeview.c */
extern int dlg_treeview(const char * /*title*/, const char * /*cprompt*/, int /*height*/, int /*width*/, int /*list_height*/, int /*item_no*/, DIALOG_LISTITEM * /*items*/, const char * /*states*/, int * /*depths*/, int /*flag*/, int * /*current_item*/);
/* ttysize.c */
extern int dlg_ttysize(int /* fd */, int * /* height */, int * /* width */);
/* ui_getc.c */
extern int dlg_getc(WINDOW * /*win*/, int * /*fkey*/);
extern int dlg_getc_callbacks(int /*ch*/, int /*fkey*/, int * /*result*/);
@ -809,11 +845,17 @@ extern int dlg_strcmp(const char * /*a*/, const char * /*b*/);
#ifdef HAVE_DLG_TRACE
#define DLG_TRACE(params) dlg_trace_msg params
extern void dlg_trace_msg(const char *fmt, ...) GCC_PRINTFLIKE(1,2);
#define DLG_TRACE2S(name,value) dlg_trace_2s (name,value)
#define DLG_TRACE2N(name,value) dlg_trace_2n (name,value)
extern void dlg_trace_2s(const char * /*name*/, const char * /*value*/);
extern void dlg_trace_2n(const char * /*name*/, int /*value*/);
extern void dlg_trace_win(WINDOW * /*win*/);
extern void dlg_trace_chr(int /*ch*/, int /*fkey*/);
extern void dlg_trace(const char * /*fname*/);
#else
#define DLG_TRACE(params) /* nothing */
#define DLG_TRACE2S(name,value) /* nothing */
#define DLG_TRACE2N(name,value) /* nothing */
#define dlg_trace_win(win) /* nothing */
#define dlg_trace_chr(ch,fkey) /* nothing */
#define dlg_trace(fname) /* nothing */
@ -821,6 +863,7 @@ extern void dlg_trace(const char * /*fname*/);
#ifdef KEY_RESIZE
extern void dlg_move_window(WINDOW * /*win*/, int /*height*/, int /*width*/, int /*y*/, int /*x*/);
extern void dlg_will_resize(WINDOW * /*win*/);
#endif
/*
@ -840,7 +883,7 @@ typedef struct mseRegion {
#if defined(NCURSES_MOUSE_VERSION)
#define mouse_open() mousemask(BUTTON1_CLICKED, (mmask_t *) 0)
#define mouse_open() mousemask(BUTTON1_PRESSED, (mmask_t *) 0)
#define mouse_close() mousemask(0, (mmask_t *) 0)
extern mseRegion * dlg_mouse_mkregion (int /*y*/, int /*x*/, int /*height*/, int /*width*/, int /*code*/);

696
dialog.pl
View File

@ -1,6 +1,30 @@
# Functions that handle calling dialog(1) -*-perl-*-
# $Id: dialog.pl,v 1.4 2001/10/13 00:40:22 tom Exp $
# $Id: dialog.pl,v 1.18 2018/06/12 21:01:58 tom Exp $
################################################################################
# Copyright 2018 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
# as published by the Free Software Foundation.
#
# 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.
################################################################################
# The "rhs_" functions, as well as return_output originally came from Redhat
# 4.0, e.g.,
# http://www.ibiblio.org/pub/historic-linux/distributions/redhat-4.0/i386/live/usr/bin/Xconfigurator.pl
# The other functions were added to make this more useful for demonstrations.
# These comments are from the original file:
#------------------------------------------------------------------------------
# Return values are 1 for success and 0 for failure (or cancel)
# Resultant text (if any) is in dialog_result
@ -10,443 +34,565 @@
# Note that dialog generally returns 0 for success, so I invert the
# sense of the return code for more readable boolean expressions.
#------------------------------------------------------------------------------
$scr_lines = 24;
use warnings;
use strict;
use diagnostics;
our $DIALOG = "dialog";
our $GAUGE;
our $gauge_width;
our $scr_lines = 24;
our $scr_cols = 80;
our @dialog_result;
our $trace = 0;
require "flush.pl";
sub trace {
if ($trace) {
if ( open TRACE, ">>dialog.log" ) {
printf TRACE $_[0], @_[ 1 .. $#_ ];
close TRACE;
}
}
}
sub quoted($) {
my $text = shift;
$text =~ s/[\r\n]+/\n/g;
$text =~ s/[^\n\t -~]/?/g;
$text =~ s/([\\"])/\\$1/g;
return sprintf "\"%s\"", $text;
}
sub screensize() {
my $params = `$DIALOG --stdout --print-maxsize`;
$params =~ s/\s+$//;
$params =~ s/^[^:]*:\s+//;
my @params = split /,\s+/, $params;
if ( $#params == 1 ) {
$scr_lines = $params[0];
$scr_cols = $params[1];
}
else {
$scr_lines = 24;
$scr_cols = 80;
}
}
sub height_of($$) {
my $width = shift;
my $message = shift;
my $command =
"$DIALOG --stdout --print-text-size "
. &quoted($message)
. " $scr_lines $width 2>&1";
my $params = `$command`;
my @params = split( /\s/, $params );
return $params[0];
}
sub rhs_clear {
return system("dialog --clear");
return system("$DIALOG --clear");
}
sub rhs_textbox {
local ( $title, $file, $width, $height ) = @_;
my ( $title, $file, $width, $height ) = @_;
system("dialog --title \"$title\" --textbox $file $height $width");
$width = int($width);
$height = int($height);
system( "$DIALOG --title "
. &quoted($title)
. " --textbox $file $height $width" );
return 1;
}
sub rhs_msgbox {
local ( $title, $message, $width ) = @_;
local ( $tmp, $height, $message_len );
my ( $title, $message, $width ) = @_;
my ( $tmp, $height );
$message = &rhs_wordwrap($message, $width);
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = 4 + $message_len;
$width = int($width);
$message = &rhs_wordwrap( $message, $width );
$height = 5 + &height_of( $width, $message );
$tmp = system("dialog --title \"$title\" --msgbox \"$message\" $height $width");
$tmp =
system( "$DIALOG --title "
. &quoted($title)
. " --msgbox "
. &quoted($message)
. " $height $width" );
if ($tmp) {
return 0;
} else {
return 1;
return 0;
}
else {
return 1;
}
}
sub rhs_infobox {
local ( $title, $message, $width ) = @_;
local ( $tmp, $height, $message_len );
my ( $title, $message, $width ) = @_;
my ( $tmp, $height );
$message = &rhs_wordwrap($message, $width);
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = 2 + $message_len;
$width = int($width);
$message = &rhs_wordwrap( $message, $width );
$height = 2 + &height_of( $width, $message );
return system("dialog --title \"$title\" --infobox \"$message\" $height $width");
return
system( "$DIALOG --title "
. &quoted($title)
. " --infobox "
. &quoted($message)
. " $height $width" );
}
sub rhs_yesno {
local ( $title, $message, $width ) = @_;
local ( $tmp, $height, $message_len );
my ( $title, $message, $width ) = @_;
my ( $tmp, $height );
$message = &rhs_wordwrap($message, $width);
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = 4 + $message_len;
$width = int($width);
$message = &rhs_wordwrap( $message, $width );
$height = 4 + &height_of( $width, $message );
$tmp =
system( "$DIALOG --title "
. &quoted($title)
. " --yesno "
. &quoted($message)
. " $height $width" );
$tmp = system("dialog --title \"$title\" --yesno \"$message\" $height $width");
# Dumb: dialog returns 0 for "yes" and 1 for "no"
if (! $tmp) {
return 1;
} else {
return 0;
if ( !$tmp ) {
return 1;
}
else {
return 0;
}
}
sub rhs_gauge {
local ( $title, $message, $width, $percent ) = @_;
local ( $tmp, $height, $message_len );
my ( $title, $message, $width, $percent ) = @_;
my ( $tmp, $height );
$width = int($width);
$gauge_width = $width;
$message = &rhs_wordwrap($message, $width);
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = 5 + $message_len;
$message = &rhs_wordwrap( $message, $width );
$height = 5 + &height_of( $width, $message );
open(GAUGE, "|dialog --title \"$title\" --gauge \"$message\" $height $width $percent");
open( $GAUGE,
"|$DIALOG --title "
. &quoted($title)
. " --gauge "
. &quoted($message)
. " $height $width $percent" );
}
sub rhs_update_gauge {
local ( $percent ) = @_;
my ($percent) = @_;
&printflush(GAUGE, "$percent\n");
&printflush( $GAUGE, "$percent\n" );
}
sub rhs_update_gauge_and_message {
local ( $message, $percent ) = @_;
my ( $message, $percent ) = @_;
$message = &rhs_wordwrap($message, $gauge_width);
$message = &rhs_wordwrap( $message, $gauge_width );
$message =~ s/\n/\\n/g;
&printflush(GAUGE, "XXX\n$percent\n$message\nXXX\n");
&printflush( $GAUGE, "XXX\n$percent\n$message\nXXX\n" );
}
sub rhs_stop_gauge {
close GAUGE;
close $GAUGE;
}
sub rhs_inputbox {
local ( $title, $message, $width, $instr ) = @_;
local ( $tmp, $height, $message_len );
my ( $title, $message, $width, $instr ) = @_;
my ( $tmp, $height );
$message = &rhs_wordwrap($message, $width);
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = 7 + $message_len;
$width = int($width);
$message = &rhs_wordwrap( $message, $width );
$height = 7 + &height_of( $width, $message );
return &return_output(0, "dialog --title \"$title\" --inputbox \"$message\" $height $width \"$instr\"");
return &return_output( 0,
"$DIALOG --title "
. &quoted($title)
. " --inputbox "
. &quoted($message)
. " $height $width "
. &quoted($instr) );
}
sub rhs_menu {
local ( $title, $message, $width, $numitems ) = @_;
local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
my ( $title, $message, $width, $numitems ) = @_;
my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
shift; shift; shift; shift;
$width = int($width);
$numitems = int($numitems);
shift;
shift;
shift;
shift;
@list = ();
for ($i = 0; $i < $numitems; $i++) {
$ent = shift;
$list[@list] = "\"$ent\"";
$ent = shift;
$list[@list] = "\"$ent\"";
for ( $i = 0 ; $i < $numitems ; $i++ ) {
$ent = shift;
$list[@list] = &quoted($ent);
$ent = shift;
$list[@list] = &quoted($ent);
}
$message = &rhs_wordwrap($message, $width);
$message = &rhs_wordwrap( $message, $width );
$listheight = &height_of( $width, $message );
$height = 6 + $listheight + $numitems;
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = $message_len + 6 + $numitems;
if ($height <= $scr_lines) {
if ( $height <= $scr_lines ) {
$menuheight = $numitems;
} else {
$height = $scr_lines;
$menuheight = $scr_lines - $message_len - 6;
}
else {
$height = $scr_lines;
$menuheight = $scr_lines - $listheight - 6;
}
return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
return &return_output( 0,
"$DIALOG --title "
. &quoted($title)
. " --menu "
. &quoted($message)
. " $height $width $menuheight @list" );
}
sub rhs_menul {
local ( $title, $message, $width, $numitems ) = @_;
local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
my ( $title, $message, $width, $numitems ) = @_;
my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
shift; shift; shift; shift;
$width = int($width);
$numitems = int($numitems);
shift;
shift;
shift;
shift;
@list = ();
for ($i = 0; $i < $numitems; $i++) {
$ent = shift;
$list[@list] = "\"$ent\"";
$list[@list] = "\"\"";
for ( $i = 0 ; $i < $numitems ; $i++ ) {
$ent = shift;
$list[@list] = &quoted($ent);
$list[@list] = &quoted("");
}
$message = &rhs_wordwrap($message, $width);
$message = &rhs_wordwrap( $message, $width );
$listheight = &height_of( $width, $message );
$height = 6 + $listheight + $numitems;
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = $message_len + 6 + $numitems;
if ($height <= $scr_lines) {
if ( $height <= $scr_lines ) {
$menuheight = $numitems;
} else {
$height = $scr_lines;
$menuheight = $scr_lines - $message_len - 6;
}
else {
$height = $scr_lines;
$menuheight = $scr_lines - $listheight - 6;
}
return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
return &return_output( 0,
"$DIALOG --title "
. &quoted($title)
. " --menu "
. &quoted($message)
. " $height $width $menuheight @list" );
}
sub rhs_menua {
local ( $title, $message, $width, %items ) = @_;
local ( $tmp, $ent, $height, $menuheight, @list, $message_len );
my ( $title, $message, $width, %items ) = @_;
my ( $tmp, $ent, $height, $listheight, $menuheight, @list );
@list = ();
foreach $ent (sort keys (%items)) {
$list[@list] = "\"$ent\"";
$list[@list] = "\"$items{$ent}\"";
$width = int($width);
@list = ();
foreach $ent ( sort keys(%items) ) {
$list[@list] = &quoted($ent);
$list[@list] = &quoted( $items{$ent} );
}
$message = &rhs_wordwrap($message, $width);
my $numitems = keys(%items);
$message = &rhs_wordwrap( $message, $width );
$listheight = &height_of( $width, $message );
$height = 6 + $listheight + $numitems;
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$numitems = keys(%items);
$height = $message_len + 6 + $numitems;
if ($height <= $scr_lines) {
if ( $height <= $scr_lines ) {
$menuheight = $numitems;
} else {
$height = $scr_lines;
$menuheight = $scr_lines - $message_len - 6;
}
else {
$height = $scr_lines;
$menuheight = $scr_lines - $listheight - 6;
}
return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
return &return_output( 0,
"$DIALOG --title "
. &quoted($title)
. " --menu "
. &quoted($message)
. " $height $width $menuheight @list" );
}
sub rhs_checklist {
local ( $title, $message, $width, $numitems ) = @_;
local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
my ( $title, $message, $width, $numitems ) = @_;
my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
shift; shift; shift; shift;
$width = int($width);
$numitems = int($numitems);
shift;
shift;
shift;
shift;
@list = ();
for ($i = 0; $i < $numitems; $i++) {
$ent = shift;
$list[@list] = "\"$ent\"";
$ent = shift;
$list[@list] = "\"$ent\"";
$ent = shift;
if ($ent) {
$list[@list] = "ON";
} else {
$list[@list] = "OFF";
}
for ( $i = 0 ; $i < $numitems ; $i++ ) {
$ent = shift;
$list[@list] = &quoted($ent);
$ent = shift;
$list[@list] = &quoted($ent);
$ent = shift;
if ($ent) {
$list[@list] = "ON";
}
else {
$list[@list] = "OFF";
}
}
$message = &rhs_wordwrap($message, $width);
$message = &rhs_wordwrap( $message, $width );
$listheight = &height_of( $width, $message );
$height = 6 + $listheight + $numitems;
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = $message_len + 6 + $numitems;
if ($height <= $scr_lines) {
if ( $height <= $scr_lines ) {
$menuheight = $numitems;
} else {
$height = $scr_lines;
$menuheight = $scr_lines - $message_len - 6;
}
else {
$height = $scr_lines;
$menuheight = $scr_lines - $listheight - 6;
}
return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
return &return_output( "list",
"$DIALOG --title "
. &quoted($title)
. " --separate-output --checklist "
. &quoted($message)
. " $height $width $menuheight @list" );
}
sub rhs_checklistl {
local ( $title, $message, $width, $numitems ) = @_;
local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
my ( $title, $message, $width, $numitems ) = @_;
my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
shift; shift; shift; shift;
$width = int($width);
$numitems = int($numitems);
shift;
shift;
shift;
shift;
@list = ();
for ($i = 0; $i < $numitems; $i++) {
$ent = shift;
$list[@list] = "\"$ent\"";
$list[@list] = "\"\"";
$list[@list] = "OFF";
for ( $i = 0 ; $i < $numitems ; $i++ ) {
$ent = shift;
$list[@list] = &quoted($ent);
$list[@list] = &quoted("");
$list[@list] = "OFF";
}
$message = &rhs_wordwrap($message, $width);
$message = &rhs_wordwrap( $message, $width );
$listheight = &height_of( $width, $message );
$height = 6 + $listheight + $numitems;
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = $message_len + 6 + $numitems;
if ($height <= $scr_lines) {
if ( $height <= $scr_lines ) {
$menuheight = $numitems;
} else {
$height = $scr_lines;
$menuheight = $scr_lines - $message_len - 6;
}
return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
else {
$height = $scr_lines;
$menuheight = $scr_lines - $listheight - 6;
}
return &return_output( "list",
"$DIALOG --title "
. &quoted($title)
. " --separate-output --checklist "
. &quoted($message)
. " $height $width $menuheight @list" );
}
sub rhs_checklista {
local ( $title, $message, $width, %items ) = @_;
local ( $tmp, $ent, $height, $menuheight, @list, $message_len );
my ( $title, $message, $width, %items ) = @_;
my ( $tmp, $ent, $height, $listheight, $menuheight, @list );
shift; shift; shift; shift;
shift;
shift;
shift;
shift;
@list = ();
foreach $ent (sort keys (%items)) {
$list[@list] = "\"$ent\"";
$list[@list] = "\"$items{$ent}\"";
$list[@list] = "OFF";
foreach $ent ( sort keys(%items) ) {
$list[@list] = &quoted($ent);
$list[@list] = &quoted( $items{$ent} );
$list[@list] = "OFF";
}
$message = &rhs_wordwrap($message, $width);
my $numitems = keys(%items);
$message = &rhs_wordwrap( $message, $width );
$listheight = &height_of( $width, $message );
$height = 6 + $listheight + $numitems;
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$numitems = keys(%items);
$height = $message_len + 6 + $numitems;
if ($height <= $scr_lines) {
if ( $height <= $scr_lines ) {
$menuheight = $numitems;
} else {
$height = $scr_lines;
$menuheight = $scr_lines - $message_len - 6;
}
else {
$height = $scr_lines;
$menuheight = $scr_lines - $listheight - 6;
}
return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
return &return_output( "list",
"$DIALOG --title "
. &quoted($title)
. " --separate-output --checklist "
. &quoted($message)
. " $height $width $menuheight @list" );
}
sub rhs_radiolist {
local ( $title, $message, $width, $numitems ) = @_;
local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );
my ( $title, $message, $width, $numitems ) = @_;
my ( $i, $tmp, $ent, $height, $listheight, $menuheight, @list );
shift; shift; shift; shift;
$width = int($width);
$numitems = int($numitems);
shift;
shift;
shift;
shift;
@list = ();
for ($i = 0; $i < $numitems; $i++) {
$ent = shift;
$list[@list] = "\"$ent\"";
$ent = shift;
$list[@list] = "\"$ent\"";
$ent = shift;
if ($ent) {
$list[@list] = "ON";
} else {
$list[@list] = "OFF";
}
for ( $i = 0 ; $i < $numitems ; $i++ ) {
$ent = shift;
$list[@list] = &quoted($ent);
$ent = shift;
$list[@list] = &quoted($ent);
$ent = shift;
if ($ent) {
$list[@list] = "ON";
}
else {
$list[@list] = "OFF";
}
}
$message = &rhs_wordwrap($message, $width);
$message = &rhs_wordwrap( $message, $width );
$listheight = &height_of( $width, $message );
$height = 6 + $listheight + $numitems;
$message_len = split(/^/, $message);
$tmp = $message;
if (chop($tmp) eq "\n") {
$message_len++;
}
$height = $message_len + 6 + $numitems;
if ($height <= $scr_lines) {
if ( $height <= $scr_lines ) {
$menuheight = $numitems;
} else {
$height = $scr_lines;
$menuheight = $scr_lines - $message_len - 6;
}
else {
$height = $scr_lines;
$menuheight = $scr_lines - $listheight - 6;
}
return &return_output(0 , "dialog --title \"$title\" --radiolist \"$message\" $height $width $menuheight @list");
return &return_output( 0,
"$DIALOG --title "
. &quoted($title)
. " --radiolist "
. &quoted($message)
. " $height $width $menuheight @list" );
}
sub return_output {
local ( $listp, $command ) = @_;
local ( $res ) = 1;
my ( $listp, $command ) = @_;
my ($res) = 1;
pipe( PARENT_READER, CHILD_WRITER );
pipe(PARENT_READER, CHILD_WRITER);
# We have to fork (as opposed to using "system") so that the parent
# process can read from the pipe to avoid deadlock.
my ($pid) = fork;
if ($pid == 0) { # child
close(PARENT_READER);
open(STDERR, ">&CHILD_WRITER");
exec($command);
die("no exec");
if ( $pid == 0 ) { # child
close(PARENT_READER);
open( STDERR, ">&CHILD_WRITER" );
exec($command);
die("no exec");
}
if ($pid > 0) { # parent
close( CHILD_WRITER );
if ($listp) {
@dialog_result = ();
while (<PARENT_READER>) {
chop;
$dialog_result[@dialog_result] = $_;
}
}
else { $dialog_result = <PARENT_READER>; }
close(PARENT_READER);
waitpid($pid,0);
$res = $?;
if ( $pid > 0 ) { # parent
close(CHILD_WRITER);
if ($listp) {
@dialog_result = ();
while (<PARENT_READER>) {
chop;
$dialog_result[@dialog_result] = $_;
}
}
else {
@dialog_result = <PARENT_READER>;
}
close(PARENT_READER);
waitpid( $pid, 0 );
$res = $?;
}
# Again, dialog returns results backwards
if (! $res) {
return 1;
} else {
return 0;
if ( !$res ) {
return 1;
}
else {
return 0;
}
}
sub rhs_wordwrap {
local ( $intext, $width ) = @_;
local ( $outtext, $i, $j, @lines, $wrap, @words, $pos, $pad );
my ( $intext, $width ) = @_;
my ( $outtext, $i, $j, @lines, $wrap, @words, $pos, $pad );
&trace( "rhs_wordwrap\n\tintext:%s\n\twidth:%d\n", $intext, $width );
&screensize;
$width = int($width);
$outtext = "";
$pad = 3; # leave 3 spaces around each line
$pos = $pad; # current insert position
$wrap = 0; # 1 if we have been auto wraping
$insert_nl = 0; # 1 if we just did an absolute
# and we should preface any new text
# with a new line
@lines = split(/\n/, $intext);
for ($i = 0; $i <= $#lines; $i++) {
if ($lines[$i] =~ /^>/) {
$outtext .= "\n" if ($insert_nl);
$pad = 3; # leave 3 spaces around each line
$pos = $pad; # current insert position
$wrap = 0; # 1 if we have been auto wrapping
my $insert_nl = 0; # 1 if we just did an absolute
# and we should preface any new text
# with a new line
@lines = split( /\n/, $intext );
for ( $i = 0 ; $i <= $#lines ; $i++ ) {
if ( $lines[$i] =~ /^>/ ) {
$outtext .= "\n" if ($insert_nl);
$outtext .= "\n" if ($wrap);
$lines[$i] =~ /^>(.*)$/;
$lines[$i] =~ /^>(.*)$/;
$outtext .= $1;
$insert_nl = 1;
$wrap = 0;
$pos = $pad;
} else {
$insert_nl = 1;
$wrap = 0;
$pos = $pad;
}
else {
$wrap = 1;
@words = split(/\s+/,$lines[$i]);
for ($j = 0; $j <= $#words; $j++) {
if ($insert_nl) {
$outtext .= "\n";
$insert_nl = 0;
}
if ((length($words[$j]) + $pos) > $width - $pad) {
@words = split( /\s+/, $lines[$i] );
for ( $j = 0 ; $j <= $#words ; $j++ ) {
if ($insert_nl) {
$outtext .= "\n";
$insert_nl = 0;
}
if ( ( length( $words[$j] ) + $pos ) > $width - $pad ) {
$outtext .= "\n";
$pos = $pad;
}
$outtext .= $words[$j] . " ";
$pos += length($words[$j]) + 1;
$pos += length( $words[$j] ) + 1;
}
}
}
&trace( "\touttext:%s\n", $outtext );
return $outtext;
}

View File

@ -1,9 +1,9 @@
/*
* $Id: dlg_keys.c,v 1.34 2011/10/14 00:41:08 tom Exp $
* $Id: dlg_keys.c,v 1.45 2018/05/28 17:27:10 tom Exp $
*
* dlg_keys.c -- runtime binding support for dialog
*
* Copyright 2006-2009,2011 Thomas E. Dickey
* Copyright 2006-2017,2018 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
@ -26,6 +26,10 @@
#define LIST_BINDINGS struct _list_bindings
#define CHR_BACKSLASH '\\'
#define IsOctal(ch) ((ch) >= '0' && (ch) <= '7')
#define TableSize(name) (sizeof(name)/sizeof(name[0]))
LIST_BINDINGS {
LIST_BINDINGS *link;
WINDOW *win; /* window on which widget gets input */
@ -57,10 +61,11 @@ dlg_register_window(WINDOW *win, const char *name, DLG_KEYS_BINDING * binding)
p->win = win;
p->name = name;
p->binding = binding;
if (q != 0)
if (q != 0) {
q->link = p;
else
} else {
all_bindings = p;
}
}
#if defined(HAVE_DLG_TRACE) && defined(HAVE_RC_FILE)
/*
@ -70,8 +75,10 @@ dlg_register_window(WINDOW *win, const char *name, DLG_KEYS_BINDING * binding)
* registered, there is no other way to see what bindings are available,
* than by running dialog and tracing it.
*/
dlg_trace_msg("# dlg_register_window %s\n", name);
DLG_TRACE(("# dlg_register_window %s\n", name));
dlg_dump_keys(dialog_state.trace_output);
dlg_dump_window_keys(dialog_state.trace_output, win);
DLG_TRACE(("# ...done dlg_register_window %s\n", name));
#endif
}
@ -194,8 +201,8 @@ dlg_unregister_window(WINDOW *win)
* Parameters:
* win is the window on which the wgetch() was done.
* curses_key is the value returned by wgetch().
* fkey in/out (on input, it is true if curses_key is a function key,
* and on output, it is true if the result is a function key).
* fkey in/out (on input, it is nonzero if curses_key is a function key,
* and on output, it is nonzero if the result is a function key).
*/
int
dlg_lookup_key(WINDOW *win, int curses_key, int *fkey)
@ -230,7 +237,9 @@ dlg_lookup_key(WINDOW *win, int curses_key, int *fkey)
}
}
for (p = all_bindings; p != 0; p = p->link) {
if (p->win == win || (p->win == 0 && !strcmp(p->name, name))) {
if (p->win == win ||
(p->win == 0 &&
(!strcmp(p->name, name) || !strcmp(p->name, WILDNAME)))) {
int function_key = (*fkey != 0);
for (q = p->binding; q->is_function_key >= 0; ++q) {
if (p->buttons
@ -318,7 +327,7 @@ typedef struct {
#define ASCII_NAME(name,code) { #name, code }
#define CURSES_NAME(upper) { #upper, KEY_ ## upper }
#define COUNT_CURSES sizeof(curses_names)/sizeof(curses_names[0])
#define COUNT_CURSES TableSize(curses_names)
static const CODENAME curses_names[] =
{
ASCII_NAME(ESC, '\033'),
@ -417,7 +426,7 @@ static const CODENAME curses_names[] =
};
#define DIALOG_NAME(upper) { #upper, DLGK_ ## upper }
#define COUNT_DIALOG sizeof(dialog_names)/sizeof(dialog_names[0])
#define COUNT_DIALOG TableSize(dialog_names)
static const CODENAME dialog_names[] =
{
DIALOG_NAME(OK),
@ -453,9 +462,29 @@ static const CODENAME dialog_names[] =
DIALOG_NAME(FINAL),
DIALOG_NAME(SELECT),
DIALOG_NAME(HELPFILE),
DIALOG_NAME(TRACE)
DIALOG_NAME(TRACE),
DIALOG_NAME(TOGGLE)
};
#define MAP2(letter,actual) { letter, actual }
static const struct {
int letter;
int actual;
} escaped_letters[] = {
MAP2('a', DLG_CTRL('G')),
MAP2('b', DLG_CTRL('H')),
MAP2('f', DLG_CTRL('L')),
MAP2('n', DLG_CTRL('J')),
MAP2('r', DLG_CTRL('M')),
MAP2('s', CHR_SPACE),
MAP2('t', DLG_CTRL('I')),
MAP2('\\', '\\'),
};
#undef MAP2
static char *
skip_white(char *s)
{
@ -574,8 +603,52 @@ make_binding(char *widget, int curses_key, int is_function, int dialog_key)
return result;
}
static int
decode_escaped(char **string)
{
unsigned n;
int result = 0;
if (IsOctal(**string)) {
int limit = 3;
while (limit-- > 0 && IsOctal(**string)) {
int ch = (**string);
*string += 1;
result = (result << 3) | (ch - '0');
}
} else {
for (n = 0; n < TableSize(escaped_letters); ++n) {
if (**string == escaped_letters[n].letter) {
*string += 1;
result = escaped_letters[n].actual;
break;
}
}
}
return result;
}
static char *
encode_escaped(int value)
{
static char result[80];
unsigned n;
bool found = FALSE;
for (n = 0; n < TableSize(escaped_letters); ++n) {
if (value == escaped_letters[n].actual) {
found = TRUE;
sprintf(result, "%c", escaped_letters[n].letter);
break;
}
}
if (!found) {
sprintf(result, "%03o", value & 0xff);
}
return result;
}
/*
* Parse the parameters of the "bindkeys" configuration-file entry. This
* Parse the parameters of the "bindkey" configuration-file entry. This
* expects widget name which may be "*", followed by curses key definition and
* then dialog key definition.
*
@ -612,8 +685,8 @@ dlg_parse_bindkey(char *params)
while (*p != '\0' && curses_key < 0) {
if (escaped) {
escaped = FALSE;
curses_key = *p;
} else if (*p == '\\') {
curses_key = decode_escaped(&p);
} else if (*p == CHR_BACKSLASH) {
escaped = TRUE;
} else if (modified) {
if (*p == '?') {
@ -690,6 +763,12 @@ dump_curses_key(FILE *fp, int curses_key)
}
}
if (!found) {
#ifdef KEY_MOUSE
if (is_DLGK_MOUSE(curses_key)) {
fprintf(fp, "MOUSE-");
dump_curses_key(fp, curses_key - M_EVENT);
} else
#endif
if (curses_key >= KEY_F(0)) {
fprintf(fp, "F%d", curses_key - KEY_F(0));
} else {
@ -704,8 +783,12 @@ dump_curses_key(FILE *fp, int curses_key)
fprintf(fp, "~%c", curses_key - 64);
} else if (curses_key == 255) {
fprintf(fp, "~?");
} else if (curses_key > 32 &&
curses_key < 127 &&
curses_key != CHR_BACKSLASH) {
fprintf(fp, "%c", curses_key);
} else {
fprintf(fp, "\\%c", curses_key);
fprintf(fp, "%c%s", CHR_BACKSLASH, encode_escaped(curses_key));
}
}
@ -727,12 +810,28 @@ dump_dialog_key(FILE *fp, int dialog_key)
}
static void
dump_one_binding(FILE *fp, const char *widget, DLG_KEYS_BINDING * binding)
dump_one_binding(FILE *fp,
WINDOW *win,
const char *widget,
DLG_KEYS_BINDING * binding)
{
int actual;
int fkey = (binding->curses_key > 255);
fprintf(fp, "bindkey %s ", widget);
dump_curses_key(fp, binding->curses_key);
fputc(' ', fp);
dump_dialog_key(fp, binding->dialog_key);
actual = dlg_lookup_key(win, binding->curses_key, &fkey);
#ifdef KEY_MOUSE
if (is_DLGK_MOUSE(binding->curses_key) && is_DLGK_MOUSE(actual)) {
; /* EMPTY */
} else
#endif
if (actual != binding->dialog_key) {
fprintf(fp, "\t# overridden by ");
dump_dialog_key(fp, actual);
}
fputc('\n', fp);
}
@ -752,12 +851,13 @@ dlg_dump_window_keys(FILE *fp, WINDOW *win)
for (p = all_bindings; p != 0; p = p->link) {
if (p->win == win) {
if (dlg_strcmp(last, p->name)) {
fprintf(fp, "\n# key bindings for %s widgets\n",
!strcmp(p->name, WILDNAME) ? "all" : p->name);
fprintf(fp, "# key bindings for %s widgets%s\n",
!strcmp(p->name, WILDNAME) ? "all" : p->name,
win == 0 ? " (user-defined)" : "");
last = p->name;
}
for (q = p->binding; q->is_function_key >= 0; ++q) {
dump_one_binding(fp, p->name, q);
dump_one_binding(fp, win, p->name, q);
}
}
}

View File

@ -1,9 +1,9 @@
/*
* $Id: dlg_keys.h,v 1.32 2012/12/21 21:54:30 tom Exp $
* $Id: dlg_keys.h,v 1.36 2016/08/28 21:23:17 tom Exp $
*
* dlg_keys.h -- runtime binding support for dialog
*
* Copyright 2005-2011,2012 Thomas E. Dickey
* Copyright 2005-2012,2016 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
@ -96,7 +96,8 @@ typedef enum {
DLGK_FINAL,
DLGK_SELECT,
DLGK_HELPFILE,
DLGK_TRACE
DLGK_TRACE,
DLGK_TOGGLE
} DLG_KEYS_ENUM;
#define is_DLGK_MOUSE(code) ((code) >= M_EVENT)
@ -146,7 +147,7 @@ typedef enum {
DLG_KEYS_DATA( DLGK_PAGE_PREV, 'b' )
#define TRAVERSE_BINDINGS \
DLG_KEYS_DATA( DLGK_ENTER, ' ' ), \
DLG_KEYS_DATA( DLGK_ENTER, CHR_SPACE ), \
DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_DOWN ), \
DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), \
DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), \
@ -154,6 +155,9 @@ typedef enum {
DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), \
DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT )
#define TOGGLEKEY_BINDINGS \
DLG_KEYS_DATA( DLGK_TOGGLE, CHR_SPACE )
extern int dlg_lookup_key(WINDOW * /*win*/, int /*curses_key*/, int * /*dialog_key*/);
extern int dlg_result_key(int /*dialog_key*/, int /*fkey*/, int * /*resultp*/);
extern void dlg_register_buttons(WINDOW * /*win*/, const char * /*name*/, const char ** /*buttons*/);

View File

@ -1,9 +1,9 @@
/*
* $Id: editbox.c,v 1.62 2013/03/17 15:03:41 tom Exp $
* $Id: editbox.c,v 1.70 2018/06/19 22:57:01 tom Exp $
*
* editbox.c -- implements the edit box
*
* Copyright 2007-2012,2013 Thomas E. Dickey
* Copyright 2007-2016,2018 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
@ -69,7 +69,7 @@ load_list(const char *file, char ***list, int *rows)
dlg_exiterr("Not a file: %s", file);
size = (size_t) sb.st_size;
if ((blob = dlg_malloc(char, size + 1)) == 0) {
if ((blob = dlg_malloc(char, size + 2)) == 0) {
fail_list();
} else {
blob[size] = '\0';
@ -79,6 +79,14 @@ load_list(const char *file, char ***list, int *rows)
size = fread(blob, sizeof(char), size, fp);
fclose(fp);
/*
* If the file is not empty, ensure that it ends with a newline.
*/
if (size != 0 && blob[size - 1] != '\n') {
blob[++size - 1] = '\n';
blob[size] = '\0';
}
for (pass = 0; pass < 2; ++pass) {
int first = TRUE;
need = 0;
@ -318,6 +326,7 @@ dlg_editbox(const char *title,
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
NAVIGATE_BINDINGS,
TOGGLEKEY_BINDINGS,
END_KEYS_BINDING
};
static DLG_KEYS_BINDING binding2[] = {
@ -325,6 +334,7 @@ dlg_editbox(const char *title,
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
NAVIGATE_BINDINGS,
/* no TOGGLEKEY_BINDINGS, since that includes space... */
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -354,6 +364,12 @@ dlg_editbox(const char *title,
const char **buttons = dlg_ok_labels();
int mincols = (3 * COLS / 4);
DLG_TRACE(("# editbox args:\n"));
DLG_TRACE2S("title", title);
/* FIXME dump the rows & list */
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
dlg_save_vars(&save_vars);
dialog_vars.separate_output = TRUE;
@ -389,7 +405,7 @@ dlg_editbox(const char *title,
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
/* Draw the editing field in a box */
box_y = MARGIN + 0;
@ -517,13 +533,18 @@ dlg_editbox(const char *title,
&& (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;
int check = (cell / wide) + base_row;
if (check < listsize) {
thisrow = check;
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;
}
} else {
beep();
}
continue;
} else if (was_mouse && key >= KEY_MIN) {
@ -637,10 +658,14 @@ dlg_editbox(const char *title,
/* handle functionkeys */
if (fkey) {
switch (key) {
case DLGK_GRID_UP:
case DLGK_GRID_LEFT:
case DLGK_FIELD_PREV:
show_buttons = TRUE;
state = dlg_prev_ok_buttonindex(state, sTEXT);
break;
case DLGK_GRID_RIGHT:
case DLGK_GRID_DOWN:
case DLGK_FIELD_NEXT:
show_buttons = TRUE;
state = dlg_next_ok_buttonindex(state, sTEXT);
@ -670,27 +695,31 @@ dlg_editbox(const char *title,
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
/* repaint */
dlg_clear();
dlg_unregister_window(editing);
dlg_del_window(editing);
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
/* repaint */
goto retry;
#endif
case DLGK_TOGGLE:
if (state != sTEXT) {
result = dlg_ok_buttoncode(state);
} else {
beep();
}
break;
default:
beep();
break;
}
} else {
if ((key == ' ') && (state != sTEXT)) {
result = dlg_ok_buttoncode(state);
} else {
beep();
}
beep();
}
}

View File

@ -1,9 +1,9 @@
/*
* $Id: formbox.c,v 1.87 2013/09/02 17:02:05 tom Exp $
* $Id: formbox.c,v 1.95 2018/06/21 08:23:31 tom Exp $
*
* formbox.c -- implements the form (i.e, some pairs label/editbox)
* formbox.c -- implements the form (i.e., some pairs label/editbox)
*
* Copyright 2003-2012,2013 Thomas E. Dickey
* Copyright 2003-2016,2018 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
@ -447,9 +447,11 @@ prev_valid_buttonindex(int state, int extra, bool non_editable)
DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), \
DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ), \
DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), \
DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_RIGHT ), \
DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_NEXT ), \
DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ), \
DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_PREVIOUS ), \
DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_LEFT ), \
DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), \
DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), \
DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE )
@ -471,6 +473,7 @@ dlg_form(const char *title,
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
NAVIGATE_BINDINGS,
TOGGLEKEY_BINDINGS,
END_KEYS_BINDING
};
static DLG_KEYS_BINDING binding2[] = {
@ -478,6 +481,7 @@ dlg_form(const char *title,
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
NAVIGATE_BINDINGS,
/* no TOGGLEKEY_BINDINGS, since that includes space... */
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -488,10 +492,12 @@ dlg_form(const char *title,
#endif
int form_width;
int first = TRUE;
int first_trace = TRUE;
bool first = TRUE;
bool first_trace = TRUE;
int chr_offset = 0;
int state = dialog_vars.default_button >= 0 ? dlg_default_button() : sTEXT;
int state = (dialog_vars.default_button >= 0
? dlg_default_button()
: sTEXT);
int x, y, cur_x, cur_y, box_x, box_y;
int code;
int key = 0;
@ -507,19 +513,32 @@ dlg_form(const char *title,
bool field_changed = FALSE;
bool non_editable = FALSE;
WINDOW *dialog, *form;
char *prompt = dlg_strclone(cprompt);
char *prompt;
const char **buttons = dlg_ok_labels();
DIALOG_FORMITEM *current;
DLG_TRACE(("# %sform args:\n", (dialog_vars.formitem_type
? "password"
: "")));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("lheight", form_height);
DLG_TRACE2N("llength", item_no);
/* FIXME dump the items[][] too */
DLG_TRACE2N("current", *current_item);
make_FORM_ELTs(items, item_no, &min_height, &min_width);
dlg_button_layout(buttons, &min_width);
dlg_does_output();
dlg_tab_correct_str(prompt);
#ifdef KEY_RESIZE
retry:
#endif
prompt = dlg_strclone(cprompt);
dlg_tab_correct_str(prompt);
dlg_auto_size(title, prompt, &height, &width,
1 + 3 * MARGIN,
MAX(26, 2 + min_width));
@ -554,7 +573,7 @@ dlg_form(const char *title,
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
form_width = width - 6;
@ -651,10 +670,6 @@ dlg_form(const char *title,
result = dlg_ok_buttoncode(code);
continue;
}
if (key == ' ') {
fkey = TRUE;
key = DLGK_ENTER;
}
}
}
@ -677,6 +692,7 @@ dlg_form(const char *title,
move_by = form_height;
break;
case DLGK_TOGGLE:
case DLGK_ENTER:
dlg_del_window(dialog);
result = (state >= 0) ? dlg_enter_buttoncode(state) : DLG_EXIT_OK;
@ -759,14 +775,16 @@ dlg_form(const char *title,
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
/* repaint */
free(prompt);
dlg_clear();
dlg_unregister_window(form);
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
/* repaint */
goto retry;
#endif
default:
@ -861,6 +879,7 @@ dlg_form(const char *title,
}
dlg_mouse_free_regions();
dlg_unregister_window(form);
dlg_del_window(dialog);
free(prompt);
@ -910,7 +929,7 @@ dialog_form(const char *title,
char **items)
{
int result;
int choice;
int choice = 0;
int i;
DIALOG_FORMITEM *listitems;
DIALOG_VARS save_vars;

View File

@ -1,9 +1,9 @@
/*
* $Id: fselect.c,v 1.93 2012/12/30 20:52:25 tom Exp $
* $Id: fselect.c,v 1.102 2018/06/21 23:28:04 tom Exp $
*
* fselect.c -- implements the file-selector box
*
* Copyright 2000-2011,2012 Thomas E. Dickey
* Copyright 2000-2017,2018 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
@ -230,11 +230,11 @@ display_list(LIST * list)
break;
(void) wmove(list->win, y, 0);
if (n == list->choice)
(void) wattrset(list->win, item_selected_attr);
dlg_attrset(list->win, item_selected_attr);
(void) waddstr(list->win, list->data[n]);
(void) wattrset(list->win, item_attr);
dlg_attrset(list->win, item_attr);
}
(void) wattrset(list->win, item_attr);
dlg_attrset(list->win, item_attr);
getparyx(list->win, y, x);
@ -290,10 +290,10 @@ fix_arrows(LIST * list)
}
}
static int
show_list(char *target, LIST * list, int keep)
static bool
show_list(char *target, LIST * list, bool keep)
{
int changed = keep || find_choice(target, list);
bool changed = keep || find_choice(target, list);
display_list(list);
return changed;
}
@ -302,12 +302,12 @@ show_list(char *target, LIST * list, int keep)
* Highlight the closest match to 'target' in the given list, setting offset
* to match.
*/
static int
show_both_lists(char *input, LIST * d_list, LIST * f_list, int keep)
static bool
show_both_lists(char *input, LIST * d_list, LIST * f_list, bool keep)
{
char *leaf = leaf_of(input);
return show_list(leaf, d_list, keep) | show_list(leaf, f_list, keep);
return show_list(leaf, d_list, keep) || show_list(leaf, f_list, keep);
}
/*
@ -429,7 +429,7 @@ complete(char *name, LIST * d_list, LIST * f_list, char **buff_ptr)
}
static bool
fill_lists(char *current, char *input, LIST * d_list, LIST * f_list, int keep)
fill_lists(char *current, char *input, LIST * d_list, LIST * f_list, bool keep)
{
bool result = TRUE;
bool rescan = FALSE;
@ -475,10 +475,14 @@ fill_lists(char *current, char *input, LIST * d_list, LIST * f_list, int keep)
strcpy(path, "./");
leaf = path + strlen(path);
}
dlg_trace_msg("opendir '%s'\n", path);
DLG_TRACE(("opendir '%s'\n", path));
if ((dp = opendir(path)) != 0) {
while ((de = readdir(dp)) != 0) {
strncpy(leaf, de->d_name, NAMLEN(de))[NAMLEN(de)] = 0;
size_t len = NAMLEN(de);
if (len == 0 || (len + have + 2) >= MAX_LEN)
continue;
memcpy(leaf, de->d_name, len);
leaf[len] = '\0';
if (stat(path, &sb) == 0) {
if ((sb.st_mode & S_IFMT) == S_IFDIR)
add_to_list(d_list, leaf);
@ -557,6 +561,7 @@ dlg_fselect(const char *title, const char *path, int height, int width, int dsel
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
NAVIGATE_BINDINGS,
TOGGLEKEY_BINDINGS,
END_KEYS_BINDING
};
static DLG_KEYS_BINDING binding2[] = {
@ -564,6 +569,7 @@ dlg_fselect(const char *title, const char *path, int height, int width, int dsel
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
NAVIGATE_BINDINGS,
TOGGLEKEY_BINDINGS,
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -584,8 +590,8 @@ dlg_fselect(const char *title, const char *path, int height, int width, int dsel
int result = DLG_EXIT_UNKNOWN;
int state = dialog_vars.default_button >= 0 ? dlg_default_button() : sTEXT;
int button;
int first = (state == sTEXT);
int first_trace = TRUE;
bool first = (state == sTEXT);
bool first_trace = TRUE;
char *input;
char *completed;
char current[MAX_LEN + 1];
@ -600,6 +606,12 @@ dlg_fselect(const char *title, const char *path, int height, int width, int dsel
int min_items = height ? 0 : 4;
LIST d_list, f_list;
DLG_TRACE(("# %s args:\n", dselect ? "dselect" : "fselect"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("path", path);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
dlg_does_output();
/* Set up the initial value */
@ -631,7 +643,7 @@ dlg_fselect(const char *title, const char *path, int height, int width, int dsel
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
/* Draw the input field box */
tbox_height = 1;
@ -713,7 +725,7 @@ dlg_fselect(const char *title, const char *path, int height, int width, int dsel
if (resized) {
resized = FALSE;
dlg_show_string(w_text, input, offset, inputbox_attr,
0, 0, tbox_width, (bool) 0, (bool) first);
0, 0, tbox_width, FALSE, first);
}
#endif
@ -755,7 +767,7 @@ dlg_fselect(const char *title, const char *path, int height, int width, int dsel
break;
}
if (!fkey && key == ' ') {
if (key == DLGK_TOGGLE) {
key = DLGK_SELECT;
fkey = TRUE;
}
@ -841,6 +853,7 @@ dlg_fselect(const char *title, const char *path, int height, int width, int dsel
continue;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;

41
guage.c
View File

@ -1,9 +1,9 @@
/*
* $Id: guage.c,v 1.68 2013/09/22 19:10:22 tom Exp $
* $Id: guage.c,v 1.76 2018/06/21 08:23:43 tom Exp $
*
* guage.c -- implements the gauge dialog
*
* Copyright 2000-2012,2013 Thomas E. Dickey
* Copyright 2000-2015,2018 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
@ -121,14 +121,14 @@ repaint_text(MY_OBJ * obj)
WINDOW *dialog = obj->obj.win;
int i, x;
if (dialog != 0 && obj->obj.input != 0) {
if (dialog != 0) {
(void) werase(dialog);
dlg_draw_box2(dialog, 0, 0, obj->height, obj->width, dialog_attr,
border_attr, border2_attr);
dlg_draw_title(dialog, obj->title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_draw_helpline(dialog, FALSE);
dlg_print_autowrap(dialog, obj->prompt, obj->height, obj->width);
@ -145,7 +145,7 @@ repaint_text(MY_OBJ * obj)
* attribute.
*/
(void) wmove(dialog, obj->height - 3, 4);
(void) wattrset(dialog, gauge_attr);
dlg_attrset(dialog, gauge_attr);
for (i = 0; i < (obj->width - 2 * (3 + MARGIN)); i++)
(void) waddch(dialog, ' ');
@ -160,9 +160,9 @@ repaint_text(MY_OBJ * obj)
*/
x = (obj->percent * (obj->width - 2 * (3 + MARGIN))) / 100;
if ((gauge_attr & A_REVERSE) != 0) {
wattroff(dialog, A_REVERSE);
dlg_attroff(dialog, A_REVERSE);
} else {
(void) wattrset(dialog, A_REVERSE);
dlg_attrset(dialog, A_REVERSE);
}
(void) wmove(dialog, obj->height - 3, 4);
for (i = 0; i < x; i++) {
@ -182,11 +182,13 @@ handle_input(DIALOG_CALLBACK * cb)
{
MY_OBJ *obj = (MY_OBJ *) cb;
bool result;
bool cleanup = FALSE;
int status;
char buf[MY_LEN + 1];
if (dialog_state.pipe_input == 0) {
status = -1;
cleanup = TRUE;
} else if ((status = read_data(buf, dialog_state.pipe_input)) > 0) {
if (isMarker(buf)) {
@ -222,16 +224,19 @@ handle_input(DIALOG_CALLBACK * cb)
} else {
if (feof(dialog_state.pipe_input) ||
(ferror(dialog_state.pipe_input) && errno != EINTR)) {
delink(obj);
dlg_remove_callback(cb);
cleanup = TRUE;
}
}
repaint_text(obj);
if (status > 0) {
result = TRUE;
repaint_text(obj);
} else {
result = FALSE;
if (cleanup) {
dlg_remove_callback(cb);
delink(obj);
}
}
return result;
@ -240,7 +245,7 @@ handle_input(DIALOG_CALLBACK * cb)
static bool
handle_my_getc(DIALOG_CALLBACK * cb, int ch, int fkey, int *result)
{
int status = TRUE;
bool status = TRUE;
*result = DLG_EXIT_OK;
if (cb != 0) {
@ -265,6 +270,8 @@ my_cleanup(DIALOG_CALLBACK * cb)
free(obj->prompt);
obj->prompt = obj->prompt_buf;
}
free(obj->title);
dlg_del_window(obj->obj.win);
delink(obj);
}
}
@ -369,12 +376,12 @@ dlg_free_gauge(void *objptr)
{
MY_OBJ *obj = (MY_OBJ *) objptr;
curs_set(1);
if (valid(obj)) {
delink(obj);
obj->obj.keep_win = FALSE;
dlg_remove_callback(&(obj->obj));
delink(obj);
}
curs_set(1);
}
/*
@ -397,6 +404,13 @@ dialog_gauge(const char *title,
void *objptr = dlg_allocate_gauge(title, cprompt, height, width, percent);
MY_OBJ *obj = (MY_OBJ *) objptr;
DLG_TRACE(("# gauge args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("percent", percent);
dlg_add_callback_ref((DIALOG_CALLBACK **) & obj, my_cleanup);
dlg_update_gauge(obj, percent);
@ -407,6 +421,7 @@ dialog_gauge(const char *title,
if (fkey && ch == KEY_RESIZE) {
MY_OBJ *oldobj = obj;
dlg_will_resize(obj->obj.win);
dlg_mouse_free_regions();
obj = dlg_allocate_gauge(title,

103
headers.sh Executable file
View File

@ -0,0 +1,103 @@
#! /bin/sh
# $Id: headers.sh,v 1.3 2007/02/25 20:37:56 tom Exp $
##############################################################################
# Copyright (c) 2004,2007 Thomas E. Dickey #
# #
# Permission is hereby granted, free of charge, to any person obtaining a #
# copy of this software and associated documentation files (the "Software"), #
# to deal in the Software without restriction, including without limitation #
# the rights to use, copy, modify, merge, publish, distribute, distribute #
# with modifications, sublicense, and/or sell copies of the Software, and to #
# permit persons to whom the Software is furnished to do so, subject to the #
# following conditions: #
# #
# The above copyright notice and this permission notice shall be included in #
# all copies or substantial portions of the Software. #
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
# DEALINGS IN THE SOFTWARE. #
# #
# Except as contained in this notice, the name(s) of the above copyright #
# holders shall not be used in advertising or otherwise to promote the sale, #
# use or other dealings in this Software without prior written #
# authorization. #
##############################################################################
#
# Adjust includes for header files that reside in a subdirectory of
# /usr/include, etc.
#
# Parameters (the first case creates the sed script):
# $1 is the target directory
# $2 is the source directory
# or (the second case does the install, using the sed script):
# $1 is the script to use for installing
# $2 is the target directory
# $3 is the source directory
# $4 is the file to install, editing source/target/etc.
PACKAGE=DIALOG
PKGNAME=DLG
CONFIGH=dlg_config.h
TMPSED=headers.sed
if test $# = 2 ; then
rm -f $TMPSED
DST=$1
REF=$2
LEAF=`basename $DST`
case $DST in
/*/include/$LEAF)
END=`basename $DST`
for i in $REF/*.h
do
NAME=`basename $i`
echo "s/<$NAME>/<$END\/$NAME>/g" >> $TMPSED
done
;;
*)
echo "" >> $TMPSED
;;
esac
for name in `
egrep '^#define[ ][ ]*[_ABCDEFGHIJKLMNOPQRSTUVWXYZ]' $REF/$CONFIGH \
| sed -e 's/^#define[ ][ ]*//' \
-e 's/[ ].*//' \
| egrep -v "^${PACKAGE}_" \
| sort -u \
| egrep -v "^${PKGNAME}_"`
do
echo "s/\\<$name\\>/${PKGNAME}_$name/g" >>$TMPSED
done
else
PRG=""
while test $# != 3
do
PRG="$PRG $1"; shift
done
DST=$1
REF=$2
SRC=$3
SHOW=`basename $SRC`
TMPSRC=${TMPDIR-/tmp}/${SHOW}$$
echo " ... $SHOW"
test -f $REF/$SRC && SRC="$REF/$SRC"
rm -f $TMPSRC
sed -f $TMPSED $SRC > $TMPSRC
NAME=`basename $SRC`
# Just in case someone gzip'd manpages, remove the conflicting copy.
test -f $DST/$NAME.gz && rm -f $DST/$NAME.gz
eval $PRG $TMPSRC $DST/$NAME
rm -f $TMPSRC
fi

View File

@ -1,9 +1,9 @@
/*
* $Id: inputbox.c,v 1.76 2012/12/03 11:46:50 tom Exp $
* $Id: inputbox.c,v 1.84 2018/06/21 23:29:35 tom Exp $
*
* inputbox.c -- implements the input box
*
* Copyright 2000-2011,2012 Thomas E. Dickey
* Copyright 2000-2016,2018 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
@ -49,6 +49,7 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
NAVIGATE_BINDINGS,
TOGGLEKEY_BINDINGS,
END_KEYS_BINDING
};
static DLG_KEYS_BINDING binding2[] = {
@ -56,6 +57,7 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
NAVIGATE_BINDINGS,
/* no TOGGLEKEY_BINDINGS, since that includes space... */
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -72,8 +74,8 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
int key, fkey, code;
int result = DLG_EXIT_UNKNOWN;
int state;
int first;
int edited;
bool first;
bool edited;
char *input;
WINDOW *dialog;
WINDOW *editor;
@ -82,6 +84,14 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
dlg_does_output();
DLG_TRACE(("# inputbox args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2S("init", init);
DLG_TRACE2N("password", password);
dlg_tab_correct_str(prompt);
/* Set up the initial value */
@ -122,7 +132,7 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_draw_helpline(dialog, FALSE);
dlg_print_autowrap(dialog, prompt, height, width);
@ -142,7 +152,7 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
if (*input != '\0') {
dlg_show_string(editor, input, chr_offset, inputbox_attr,
0, 0, box_width, password, first);
0, 0, box_width, (bool) (password != 0), first);
wsyncup(editor);
wcursyncup(editor);
}
@ -162,7 +172,7 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
if (!first) {
if (*input != '\0' && !edited) {
dlg_show_string(editor, input, chr_offset, inputbox_attr,
0, 0, box_width, password, first);
0, 0, box_width, (bool) (password != 0), first);
wmove(editor, 0, chr_offset);
wsyncup(editor);
wcursyncup(editor);
@ -188,7 +198,7 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
if (edit) {
dlg_show_string(editor, input, chr_offset, inputbox_attr,
0, 0, box_width, password, first);
0, 0, box_width, (bool) (password != 0), first);
wsyncup(editor);
wcursyncup(editor);
first = FALSE;
@ -221,13 +231,14 @@ dialog_inputbox(const char *title, const char *cprompt, int height, int width,
show_buttons = TRUE;
state = dlg_next_ok_buttonindex(state, sTEXT);
break;
case ' ': /* FIXME: conflict with inputstr.c */
case DLGK_TOGGLE:
case DLGK_ENTER:
dlg_del_window(dialog);
result = (state >= 0) ? dlg_enter_buttoncode(state) : DLG_EXIT_OK;
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;

View File

@ -1,9 +1,9 @@
/*
* $Id: inputstr.c,v 1.83 2013/09/23 23:19:26 tom Exp $
* $Id: inputstr.c,v 1.88 2018/06/18 22:10:54 tom Exp $
*
* inputstr.c -- functions for input/display of a string
*
* Copyright 2000-2012,2013 Thomas E. Dickey
* Copyright 2000-2017,2018 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
@ -105,14 +105,14 @@ show_tsearch(const void *nodep, const VISIT which, const int depth)
const CACHE *p = *(CACHE * const *) nodep;
(void) depth;
if (which == postorder || which == leaf) {
dlg_trace_msg("\tcache %p %p:%s\n", p, p->string, p->string);
DLG_TRACE(("# cache %p %p:%s\n", p, p->string, p->string));
}
}
static void
trace_cache(const char *fn, int ln)
{
dlg_trace_msg("trace_cache %s@%d\n", fn, ln);
DLG_TRACE(("# trace_cache %s@%d\n", fn, ln));
twalk(sorted_cache, show_tsearch);
}
@ -120,14 +120,16 @@ trace_cache(const char *fn, int ln)
#define trace_cache(fn, ln) /* nothing */
#endif
#define CMP(a,b) (((a) > (b)) ? 1 : (((a) < (b)) ? -1 : 0))
static int
compare_cache(const void *a, const void *b)
{
const CACHE *p = (const CACHE *) a;
const CACHE *q = (const CACHE *) b;
int result = (p->cache_num - q->cache_num);
int result = CMP(p->cache_num, q->cache_num);
if (result == 0)
result = (int) (p->string_at - q->string_at);
result = CMP(p->string_at, q->string_at);
return result;
}
#endif
@ -456,7 +458,7 @@ dlg_index_columns(const char *string)
if (ch == TAB)
cache->list[inx + 1] =
((cache->list[inx] | 7) + 1) - cache->list[inx];
else if (isprint(ch))
else if (isprint(UCH(ch)))
cache->list[inx + 1] = 1;
else {
const char *printable;
@ -714,7 +716,7 @@ dlg_show_string(WINDOW *win,
compute_edit_offset(string, chr_offset, x_last, &input_x, &scrollamt);
(void) wattrset(win, attr);
dlg_attrset(win, attr);
(void) wmove(win, y_base, x_base);
for (i = scrollamt, k = 0; i < limit && k < x_last; ++i) {
int check = cols[i + 1] - cols[scrollamt];

View File

@ -1,7 +1,7 @@
# $Id: makefile.in,v 1.87 2013/09/02 19:51:58 tom Exp $
# $Id: makefile.in,v 1.97 2018/06/09 01:05:18 tom Exp $
# template makefile for DIALOG
##############################################################################
# Copyright (c) 1999-2012,2013 Thomas E. Dickey #
# Copyright (c) 1999-2017,2018 Thomas E. Dickey #
# #
# Permission is hereby granted, free of charge, to any person obtaining a #
# copy of this software and associated documentation files (the "Software"), #
@ -31,6 +31,7 @@
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
@ -42,13 +43,14 @@ top_builddir = .
x = @EXEEXT@
o = .@OBJEXT@
DESTDIR =
DESTDIR = @DESTDIR@
THIS = dialog
CFG_ROOTNAME = @CFG_ROOTNAME@
HDR_ROOTNAME = @HDR_ROOTNAME@
LIB_ROOTNAME = @LIB_ROOTNAME@
LIB_PREFIX = @LIB_PREFIX@
LIB_SUFFIX = @LIB_SUFFIX@
VERSION_MAJOR = @VERSION_MAJOR@
@ -57,12 +59,18 @@ VERSION = $(VERSION_MAJOR).$(VERSION_MINOR)
REL_VERSION = @REL_VERSION@
ABI_VERSION = @ABI_VERSION@
LIB_ROOTNAME = @LIB_ROOTNAME@
RESULTING_SYMS = @RESULTING_SYMS@
VERSIONED_SYMS = @VERSIONED_SYMS@
@SET_SHLIB_VARS@
bindir = @bindir@
includedir = @includedir@
libdir = @libdir@
mandir = @mandir@
manext = 1
libext = 3
BINDIR = $(DESTDIR)$(bindir)
INCLUDEDIR = $(DESTDIR)$(includedir)
@ -81,6 +89,7 @@ EXTRA_CFLAGS = @EXTRA_CFLAGS@
CC = @CC@
CPP = @CPP@
AR = @AR@
ARFLAGS = @ARFLAGS@
LDFLAGS = @EXTRA_LDFLAGS@ @LDFLAGS@
LIBS = @LIBS@ @INTLLIBS@
RANLIB = @LIB_PREP@
@ -123,7 +132,7 @@ PROG = @PACKAGE@$x
#
# Standard .c to .o compile line.
#
.SUFFIXES: .c .i $o .html .1 .3 .man .ps .pdf .txt
.SUFFIXES: .c .i $o .1 .man .txt @MAN2HTML_NOTE@ .html @GROFF_NOTE@ .ps .pdf
.c.i :
@RULE_CC@
@ECHO_CC@$(CPP) $(CPPFLAGS) -c $< >$@
@ -131,17 +140,17 @@ PROG = @PACKAGE@$x
@RULE_CC@
@ECHO_CC@$(LIBTOOL_COMPILE) $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CPPFLAGS) -c $<
.1.html :
GROFF_NO_SGR=stupid $(SHELL) -c "tbl $< | groff -P -o0 -I$*_ -Thtml -man" >$@
@NROFF_NOTE@.1.txt :
@NROFF_NOTE@ GROFF_NO_SGR=stupid $(SHELL) -c "tbl $< | nroff -Tascii -man | col -bx" >$@
.1.ps :
$(SHELL) -c "tbl $< | groff -man" >$@
.1.txt :
GROFF_NO_SGR=stupid $(SHELL) -c "tbl $< | nroff -Tascii -man | col -bx" >$@
.ps.pdf :
ps2pdf $*.ps
@MAN2HTML_NOTE@.1.html :
@MAN2HTML_NOTE@ ./@MAN2HTML_TEMP@ $* 1 man >$@
@MAN2HTML_NOTE@
@GROFF_NOTE@.1.ps :
@GROFF_NOTE@ $(SHELL) -c "tbl $< | groff -man" >$@
@GROFF_NOTE@
@GROFF_NOTE@.ps.pdf :
@GROFF_NOTE@ ps2pdf $*.ps
EXTRAOBJS = @EXTRAOBJS@
OBJECTS = $(EXTRAOBJS) \
@ -160,6 +169,7 @@ OBJECTS = $(EXTRAOBJS) \
mousewget$o \
msgbox$o \
textbox$o \
ttysize$o \
ui_getc$o \
util$o \
version$o \
@ -194,7 +204,7 @@ dialog$o \
$(OBJECTS) : $(srcdir)/dialog.h $(srcdir)/dlg_keys.h dlg_config.h VERSION
$(PROG)$x : $(LIB) dialog$o @INTLDIR_MAKE@ @INTLLIBS@
$(LINK) -o $@ dialog$o -L. -l@PACKAGE@ $(LDFLAGS) $(LIBS)
$(LINK) -o $@ dialog$o -L. -l@PACKAGE@ $(CFLAGS) $(LDFLAGS) $(LIBS)
clean \
distclean \
@ -219,6 +229,7 @@ distclean :: clean
$(RM) makefile dlg_config.h config.cache config.log config.status
$(RM) samples/install/makefile
$(RM) headers-sh
$(RM) man2html.*
$(RM) dialog-config
install :: install-bin install-man
@ -243,16 +254,16 @@ uninstall-bin :
$(RM) $(BINDIR)/$(ACTUAL_PROG)$x
install-man :: $(MAN1DIR)
@ echo "** installing $(ACTUAL_PROG).1"
@ echo "** installing $(ACTUAL_PROG).$(manext)"
@ $(SHELL) $(srcdir)/rename.sh \
$(srcdir)/dialog.1 \
$(MAN1DIR)/$(ACTUAL_PROG).1 \
$(MAN1DIR)/$(ACTUAL_PROG).$(manext) \
$(ACTUAL_PROG) \
@PACKAGE@ \
$(INSTALL_DATA)
uninstall-man ::
$(RM) $(MAN1DIR)/$(ACTUAL_PROG).1
$(RM) $(MAN1DIR)/$(ACTUAL_PROG).$(manext)
# most users do not want/need the library, so the install rules are distinct.
install-lib :: $(BINDIR) dialog-config
@ -279,26 +290,27 @@ uninstall-lib :: $(LIB_DIRS)
@ $(SHELL) headers-sh $(RM) $(INCLUDEDIR) . dlg_config.h
install-lib :: $(MAN3DIR)
@ echo "** installing @PACKAGE@.3"
@ echo "** installing @PACKAGE@.$(libext)"
@ $(SHELL) $(srcdir)/rename.sh \
$(srcdir)/dialog.3 \
$(MAN3DIR)/@PACKAGE@.3 \
$(MAN3DIR)/@PACKAGE@.$(libext) \
$(ACTUAL_PROG) \
@PACKAGE@ \
$(INSTALL_DATA)
uninstall-lib ::
$(RM) $(MAN3DIR)/@PACKAGE@.3
$(RM) $(MAN3DIR)/@PACKAGE@.$(libext)
headers.sed : headers-sh
$(SHELL) headers-sh $(INCLUDEDIR) $(srcdir)
################################################################################
TOP_DOCS = \
dialog.html \
dialog.pdf \
dialog.ps \
dialog.txt
@NROFF_NOTE@ dialog.txt \
@MAN2HTML_NOTE@ dialog.html \
@GROFF_NOTE@ dialog.pdf \
@GROFF_NOTE@ dialog.ps
dialog.html : dialog.1
dialog.pdf : dialog.ps
dialog.ps : dialog.1
@ -311,10 +323,11 @@ dialog_lib.1 : dialog.3
LIB_DOCS = \
dialog_lib.1 \
dialog_lib.html \
dialog_lib.pdf \
dialog_lib.ps \
dialog_lib.txt
@NROFF_NOTE@ dialog_lib.txt \
@MAN2HTML_NOTE@ dialog_lib.html \
@GROFF_NOTE@ dialog_lib.pdf \
@GROFF_NOTE@ dialog_lib.ps
dialog_lib.html : dialog_lib.1
dialog_lib.pdf : dialog_lib.ps
dialog_lib.ps : dialog_lib.1

View File

@ -1,9 +1,9 @@
/*
* $Id: menubox.c,v 1.148 2013/09/02 17:15:13 tom Exp $
* $Id: menubox.c,v 1.159 2018/06/21 23:28:56 tom Exp $
*
* menubox.c -- implements the menu box
*
* Copyright 2000-2012,2013 Thomas E. Dickey
* Copyright 2000-2016,2018 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 Licens, version 2.1e
@ -95,13 +95,13 @@ print_item(ALL_DATA * data,
/* Clear 'residue' of last item and mark current current item */
if (is_inputmenu) {
(void) wattrset(win, (selected != Unselected) ? item_selected_attr : item_attr);
dlg_attrset(win, (selected != Unselected) ? item_selected_attr : item_attr);
for (n = my_y - 1; n < my_y + INPUT_ROWS - 1; n++) {
wmove(win, n, 0);
wprintw(win, "%*s", my_width, " ");
}
} else {
(void) wattrset(win, menubox_attr);
dlg_attrset(win, menubox_attr);
wmove(win, my_y, 0);
wprintw(win, "%*s", my_width, " ");
}
@ -131,7 +131,7 @@ print_item(ALL_DATA * data,
if (selected) {
dlg_item_help(item->help);
}
(void) wattrset(win, save);
dlg_attrset(win, save);
}
/*
@ -147,7 +147,7 @@ input_menu_edit(ALL_DATA * data,
char *result;
int offset = 0;
int key = 0, fkey = 0;
int first = TRUE;
bool first = TRUE;
/* see above */
bool is_inputmenu = TRUE;
int y = ItemToRow(choice);
@ -182,7 +182,7 @@ input_menu_edit(ALL_DATA * data,
}
}
print_item(data, data->menu, items, choice, Selected, TRUE);
(void) wattrset(data->menu, save);
dlg_attrset(data->menu, save);
*resultp = result;
return code;
@ -245,7 +245,7 @@ print_menu(ALL_DATA * data, int choice, int scrollamt, int max_choice, bool is_i
if (is_inputmenu) {
int spare_lines, x_count;
spare_lines = data->menu_height % INPUT_ROWS;
(void) wattrset(data->menu, menubox_attr);
dlg_attrset(data->menu, menubox_attr);
for (; spare_lines; spare_lines--) {
wmove(data->menu, data->menu_height - spare_lines, 0);
for (x_count = 0; x_count < data->menu_width;
@ -304,7 +304,7 @@ dlg_menu(const char *title,
static DLG_KEYS_BINDING binding[] = {
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
DLG_KEYS_DATA( DLGK_FIELD_NEXT, ' ' ),
TOGGLEKEY_BINDINGS,
DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
@ -331,6 +331,8 @@ dlg_menu(const char *title,
/* *INDENT-ON* */
#ifdef KEY_RESIZE
int old_LINES = LINES;
int old_COLS = COLS;
int old_height = height;
int old_width = width;
#endif
@ -345,21 +347,36 @@ dlg_menu(const char *title,
int found;
int use_width, name_width, text_width, list_width;
WINDOW *dialog, *menu;
char *prompt = dlg_strclone(cprompt);
char *prompt = 0;
const char **buttons = dlg_ok_labels();
bool is_inputmenu = ((rename_menutext != 0)
&& (rename_menutext != dlg_dummy_menutext));
DLG_TRACE(("# menubox args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("lheight", menu_height);
DLG_TRACE2N("llength", item_no);
/* FIXME dump the items[][] too */
DLG_TRACE2N("current", *current_item);
DLG_TRACE2N("rename", rename_menutext != 0);
dialog_state.plain_buttons = TRUE;
all.items = items;
all.item_no = item_no;
dlg_does_output();
dlg_tab_correct_str(prompt);
#ifdef KEY_RESIZE
retry:
#endif
prompt = dlg_strclone(cprompt);
dlg_tab_correct_str(prompt);
all.menu_height = menu_height;
use_width = dlg_calc_list_width(item_no, items) + 10;
use_width = MAX(26, use_width);
@ -391,7 +408,7 @@ dlg_menu(const char *title,
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
all.menu_width = width - 6;
@ -642,6 +659,7 @@ dlg_menu(const char *title,
dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
FALSE, width);
break;
case DLGK_TOGGLE:
case DLGK_ENTER:
if (is_inputmenu)
result = dlg_ok_buttoncode(button);
@ -703,14 +721,19 @@ dlg_menu(const char *title,
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
/* repaint */
#define resizeit(name, NAME) \
name = ((NAME >= old_##NAME) \
? (NAME - (old_##NAME - old_##name)) \
: old_##name)
resizeit(height, LINES);
resizeit(width, COLS);
free(prompt);
dlg_clear();
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
/* repaint */
goto retry;
#endif
default:

View File

@ -1,9 +1,9 @@
/*
* $Id: mixedform.c,v 1.12 2013/09/02 17:02:05 tom Exp $
* $Id: mixedform.c,v 1.13 2018/06/15 01:23:33 tom Exp $
*
* mixedform.c -- implements the mixed form (i.e, typed pairs label/editbox)
*
* Copyright 2007-2011,2013 Thomas E. Dickey
* Copyright 2007-2013,2018 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
@ -49,7 +49,7 @@ dialog_mixedform(const char *title,
char **items)
{
int result;
int choice;
int choice = 0;
int i;
DIALOG_FORMITEM *listitems;
DIALOG_VARS save_vars;

View File

@ -1,9 +1,9 @@
/*
* $Id: mixedgauge.c,v 1.30 2012/11/18 16:30:20 tom Exp $
* $Id: mixedgauge.c,v 1.34 2018/06/18 22:09:31 tom Exp $
*
* mixedgauge.c -- implements the mixedgauge dialog
*
* Copyright 2007-2011,2012 Thomas E. Dickey
* Copyright 2007-2012,2018 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
@ -89,7 +89,7 @@ status_string(char *given, char **freeMe)
break;
}
} else if (*given == '-') {
size_t need = strlen(++given);
size_t need = strlen(++given) + 4;
char *temp = dlg_malloc(char, need);
*freeMe = temp;
sprintf(temp, "%3s%%", given);
@ -135,6 +135,7 @@ myprint_status(DIALOG_MIXEDGAUGE * dlg)
continue;
(void) wmove(win, y, 2 * MARGIN);
dlg_attrset(win, dialog_attr);
dlg_print_text(win, dlg->list[item].name, lm, &attr);
(void) wmove(win, y, lm);
@ -142,7 +143,7 @@ myprint_status(DIALOG_MIXEDGAUGE * dlg)
(void) wmove(win, y, lm + (cells - (int) strlen(status)) / 2);
if (freeMe) {
(void) wmove(win, y, lm + 1);
(void) wattrset(win, title_attr);
dlg_attrset(win, title_attr);
for (j = 0; j < cells; j++)
(void) waddch(win, ' ');
@ -150,9 +151,9 @@ myprint_status(DIALOG_MIXEDGAUGE * dlg)
(void) waddstr(win, status);
if ((title_attr & A_REVERSE) != 0) {
wattroff(win, A_REVERSE);
dlg_attroff(win, A_REVERSE);
} else {
(void) wattrset(win, A_REVERSE);
dlg_attrset(win, A_REVERSE);
}
(void) wmove(win, y, lm + 1);
@ -173,6 +174,7 @@ myprint_status(DIALOG_MIXEDGAUGE * dlg)
(void) waddstr(win, status);
}
(void) wmove(win, y, limit_x - 3);
dlg_attrset(win, dialog_attr);
(void) waddch(win, ']');
(void) wnoutrefresh(win);
}
@ -189,10 +191,10 @@ mydraw_mixed_box(WINDOW *win, int y, int x, int height, int width,
chtype attr = A_NORMAL;
const char *message = _("Overall Progress");
chtype save2 = dlg_get_attrs(win);
(void) wattrset(win, title_attr);
dlg_attrset(win, title_attr);
(void) wmove(win, y, x + 2);
dlg_print_text(win, message, width, &attr);
(void) wattrset(win, save2);
dlg_attrset(win, save2);
}
}
@ -220,7 +222,7 @@ dlg_update_mixedgauge(DIALOG_MIXEDGAUGE * dlg, int percent)
* attribute.
*/
(void) wmove(dlg->dialog, dlg->height - 3, 4);
(void) wattrset(dlg->dialog, gauge_attr);
dlg_attrset(dlg->dialog, gauge_attr);
for (i = 0; i < (dlg->width - 2 * (3 + MARGIN)); i++)
(void) waddch(dlg->dialog, ' ');
@ -235,9 +237,9 @@ dlg_update_mixedgauge(DIALOG_MIXEDGAUGE * dlg, int percent)
*/
x = (percent * (dlg->width - 2 * (3 + MARGIN))) / 100;
if ((title_attr & A_REVERSE) != 0) {
wattroff(dlg->dialog, A_REVERSE);
dlg_attroff(dlg->dialog, A_REVERSE);
} else {
(void) wattrset(dlg->dialog, A_REVERSE);
dlg_attrset(dlg->dialog, A_REVERSE);
}
(void) wmove(dlg->dialog, dlg->height - 3, 4);
for (i = 0; i < x; i++) {
@ -338,7 +340,7 @@ dlg_begin_mixedgauge(DIALOG_MIXEDGAUGE * dlg,
dlg->width,
y + dlg->item_no + (2 * MARGIN),
x);
(void) wattrset(dlg->caption, dialog_attr);
dlg_attrset(dlg->caption, dialog_attr);
dlg_print_autowrap(dlg->caption, dlg->prompt, dlg->height, dlg->width);
}
@ -383,6 +385,15 @@ dialog_mixedgauge(const char *title,
DIALOG_MIXEDGAUGE dlg;
int began = 0;
DLG_TRACE(("# mixedgauge args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("percent", percent);
DLG_TRACE2N("llength", item_no);
/* FIXME dump the items[][] too */
dlg_begin_mixedgauge(&dlg, &began, title, cprompt, height,
width, item_no, items);

38
mouse.c
View File

@ -1,9 +1,9 @@
/*
* $Id: mouse.c,v 1.20 2012/12/21 10:00:30 tom Exp $
* $Id: mouse.c,v 1.24 2017/01/31 00:27:21 tom Exp $
*
* mouse.c -- mouse support for dialog
*
* Copyright 2002-2007,2012 Thomas E. Dickey
* Copyright 2002-2016,2017 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
@ -55,6 +55,7 @@ void
dlg_mouse_setcode(int code)
{
basecode = code;
DLG_TRACE(("# mouse_setcode %d\n", code));
}
void
@ -86,21 +87,34 @@ dlg_mouse_mkregion(int y, int x, int height, int width, int code)
mseRegion *butPtr;
if ((butPtr = find_region_by_code(basecode + code)) == 0) {
butPtr = dlg_malloc(mseRegion, 1);
butPtr = dlg_calloc(mseRegion, 1);
assert_ptr(butPtr, "dlg_mouse_mkregion");
butPtr->next = regionList;
regionList = butPtr;
}
if (butPtr != 0) {
butPtr->mode = -1;
butPtr->step_x = 0;
butPtr->step_y = 0;
butPtr->y = basey + y;
butPtr->Y = basey + y + height;
butPtr->x = basex + x;
butPtr->X = basex + x + width;
butPtr->code = basecode + code;
if ((butPtr->mode != -1) ||
(butPtr->step_x != 0) ||
(butPtr->step_y != 0) ||
(butPtr->y != (basey + y)) ||
(butPtr->Y != (basey + y + height)) ||
(butPtr->x != (basex + x)) ||
(butPtr->X != (basex + x + width)) ||
(butPtr->code != basecode + code)) {
DLG_TRACE(("# mouse_mkregion %d,%d %dx%d %d (%d)\n",
y, x, height, width,
butPtr->code, code));
}
butPtr->mode = -1;
butPtr->step_x = 0;
butPtr->step_y = 0;
butPtr->y = basey + y;
butPtr->Y = basey + y + height;
butPtr->x = basex + x;
butPtr->X = basex + x + width;
butPtr->code = basecode + code;
return butPtr;
}

View File

@ -1,9 +1,9 @@
/*
* $Id: mousewget.c,v 1.22 2012/11/30 10:23:49 tom Exp $
* $Id: mousewget.c,v 1.24 2017/01/31 00:27:21 tom Exp $
*
* mousewget.c -- mouse/wgetch support for dialog
*
* Copyright 2000-2008,2012 Thomas E. Dickey
* Copyright 2000-2016,2017 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
@ -42,6 +42,10 @@ mouse_wgetch(WINDOW *win, int *fkey, bool ignore_errs)
mseRegion *p;
if (getmouse(&event) != ERR) {
DLG_TRACE(("# mouse-click abs %d,%d (rel %d,%d)\n",
event.y, event.x,
event.y - getbegy(win),
event.x - getbegx(win)));
if ((p = dlg_mouse_region(event.y, event.x)) != 0) {
key = DLGK_MOUSE(p->code);
} else if ((p = dlg_mouse_bigregion(event.y, event.x)) != 0) {

View File

@ -1,9 +1,9 @@
/*
* $Id: msgbox.c,v 1.75 2012/12/01 01:48:08 tom Exp $
* $Id: msgbox.c,v 1.81 2018/06/21 23:29:59 tom Exp $
*
* msgbox.c -- implements the message box and info box
*
* Copyright 2000-2011,2012 Thomas E. Dickey
* Copyright 2000-2012,2018 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
@ -39,8 +39,8 @@ dialog_msgbox(const char *title, const char *cprompt, int height, int width,
static DLG_KEYS_BINDING binding[] = {
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
TRAVERSE_BINDINGS,
SCROLLKEY_BINDINGS,
TRAVERSE_BINDINGS,
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -50,18 +50,25 @@ dialog_msgbox(const char *title, const char *cprompt, int height, int width,
int key = 0, fkey;
int result = DLG_EXIT_UNKNOWN;
WINDOW *dialog = 0;
char *prompt = dlg_strclone(cprompt);
char *prompt;
const char **buttons = dlg_ok_label();
int offset = 0;
int check;
bool show = TRUE;
int min_width = (pauseopt == 1 ? 12 : 0);
int save_nocancel = dialog_vars.nocancel;
bool save_nocancel = dialog_vars.nocancel;
#ifdef KEY_RESIZE
int req_high;
int req_wide;
#endif
DLG_TRACE(("# msgbox args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("pauseopt", pauseopt);
dialog_vars.nocancel = TRUE;
button = dlg_default_button();
@ -73,6 +80,7 @@ dialog_msgbox(const char *title, const char *cprompt, int height, int width,
dlg_button_layout(buttons, &min_width);
prompt = dlg_strclone(cprompt);
dlg_tab_correct_str(prompt);
dlg_auto_size(title, prompt, &height, &width,
(pauseopt == 1 ? 2 : 0),
@ -100,7 +108,7 @@ dialog_msgbox(const char *title, const char *cprompt, int height, int width,
dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
if (pauseopt) {
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
@ -128,7 +136,9 @@ dialog_msgbox(const char *title, const char *cprompt, int height, int width,
switch (key) {
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
dlg_clear();
free(prompt);
height = req_high;
width = req_wide;
show = TRUE;

View File

@ -1,3 +1,141 @@
cdialog (20180621) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Thu, 15 Feb 2018 05:02:43 -0500
cdialog (20171209) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Sat, 09 Dec 2017 10:52:09 -0500
cdialog (20170509) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Tue, 09 May 2017 19:08:48 -0400
cdialog (20170131) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Mon, 23 Jan 2017 17:41:21 -0500
cdialog (20161120) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Sun, 20 Nov 2016 06:47:59 -0500
cdialog (20160828) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Fri, 26 Aug 2016 17:41:17 -0400
cdialog (20160424) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Tue, 19 Apr 2016 06:33:50 -0400
cdialog (20160209) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Mon, 01 Feb 2016 05:18:04 -0500
cdialog (20160126) unstable; urgency=low
* maintenance updates, add --week-start option
-- Thomas E. Dickey <dickey@invisible-island.net> Mon, 25 Jan 2016 13:13:51 -0500
cdialog (20150920) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Sun, 20 Sep 2015 18:08:36 -0400
cdialog (20150528) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Thu, 28 May 2015 19:42:32 -0400
cdialog (20150513) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Wed, 13 May 2015 10:46:07 -0400
cdialog (20150512) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Sun, 10 May 2015 19:31:46 -0400
cdialog (20150225) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Wed, 25 Feb 2015 05:10:57 -0500
cdialog (20150224) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Tue, 24 Feb 2015 07:10:45 -0500
cdialog (20150125) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Sun, 25 Jan 2015 16:30:54 -0500
cdialog (20140911) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Thu, 11 Sep 2014 03:56:17 -0400
cdialog (20140910) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Wed, 10 Sep 2014 04:23:13 -0400
cdialog (20140908) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Mon, 08 Sep 2014 05:10:11 -0400
cdialog (20140901) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Mon, 01 Sep 2014 12:15:40 -0400
cdialog (20140219) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Wed, 19 Feb 2014 04:13:36 -0500
cdialog (20140112) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Sun, 12 Jan 2014 13:22:17 -0500
cdialog (20130928) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Sat, 28 Sep 2013 21:27:37 -0400
cdialog (20130923) unstable; urgency=low
* improved memory-caching for gauge widget

View File

@ -3,22 +3,22 @@ Maintainer: Thomas E. Dickey <dickey@invisible-island.net>
Section: misc
Priority: optional
Standards-Version: 3.8.4
Build-Depends: debhelper (>= 5), libncursesw5-dev (>= 5.3), groff-base
Build-Depends: debhelper (>= 5), libc6 (>= 2.11), libncursesw5-dev (>= 5.3), groff-base
Homepage: http://invisible-island.net/dialog/
Package: cdialog
Architecture: any
Depends: libncursesw5 (>= 5.3)
Depends: libc6 (>= 2.11), libncursesw5 (>= 5.3)
Description: dialog - display dialog boxes from shell scripts
Dialog is a program that will let you to present a variety of questions
or display messages using dialog boxes from a shell script. These
types of dialog boxes are implemented (though not all are necessarily
Dialog is a program that will let you present a variety of questions or
display messages using dialog boxes from a shell script. These types
of dialog boxes are implemented (though not all are necessarily
compiled into dialog):
.
calendar, checklist, dselect, editbox, form, fselect, gauge,
infobox, inputbox, inputmenu, menu, mixedform, mixedgauge,
msgbox (message), passwordbox, passwordform, pause, progressbox,
radiolist, tailbox, tailboxbg, textbox, timebox, and yesno
(yes/no).
buildlist, calendar, checklist, dselect, editbox, form, fselect,
gauge, infobox, inputbox, inputmenu, menu, mixedform,
mixedgauge, msgbox (message), passwordbox, passwordform, pause,
prgbox, programbox, progressbox, radiolist, rangebox, tailbox,
tailboxbg, textbox, timebox, treeview, and yesno (yes/no).
.
This package installs as "cdialog" to avoid conflict with other packages.

View File

@ -4,7 +4,7 @@ Current dialog upstream maintainer: Thomas Dickey <dickey@invisible-island.net>
-------------------------------------------------------------------------------
Files: *.c *.h
Copyright 2000-2012,2013 Thomas E. Dickey
Copyright 2000-2017,2018 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
@ -27,7 +27,7 @@ Files: *.c *.h
Files: aclocal.m4
Licence: other-BSD
Copyright: 1999-2010,2013 by Thomas E. Dickey
Copyright: 1999-2017,2018 by Thomas E. Dickey
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including

7
package/debian/postinst Executable file
View File

@ -0,0 +1,7 @@
#! /bin/sh
set -e
if [ "$1" = "configure" ]; then
ldconfig
fi

View File

@ -1,5 +1,5 @@
#!/usr/bin/make -f
# MAde with the aid of dh_make, by Craig Small
# Made with the aid of dh_make, by Craig Small
# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess.
# Some lines taken from debmake, by Cristoph Lameter.
@ -11,7 +11,11 @@
DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
CFLAGS =
CPPFLAGS := $(shell dpkg-buildflags --get CPPFLAGS)
CFLAGS := $(shell dpkg-buildflags --get CFLAGS)
LDFLAGS := $(shell dpkg-buildflags --get LDFLAGS)
ACTUAL_PROG = cdialog
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
CFLAGS += -O0
@ -27,7 +31,12 @@ configure: configure-stamp
configure-stamp:
dh_testdir
CFLAGS="$(CFLAGS)" ./configure \
cp -v package/dialog.map package/${ACTUAL_PROG}.map
CPPFLAGS="$(CPPFLAGS)" \
CFLAGS="$(CFLAGS)" \
LDFLAGS="$(LDFLAGS)" \
./configure \
--host=$(DEB_HOST_GNU_TYPE) \
--build=$(DEB_BUILD_GNU_TYPE) \
--prefix=/usr \
@ -35,9 +44,10 @@ configure-stamp:
--enable-nls \
--enable-header-subdir \
--enable-widec \
--with-libtool \
--with-ncursesw \
--with-package=cdialog \
--with-shared \
--with-screen=ncursesw6 \
--with-package=${ACTUAL_PROG} \
--with-versioned-syms \
--disable-rpath-hack
touch configure-stamp
@ -67,7 +77,7 @@ install-stamp: build-stamp
dh_clean -k
dh_installdirs
$(MAKE) install DESTDIR=$(CURDIR)/debian/cdialog
$(MAKE) install DESTDIR=$(CURDIR)/debian/${ACTUAL_PROG}
touch install-stamp
@ -86,6 +96,7 @@ binary-arch: build install
dh_compress
dh_fixperms
dh_installdeb
dh_makeshlibs
dh_shlibdeps
dh_gencontrol
dh_md5sums

View File

@ -1,4 +1,4 @@
version=3
opts=passive ftp://invisible-island.net/dialog/dialog-([\d.]+)\.tgz \
opts=passive ftp://ftp.invisible-island.net/dialog/dialog-([\d.]+)\.tgz \
debian uupdate

222
package/dialog.map Normal file
View File

@ -0,0 +1,222 @@
# $Id: dialog.map,v 1.7 2018/06/21 00:32:55 tom Exp $
# script for shared library symbol-versioning using ld
#
# This file was generated by ncu-mapsyms
# Configure options (1.0.20040721)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
# Configure options (1.1.20070227)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
# Configure options (1.2.20121230)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
# Configure options (1.3.20160126)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
# Configure options (1.3.20180620)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
DIALOG_1.0.20040721 {
global:
dialog_calendar;
dialog_checklist;
dialog_form;
dialog_fselect;
dialog_gauge;
dialog_inputbox;
dialog_menu;
dialog_msgbox;
dialog_state;
dialog_tailbox;
dialog_textbox;
dialog_timebox;
dialog_vars;
dialog_version;
dialog_yesno;
dlg_add_callback;
dlg_add_quoted;
dlg_add_result;
dlg_attr_clear;
dlg_auto_size;
dlg_auto_sizefile;
dlg_beeping;
dlg_box_x_ordinate;
dlg_box_y_ordinate;
dlg_button_count;
dlg_button_layout;
dlg_button_sizes;
dlg_button_x_step;
dlg_calc_listh;
dlg_calc_listw;
dlg_char_to_button;
dlg_clear;
dlg_color_count;
dlg_color_setup;
dlg_color_table;
dlg_count_columns;
dlg_count_wchars;
dlg_create_rc;
dlg_ctl_size;
dlg_default_item;
dlg_defaultno_button;
dlg_del_window;
dlg_does_output;
dlg_draw_arrows;
dlg_draw_bottom_box;
dlg_draw_box;
dlg_draw_buttons;
dlg_draw_shadow;
dlg_draw_title;
dlg_edit_offset;
dlg_edit_string;
dlg_exit;
dlg_exit_label;
dlg_exiterr;
dlg_flush_getc;
dlg_getc;
dlg_getc_callbacks;
dlg_index_columns;
dlg_index_wchars;
dlg_item_help;
dlg_killall_bg;
dlg_last_getc;
dlg_limit_columns;
dlg_match_char;
dlg_mouse_bigregion;
dlg_mouse_free_regions;
dlg_mouse_mkbigregion;
dlg_mouse_mkregion;
dlg_mouse_region;
dlg_mouse_setbase;
dlg_mouse_wgetch;
dlg_new_window;
dlg_next_button;
dlg_next_ok_buttonindex;
dlg_ok_buttoncode;
dlg_ok_label;
dlg_ok_labels;
dlg_parse_rc;
dlg_prev_button;
dlg_prev_ok_buttonindex;
dlg_print_autowrap;
dlg_print_size;
dlg_print_text;
dlg_put_backtitle;
dlg_remove_callback;
dlg_set_focus;
dlg_show_string;
dlg_strclone;
dlg_sub_window;
dlg_tab_correct_str;
dlg_trim_string;
dlg_yes_labels;
end_dialog;
init_dialog;
};
DIALOG_1.1.20070227 {
global:
dialog_dselect;
dialog_editbox;
dialog_mixedform;
dialog_mixedgauge;
dialog_pause;
dialog_progressbox;
dlg_asciibox;
dlg_boxchar;
dlg_button_to_char;
dlg_calc_list_width;
dlg_checklist;
dlg_clr_result;
dlg_color_pair;
dlg_default_formitem;
dlg_default_listitem;
dlg_draw_arrows2;
dlg_dump_keys;
dlg_editbox;
dlg_exit_buttoncode;
dlg_find_index;
dlg_form;
dlg_free_formitems;
dlg_lookup_key;
dlg_max_input;
dlg_menu;
dlg_mouse_wgetch_nowait;
dlg_move_window;
dlg_ordinate;
dlg_parse_bindkey;
dlg_print_line;
dlg_register_buttons;
dlg_register_window;
dlg_result_key;
dlg_set_result;
dlg_strempty;
dlg_trace;
dlg_trace_chr;
dlg_trace_win;
dlg_unregister_window;
dlg_yes_buttoncode;
} DIALOG_1.0.20040721;
DIALOG_1.2.20121230 {
global:
dialog_buildlist;
dialog_helpfile;
dialog_prgbox;
dialog_rangebox;
dialog_treeview;
dlg_add_callback_ref;
dlg_add_separator;
dlg_add_string;
dlg_align_columns;
dlg_allocate_gauge;
dlg_buildlist;
dlg_check_scrolled;
dlg_count_argv;
dlg_count_real_columns;
dlg_default_button;
dlg_draw_bottom_box2;
dlg_draw_box2;
dlg_draw_helpline;
dlg_draw_scrollbar;
dlg_dummy_menutext;
dlg_dump_window_keys;
dlg_eat_argv;
dlg_free_columns;
dlg_free_gauge;
dlg_get_attrs;
dlg_mouse_setcode;
dlg_need_separator;
dlg_new_modal_window;
dlg_print_listitem;
dlg_print_scrolled;
dlg_progressbox;
dlg_renamed_menutext;
dlg_restore_vars;
dlg_save_vars;
dlg_string_to_argv;
dlg_trace_msg;
dlg_treeview;
dlg_update_gauge;
dlg_wgetparent;
} DIALOG_1.1.20070227;
DIALOG_1.3.20160126 {
global:
dlg_add_help_formitem;
dlg_add_help_listitem;
dlg_add_last_key;
dlg_finish_string;
dlg_popen;
dlg_reallocate_gauge;
} DIALOG_1.2.20121230;
DIALOG_1.3.20180620 {
global:
dlg_trace_2n;
dlg_trace_2s;
dlg_ttysize;
dlg_will_resize;
} DIALOG_1.3.20160126;

View File

@ -1,29 +1,29 @@
Summary: dialog - display dialog boxes from shell scripts
%define AppProgram dialog
%define AppVersion 1.2
%define AppRelease 20130923
%define AppVersion 1.3
%define AppRelease 20180621
%define ActualProg c%{AppProgram}
# $XTermId: dialog.spec,v 1.54 2013/09/23 23:08:24 tom Exp $
# $XTermId: dialog.spec,v 1.108 2018/06/21 09:19:45 tom Exp $
Name: %{ActualProg}
Version: %{AppVersion}
Release: %{AppRelease}
License: LGPL
Group: Applications/Development
URL: ftp://invisible-island.net/%{AppProgram}
Group: Applications/System
URL: ftp://ftp.invisible-island.net/%{AppProgram}
Source0: %{AppProgram}-%{AppVersion}-%{AppRelease}.tgz
Packager: Thomas Dickey <dickey@invisible-island.net>
%description
Dialog is a program that will let you to present a variety of questions
or display messages using dialog boxes from a shell script. These
types of dialog boxes are implemented (though not all are necessarily
compiled into dialog):
Dialog is a program that will let you present a variety of questions or
display messages using dialog boxes from a shell script. These types
of dialog boxes are implemented (though not all are necessarily compiled
into dialog):
calendar, checklist, dselect, editbox, form, fselect, gauge,
infobox, inputbox, inputmenu, menu, mixedform, mixedgauge,
msgbox (message), passwordbox, passwordform, pause, progressbox,
radiolist, tailbox, tailboxbg, textbox, timebox, and yesno
(yes/no).
buildlist, calendar, checklist, dselect, editbox, form, fselect,
gauge, infobox, inputbox, inputmenu, menu, mixedform,
mixedgauge, msgbox (message), passwordbox, passwordform, pause,
prgbox, programbox, progressbox, radiolist, rangebox, tailbox,
tailboxbg, textbox, timebox, treeview, and yesno (yes/no).
This package installs as "cdialog" to avoid conflict with other packages.
%prep
@ -34,32 +34,34 @@ This package installs as "cdialog" to avoid conflict with other packages.
%build
cp -v package/dialog.map package/%{ActualProg}.map
INSTALL_PROGRAM='${INSTALL}' \
./configure \
--target %{_target_platform} \
--prefix=%{_prefix} \
--bindir=%{_bindir} \
--libdir=%{_libdir} \
--mandir=%{_mandir} \
--with-package=%{ActualProg} \
--enable-header-subdir \
--enable-nls \
--enable-widec \
--with-libtool \
--with-ncursesw \
--disable-rpath-hack
%configure \
--target %{_target_platform} \
--prefix=%{_prefix} \
--bindir=%{_bindir} \
--libdir=%{_libdir} \
--mandir=%{_mandir} \
--with-package=%{ActualProg} \
--enable-header-subdir \
--enable-nls \
--enable-widec \
--with-shared \
--with-ncursesw \
--with-versioned-syms \
--disable-rpath-hack
make
%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
make install-full DESTDIR=$RPM_BUILD_ROOT
libtool --finish %{_libdir}
strip $RPM_BUILD_ROOT%{_bindir}/%{ActualProg}
chmod 755 $RPM_BUILD_ROOT%{_libdir}/lib%{ActualProg}.so.*.*.*
rm -f $RPM_BUILD_ROOT%{_libdir}/lib%{ActualProg}.la
chmod 755 $RPM_BUILD_ROOT%{_libdir}/lib%{ActualProg}.so.*
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
@ -80,6 +82,12 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/lib%{ActualProg}.la
%changelog
# each patch should add its ChangeLog entries here
* Sat Dec 09 2017 Thomas Dickey
- update ftp url
* Thu Apr 21 2016 Thomas Dickey
- remove stray call to libtool
* Tue Oct 18 2011 Thomas Dickey
- add executable permissions for shared libraries, discard ".la" file.

202
package/dialog.sym Normal file
View File

@ -0,0 +1,202 @@
# $Id: dialog.sym,v 1.7 2018/06/21 00:32:55 tom Exp $
# script for shared library symbol-visibility using libtool
#
# This file was generated by ncu-mapsyms
# Configure options (1.0.20040721)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
# Configure options (1.1.20070227)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
# Configure options (1.2.20121230)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
# Configure options (1.3.20160126)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
# Configure options (1.3.20180620)
# --disable-leaks --enable-trace
# --disable-leaks --enable-trace --enable-widec
dialog_buildlist
dialog_calendar
dialog_checklist
dialog_dselect
dialog_editbox
dialog_form
dialog_fselect
dialog_gauge
dialog_helpfile
dialog_inputbox
dialog_menu
dialog_mixedform
dialog_mixedgauge
dialog_msgbox
dialog_pause
dialog_prgbox
dialog_progressbox
dialog_rangebox
dialog_state
dialog_tailbox
dialog_textbox
dialog_timebox
dialog_treeview
dialog_vars
dialog_version
dialog_yesno
dlg_add_callback
dlg_add_callback_ref
dlg_add_help_formitem
dlg_add_help_listitem
dlg_add_last_key
dlg_add_quoted
dlg_add_result
dlg_add_separator
dlg_add_string
dlg_align_columns
dlg_allocate_gauge
dlg_asciibox
dlg_attr_clear
dlg_auto_size
dlg_auto_sizefile
dlg_beeping
dlg_box_x_ordinate
dlg_box_y_ordinate
dlg_boxchar
dlg_buildlist
dlg_button_count
dlg_button_layout
dlg_button_sizes
dlg_button_to_char
dlg_button_x_step
dlg_calc_list_width
dlg_calc_listh
dlg_calc_listw
dlg_char_to_button
dlg_check_scrolled
dlg_checklist
dlg_clear
dlg_clr_result
dlg_color_count
dlg_color_pair
dlg_color_setup
dlg_color_table
dlg_count_argv
dlg_count_columns
dlg_count_real_columns
dlg_count_wchars
dlg_create_rc
dlg_ctl_size
dlg_default_button
dlg_default_formitem
dlg_default_item
dlg_default_listitem
dlg_defaultno_button
dlg_del_window
dlg_does_output
dlg_draw_arrows
dlg_draw_arrows2
dlg_draw_bottom_box
dlg_draw_bottom_box2
dlg_draw_box
dlg_draw_box2
dlg_draw_buttons
dlg_draw_helpline
dlg_draw_scrollbar
dlg_draw_shadow
dlg_draw_title
dlg_dummy_menutext
dlg_dump_keys
dlg_dump_window_keys
dlg_eat_argv
dlg_edit_offset
dlg_edit_string
dlg_editbox
dlg_exit
dlg_exit_buttoncode
dlg_exit_label
dlg_exiterr
dlg_find_index
dlg_finish_string
dlg_flush_getc
dlg_form
dlg_free_columns
dlg_free_formitems
dlg_free_gauge
dlg_get_attrs
dlg_getc
dlg_getc_callbacks
dlg_index_columns
dlg_index_wchars
dlg_item_help
dlg_killall_bg
dlg_last_getc
dlg_limit_columns
dlg_lookup_key
dlg_match_char
dlg_max_input
dlg_menu
dlg_mouse_bigregion
dlg_mouse_free_regions
dlg_mouse_mkbigregion
dlg_mouse_mkregion
dlg_mouse_region
dlg_mouse_setbase
dlg_mouse_setcode
dlg_mouse_wgetch
dlg_mouse_wgetch_nowait
dlg_move_window
dlg_need_separator
dlg_new_modal_window
dlg_new_window
dlg_next_button
dlg_next_ok_buttonindex
dlg_ok_buttoncode
dlg_ok_label
dlg_ok_labels
dlg_ordinate
dlg_parse_bindkey
dlg_parse_rc
dlg_popen
dlg_prev_button
dlg_prev_ok_buttonindex
dlg_print_autowrap
dlg_print_line
dlg_print_listitem
dlg_print_scrolled
dlg_print_size
dlg_print_text
dlg_progressbox
dlg_put_backtitle
dlg_reallocate_gauge
dlg_register_buttons
dlg_register_window
dlg_remove_callback
dlg_renamed_menutext
dlg_restore_vars
dlg_result_key
dlg_save_vars
dlg_set_focus
dlg_set_result
dlg_show_string
dlg_strclone
dlg_strempty
dlg_string_to_argv
dlg_sub_window
dlg_tab_correct_str
dlg_trace
dlg_trace_2n
dlg_trace_2s
dlg_trace_chr
dlg_trace_msg
dlg_trace_win
dlg_treeview
dlg_trim_string
dlg_ttysize
dlg_unregister_window
dlg_update_gauge
dlg_wgetparent
dlg_will_resize
dlg_yes_buttoncode
dlg_yes_labels
end_dialog
init_dialog

View File

@ -7,10 +7,10 @@
#
PORTNAME= cdialog
PORTVERSION= 1.2.20130923
PORTVERSION= 1.3.20180621
PORTEPOCH= 1
CATEGORIES= devel
MASTER_SITES= ftp://invisible-island.net/${PORTNAME:S|^c||}/
MASTER_SITES= ftp://ftp.invisible-island.net/${PORTNAME:S|^c||}/
DISTNAME= ${PORTNAME:S|^c||}-${PORTVERSION:R}-${PORTVERSION:E}
EXTRACT_SUFX= .tgz

32
pause.c
View File

@ -1,9 +1,9 @@
/*
* $Id: pause.c,v 1.36 2012/07/03 00:01:59 tom Exp $
* $Id: pause.c,v 1.39 2018/06/19 22:57:01 tom Exp $
*
* pause.c -- implements the pause dialog
*
* Copyright 2004-2011,2012 Thomas E. Dickey
* Copyright 2004-2012,2018 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
@ -76,22 +76,28 @@ dialog_pause(const char *title,
int result = DLG_EXIT_UNKNOWN;
int button_high = (have_buttons ? BTN_HIGH : MARGIN);
int gauge_y;
char *prompt = dlg_strclone(cprompt);
char *prompt;
int save_timeout = dialog_vars.timeout_secs;
curs_set(0);
DLG_TRACE(("# pause args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("seconds", seconds);
dlg_tab_correct_str(prompt);
curs_set(0);
dialog_vars.timeout_secs = 0;
seconds_orig = (seconds > 0) ? seconds : 1;
#ifdef KEY_RESIZE
retry:
height = old_height;
width = old_width;
#endif
prompt = dlg_strclone(cprompt);
dlg_tab_correct_str(prompt);
if (have_buttons) {
dlg_auto_size(title, prompt, &height, &width,
MIN_HIGH,
@ -125,7 +131,7 @@ dialog_pause(const char *title,
dlg_draw_title(dialog, title);
dlg_draw_helpline(dialog, FALSE);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
dlg_draw_box2(dialog,
@ -141,7 +147,7 @@ dialog_pause(const char *title,
* attribute.
*/
(void) wmove(dialog, gauge_y + MARGIN, 4);
(void) wattrset(dialog, title_attr);
dlg_attrset(dialog, title_attr);
for (i = 0; i < (width - 2 * (3 + MARGIN)); i++)
(void) waddch(dialog, ' ');
@ -156,9 +162,9 @@ dialog_pause(const char *title,
*/
x = (seconds * (width - 2 * (3 + MARGIN))) / seconds_orig;
if ((title_attr & A_REVERSE) != 0) {
wattroff(dialog, A_REVERSE);
dlg_attroff(dialog, A_REVERSE);
} else {
(void) wattrset(dialog, A_REVERSE);
dlg_attrset(dialog, A_REVERSE);
}
(void) wmove(dialog, gauge_y + MARGIN, 4);
for (i = 0; i < x; i++) {
@ -196,8 +202,12 @@ dialog_pause(const char *title,
switch (key) {
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
dlg_clear(); /* fill the background */
dlg_del_window(dialog); /* delete this window */
height = old_height;
width = old_width;
free(prompt);
refresh(); /* get it all onto the terminal */
goto retry;
#endif

View File

@ -3,67 +3,70 @@
# This file is distributed under the same license as the dialog package.
#
# Michael Piefel <piefel@informatik.hu-berlin.de>, 2002.
# Roland Illig <roland.illig@gmx.de>, 2009.
# Roland Illig <roland.illig@gmx.de>, 2009-2014.
#
msgid ""
msgstr ""
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-01-16 17:57-0500\n"
"PO-Revision-Date: 2009-11-08 23:48+0100\n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2014-09-01 12:39+0100\n"
"Last-Translator: Roland Illig <roland.illig@gmx.de>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.6.9\n"
#: buttons.c:387
#: buttons.c:385
msgid "Yes"
msgstr "Ja"
#: buttons.c:395
#: buttons.c:393
msgid "No"
msgstr "Nein"
#: buttons.c:403
#: buttons.c:401
msgid "OK"
msgstr "OK"
#: buttons.c:411
#: buttons.c:409
msgid "Cancel"
msgstr "Abbrechen"
#: buttons.c:419
#: buttons.c:417
msgid "EXIT"
msgstr "VERLASSEN"
#: buttons.c:427
#: buttons.c:425
msgid "Extra"
msgstr "Extra"
#: buttons.c:435
#: buttons.c:433
msgid "Help"
msgstr "Hilfe"
#. Headline "Month"
#: calendar.c:298
#: calendar.c:273
msgid "Month"
msgstr "Monat"
#. Headline "Year"
#: calendar.c:318
#: calendar.c:293
msgid "Year"
msgstr "Jahr"
#: dialog.c:756
#: dialog.c:741
msgid "Rename"
msgstr "Bearbeiten"
msgstr "Umbenennen"
#: fselect.c:571
#: fselect.c:550
msgid "Directories"
msgstr "Verzeichnisse"
#: fselect.c:572
#: fselect.c:551
msgid "Files"
msgstr "Dateien"
@ -107,6 +110,6 @@ msgstr "N/A"
msgid "Overall Progress"
msgstr "Gesamtfortschritt"
#: textbox.c:468
#: textbox.c:489
msgid "Search"
msgstr "Suche"

View File

@ -1,66 +1,67 @@
# Dialog
# Copyright 2003-2010,2011 # Thomas Dickey
# Copyright 2003-2014,2015 # Thomas Dickey
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: dialog 1.1.20110116\n"
"Project-Id-Version: dialog 1.2.20150510\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-01-16 17:57-0500\n"
"POT-Creation-Date: 2015-05-10 21:00-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: buttons.c:387
#: buttons.c:480
msgid "Yes"
msgstr ""
#: buttons.c:395
#: buttons.c:488
msgid "No"
msgstr ""
#: buttons.c:403
#: buttons.c:496
msgid "OK"
msgstr ""
#: buttons.c:411
#: buttons.c:504
msgid "Cancel"
msgstr ""
#: buttons.c:419
#: buttons.c:512
msgid "EXIT"
msgstr ""
#: buttons.c:427
#: buttons.c:520
msgid "Extra"
msgstr ""
#: buttons.c:435
#: buttons.c:528
msgid "Help"
msgstr ""
#. Headline "Month"
#: calendar.c:298
#: calendar.c:300
msgid "Month"
msgstr ""
#. Headline "Year"
#: calendar.c:318
#: calendar.c:322
msgid "Year"
msgstr ""
#: dialog.c:756
#: dialog.c:728
msgid "Rename"
msgstr ""
#: fselect.c:571
#: fselect.c:596
msgid "Directories"
msgstr ""
#: fselect.c:572
#: fselect.c:597
msgid "Files"
msgstr ""
@ -100,10 +101,10 @@ msgstr ""
msgid "N/A"
msgstr ""
#: mixedgauge.c:193
#: mixedgauge.c:190
msgid "Overall Progress"
msgstr ""
#: textbox.c:468
#: textbox.c:502
msgid "Search"
msgstr ""

View File

@ -7,62 +7,62 @@ msgid ""
msgstr ""
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-01-16 17:57-0500\n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2010-02-14 14:26+0100\n"
"Last-Translator: Santiago Vila Doncel <sanvila@unex.es>\n"
"Language-Team: Spanish <es@li.org>\n"
"Language-Team: Spanish <es@tp.org.es>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
#: buttons.c:387
#: buttons.c:385
msgid "Yes"
msgstr "Sí"
#: buttons.c:395
#: buttons.c:393
msgid "No"
msgstr "No"
#: buttons.c:403
#: buttons.c:401
msgid "OK"
msgstr "Aceptar"
#: buttons.c:411
#: buttons.c:409
msgid "Cancel"
msgstr "Cancelar"
#: buttons.c:419
#: buttons.c:417
msgid "EXIT"
msgstr "Salir"
#: buttons.c:427
#: buttons.c:425
msgid "Extra"
msgstr "Extra"
#: buttons.c:435
#: buttons.c:433
msgid "Help"
msgstr "Ayuda"
#. Headline "Month"
#: calendar.c:298
#: calendar.c:273
msgid "Month"
msgstr "Mes"
#. Headline "Year"
#: calendar.c:318
#: calendar.c:293
msgid "Year"
msgstr "Año"
#: dialog.c:756
#: dialog.c:741
msgid "Rename"
msgstr "Renombrar"
#: fselect.c:571
#: fselect.c:550
msgid "Directories"
msgstr "Directorios"
#: fselect.c:572
#: fselect.c:551
msgid "Files"
msgstr "Ficheros"
@ -107,6 +107,6 @@ msgstr "N/A"
msgid "Overall Progress"
msgstr "Progreso total"
#: textbox.c:468
#: textbox.c:489
msgid "Search"
msgstr "Buscar"

113
po/fur.po Normal file
View File

@ -0,0 +1,113 @@
# Dialog
# Copyright 2003-2007,2008 # Thomas Dickey
# This file is distributed under the same license as the dialog package.
# Fabio Tomat <f.t.public@gmail.com>, 2016.
msgid ""
msgstr ""
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2016-11-20 07:14+0100\n"
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
"Language-Team: Friulian <f.t.public@gmail.com>\n"
"Language: fur\n"
"X-Bugs: Report translation errors to the Language-Team address.\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: buttons.c:385
msgid "Yes"
msgstr "Sì"
#: buttons.c:393
msgid "No"
msgstr "No"
#: buttons.c:401
msgid "OK"
msgstr "OK"
#: buttons.c:409
msgid "Cancel"
msgstr "Anule"
#: buttons.c:417
msgid "EXIT"
msgstr "JES"
#: buttons.c:425
msgid "Extra"
msgstr "Adizionâl"
#: buttons.c:433
msgid "Help"
msgstr "Jutori"
#. Headline "Month"
#: calendar.c:273
msgid "Month"
msgstr "Mês"
#. Headline "Year"
#: calendar.c:293
msgid "Year"
msgstr "An"
#: dialog.c:741
msgid "Rename"
msgstr "Cambie non"
#: fselect.c:550
msgid "Directories"
msgstr "Cartelis"
#: fselect.c:551
msgid "Files"
msgstr "File"
#: mixedgauge.c:58
msgid "Succeeded"
msgstr "Riessût"
#: mixedgauge.c:61
msgid "Failed"
msgstr "Falît"
#: mixedgauge.c:64
msgid "Passed"
msgstr "Superât"
#: mixedgauge.c:67
msgid "Completed"
msgstr "Completât"
#: mixedgauge.c:70
msgid "Checked"
msgstr "Controlât"
#: mixedgauge.c:73
msgid "Done"
msgstr "Fat"
#: mixedgauge.c:76
msgid "Skipped"
msgstr "Saltât"
#: mixedgauge.c:79
msgid "In Progress"
msgstr "In cors"
#: mixedgauge.c:85
msgid "N/A"
msgstr "N/D"
#: mixedgauge.c:193
msgid "Overall Progress"
msgstr "Progrès gjenerâl"
#: textbox.c:489
msgid "Search"
msgstr "Cîr"

111
po/gd.po Normal file
View File

@ -0,0 +1,111 @@
# Scottish Gaelic translation of Dialog.
# Copyright 2003-2007,2008 # Thomas Dickey
# This file is distributed under the same license as the dialog package.
# GunChleoc <fios@foramnagaidhlig.net>, 2014.
msgid ""
msgstr ""
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2014-02-11 11:19-0000\n"
"Last-Translator: GunChleoc <fios@foramnagaidhlig.net>\n"
"Language-Team: Scottish Gaelic <fios@foramnagaidhlig.net>\n"
"Language: gd\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n==1 || n==11) ? 0 : (n==2 || n==12) ? 1 : (n > 2 && n < 20) ? 2 : 3;\n"
#: buttons.c:385
msgid "Yes"
msgstr "Tha"
#: buttons.c:393
msgid "No"
msgstr "Chan eil"
#: buttons.c:401
msgid "OK"
msgstr "Ceart ma-thà"
#: buttons.c:409
msgid "Cancel"
msgstr "Sguir dheth"
#: buttons.c:417
msgid "EXIT"
msgstr "FÀG AN-SEO"
#: buttons.c:425
msgid "Extra"
msgstr "Barrachd"
#: buttons.c:433
msgid "Help"
msgstr "Cobhair"
#. Headline "Month"
#: calendar.c:273
msgid "Month"
msgstr "Mìos"
#. Headline "Year"
#: calendar.c:293
msgid "Year"
msgstr "Bliadhna"
#: dialog.c:741
msgid "Rename"
msgstr "Cuir ainm ùr air"
#: fselect.c:550
msgid "Directories"
msgstr "Pasganan"
#: fselect.c:551
msgid "Files"
msgstr "Faidhlichean"
#: mixedgauge.c:58
msgid "Succeeded"
msgstr "Soirbheachail"
#: mixedgauge.c:61
msgid "Failed"
msgstr "Dh'fhàillig leis"
#: mixedgauge.c:64
msgid "Passed"
msgstr "Soirbheachail"
#: mixedgauge.c:67
msgid "Completed"
msgstr "Coileanta"
#: mixedgauge.c:70
msgid "Checked"
msgstr "Air a dhearbhadh"
#: mixedgauge.c:73
msgid "Done"
msgstr "Dèanta"
#: mixedgauge.c:76
msgid "Skipped"
msgstr "Air a leigeil seachad"
#: mixedgauge.c:79
msgid "In Progress"
msgstr "A' dol air adhart"
#: mixedgauge.c:85
msgid "N/A"
msgstr "Chan eil seo iomchaidh"
#: mixedgauge.c:193
msgid "Overall Progress"
msgstr "Adhartas san fharsaingeachd"
#: textbox.c:489
msgid "Search"
msgstr "Lorg"

View File

@ -8,14 +8,16 @@ msgstr ""
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2012-03-31 00:10+0200\n"
"Last-Translator: Tomislav Krznar <tomislav.krznar@gmail.com>\n"
"PO-Revision-Date: 2017-03-26 15:31+0200\n"
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"Language-Team: Croatian <lokalizacija@linux.hr>\n"
"Language: hr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
"X-Bugs: Report translation errors to the Language-Team address.\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 1.8.7.1\n"
#: buttons.c:385
msgid "Yes"
@ -31,7 +33,7 @@ msgstr "U redu"
#: buttons.c:409
msgid "Cancel"
msgstr "Otkaži"
msgstr "Odustani"
#: buttons.c:417
msgid "EXIT"
@ -81,7 +83,7 @@ msgstr "Prošlo"
#: mixedgauge.c:67
msgid "Completed"
msgstr "Dovršeno"
msgstr "Završeno"
#: mixedgauge.c:70
msgid "Checked"

View File

@ -1,19 +1,23 @@
# Dialog
# Copyright 2003, # Thomas Dickey
# Arpad Biro <biro_arpad@yahoo.com>, 2003
# Hungarian translation of dialog
# Copyright (C) 2003, 2014 Free Software Foundation, Inc.
# This file is distributed under the same license as the dialog package.
#
# Árpad Biró <biro_arpad@yahoo.com>, 2003.
# Balázs Úr <urbalazs@gmail.com>, 2014.
msgid ""
msgstr ""
"Project-Id-Version: dialog 1.0-rel20041222\n"
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2005-02-02 08:21+0100\n"
"Last-Translator: Németh Csaba <csaba@sopron.hu>\n"
"PO-Revision-Date: 2014-03-20 23:07+0100\n"
"Last-Translator: Balázs Úr <urbalazs@gmail.com>\n"
"Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: KBabel 1.0.1\n"
"X-Generator: Lokalize 1.2\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: buttons.c:385
msgid "Yes"
@ -29,7 +33,7 @@ msgstr "OK"
#: buttons.c:409
msgid "Cancel"
msgstr "Mégsem"
msgstr "Mégse"
#: buttons.c:417
msgid "EXIT"
@ -67,44 +71,43 @@ msgstr "Fájlok"
#: mixedgauge.c:58
msgid "Succeeded"
msgstr ""
msgstr "Sikerült"
#: mixedgauge.c:61
#, fuzzy
msgid "Failed"
msgstr "Fájlok"
msgstr "Meghiúsult"
#: mixedgauge.c:64
msgid "Passed"
msgstr ""
msgstr "Teljesült"
#: mixedgauge.c:67
msgid "Completed"
msgstr ""
msgstr "Befejezve"
#: mixedgauge.c:70
msgid "Checked"
msgstr ""
msgstr "Bejelölve"
#: mixedgauge.c:73
msgid "Done"
msgstr ""
msgstr "Kész"
#: mixedgauge.c:76
msgid "Skipped"
msgstr ""
msgstr "Kihagyva"
#: mixedgauge.c:79
msgid "In Progress"
msgstr ""
msgstr "Folyamatban"
#: mixedgauge.c:85
msgid "N/A"
msgstr ""
msgstr "N/A"
#: mixedgauge.c:193
msgid "Overall Progress"
msgstr ""
msgstr "Teljes folyamat"
#: textbox.c:489
msgid "Search"

View File

@ -4,70 +4,71 @@
# This file is distributed under the same license as the dialog package.
#
# Rihards Prieditis <RPrieditis@inbox.lv>, 2009.
# Rūdolfs Mazurs <rudolfs.mazurs@gmail.com>, 2014.
msgid ""
msgstr ""
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-01-16 17:57-0500\n"
"PO-Revision-Date: 2009-04-11 20:50+0300\n"
"Last-Translator: Rihards Prieditis <RPrieditis@inbox.lv>\n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2014-04-20 14:12+0300\n"
"Last-Translator: Rihards Prieditis <rprieditis@gmail.com>\n"
"Language-Team: Latvian <translation-team-lv@lists.sourceforge.net>\n"
"Language: lv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 0.3\n"
"X-Generator: Lokalize 1.5\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n"
#: buttons.c:387
#: buttons.c:385
msgid "Yes"
msgstr "Jā"
#: buttons.c:395
#: buttons.c:393
msgid "No"
msgstr "Nē"
#: buttons.c:403
#: buttons.c:401
msgid "OK"
msgstr "Labi"
#: buttons.c:411
#: buttons.c:409
msgid "Cancel"
msgstr "Atcelt"
#: buttons.c:419
#: buttons.c:417
msgid "EXIT"
msgstr "IZIET"
#: buttons.c:427
#: buttons.c:425
msgid "Extra"
msgstr "Papildus"
#: buttons.c:435
#: buttons.c:433
msgid "Help"
msgstr "Palīdzība"
#. Headline "Month"
#: calendar.c:298
#: calendar.c:273
msgid "Month"
msgstr "Mēnesis"
#. Headline "Year"
#: calendar.c:318
#: calendar.c:293
msgid "Year"
msgstr "Gads"
#: dialog.c:756
#: dialog.c:741
msgid "Rename"
msgstr "Pārdēvēt"
#: fselect.c:571
#: fselect.c:550
msgid "Directories"
msgstr "Direktorijas"
#: fselect.c:572
#: fselect.c:551
msgid "Files"
msgstr "Faili"
msgstr "Datnes"
#: mixedgauge.c:58
msgid "Succeeded"
@ -109,6 +110,6 @@ msgstr "n/z"
msgid "Overall Progress"
msgstr "Vispārējais progress"
#: textbox.c:468
#: textbox.c:489
msgid "Search"
msgstr "Meklēt"

View File

@ -1,22 +1,25 @@
# Mesajele în limba română pentru dialog.
# Copyright (C) 2003 Free Software Foundation, Inc.
# Acest fişier este distribuit sub aceeaşi licenţă ca şi pachetul dialog.
# Translation of dialog messages in Romanian.
# Copyright (C) 2015 Free Software Foundation, Inc.
# This file is distributed under the same license as the dialog package.
# Laurentiu Buzdugan <lbuz@rolix.org>, 2005.
#
# Mihai Cristescu <mihai.cristescu@archlinux.info>, 2015.
#
#
msgid ""
msgstr ""
"Project-Id-Version: dialog 1.0-rel20041222\n"
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-07-20 14:31-0400\n"
"PO-Revision-Date: 2005-01-20 12:00-0500\n"
"Last-Translator: Laurentiu Buzdugan <lbuz@rolix.org>\n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2015-03-13 19:50+0200\n"
"Last-Translator: Mihai Cristescu <mihai.cristescu@archlinux.info>\n"
"Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
"Language: ro\n"
"X-Bugs: Report translation errors to the Language-Team address.\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n"
"X-Generator: Poedit 1.7.4\n"
#: buttons.c:385
msgid "Yes"
@ -32,7 +35,7 @@ msgstr "OK"
#: buttons.c:409
msgid "Cancel"
msgstr "Renunţă"
msgstr "Renunță"
#: buttons.c:417
msgid "EXIT"
@ -49,16 +52,16 @@ msgstr "Ajutor"
#. Headline "Month"
#: calendar.c:273
msgid "Month"
msgstr "Luna"
msgstr "Lună"
#. Headline "Year"
#: calendar.c:293
msgid "Year"
msgstr "An"
#: dialog.c:744
#: dialog.c:741
msgid "Rename"
msgstr "Redenumeşte"
msgstr "Redenumește"
#: fselect.c:550
msgid "Directories"
@ -66,48 +69,47 @@ msgstr "Directoare"
#: fselect.c:551
msgid "Files"
msgstr "Fişiere"
msgstr "Fișiere"
#: mixedgauge.c:58
msgid "Succeeded"
msgstr ""
msgstr "A reușit"
#: mixedgauge.c:61
#, fuzzy
msgid "Failed"
msgstr "Fişiere"
msgstr "A eșuat"
#: mixedgauge.c:64
msgid "Passed"
msgstr ""
msgstr "A trecut"
#: mixedgauge.c:67
msgid "Completed"
msgstr ""
msgstr "Complet"
#: mixedgauge.c:70
msgid "Checked"
msgstr ""
msgstr "Verificat"
#: mixedgauge.c:73
msgid "Done"
msgstr ""
msgstr "Gata"
#: mixedgauge.c:76
msgid "Skipped"
msgstr ""
msgstr "Omis"
#: mixedgauge.c:79
msgid "In Progress"
msgstr ""
msgstr "În curs"
#: mixedgauge.c:85
msgid "N/A"
msgstr ""
msgstr "N/A"
#: mixedgauge.c:193
msgid "Overall Progress"
msgstr ""
msgstr "Progres pe ansamblu"
#: textbox.c:489
msgid "Search"

View File

@ -1,20 +1,24 @@
# Turkish translation of dialog.
# Copyright (C) 2005 dialog GNU GPL:
# This file is distributed under the same license as the dialog package.
# Abdullah Ulas <potkal@bioinformatics.org>, 2005.
#
#, fuzzy
# Abdullah Ulas <potkal@bioinformatics.org>, 2005.
# Volkan Gezer <volkangezer@gmail.com>, 2017.
msgid ""
msgstr ""
"Project-Id-Version: dialog 1.0-rel20041222\n"
"Project-Id-Version: dialog 1.1.20080819\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-06-18 18:26-0400\n"
"PO-Revision-Date: 2005-04-08 18:29+0300\n"
"Last-Translator: Abdullah Ulas <potkal@bioinformatics.org>\n"
"PO-Revision-Date: 2017-05-05 12:35+0100\n"
"Last-Translator: Volkan Gezer <volkangezer@gmail.com>\n"
"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Bugs: Report translation errors to the Language-Team address.\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Lokalize 2.0\n"
#: buttons.c:385
msgid "Yes"
@ -68,44 +72,43 @@ msgstr "Dosyalar"
#: mixedgauge.c:58
msgid "Succeeded"
msgstr ""
msgstr "Başarılı"
#: mixedgauge.c:61
#, fuzzy
msgid "Failed"
msgstr "Dosyalar"
msgstr "Başarısız"
#: mixedgauge.c:64
msgid "Passed"
msgstr ""
msgstr "Geçti"
#: mixedgauge.c:67
msgid "Completed"
msgstr ""
msgstr "Tamamlandı"
#: mixedgauge.c:70
msgid "Checked"
msgstr ""
msgstr "Denetlendi"
#: mixedgauge.c:73
msgid "Done"
msgstr ""
msgstr "Bitti"
#: mixedgauge.c:76
msgid "Skipped"
msgstr ""
msgstr "Atlandı"
#: mixedgauge.c:79
msgid "In Progress"
msgstr ""
msgstr "Devam Etmekte"
#: mixedgauge.c:85
msgid "N/A"
msgstr ""
msgstr "N/A"
#: mixedgauge.c:193
msgid "Overall Progress"
msgstr ""
msgstr "Genel İlerleme"
#: textbox.c:489
msgid "Search"

View File

@ -1,9 +1,9 @@
/*
* $Id: prgbox.c,v 1.9 2012/12/02 23:40:30 tom Exp $
* $Id: prgbox.c,v 1.13 2016/01/27 01:37:26 tom Exp $
*
* prgbox.c -- implements the prg box
*
* Copyright 2011,2012 Thomas E. Dickey
* Copyright 2011-2014,2016 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
@ -32,7 +32,7 @@ reapchild(int sig)
/*
* Open a pipe which ties stderr and stdout together.
*/
static FILE *
FILE *
dlg_popen(const char *command, const char *type)
{
FILE *result = 0;
@ -67,8 +67,8 @@ dlg_popen(const char *command, const char *type)
* given command. Also, it needs the command to be parsed into
* tokens.
*/
if ((blob = malloc(4 + strlen(command))) != 0) {
sprintf(blob, "-c %s", command);
if ((blob = malloc(10 + strlen(command))) != 0) {
sprintf(blob, "sh -c \"%s\"", command);
argv = dlg_string_to_argv(blob);
execvp("sh", argv);
}

View File

@ -1,10 +1,10 @@
/*
* $Id: progressbox.c,v 1.23 2012/12/21 10:00:05 tom Exp $
* $Id: progressbox.c,v 1.47 2018/06/21 09:14:47 tom Exp $
*
* progressbox.c -- implements the progress box
*
* Copyright 2005 Valery Reznic
* Copyright 2006-2012 Thomas E. Dickey
* Copyright 2006-2014,2018 Thomas E. Dickey
* Copyright 2005 Valery Reznic
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
@ -26,35 +26,150 @@
#include <dialog.h>
#include <dlg_keys.h>
#ifdef KEY_RESIZE
#include <errno.h>
#endif
#define MIN_HIGH (4)
#define MIN_WIDE (10 + 2 * (2 + MARGIN))
#ifdef KEY_RESIZE
typedef struct _wrote {
struct _wrote *link;
char *text;
} WROTE;
#endif
typedef struct {
DIALOG_CALLBACK obj;
WINDOW *text;
char *prompt;
int high, wide;
int old_high, old_wide;
char line[MAX_LEN + 1];
int is_eof;
#ifdef KEY_RESIZE
WROTE *wrote;
#endif
} MY_OBJ;
static void
free_obj(MY_OBJ * obj)
{
dlg_del_window(obj->obj.win);
free(obj->prompt);
#ifdef KEY_RESIZE
while (obj->wrote) {
WROTE *wrote = obj->wrote;
obj->wrote = wrote->link;
free(wrote->text);
free(wrote);
}
#endif
free(obj);
}
static void
restart_obj(MY_OBJ * obj)
{
free(obj->prompt);
obj->high = obj->old_high;
obj->wide = obj->old_wide;
dlg_clear();
dlg_del_window(obj->obj.win);
}
static void
start_obj(MY_OBJ * obj, const char *title, const char *cprompt)
{
int y, x, thigh;
int i;
obj->prompt = dlg_strclone(cprompt);
dlg_tab_correct_str(obj->prompt);
dlg_auto_size(title, obj->prompt, &obj->high, &obj->wide, MIN_HIGH, MIN_WIDE);
dlg_print_size(obj->high, obj->wide);
dlg_ctl_size(obj->high, obj->wide);
x = dlg_box_x_ordinate(obj->wide);
y = dlg_box_y_ordinate(obj->high);
thigh = obj->high - (2 * MARGIN);
obj->obj.win = dlg_new_window(obj->high, obj->wide, y, x);
dlg_draw_box2(obj->obj.win,
0, 0,
obj->high, obj->wide,
dialog_attr,
border_attr,
border2_attr);
dlg_draw_title(obj->obj.win, title);
dlg_draw_helpline(obj->obj.win, FALSE);
if (obj->prompt[0] != '\0') {
int y2, x2;
dlg_attrset(obj->obj.win, dialog_attr);
dlg_print_autowrap(obj->obj.win, obj->prompt, obj->high, obj->wide);
getyx(obj->obj.win, y2, x2);
(void) x2;
++y2;
wmove(obj->obj.win, y2, MARGIN);
for (i = 0; i < getmaxx(obj->obj.win) - 2 * MARGIN; i++)
(void) waddch(obj->obj.win, dlg_boxchar(ACS_HLINE));
y += y2;
thigh -= y2;
}
/* Create window for text region, used for scrolling text */
obj->text = dlg_sub_window(obj->obj.win,
thigh,
obj->wide - (2 * MARGIN),
y + MARGIN,
x + MARGIN);
(void) wrefresh(obj->obj.win);
(void) wmove(obj->obj.win, getmaxy(obj->text), (MARGIN + 1));
(void) wnoutrefresh(obj->obj.win);
dlg_attr_clear(obj->text, getmaxy(obj->text), getmaxx(obj->text), dialog_attr);
}
/*
* Return current line of text.
*/
static char *
get_line(MY_OBJ * obj)
get_line(MY_OBJ * obj, int *restart)
{
FILE *fp = obj->obj.input;
int col = 0;
int j, tmpint, ch;
char *result = obj->line;
*restart = 0;
for (;;) {
if ((ch = getc(fp)) == EOF) {
obj->is_eof = 1;
if (col) {
ch = getc(fp);
#ifdef KEY_RESIZE
/* SIGWINCH may have interrupted this - try to ignore if resizable */
if (ferror(fp)) {
switch (errno) {
case EINTR:
clearerr(fp);
continue;
default:
break;
} else {
return NULL;
}
}
#endif
if (feof(fp) || ferror(fp)) {
obj->is_eof = 1;
if (!col) {
result = NULL;
}
break;
}
if (ch == '\n')
break;
if (ch == '\r')
@ -80,36 +195,84 @@ get_line(MY_OBJ * obj)
obj->line[col] = '\0';
return obj->line;
#ifdef KEY_RESIZE
if (result != NULL) {
WINDOW *win = obj->text;
WROTE *wrote = dlg_calloc(WROTE, 1);
if (wrote != 0) {
wrote->text = dlg_strclone(obj->line);
wrote->link = obj->wrote;
obj->wrote = wrote;
}
nodelay(win, TRUE);
if ((ch = wgetch(win)) == KEY_RESIZE) {
*restart = 1;
}
nodelay(win, FALSE);
}
#endif
return result;
}
/*
* Print a new line of text.
*/
static void
print_line(MY_OBJ * obj, WINDOW *win, int row, int width)
print_line(MY_OBJ * obj, const char *line, int row)
{
int i, y, x;
char *line = obj->line;
int width = obj->wide - (2 * MARGIN);
int limit = MIN((int) strlen(line), width - 2);
(void) wmove(win, row, 0); /* move cursor to correct line */
(void) waddch(win, ' ');
#ifdef NCURSES_VERSION
(void) waddnstr(win, line, MIN((int) strlen(line), width - 2));
#else
line[MIN((int) strlen(line), width - 2)] = '\0';
waddstr(win, line);
#endif
(void) wmove(obj->text, row, 0); /* move cursor to correct line */
wprintw(obj->text, " %.*s", limit, line);
wclrtoeol(obj->text);
}
getyx(win, y, x);
(void) y;
/* Clear 'residue' of previous line */
for (i = 0; i < width - x; i++)
(void) waddch(win, ' ');
#ifdef KEY_RESIZE
static int
wrote_size(MY_OBJ * obj, int want)
{
int result = 0;
WROTE *wrote = obj->wrote;
while (wrote != NULL && want > 0) {
wrote = wrote->link;
want--;
result++;
}
return result;
}
static const char *
wrote_data(MY_OBJ * obj, int want)
{
const char *result = NULL;
WROTE *wrote = obj->wrote;
while (wrote != NULL && want > 0) {
result = wrote->text;
wrote = wrote->link;
want--;
}
return result;
}
static int
pause_for_ok(WINDOW *dialog, int height, int width)
reprint_lines(MY_OBJ * obj, int buttons)
{
int want = getmaxy(obj->text) - (buttons ? 2 : 0);
int have = wrote_size(obj, want);
int n;
for (n = 0; n < have; ++n) {
print_line(obj, wrote_data(obj, have - n), n);
}
(void) wrefresh(obj->text);
return have;
}
#endif
static int
pause_for_ok(MY_OBJ * obj, const char *title, const char *cprompt)
{
/* *INDENT-OFF* */
static DLG_KEYS_BINDING binding[] = {
@ -125,30 +288,33 @@ pause_for_ok(WINDOW *dialog, int height, int width)
int result = DLG_EXIT_UNKNOWN;
const char **buttons = dlg_ok_label();
int check;
int save_nocancel = dialog_vars.nocancel;
bool save_nocancel = dialog_vars.nocancel;
bool redraw = TRUE;
dialog_vars.nocancel = TRUE;
button = dlg_default_button();
dlg_register_window(dialog, "progressbox", binding);
dlg_register_buttons(dialog, "progressbox", buttons);
#ifdef KEY_RESIZE
restart:
#endif
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
mouse_mkbutton(height - 2, width / 2 - 4, 6, '\n');
dlg_register_window(obj->obj.win, "progressbox", binding);
dlg_register_buttons(obj->obj.win, "progressbox", buttons);
dlg_draw_bottom_box2(obj->obj.win, border_attr, border2_attr, dialog_attr);
while (result == DLG_EXIT_UNKNOWN) {
if (redraw) {
redraw = FALSE;
if (button < 0)
button = 0;
dlg_draw_buttons(dialog,
height - 2, 0,
dlg_draw_buttons(obj->obj.win,
obj->high - 2, 0,
buttons, button,
FALSE, width);
FALSE, obj->wide);
}
key = dlg_mouse_wgetch(dialog, &fkey);
key = dlg_mouse_wgetch(obj->obj.win, &fkey);
if (dlg_result_key(key, fkey, &result))
break;
@ -170,6 +336,15 @@ pause_for_ok(WINDOW *dialog, int height, int width)
case DLGK_ENTER:
result = dlg_ok_buttoncode(button);
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(obj->obj.win);
restart_obj(obj);
start_obj(obj, title, cprompt);
reprint_lines(obj, TRUE);
redraw = TRUE;
goto restart;
#endif
default:
if (is_DLGK_MOUSE(key)) {
result = dlg_ok_buttoncode(key - M_EVENT);
@ -185,7 +360,8 @@ pause_for_ok(WINDOW *dialog, int height, int width)
beep();
}
}
dlg_unregister_window(dialog);
dlg_mouse_free_regions();
dlg_unregister_window(obj->obj.win);
dialog_vars.nocancel = save_nocancel;
return result;
@ -200,90 +376,85 @@ dlg_progressbox(const char *title,
FILE *fp)
{
int i;
int x, y, thigh;
WINDOW *dialog, *text;
MY_OBJ *obj;
char *prompt = dlg_strclone(cprompt);
int again = 0;
int toprow = 0;
int result;
dlg_tab_correct_str(prompt);
dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, MIN_WIDE);
dlg_print_size(height, width);
dlg_ctl_size(height, width);
x = dlg_box_x_ordinate(width);
y = dlg_box_y_ordinate(height);
thigh = height - (2 * MARGIN);
dialog = dlg_new_window(height, width, y, x);
dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
dlg_draw_title(dialog, title);
dlg_draw_helpline(dialog, FALSE);
if (*prompt != '\0') {
int y2, x2;
(void) wattrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
getyx(dialog, y2, x2);
(void) x2;
++y2;
wmove(dialog, y2, MARGIN);
for (i = 0; i < getmaxx(dialog) - 2 * MARGIN; i++)
(void) waddch(dialog, dlg_boxchar(ACS_HLINE));
y += y2;
thigh -= y2;
}
/* Create window for text region, used for scrolling text */
text = dlg_sub_window(dialog,
thigh,
width - (2 * MARGIN),
y + MARGIN,
x + MARGIN);
(void) wrefresh(dialog);
(void) wmove(dialog, thigh, (MARGIN + 1));
(void) wnoutrefresh(dialog);
DLG_TRACE(("# progressbox args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("pause", pauseopt);
DLG_TRACE2N("fp", fp ? fileno(fp) : -1);
obj = dlg_calloc(MY_OBJ, 1);
assert_ptr(obj, "dlg_progressbox");
obj->obj.input = fp;
obj->obj.win = dialog;
obj->text = text;
dlg_attr_clear(text, thigh, getmaxx(text), dialog_attr);
for (i = 0; get_line(obj); i++) {
if (i < thigh) {
print_line(obj, text, i, width - (2 * MARGIN));
} else {
scrollok(text, TRUE);
scroll(text);
scrollok(text, FALSE);
print_line(obj, text, thigh - 1, width - (2 * MARGIN));
obj->high = height;
obj->wide = width;
#ifdef KEY_RESIZE
obj->old_high = height;
obj->old_wide = width;
curs_set(0);
restart:
#endif
start_obj(obj, title, cprompt);
#ifdef KEY_RESIZE
if (again) {
toprow = reprint_lines(obj, FALSE);
}
#endif
for (i = toprow; get_line(obj, &again); i++) {
#ifdef KEY_RESIZE
if (again) {
dlg_will_resize(obj->obj.win);
restart_obj(obj);
goto restart;
}
(void) wrefresh(text);
dlg_trace_win(dialog);
#endif
if (i < getmaxy(obj->text)) {
print_line(obj, obj->line, i);
} else {
scrollok(obj->text, TRUE);
scroll(obj->text);
scrollok(obj->text, FALSE);
print_line(obj, obj->line, getmaxy(obj->text) - 1);
}
(void) wrefresh(obj->text);
if (obj->is_eof)
break;
}
dlg_trace_win(obj->obj.win);
curs_set(1);
if (pauseopt) {
scrollok(text, TRUE);
wscrl(text, 1 + MARGIN);
(void) wrefresh(text);
result = pause_for_ok(dialog, height, width);
int need = 1 + MARGIN;
int base = getmaxy(obj->text) - need;
if (i >= base) {
i -= base;
if (i > need)
i = need;
if (i > 0) {
scrollok(obj->text, TRUE);
}
wscrl(obj->text, i);
}
(void) wrefresh(obj->text);
result = pause_for_ok(obj, title, cprompt);
} else {
wrefresh(dialog);
wrefresh(obj->obj.win);
result = DLG_EXIT_OK;
}
dlg_del_window(dialog);
free(prompt);
free(obj);
free_obj(obj);
return result;
}

View File

@ -1,9 +1,9 @@
/*
* $Id: rangebox.c,v 1.17 2013/03/17 16:02:00 tom Exp $
* $Id: rangebox.c,v 1.24 2018/06/19 22:57:01 tom Exp $
*
* rangebox.c -- implements the rangebox dialog
*
* Copyright 2012,2013 Thomas E. Dickey
* Copyright 2012-2017,2018 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
@ -128,7 +128,7 @@ draw_value(VALUE * data, int value)
scaled = offset;
}
(void) wattrset(win, gauge_attr);
dlg_attrset(win, gauge_attr);
wmove(win, data->slide_y, data->slide_x);
for (n = 0; n < data->slide_len; ++n) {
(void) waddch(win, ' ');
@ -136,9 +136,9 @@ draw_value(VALUE * data, int value)
wmove(win, data->slide_y, data->value_x);
wprintw(win, "%*d", data->value_len, value);
if ((gauge_attr & A_REVERSE) != 0) {
wattroff(win, A_REVERSE);
dlg_attroff(win, A_REVERSE);
} else {
(void) wattrset(win, A_REVERSE);
dlg_attrset(win, A_REVERSE);
}
wmove(win, data->slide_y, data->slide_x);
for (n = 0; n < scaled; ++n) {
@ -148,17 +148,17 @@ draw_value(VALUE * data, int value)
}
(void) waddch(win, ch2);
}
(void) wattrset(win, dialog_attr);
dlg_attrset(win, dialog_attr);
wmove(win, y, x);
data->current = value;
dlg_trace_msg("drew %d offset %d scaled %d limit %d inc %d\n",
value,
offset,
scaled,
data->slide_len,
data->slide_inc);
DLG_TRACE(("# drew %d offset %d scaled %d limit %d inc %d\n",
value,
offset,
scaled,
data->slide_len,
data->slide_inc));
dlg_trace_win(win);
}
@ -181,7 +181,7 @@ dialog_rangebox(const char *title,
DLG_KEYS_DATA( DLGK_DELETE_RIGHT,KEY_DC ),
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
DLG_KEYS_DATA( DLGK_ENTER, ' ' ),
TOGGLEKEY_BINDINGS,
DLG_KEYS_DATA( DLGK_FIELD_NEXT, CHR_NEXT ),
DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
@ -215,13 +215,22 @@ dialog_rangebox(const char *title,
WINDOW *dialog;
int state = dlg_default_button();
const char **buttons = dlg_ok_labels();
char *prompt = dlg_strclone(cprompt);
char *prompt;
char buffer[MAX_LEN];
int cur_value = default_value;
int usable;
int ranges;
int yorg, xorg;
DLG_TRACE(("# tailbox args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("minval", min_value);
DLG_TRACE2N("maxval", max_value);
DLG_TRACE2N("default", default_value);
if (max_value < min_value)
max_value = min_value;
if (cur_value > max_value)
@ -235,7 +244,9 @@ dialog_rangebox(const char *title,
retry:
#endif
prompt = dlg_strclone(cprompt);
dlg_auto_size(title, prompt, &height, &width, 0, 0);
height += MIN_HIGH;
if (width < MIN_WIDE)
width = MIN_WIDE;
@ -298,7 +309,7 @@ dialog_rangebox(const char *title,
dlg_draw_title(dialog, title);
dlg_draw_helpline(dialog, FALSE);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
dlg_trace_win(dialog);
@ -321,6 +332,7 @@ dialog_rangebox(const char *title,
/* handle function-keys */
if (fkey) {
switch (key) {
case DLGK_TOGGLE:
case DLGK_ENTER:
result = dlg_ok_buttoncode(button);
break;
@ -374,13 +386,14 @@ dialog_rangebox(const char *title,
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
/* repaint */
free(prompt);
dlg_clear();
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
goto retry;
#endif

25
rc.c
View File

@ -1,9 +1,9 @@
/*
* $Id: rc.c,v 1.51 2012/11/30 21:32:39 tom Exp $
* $Id: rc.c,v 1.53 2018/05/31 20:32:15 tom Exp $
*
* rc.c -- routines for processing the configuration file
*
* Copyright 2000-2011,2012 Thomas E. Dickey
* Copyright 2000-2012,2018 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
@ -69,11 +69,8 @@ typedef enum {
/* number of configuration variables */
#define VAR_COUNT (sizeof(vars) / sizeof(vars_st))
/* check if character is white space */
#define whitespace(c) (c == ' ' || c == TAB)
/* check if character is string quoting characters */
#define isquote(c) (c == '"' || c == '\'')
#define isquote(c) ((c) == '"' || (c) == '\'')
/* get last character of string */
#define lastch(str) str[strlen(str)-1]
@ -130,7 +127,7 @@ static const vars_st vars[] =
static int
skip_whitespace(char *str, int n)
{
while (whitespace(str[n]) && str[n] != '\0')
while (isblank(UCH(str[n])) && str[n] != '\0')
n++;
return n;
}
@ -246,13 +243,13 @@ str_to_attr(char *str, int *fg, int *bg, int *hl)
part = tempstr + i; /* set 'part' to start of fg/bg string */
/* find end of fg/bg string */
while (!whitespace(tempstr[i]) && tempstr[i] != ','
while (!isblank(UCH(tempstr[i])) && tempstr[i] != ','
&& tempstr[i] != '\0')
i++;
if (tempstr[i] == '\0')
return -1; /* invalid representation */
else if (whitespace(tempstr[i])) { /* not yet ',' */
else if (isblank(UCH(tempstr[i]))) { /* not yet ',' */
tempstr[i++] = '\0';
/* skip white space before ',' */
@ -284,7 +281,7 @@ str_to_attr(char *str, int *fg, int *bg, int *hl)
/* trim trailing white space from highlight string */
i = (int) strlen(part) - 1;
while (whitespace(part[i]) && i > 0)
while (isblank(UCH(part[i])) && i > 0)
i--;
part[i + 1] = '\0';
@ -353,7 +350,7 @@ parse_line(char *line, char **var, char **value)
*var = line + i++; /* skip to next character */
/* find end of variable name */
while (!whitespace(line[i]) && line[i] != '=' && line[i] != '\0')
while (!isblank(UCH(line[i])) && line[i] != '=' && line[i] != '\0')
i++;
if (line[i] == '\0') /* syntax error */
@ -382,7 +379,7 @@ parse_line(char *line, char **var, char **value)
/* trim trailing white space from 'value' */
i = (int) strlen(*value) - 1;
while (whitespace((*value)[i]) && i > 0)
while (isblank(UCH((*value)[i])) && i > 0)
i--;
(*value)[i + 1] = '\0';
@ -524,10 +521,10 @@ dlg_parse_rc(void)
return 0; /* step (c) failed, use default values */
}
DLG_TRACE(("opened rc file \"%s\"\n", tempptr));
DLG_TRACE(("# opened rc file \"%s\"\n", tempptr));
/* Scan each line and set variables */
while ((result == 0) && (fgets(str, MAX_LEN, rc_file) != NULL)) {
DLG_TRACE(("rc:%s", str));
DLG_TRACE(("#\t%s", str));
if (*str == '\0' || lastch(str) != '\n') {
/* ignore rest of file if line too long */
fprintf(stderr, "\nParse error: line %d of configuration"

29
samples/copifuncs/copi.ifman1 Executable file
View File

@ -0,0 +1,29 @@
#! /usr/bin/perl
#
# This is a utility script to manipulate Fidonet-related issues
# using Eugene Crosser's ifmail package
#
# Version 0.1
#
# (C) Michael Bravo and The Communication Tube, 1994
#
# You can do whatever you want with this script. I take no responsibility
# whatsoever in anything related to this script. If you make some useful
# additions to this, please think of sending them to me so I could partake
# of your wisdom.
#
# This script was written to help attaching and requesting files from the
# commandline, much like you do with Squish under DOS or OS/2. It is certainly
# not perfect - I used it as an exercise in Perl. It also probably lacks
# some other useful features, like ability to specify trunc/sent or kill/sent
# attributes etc etc. If you really want this or some other features
# implemented, write me at mbravo@tctube.spb.su or mbravo@octopus.spb.su
# and I will try to do what I can.
#
# Note - files don't get copied to any spool dir, so if you move attached
# files somewhere, they won't get sent.
#
# This script is supposed to read ifmail's config to determine where outbound
# directory and logfile are. The only two parameters to modify in most cases
# are below.

68
samples/copifuncs/copi.ifmcfg2 Executable file
View File

@ -0,0 +1,68 @@
# Transport programs for mail and news, used by iftoss
sendmail /usr/lib/sendmail -f $F $T
rnews /usr/lib/news/rnews
# Unpackers, used by ifunpack.
# $F expands to archieve file name
unzip /usr/bin/unzip -oq $F
unarj /usr/bin/unarj e $F
#unarc /usr/bin/unpack $F
unzoo /usr/bin/zoo -extract $F
unlzh /usr/bin/lharc -x $F
# Packer program, used by ifpack
# $F expands to archieve file name, $P - to list of packet names
packer /usr/bin/zip $F $P
# Maximum arcmail file size, will start new arcmail file if exceeds
maxfsize 65000
# Maximum packet size, ifmail/ifnews will start new packet if exeeds.
# .out files are NOT created if nonzero specified, you must run ifpack
# to make packets out. (unimplemented)
maxpsize 65000
# cnews log file and (temporary) database for seen-bys
newslog /usr/lib/news/log
msgidbm /tmp/ifmsgids
# From this line on, values may be prefixed by a logical expression in
# round brackets. Operators are: '!', '&', '|', 'Xor'.
# Possible elements are:
# - Nodelist flags (like "CM", "MNP", "V32" etc.)
# - speed <operator> <numeric>
# where <operator> is '=', '!=', '<', '>', '<=', '>='
# - address <wildcard>
# where <wildcard> is an (possibly incomplete) fidonet address,
# e.g. "5020/*"
# - time <interval>[,<interval>,...]
# where <interval> is a day spec. with optional time spec., e.g.
# Wk2000-0900,Sat1800-0000,Sun
# - phone <prefix>
# e.g. "phone 7-095-"
# Dialing parameters
# of multiple "ModemPort", "ModemReset", "ModemDial", "ModemHangup" lines,
# first matching is used.
# of multiple "PhoneTrans", "ModemConnect", "ModemError" lines, all matching
# are used.
# In send and expect strings, following substitutions are made:
# \\ '\' character
# \r carriage return (0x0d)
# \n new line (0x0a)
# \t tab (0x09)
# \b backspace (0x08)
# \s space (0x20)
# \NNN (where N is an octal digit) - character with octal code NNN
# \d 1 second delay (send strings only)
# \p 1/4 second pause (send strings only)
# \T translated telephone no. (send strings only)
# \D untranslated telephone no. (send strings only)
# ModemPort present a blank-separated list of ports with possible speed
# extention (separated by colon); if speed is prefixed with 'L', it is
# a "locked" port speed, otherwise it is a maximum speed to be set, while
# actual speed is taken from the nodelist. If speed is omitted (or set
# to zero), previous port speed is not changed.
#ModemPort (time Any0000-0900,Sat,Sun) ttyS0
#ModemPort cua0:L38400

30
samples/copifuncs/copi.ifmcfg4 Executable file
View File

@ -0,0 +1,30 @@
ModemHangup +++ATH\r
ModemOK OK
ModemConnect CONNECT
ModemError BUSY
ModemError NO\sCARRIER
ModemError NO\sDIAL
ModemError RING\r
ModemError ERROR
# Call options (time, address and nodelist flag dependant)
# All matching are applied in the order they are specified.
# Possible options are "[No]Call", "[No]Hold", "[No]PUA", "[No]EMSI",
# "[No]WaZOO", "[No]Freqs", "[No]Zmodem", "[No]ZedZap", "[No]Janus",
# "[No]Hydra". Here, WaZOO stands for YooHoo/2U2 handshake, not for
# the transfer scheme. FTS-0001 handshake and DietIFNA scheme cannot
# be disallowed (because they are mandatory by standart). "Hold"
# means really hold "hold" type packets and files: do not send them
# if our system initiated the session, "NoHold" means send "hold"
# packets when our system initiated the session. "NoPUA" stands for
# "No PickUp All", i.e. PUP ("Pick Up Primary"). NoCall means do not
# perform outbound call. This flag has no effect on the nodes
# explicitly specified in the command line.
# Default options are "everything allowed".
# options ((!CM) & time Any0700-0200) Nocall
#options (time Any0900-2100 & ! address 2:5020/*) Nocall
# EMSI data for this node
# From this line on values CANNOT be prefixed with logical expression
# For now, escaping of '}' and ']' unimplemented, try to avoid these
# characters please!

14
samples/copifuncs/copi.ifmcfg5 Executable file
View File

@ -0,0 +1,14 @@
# PhoneTrans lines provide rules to change phone prefixes to make local
# or long-distance calls. In the example below, my country code is 7,
# and local dialing area is 095. From the numbers starting with "7-095-"
# the prefix is stripped and the 7-digit remainder is dialed. For
# the numbers starting with "7-" but not with "7-095-", the country prefix
# "7-" is stripped and the long-distance dialing prefix "8W" substituted.
# For the numbers not matching any of the above, international
# call is performed: international dialing prefix "8W10" is prepended
# to the unmodified 11-digit number. Generally, the syntax is:
# "PhoneTrans <what-to-strip> / <what-to-substitute-instead>"
#PhoneTrans 7-095- /
#PhoneTrans 7- / 8W
#PhoneTrans / 8W10

9
samples/copifuncs/copi.ifpoll1 Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
# ver 0.7
# ifpoll, poll my boss node or the node given as argument 1
#
# i start this shell script every day by crond, but you can
# start it also by hand :) start it as the owner of ifcico.
# rasca, berlin 1993 (Rasca Gmelch, 2:2410/305.4)
#
# where "ifcico" and "ifpack" reside

20
samples/copifuncs/copi.ifreq1 Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/perl
$ver = "0.4";
#
# this perl script is designed for the ifmail package by eugene grosser.
#
# request a file (first argument) from a fido-node (second argument),
# don't forget to quote if you use wildcards, e.g.:
# ifreq 'files*' 2:2410/305
# or
# ifreq 'files newfile' 2:2410/305
#
# this perl script does only add an entry to the corresponding flo-file,
# the mailer ifcico is not started!
#
# rasca, berlin 1994 (rasca@marie.physik.tu-berlin.de, 2:2410/305.4)
#
# multi-zone support added by
# Roland Rosenfeld 15.05.1994 (roland@p13.flokiste.fido.de, 2:2450/300.13)

79
samples/copifuncs/copi.rcnews Executable file
View File

@ -0,0 +1,79 @@
#! /bin/sh
## $Revision: 1.1 $
## News boot script.
## =()<. @<_PATH_SHELLVARS>@>()=
. /usr/lib/news/innshellvars
## Pick ${INND} or ${INNDSTART}
WHAT=${INNDSTART}
## Set to true or false
DOINNWATCH=false
MAIL="${MAILCMD} -s 'Boot-time Usenet warning on `hostname`' ${NEWSMASTER}"
## RFLAG is set below; set FLAGS as appropriate.
RFLAG=""
FLAGS="-i0 -c0"
## Clean shutdown?
if [ -f ${SERVERPID} ] ; then
( echo 'INND: PID file exists -- unclean shutdown!' >/dev/console )
RFLAG="-r"
fi
if [ ! -f ${NEWSLIB}/.news.daily ] ; then
echo 'No .news.daily file; need to run news.daily?' | eval ${MAIL}
else
case `find ${NEWSLIB} -name .news.daily -mtime +1 -print 2>/dev/null` in
"")
;;
*)
echo 'Old .news.daily file; need to run news.daily?' | eval ${MAIL}
;;
esac
fi
## Active file recovery.
if [ ! -s ${ACTIVE} ] ; then
if [ -s ${NEWACTIVE} ] ; then
mv ${NEWACTIVE} ${ACTIVE}
else
if [ -s ${OLDACTIVE} ] ; then
cp ${OLDACTIVE} ${ACTIVE}
else
( echo 'INND: No active file!' >/dev/console )
exit 1
fi
fi
RFLAG="-r"
# You might want to rebuild the DBZ database, too:
#echo "cd ${NEWSLIB} \
# && makehistory -r \
# && mv history.n.dir history.dir \
# && mv history.n.pag history.pag" | su ${NEWSUSER}
fi
## Remove temporary batchfiles and lock files.
( cd ${BATCH} && rm -f bch* )
( cd ${LOCKS} && rm -f LOCK* )
( cd ${TEMPSOCKDIR} && rm -f ${TEMPSOCK} )
rm -f ${NEWSCONTROL} ${NNTPCONNECT} ${SERVERPID}
## Start the show.
( echo 'Starting innd.' >/dev/console )
eval ${WHAT} ${RFLAG} ${FLAGS}
# Gee, looks like lisp, doesn't it?
${DOINNWATCH} && {
echo "( ( sleep 60 ; ${INNWATCH} ) & )" | su ${NEWSUSER}
}
RMFILE=${MOST_LOGS}/expire.rm
if [ -s ${MOST_LOGS}/expire.rm ] ; then
( echo "Removing articles from pre-downtime expire run." >/dev/console )
(
echo 'System shut down during expire. Unlinking articles listed in'
echo ${RMFILE}
) | eval ${MAIL}
echo "${NEWSBIN}/expirerm ${RMFILE}" | su ${NEWSUSER} &
fi

15
samples/copifuncs/copi.sendifm2 Executable file
View File

@ -0,0 +1,15 @@
${SITE} ${BATCHFILE}
echo "${PROGNAME}: [$$] end ${SITE}"
done
case ${HAVE_UUSTAT} in
DONT)
rm -f ${TEMP}
;;
esac
## Remove the lock file.
rm -f ${LOCK}
echo "${PROGNAME}: [$$] end `date`"

View File

@ -0,0 +1,13 @@
TRNINIT="-x -e -X -F\" :> \""
HIDELINE="^X-FTN"
NEWSHEADER="Newsgroups: %(%F=^\$?%C:%F)
Subject: %(%S=^\$?%\"\n\nSubject: \":%S)
%(%R=^\$?:References: %R
)Sender:
Distribution: %(%i=^\$?%\"\nDistribution: \":%D)
Organization: %o
X-Comment-To: %f\n\n"
ATTRIBUTION="%f writes:\n"
YOUSAID="In article %i \n of newsgroup %C you write about \"%s\":\n"
MAILCALL="(New Mail)"
export NEWSHEADER HIDELINE TRNINIT ATTRIBUTION MAILCALL YOUSAID EDITOR

101
samples/copifuncs/ifpatch Normal file
View File

@ -0,0 +1,101 @@
--- ifgate/message.c.orig Mon Jul 24 15:17:47 1995
+++ ifgate/message.c Mon Jul 24 15:18:00 1995
@@ -48,12 +48,26 @@
if (!strcasecmp(msg->key,"X-UUCP-From")) return 0;
if (!strcasecmp(msg->key,"X-Body-Start")) return 0;
if (!strncasecmp(msg->key,"X-FTN-",6)) return 0;
- if (!strcasecmp(msg->key,"Path")) return isftnpath(msg->val)?0:1;
+ if (!strcasecmp(msg->key,"Path"))
+
+#ifdef LESS_RFC_KLUDGES
+ return 0;
+#else
+ return isftnpath(msg->val)?0:1;
+#endif
+
if (!strcasecmp(msg->key,"Newsgroups")) return newsmode?0:2;
if (!strcasecmp(msg->key,"Xref")) return 0;
if (!strcasecmp(msg->key,"Return-Receipt-To")) return 1;
if (!strcasecmp(msg->key,"Received")) return newsmode?0:2;
- if (!strcasecmp(msg->key,"From")) return ftnorigin?0:2;
+ if (!strcasecmp(msg->key,"From"))
+
+#ifdef LESS_RFC_KLUDGES
+ return 0;
+#else
+ return ftnorigin?0:2;
+#endif
+
if (!strcasecmp(msg->key,"To"))
{
if (newsmode) return 0;
@@ -66,7 +80,14 @@
}
if (!strcasecmp(msg->key,"Cc")) return 2;
if (!strcasecmp(msg->key,"Bcc")) return 2;
- if (!strcasecmp(msg->key,"Reply-To")) return 2;
+ if (!strcasecmp(msg->key,"Reply-To"))
+
+#ifdef LESS_RFC_KLUDGES
+ return 0;
+#else
+ return 2;
+#endif
+
if (!strcasecmp(msg->key,"Lines")) return 0;
if (!strcasecmp(msg->key,"Date")) return 0;
if (!strcasecmp(msg->key,"Subject"))
@@ -77,8 +98,22 @@
if (!strcasecmp(msg->key,"Organization")) return removeorg?0:1;
if (!strcasecmp(msg->key,"Comment-To")) return 0;
if (!strcasecmp(msg->key,"X-Comment-To")) return 0;
- if (!strcasecmp(msg->key,"Keywords")) return 2;
- if (!strcasecmp(msg->key,"Summary")) return 2;
+ if (!strcasecmp(msg->key,"Keywords"))
+
+#ifdef LESS_RFC_KLUDGES
+ return 0;
+#else
+ return 2;
+#endif
+
+ if (!strcasecmp(msg->key,"Summary"))
+
+#ifdef LESS_RFC_KLUDGES
+ return 0;
+#else
+ return 2;
+#endif
+
if (!strcasecmp(msg->key,"MIME-Version")) return removemime?0:1;
if (!strcasecmp(msg->key,"Content-Type")) return removemime?0:1;
if (!strcasecmp(msg->key,"Content-Length")) return removemime?0:1;
@@ -86,8 +121,26 @@
if (!strcasecmp(msg->key,"Content-Name")) return 2;
if (!strcasecmp(msg->key,"Content-Description")) return 2;
if (!strcasecmp(msg->key,"Message-ID")) return ftnorigin?0:1;
- if (!strcasecmp(msg->key,"References")) return removeref?0:1;
- if (!strcasecmp(msg->key,"Distribution")) return ftnorigin?0:1;
+ if (!strcasecmp(msg->key,"References"))
+
+#ifdef LESS_RFC_KLUDGES
+ return 0;
+#else
+ return removeref?0:1;
+#endif
+
+ if (!strcasecmp(msg->key,"Distribution"))
+
+#ifdef LESS_RFC_KLUDGES
+ return 0;
+#else
+ return ftnorigin?0:1;
+#endif
+
+#ifdef LESS_RFC_KLUDGES
+ if (!strcasecmp(msg->key,"NNTP-Posting-Host")) return 0;
+#endif
+
/*if (!strcasecmp(msg->key,"")) return ;*/
return 1;
}

11
samples/dselect Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
# $Id: dselect,v 1.7 2016/01/26 22:52:53 tom Exp $
. ./setup-vars
exec 3>&1
RESULT=`$DIALOG --title "Please choose a file" "$@" --dselect $HOME/ 14 48 2>&1 1>&3`
retval=$?
exec 3>&-
. ./report-string

View File

@ -0,0 +1,28 @@
Disk /dev/hda: 14 heads, 62 sectors, 1018 cylinders
Units = cylinders of 868 * 512 bytes
Device Boot Begin Start End Blocks Id System
/dev/hda1 1 1 3 1271 a OS/2 Boot Manager
/dev/hda2 4 4 287 123256 6 DOS 16-bit >=32M
/dev/hda3 * 288 288 649 157108 83 Linux native
/dev/hda4 650 650 1018 160146 83 Linux native
Disk /dev/sda: 64 heads, 32 sectors, 511 cylinders
Units = cylinders of 2048 * 512 bytes
Device Boot Begin Start End Blocks Id System
/dev/sda1 1 1 21 21488 82 Linux swap
/dev/sda2 22 22 511 501760 83 Linux native
Disk /dev/sdb: 64 heads, 32 sectors, 4106 cylinders
Units = cylinders of 2048 * 512 bytes
Device Boot Begin Start End Blocks Id System
/dev/sdb1 1 1 201 205808 83 Linux native
/dev/sdb2 202 202 402 205824 83 Linux native
/dev/sdb3 403 403 603 205824 83 Linux native
/dev/sdb4 604 604 4106 3587072 5 Extended
/dev/sdb5 604 604 1803 1228784 83 Linux native
/dev/sdb6 1024 1804 3003 1228784 83 Linux native
/dev/sdb7 2048 3004 4106 1129456 83 Linux native

View File

@ -0,0 +1,35 @@
# $Id: makefile.in,v 1.1 2000/10/08 17:22:53 tom Exp $
# template makefile for DIALOG sample 'install'
#
SHELL = /bin/sh
prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
top_builddir = ../..
DESTDIR =
bindir = $(DESTDIR)@bindir@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@ @DEFS@ -I$(top_builddir) -I$(srcdir)/../.. -I. -I$(srcdir)
EXTRA_CFLAGS = @EXTRA_CFLAGS@
CC = @CC@
LDFLAGS = @LDFLAGS@
LIBS = -L../.. -ldialog @LIBS@
RANLIB = @RANLIB@
RM = rm -f
all: setup
setup: setup.o
$(CC) -o $@ setup.o $(LIBS)
clean:
rm -f *.o setup
test: setup
./setup

371
samples/install/setup.c Normal file
View File

@ -0,0 +1,371 @@
/* Copyright (C) 1995 Florian La Roche */
/* Who wants to help coding? I don't like doing this... */
/* You can just start setup as normal user and see how far it is coded
right now. This will do a fake installation and won't actually chnage
any data on your computer. */
/* TODO: write a good package selection code
change functions to return better error code
*/
/* Show an extra text-box with the contents of all external commands,
before they are executed. So you can abort the installation, if any
wrong commands are to be executed. (So don't format wrong partition.) */
#define VERBOSE 1
/* If defined, don't actually execute any comands and don't actually modify
any files. So you can test any possible installation without doing any
damage to your computer.
The file FDISK.TEST is used instead of real "fdisk -l" output, so that
it can be started as normal user. */
#define DEBUG_THIS 1
#include <dialog.h>
/* max length of a partition name like e.g. '/dev/hda1' */
#define MAX_DEV_NAME 25
/* max number of possible Linux/Swap/MsDos partitions */
#define MAX_PARTS 20
char *progname = NULL;
static void
error(const char *s)
{
fprintf(stderr, "%s: %s\n", progname, s);
exit(1);
}
static int
my_system(const char *s,...)
{
int ret, i;
va_list ap;
char sh[200];
va_start(ap, s);
vsprintf(sh, s, ap);
va_end(ap);
#ifdef VERBOSE
i = dialog_msgbox("I will run the following command:", sh, 10, 65, 1);
dialog_clear();
#ifdef DEBUG_THIS
return 0;
#endif
#endif
ret = system(sh);
if (!(ret >> 8))
return 0;
i = dialog_msgbox("Error-Exit on the following command:",
sh, 12, 73, 1);
dialog_clear();
return 1;
}
/* We support to install from DOS/Linux-partitions. */
enum partition_type {
MsDos,
Linux,
Swap
};
struct partition {
enum partition_type type;
char name[MAX_DEV_NAME];
int blocks;
int flag;
} partitions[MAX_PARTS];
int num_partition = 0;
int num_linux = 0;
int num_swap = 0;
int num_msdos = 0;
static int
get_line(char *line, int size, FILE * f)
{
char *ptr = line;
int c;
if (feof(f))
return -1;
while (size-- && ((c = getc(f)) != EOF) && (c != '\n'))
*ptr++ = c;
*ptr++ = '\0';
return (int) (ptr - line);
}
static void
read_partitions(void)
{
FILE *f;
char line[200];
int length;
#ifndef DEBUG_THIS
int ret = system("fdisk -l 2>/dev/null 1>/tmp/fdisk.output");
if ((ret >> 8) != 0) {
error("fdisk didn't run");
}
if ((f = fopen("/tmp/fdisk.output", "r")) == NULL)
#else
if ((f = fopen("FDISK.TEST", "r")) == NULL)
#endif
error("cannot read fdisk output");
while (num_partition <= MAX_PARTS
&& (length = get_line(line, 200, f)) >= 0) {
if (strncmp(line, "/dev/", 5) == 0) {
int n = 0;
char *s = line + 5;
char *t = partitions[num_partition].name;
strcpy(t, "/dev/");
t += 5;
while (n < MAX_DEV_NAME && *s != '\0'
&& !isspace((unsigned char) *s)) {
*t++ = *s++;
n++;
}
*t = '\0';
/* Read the size of the partition. */
t = line + 37;
while (isspace((unsigned char) *t))
t++;
partitions[num_partition].blocks = atoi(t);
if (strstr(line, "Linux native")) {
partitions[num_partition].type = Linux;
num_partition++;
num_linux++;
} else if (strstr(line, "Linux swap")) {
partitions[num_partition].type = Swap;
num_partition++;
num_swap++;
} else if (strstr(line, "DOS")) {
partitions[num_partition].type = MsDos;
num_partition++;
num_msdos++;
}
}
}
fclose(f);
#ifndef DEBUG_THIS
unlink("/tmp/fdisk.output");
#endif
}
static int
select_partition(const char *title, const char *prompt, int y, int x)
{
int i, num, ret;
char info[MAX_PARTS][40];
char *items[MAX_PARTS * 2];
int num_pa[MAX_PARTS];
num = 0;
for (i = 0; i < num_partition; i++) {
if (partitions[i].type == Linux) {
items[num * 2] = partitions[i].name;
sprintf(info[num], "Linux partition with %d blocks",
partitions[i].blocks);
items[num * 2 + 1] = info[num];
num_pa[num] = i;
num++;
}
}
ret = dialog_menu(title, prompt, y + num, x, num, num, items);
dialog_clear();
if (ret >= 0) /* item selected */
ret = num_pa[ret];
return ret;
}
static int
select_install_partition(void)
{
return select_partition("Select Install Partition",
"\\nWhere do you want to install Linux?\\n", 9, 60);
}
static int
select_source_partition(void)
{
return select_partition("Select Source Partition",
"\\nOn which partition is the source?\\n", 9, 60);
}
const char *null = ">/dev/null 2>/dev/null";
const char *install_partition = NULL;
static void
extract_packages(const char *source_path)
{
#ifndef DEBUG_THIS
FILE *f;
#endif
if (my_system("mkdir -p /install/var/installed/packages %s", null))
return;
if (my_system("cd /install; for i in /source%s/*.tgz; do "
"tar xzplvvkf $i >> var/installed/packages/base "
"2>>var/installed/packages/ERROR; done", source_path))
return;
#ifndef DEBUG_THIS
if ((f = fopen("/install/etc/fstab", "w")) == NULL) {
/* i = */ dialog_msgbox("Error", "Cannot write /etc/fstab",
12, 40, 1);
return;
}
fprintf(f, "%s / ext2 defaults 1 1\n", install_partition);
fprintf(f, "none /proc proc defaults 0 2\n");
/* XXX write swap-partitions */
fclose(f);
#endif
}
static void
install_premounted(void)
{
extract_packages("");
}
static void
install_harddisk(void)
{
const char *name;
int part, ret;
if ((part = select_source_partition()) <= -1)
return;
name = partitions[part].name;
if (my_system("mount -t ext2 %s /source %s", name, null))
return;
ret = dialog_inputbox("Path in partition",
"Please enter the directory in which the "
"source files are.", 13, 50, "", FALSE);
dialog_clear();
if (ret != 0)
return;
/* XXX strdup */
extract_packages(strdup(dialog_input_result));
if (my_system("umount /source %s", null))
return;
}
static void
install_nfs(void)
{
if (my_system("ifconfig eth0 134.96.81.36 netmask 255.255.255.224 "
"broadcast 134.96.81.63 %s", null))
return;
if (my_system("route add -net 134.96.81.32 %s", null))
return;
if (my_system("mount -t nfs 134.96.81.38:"
"/local/ftp/pub/linux/ELF.binary/tar /source %s", null))
return;
extract_packages("/base");
if (my_system("umount /source %s", null))
return;
if (my_system("ifconfig eth0 down %s", null))
return;
}
static void
main_install(void)
{
int part, ret;
const char *name;
char *items1[] =
{
"1", "Harddisk Install",
"2", "Network Install(NFS)",
"3", "Premounted on /source"
};
if (num_linux == 0) {
/* XXX */
return;
}
if ((part = select_install_partition()) <= -1)
return;
install_partition = name = partitions[part].name;
if (my_system("mke2fs %s %s", name, null))
return;
if (my_system("mount -t ext2 %s /install %s", name, null))
return;
ret = dialog_menu("Choose install medium",
"\\nPlease say from where you want to install.\\n",
12, 62, 3, 3, items1);
dialog_clear();
switch (ret) {
case 0:
install_harddisk();
break;
case 1:
install_nfs();
break;
case 2:
install_premounted();
break;
case -2: /* cancel */
case -1:
break; /* esc */
}
if (my_system("umount /install %s", null))
return;
}
int
main(int argc, char **argv)
{
int stop = 0;
int ret;
char *items1[] =
{
"1", "Display a help text",
"2", "Start an installation",
"3", "Exit to the shell"
};
progname = argv[0];
read_partitions();
if (num_linux == 0) {
printf("\n\nPlease start \"fdisk\" or \"cfdisk\" and create a"
"\nnative Linux-partition to install Linux on.\n\n");
exit(1);
}
init_dialog();
while (!stop) {
ret = dialog_menu("Linux Install Utility",
"\\nCopyright (C) 1995 Florian La Roche\\n"
"\\nPre-Alpha version, be careful, read the doc!!!"
"\\nemail: florian@jurix.jura.uni-sb.de, "
"flla@stud.uni-sb.de\\n",
15, 64, 3, 3, items1);
dialog_clear();
switch (ret) {
case 0:
ret = dialog_textbox("Help Text",
"setup.help", 20, 70);
dialog_clear();
break;
case 1:
main_install();
break;
case 2:
stop = 1;
break;
case -2: /* cancel */
case -1:
stop = 1; /* esc */
}
}
end_dialog();
printf("\nExecute \"reboot\" to restart your computer...\n");
exit(0);
}

View File

@ -0,0 +1,49 @@
At the moment, only installation from a harddisk
is supported. All commands are shown to you on
the screen before executing. This is just to make
sure that nothing bad is done to your harddisk :-)
You can also select to install from a premounted dir.
Then the "tar/base" directory must be mounted on
"/install", so that all tar-packages from the basic
stuff are in "/install/*.tgz". (So you could be able
to install via NFS...)
Good luck...,
anyone wants to help programming this tool?,
Florian La Roche
Contents:
=========
- overview about what "setup" does.
- creating a Linux-partition before starting "setup"
- about lilo
- how to use "setup", what keys are supported
What does "setup" do on my computer?
====================================
Setup will ask you for a partition on your harddisk,
where you would like to have Linux installed.
You can then choose to install this distribution from
your local harddisk or via network (NFS).
setup will install a very basic system.
At the end, you can install lilo, the Linux Loader.
Rebooting your computer with this little linux system
and then runing the setup-program on it, will give
the possibility to install more packages.
Creating a Linux-partition:
===========================
To install this Linux distribution, you need to
create an extra partition on your harddisk for
Linux.
What is lilo and how should I install it?
=========================================
Read the lilo-documentation for this...
Florian La Roche

31
samples/menubox11 Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
# $Id: menubox11,v 1.2 2018/06/13 21:59:21 tom Exp $
# zero-width column
. ./setup-vars
exec 3>&1
RESULT=`$DIALOG --backtitle "Debian Configuration" \
--title "Configuring debconf" \
--default-item Dialog "$@" \
--menu "Packages that use debconf for configuration share a common look and feel. You can
select the type of user interface they use.
\n\n\
The dialog frontend is a full-screen, character based interface, while the readline
frontend uses a more traditional plain text interface, and both the gnome and kde
frontends are modern X interfaces, fitting the respective desktops (but may be used
in any X environment). The editor frontend lets you configure things using your
favorite text editor. The noninteractive frontend never asks you any questions.
\n\n\
Interface to use:" 0 0 6 \
Dialog "" \
Readline "" \
Gnome "" \
Kde "" \
Editor "" \
Noninteractive "" \
2>&1 1>&3`
retval=$?
exec 3>&-
. ./report-string

View File

@ -1,5 +1,5 @@
#!/bin/sh
# $Id: programbox,v 1.1 2011/03/02 01:17:28 tom Exp $
# $Id: programbox,v 1.3 2018/06/17 20:45:25 tom Exp $
. ./setup-vars
@ -11,9 +11,12 @@ while true
do
read text
test -z "$text" && break
ls -ld "$text"
ls -ld "$text" || break
sleep 0.1
done <$tempfile
) |
$DIALOG --title "PROGRAMBOX" "$@" --programbox 20 70
retval=$?
. ./report-button

View File

@ -1,5 +1,5 @@
#!/bin/sh
# $Id: programbox2,v 1.1 2011/03/02 01:25:31 tom Exp $
# $Id: programbox2,v 1.3 2018/06/17 20:45:25 tom Exp $
. ./setup-vars
@ -11,9 +11,12 @@ while true
do
read text
test -z "$text" && break
ls -ld "$text"
ls -ld "$text" || break
sleep 0.1
done <$tempfile
) |
$DIALOG --title "PROGRAMBOX" "$@" --programbox "ProgramBox" 20 70
retval=$?
. ./report-button

View File

@ -1,5 +1,5 @@
#!/bin/sh
# $Id: progress,v 1.5 2010/01/13 10:20:03 tom Exp $
# $Id: progress,v 1.7 2018/06/17 20:45:25 tom Exp $
. ./setup-vars
@ -11,9 +11,12 @@ while true
do
read text
test -z "$text" && break
ls -ld "$text"
ls -ld "$text" || break
sleep 1
done <$tempfile
) |
$DIALOG --title "PROGRESS" "$@" --progressbox 20 70
retval=$?
. ./report-button

View File

@ -1,5 +1,5 @@
#!/bin/sh
# $Id: progress2,v 1.5 2010/01/13 10:20:03 tom Exp $
# $Id: progress2,v 1.7 2018/06/17 20:45:25 tom Exp $
. ./setup-vars
@ -11,9 +11,12 @@ while true
do
read text
test -z "$text" && break
ls -ld "$text"
ls -ld "$text" || break
sleep 1
done <$tempfile
) |
$DIALOG --title "PROGRESS" "$@" --progressbox "This is a detailed description\nof the progress-box." 20 70
retval=$?
. ./report-button

56
samples/run_test.sh Executable file
View File

@ -0,0 +1,56 @@
#!/bin/sh
# $Id: run_test.sh,v 1.4 2017/02/01 01:50:09 tom Exp $
# vile:ts=4 sw=4
THIS=`basename $0`
if [ -z "$DIALOG" ]
then
have=
want=dialog
for p in . .. ../bin
do
prog=$p/$want
[ -f $prog ] || continue
if [ -x $prog ]
then
have=$prog
break
fi
done
if [ -z "$have" ]
then
echo "? did not find $want" >&2
exit
fi
DIALOG=$have
export DIALOG
fi
want=`basename $DIALOG`
DIALOGOPTS="$DIALOGOPTS --trace $want.log"
export DIALOGOPTS
mylog=run_test.log
cat >$mylog <<EOF
** `date`
EOF
for name in "$@"
do
[ -f "$name" ] || continue
[ -x "$name" ] || continue
# skip this script and known utility-scripts
case `basename $name` in
$THIS|dft-*|killall|listing|rotated-data|shortlist|with-*)
echo "** skipping $name" >>$mylog
continue
;;
esac
rm -f trace $want.log $name.log
echo "** running $name" >>$mylog
$name
[ -f $want.log ] && cp $want.log $name.log
done

View File

@ -1,7 +1,7 @@
#!/bin/sh
# $Id: setup-edit,v 1.2 2012/06/29 09:31:49 tom Exp $
# $Id: setup-edit,v 1.3 2016/01/26 22:42:44 tom Exp $
# vile:shmode
input=`tempfile 2>/dev/null` || input=/tmp/input$$
output=`tempfile 2>/dev/null` || output=/tmp/test$$
trap "rm -f $input $output" $SIG_NONE $SIG_HUP $SIG_INT $SIG_TRAP $SIG_TERM
trap "rm -f $input $output" $SIG_NONE $SIG_HUP $SIG_INT $SIG_QUIT $SIG_TERM

View File

@ -1,6 +1,6 @@
#!/bin/sh
# $Id: setup-tempfile,v 1.3 2012/07/06 17:51:56 tom Exp $
# $Id: setup-tempfile,v 1.4 2016/01/26 22:42:47 tom Exp $
# vile:shmode
tempfile=`(tempfile) 2>/dev/null` || tempfile=/tmp/test$$
trap "rm -f $tempfile" 0 $SIG_NONE $SIG_HUP $SIG_INT $SIG_TRAP $SIG_TERM
trap "rm -f $tempfile" 0 $SIG_NONE $SIG_HUP $SIG_INT $SIG_QUIT $SIG_TERM

View File

@ -1,9 +1,9 @@
/*
* $Id: tailbox.c,v 1.68 2012/11/18 15:48:52 tom Exp $
* $Id: tailbox.c,v 1.72 2018/06/19 22:57:01 tom Exp $
*
* tailbox.c -- implements the tail box
*
* Copyright 2000-2011,2012 Thomas E. Dickey
* Copyright 2000-2012,2018 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
@ -88,12 +88,7 @@ print_line(MY_OBJ * obj, WINDOW *win, int row, int width)
(void) wmove(win, row, 0); /* move cursor to correct line */
(void) waddch(win, ' ');
#ifdef NCURSES_VERSION
(void) waddnstr(win, line, MIN((int) strlen(line), width - 2));
#else
line[MIN((int) strlen(line), width - 2)] = '\0';
waddstr(win, line);
#endif
getyx(win, y, x);
(void) y;
@ -219,12 +214,29 @@ handle_input(DIALOG_CALLBACK * cb)
return TRUE;
}
static bool
valid_callback(DIALOG_CALLBACK * cb)
{
bool valid = FALSE;
DIALOG_CALLBACK *p;
for (p = dialog_state.getc_callbacks; p != 0; p = p->next) {
if (p == cb) {
valid = TRUE;
break;
}
}
return valid;
}
static bool
handle_my_getc(DIALOG_CALLBACK * cb, int ch, int fkey, int *result)
{
MY_OBJ *obj = (MY_OBJ *) cb;
bool done = FALSE;
if (!valid_callback(cb))
return FALSE;
if (!fkey && dlg_char_to_button(ch, obj->buttons) == 0) {
ch = DLGK_ENTER;
fkey = TRUE;
@ -281,7 +293,11 @@ handle_my_getc(DIALOG_CALLBACK * cb, int ch, int fkey, int *result)
* Display text from a file in a dialog box, like in a "tail -f".
*/
int
dialog_tailbox(const char *title, const char *file, int height, int width, int bg_task)
dialog_tailbox(const char *title,
const char *filename,
int height,
int width,
int bg_task)
{
/* *INDENT-OFF* */
static DLG_KEYS_BINDING binding[] = {
@ -311,14 +327,21 @@ dialog_tailbox(const char *title, const char *file, int height, int width, int b
FILE *fd;
int min_width = 12;
DLG_TRACE(("# tailbox args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("filename", filename);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("bg_task", bg_task);
/* Open input file for reading */
if ((fd = fopen(file, "rb")) == NULL)
if ((fd = fopen(filename, "rb")) == NULL)
dlg_exiterr("Can't open input file in dialog_tailbox().");
#ifdef KEY_RESIZE
retry:
#endif
dlg_auto_sizefile(title, file, &height, &width, 2, min_width);
dlg_auto_sizefile(title, filename, &height, &width, 2, min_width);
dlg_print_size(height, width);
dlg_ctl_size(height, width);
@ -381,6 +404,7 @@ dialog_tailbox(const char *title, const char *file, int height, int width, int b
ch = dlg_getc(dialog, &fkey);
#ifdef KEY_RESIZE
if (fkey && ch == KEY_RESIZE) {
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;

View File

@ -1,9 +1,9 @@
/*
* $Id: textbox.c,v 1.110 2012/12/01 01:48:08 tom Exp $
* $Id: textbox.c,v 1.117 2018/06/19 22:57:01 tom Exp $
*
* textbox.c -- implements the text box
*
* Copyright 2000-2011,2012 Thomas E. Dickey
* Copyright 2000-2017,2018 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
@ -92,7 +92,7 @@ lseek_end(MY_OBJ * obj, long offset)
{
long actual = lseek_obj(obj, offset, SEEK_END);
if (actual > offset) {
if (offset == 0L && actual > offset) {
obj->file_size = actual;
}
}
@ -103,7 +103,7 @@ lseek_cur(MY_OBJ * obj, long offset)
long actual = lseek_obj(obj, offset, SEEK_CUR);
if (actual != offset) {
dlg_trace_msg("Lseek returned %ld, expected %ld\n", actual, offset);
DLG_TRACE(("# Lseek returned %ld, expected %ld\n", actual, offset));
}
}
@ -525,7 +525,7 @@ get_search_term(WINDOW *dialog, char *input, int height, int width)
searchbox_attr,
searchbox_border_attr,
searchbox_border2_attr);
(void) wattrset(widget, searchbox_title_attr);
dlg_attrset(widget, searchbox_title_attr);
(void) wmove(widget, 0, (box_width - len_caption) / 2);
indx = dlg_index_wchars(caption);
@ -599,7 +599,7 @@ perform_search(MY_OBJ * obj, int height, int width, int key, char *search_term)
}
#endif
/* ESC pressed, or no search term, reprint page to clear box */
(void) wattrset(obj->text, dialog_attr);
dlg_attrset(obj->text, dialog_attr);
back_lines(obj, obj->page_length);
return TRUE;
}
@ -644,7 +644,7 @@ perform_search(MY_OBJ * obj, int height, int width, int key, char *search_term)
back_lines(obj, 1L);
}
/* Reprint page */
(void) wattrset(obj->text, dialog_attr);
dlg_attrset(obj->text, dialog_attr);
moved = TRUE;
} else { /* no need to find */
(void) beep();
@ -656,7 +656,7 @@ perform_search(MY_OBJ * obj, int height, int width, int key, char *search_term)
* Display text from a file in a dialog box.
*/
int
dialog_textbox(const char *title, const char *file, int height, int width)
dialog_textbox(const char *title, const char *filename, int height, int width)
{
/* *INDENT-OFF* */
static DLG_KEYS_BINDING binding[] = {
@ -679,7 +679,7 @@ dialog_textbox(const char *title, const char *file, int height, int width)
DLG_KEYS_DATA( DLGK_PAGE_LAST, 'G' ),
DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ),
DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ),
DLG_KEYS_DATA( DLGK_PAGE_NEXT, ' ' ),
DLG_KEYS_DATA( DLGK_PAGE_NEXT, CHR_SPACE ),
DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
DLG_KEYS_DATA( DLGK_PAGE_PREV, 'B' ),
DLG_KEYS_DATA( DLGK_PAGE_PREV, 'b' ),
@ -709,6 +709,12 @@ dialog_textbox(const char *title, const char *file, int height, int width)
int button = dlg_default_button();
int min_width = 12;
DLG_TRACE(("# textbox args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("filename", filename);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
search_term[0] = '\0'; /* no search term entered yet */
memset(&obj, 0, sizeof(obj));
@ -719,8 +725,8 @@ dialog_textbox(const char *title, const char *file, int height, int width)
obj.buttons = dlg_exit_label();
/* Open input file for reading */
if ((obj.fd = open(file, O_RDONLY)) == -1)
dlg_exiterr("Can't open input file %s", file);
if ((obj.fd = open(filename, O_RDONLY)) == -1)
dlg_exiterr("Can't open input file %s", filename);
/* Get file size. Actually, 'file_size' is the real file size - 1,
since it's only the last byte offset from the beginning */
@ -738,7 +744,7 @@ dialog_textbox(const char *title, const char *file, int height, int width)
#endif
moved = TRUE;
dlg_auto_sizefile(title, file, &height, &width, 2, min_width);
dlg_auto_sizefile(title, filename, &height, &width, 2, min_width);
dlg_print_size(height, width);
dlg_ctl_size(height, width);
@ -942,6 +948,7 @@ dialog_textbox(const char *title, const char *file, int height, int width)
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
@ -949,7 +956,6 @@ dialog_textbox(const char *title, const char *file, int height, int width)
/* repaint */
dlg_clear();
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
goto retry;
#endif

View File

@ -1,9 +1,9 @@
/*
* $Id: timebox.c,v 1.54 2013/03/17 15:03:41 tom Exp $
* $Id: timebox.c,v 1.59 2018/06/19 22:57:01 tom Exp $
*
* timebox.c -- implements the timebox dialog
*
* Copyright 2001-2012,2013 Thomas E. Dickey
* Copyright 2001-2016,2018 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
@ -82,7 +82,7 @@ draw_cell(BOX * data)
data->height + (2 * MARGIN), data->width + (2 * MARGIN),
menubox_border_attr, menubox_border2_attr);
(void) wattrset(data->window, item_attr);
dlg_attrset(data->window, item_attr);
wprintw(data->window, "%02d", data->value);
return 0;
}
@ -148,7 +148,7 @@ dialog_timebox(const char *title,
DLG_KEYS_DATA( DLGK_DELETE_RIGHT,KEY_DC ),
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
DLG_KEYS_DATA( DLGK_ENTER, ' ' ),
TOGGLEKEY_BINDINGS,
DLG_KEYS_DATA( DLGK_FIELD_FIRST,KEY_HOME ),
DLG_KEYS_DATA( DLGK_FIELD_LAST, KEY_END ),
DLG_KEYS_DATA( DLGK_FIELD_LAST, KEY_LL ),
@ -184,10 +184,19 @@ dialog_timebox(const char *title,
struct tm current;
int state = dlg_default_button();
const char **buttons = dlg_ok_labels();
char *prompt = dlg_strclone(subtitle);
char *prompt;
char buffer[MAX_LEN];
DIALOG_VARS save_vars;
DLG_TRACE(("# timebox args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", subtitle);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("hour", hour);
DLG_TRACE2N("minute", minute);
DLG_TRACE2N("second", second);
now_time = time((time_t *) 0);
current = *localtime(&now_time);
@ -200,7 +209,9 @@ dialog_timebox(const char *title,
retry:
#endif
prompt = dlg_strclone(subtitle);
dlg_auto_size(title, prompt, &height, &width, 0, 0);
height += MIN_HIGH;
if (width < MIN_WIDE)
width = MIN_WIDE;
@ -224,7 +235,7 @@ dialog_timebox(const char *title,
dlg_draw_title(dialog, title);
dlg_draw_helpline(dialog, FALSE);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
/* compute positions of hour, month and year boxes */
@ -303,6 +314,7 @@ dialog_timebox(const char *title,
case DLGK_MOUSE('S'):
state = sSC;
break;
case DLGK_TOGGLE:
case DLGK_ENTER:
result = dlg_ok_buttoncode(button);
break;
@ -340,6 +352,7 @@ dialog_timebox(const char *title,
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
@ -347,9 +360,9 @@ dialog_timebox(const char *title,
minute = mn_box.value;
second = sc_box.value;
/* repaint */
free(prompt);
dlg_clear();
dlg_del_window(dialog);
refresh();
dlg_mouse_free_regions();
goto retry;
#endif

56
trace.c
View File

@ -1,9 +1,9 @@
/*
* $Id: trace.c,v 1.20 2011/10/18 10:47:26 tom Exp $
* $Id: trace.c,v 1.26 2018/06/13 00:06:48 tom Exp $
*
* trace.c -- implements screen-dump and keystroke-logging
*
* Copyright 2007-2010,2011 Thomas E. Dickey
* Copyright 2007-2017,2018 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
@ -52,6 +52,40 @@ dlg_trace_msg(const char *fmt,...)
}
}
void
dlg_trace_2s(const char *name, const char *value)
{
bool first = TRUE;
const char *next;
int left, right = 0;
if (value == 0)
value = "<NULL>";
while (value[right] != '\0') {
value += right;
if ((next = strchr(value, '\n')) != 0) {
left = (int) (next - value);
right = left + 1;
} else {
left = (int) strlen(value);
right = left;
}
if (first) {
first = FALSE;
dlg_trace_msg("#%14s=%.*s\n", name, left, value);
} else {
dlg_trace_msg("#+\t\t%.*s\n", left, value);
}
}
}
void
dlg_trace_2n(const char *name, int value)
{
dlg_trace_msg("#\t%7s=%d\n", name, value);
}
void
dlg_trace_win(WINDOW *win)
{
@ -93,7 +127,7 @@ dlg_trace_win(WINDOW *win)
wchar_t *uc;
if (win_wch(win, &cch) == ERR
|| (uc = wunctrl(&cch)) == 0
|| (uc = wunctrl((&cch))) == 0
|| uc[1] != 0
|| wcwidth(uc[0]) <= 0) {
buffer[0] = '.';
@ -185,6 +219,7 @@ dlg_trace_chr(int ch, int fkey)
CASE(DLGK_SELECT);
CASE(DLGK_HELPFILE);
CASE(DLGK_TRACE);
CASE(DLGK_TOGGLE);
}
}
} else if (ch == ERR) {
@ -195,9 +230,11 @@ dlg_trace_chr(int ch, int fkey)
if (fkey_name == 0)
fkey_name = "UNKNOWN";
}
fprintf(myFP, "chr %s (ch=%#x, fkey=%d)\n",
fkey_name,
ch, fkey);
if (ch >= 0) {
fprintf(myFP, "chr %s (ch=%#x, fkey=%d)\n", fkey_name, ch, fkey);
} else {
fprintf(myFP, "chr %s (ch=%d, fkey=%d)\n", fkey_name, ch, fkey);
}
fflush(myFP);
}
}
@ -209,12 +246,13 @@ dlg_trace(const char *fname)
if (myFP == 0) {
myFP = fopen(fname, "a");
if (myFP != 0) {
dlg_trace_time("** opened at");
dlg_trace_msg("** dialog %s\n", dialog_version());
dlg_trace_time("## opened at");
DLG_TRACE(("## dialog %s\n", dialog_version()));
DLG_TRACE(("## vile: confmode\n"));
}
}
} else if (myFP != 0) {
dlg_trace_time("** closed at");
dlg_trace_time("## closed at");
fclose(myFP);
myFP = 0;
}

View File

@ -1,9 +1,9 @@
/*
* $Id: treeview.c,v 1.24 2013/09/02 17:13:33 tom Exp $
* $Id: treeview.c,v 1.32 2018/06/19 22:57:01 tom Exp $
*
* treeview.c -- implements the treeview dialog
*
* Copyright 2012,2013 Thomas E. Dickey
* Copyright 2012-2016,2018 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
@ -67,19 +67,19 @@ print_item(ALL_DATA * data,
: item->text);
/* Clear 'residue' of last item */
(void) wattrset(win, menubox_attr);
dlg_attrset(win, menubox_attr);
(void) wmove(win, choice, 0);
for (i = 0; i < data->use_width; i++)
(void) waddch(win, ' ');
(void) wmove(win, choice, data->check_x);
(void) wattrset(win, selected ? check_selected_attr : check_attr);
dlg_attrset(win, selected ? check_selected_attr : check_attr);
(void) wprintw(win,
data->is_check ? "[%c]" : "(%c)",
states[item->state]);
(void) wattrset(win, menubox_attr);
dlg_attrset(win, menubox_attr);
(void) wattrset(win, selected ? item_selected_attr : item_attr);
dlg_attrset(win, selected ? item_selected_attr : item_attr);
for (i = 0; i < depths; ++i) {
int j;
(void) wmove(win, choice, data->item_x + INDENT * i);
@ -94,7 +94,7 @@ print_item(ALL_DATA * data,
if (selected) {
dlg_item_help(item->help);
}
(void) wattrset(win, save);
dlg_attrset(win, save);
}
static void
@ -185,6 +185,7 @@ dlg_treeview(const char *title,
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) ),
TOGGLEKEY_BINDINGS,
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -215,6 +216,8 @@ dlg_treeview(const char *title,
states = " *";
num_states = (int) strlen(states);
dialog_state.plain_buttons = TRUE;
memset(&all, 0, sizeof(all));
all.items = items;
all.item_no = item_no;
@ -276,7 +279,7 @@ dlg_treeview(const char *title,
dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
dlg_draw_title(dialog, title);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
dlg_print_autowrap(dialog, prompt, height, width);
all.use_width = width - 4;
@ -372,7 +375,7 @@ dlg_treeview(const char *title,
choice = (key - KEY_MAX);
print_list(&all, choice, scrollamt, max_choice);
key = ' '; /* force the selected item to toggle */
key = DLGK_TOGGLE; /* force the selected item to toggle */
} else {
beep();
continue;
@ -385,7 +388,7 @@ dlg_treeview(const char *title,
/*
* A space toggles the item status.
*/
if (key == ' ') {
if (key == DLGK_TOGGLE) {
int current = scrollamt + choice;
int next = items[current].state + 1;
@ -529,6 +532,7 @@ dlg_treeview(const char *title,
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
/* reset data */
height = old_height;
width = old_width;
@ -581,6 +585,16 @@ dialog_treeview(const char *title,
int current = 0;
char *help_result;
DLG_TRACE(("# treeview args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
DLG_TRACE2N("lheight", list_height);
DLG_TRACE2N("llength", item_no);
/* FIXME dump the items[][] too */
DLG_TRACE2N("flag", flag);
listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
assert_ptr(listitems, "dialog_treeview");

87
ttysize.c Normal file
View File

@ -0,0 +1,87 @@
/*
* $Id: ttysize.c,v 1.1 2018/06/09 02:03:03 tom Exp $
*
* ttysize.c -- obtain terminal-size for dialog
*
* Copyright 2018 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
* as published by the Free Software Foundation.
*
* 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.
*
* An earlier version of this program lists as authors
* Savio Lam (lam836@cs.cuhk.hk)
*/
#include <dialog.h>
/*
* This is based on work I did for ncurses in 1997, and improved/extended for
* other terminal-based programs. The comments are from my original version -TD
*/
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef NEED_PTEM_H
/* On SCO, they neglected to define struct winsize in termios.h -- it's only
* in termio.h and ptem.h (the former conflicts with other definitions).
*/
# include <sys/stream.h>
# include <sys/ptem.h>
#endif
/*
* SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS,
* Solaris, IRIX) define TIOCGWINSZ and struct winsize.
*/
#if defined(TIOCGSIZE)
# define IOCTL_WINSIZE TIOCGSIZE
# define STRUCT_WINSIZE struct ttysize
# define WINSIZE_ROWS(n) (int)n.ts_lines
# define WINSIZE_COLS(n) (int)n.ts_cols
#elif defined(TIOCGWINSZ)
# define IOCTL_WINSIZE TIOCGWINSZ
# define STRUCT_WINSIZE struct winsize
# define WINSIZE_ROWS(n) (int)n.ws_row
# define WINSIZE_COLS(n) (int)n.ws_col
#else
# undef HAVE_SIZECHANGE
#endif
int
dlg_ttysize(int fd, int *high, int *wide)
{
int rc = -1;
#ifdef HAVE_SIZECHANGE
if (isatty(fd)) {
STRUCT_WINSIZE size;
if (ioctl(fd, IOCTL_WINSIZE, &size) >= 0) {
*high = WINSIZE_ROWS(size);
*wide = WINSIZE_COLS(size);
rc = 0;
}
}
#else
high = 24;
wide = 80;
#endif /* HAVE_SIZECHANGE */
return rc;
}

View File

@ -1,9 +1,9 @@
/*
* $Id: ui_getc.c,v 1.67 2013/03/24 23:53:19 tom Exp $
* $Id: ui_getc.c,v 1.70 2018/06/14 00:05:05 tom Exp $
*
* ui_getc.c - user interface glue for getc()
*
* Copyright 2001-2012,2013 Thomas E. Dickey
* Copyright 2001-2013,2018 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
@ -89,10 +89,16 @@ dlg_remove_callback(DIALOG_CALLBACK * p)
DIALOG_CALLBACK *q;
if (p->input != 0) {
fclose(p->input);
FILE *input = p->input;
fclose(input);
if (p->input == dialog_state.pipe_input)
dialog_state.pipe_input = 0;
p->input = 0;
/* more than one callback can have the same input */
for (q = dialog_state.getc_callbacks; q != 0; q = q->next) {
if (q->input == input) {
q->input = 0;
}
}
}
if (!(p->keep_win))
@ -147,8 +153,9 @@ handle_inputs(WINDOW *win)
if (result) {
(void) wmove(win, cur_y, cur_x); /* Restore cursor position */
wrefresh(win);
curs_set(state);
}
if (state != ERR)
curs_set(state);
return result;
}
@ -480,10 +487,12 @@ dlg_getc(WINDOW *win, int *fkey)
case ERR: /* wtimeout() in effect; check for file I/O */
if (interval > 0
&& current >= expired) {
dlg_exiterr("timeout");
}
if (!valid_file(stdin)
|| !valid_file(dialog_state.screen_output)) {
DLG_TRACE(("# dlg_getc: timeout expired\n"));
ch = ESC;
done = TRUE;
} else if (!valid_file(stdin)
|| !valid_file(dialog_state.screen_output)) {
DLG_TRACE(("# dlg_getc: input or output is invalid\n"));
ch = ESC;
done = TRUE;
} else if (check_inputs()) {

253
util.c
View File

@ -1,9 +1,9 @@
/*
* $Id: util.c,v 1.258 2013/09/22 00:41:40 tom Exp $
* $Id: util.c,v 1.272 2018/06/21 23:47:10 tom Exp $
*
* util.c -- miscellaneous utilities for dialog
*
* Copyright 2000-2012,2013 Thomas E. Dickey
* Copyright 2000-2016,2018 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
@ -193,7 +193,7 @@ dlg_put_backtitle(void)
chtype attr = A_NORMAL;
int backwidth = dlg_count_columns(dialog_vars.backtitle);
(void) wattrset(stdscr, screen_attr);
dlg_attrset(stdscr, screen_attr);
(void) wmove(stdscr, 0, 1);
dlg_print_text(stdscr, dialog_vars.backtitle, COLS - 2, &attr);
for (i = 0; i < COLS - backwidth; i++)
@ -215,7 +215,7 @@ dlg_attr_clear(WINDOW *win, int height, int width, chtype attr)
{
int i, j;
(void) wattrset(win, attr);
dlg_attrset(win, attr);
for (i = 0; i < height; i++) {
(void) wmove(win, i, 0);
for (j = 0; j < width; j++)
@ -555,15 +555,19 @@ dlg_color_pair(int foreground, int background)
static chtype
define_color(WINDOW *win, int foreground)
{
chtype attrs = dlg_get_attrs(win);
int pair;
short fg, bg, background;
if ((pair = PAIR_NUMBER(attrs)) != 0
&& pair_content((short) pair, &fg, &bg) != ERR) {
background = bg;
} else {
if (dialog_state.text_only) {
background = COLOR_BLACK;
} else {
chtype attrs = dlg_get_attrs(win);
if ((pair = PAIR_NUMBER(attrs)) != 0
&& pair_content((short) pair, &fg, &bg) != ERR) {
background = bg;
} else {
background = COLOR_BLACK;
}
}
return dlg_color_pair(foreground, background);
}
@ -674,13 +678,13 @@ dlg_print_listitem(WINDOW *win,
attrs[1] = tag_selected_attr;
attrs[0] = tag_attr;
(void) wattrset(win, selected ? attrs[3] : attrs[2]);
dlg_attrset(win, selected ? attrs[3] : attrs[2]);
(void) waddnstr(win, text, indx[1]);
if ((int) strlen(text) > indx[1]) {
limit = dlg_limit_columns(text, climit, 1);
if (limit > 1) {
(void) wattrset(win, selected ? attrs[1] : attrs[0]);
dlg_attrset(win, selected ? attrs[1] : attrs[0]);
(void) waddnstr(win,
text + indx[1],
indx[limit] - indx[1]);
@ -694,7 +698,7 @@ dlg_print_listitem(WINDOW *win,
limit = dlg_limit_columns(text, climit, 0);
if (limit > 0) {
(void) wattrset(win, selected ? attrs[1] : attrs[0]);
dlg_attrset(win, selected ? attrs[1] : attrs[0]);
dlg_print_text(win, text, cols[limit], &attr);
}
}
@ -718,7 +722,12 @@ dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr)
int combined = 0;
#endif
getyx(win, y_origin, x_origin);
if (dialog_state.text_only) {
y_origin = y_after = 0;
x_origin = x_after = 0;
} else {
getyx(win, y_origin, x_origin);
}
while (cols > 0 && (*txt != '\0')) {
if (dialog_vars.colors) {
while (isOurEscape(txt)) {
@ -792,12 +801,29 @@ dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr)
* more blanks.
*/
thisTab = (CharOf(*txt) == TAB);
if (thisTab) {
getyx(win, y_before, x_before);
(void) y_before;
if (dialog_state.text_only) {
y_before = y_after;
x_before = x_after;
} else {
if (thisTab) {
getyx(win, y_before, x_before);
(void) y_before;
}
}
if (dialog_state.text_only) {
int ch = CharOf(*txt++);
if (thisTab) {
while ((x_after++) % 8) {
fputc(' ', dialog_state.output);
}
} else {
fputc(ch, dialog_state.output);
x_after++; /* FIXME: handle meta per locale */
}
} else {
(void) waddch(win, CharOf(*txt++) | useattr);
getyx(win, y_after, x_after);
}
(void) waddch(win, CharOf(*txt++) | useattr);
getyx(win, y_after, x_after);
if (thisTab && (y_after == y_origin))
tabbed += (x_after - x_before);
if ((y_after != y_origin) ||
@ -809,6 +835,9 @@ dlg_print_text(WINDOW *win, const char *txt, int cols, chtype *attr)
ended = TRUE;
}
}
if (dialog_state.text_only) {
fputc('\n', dialog_state.output);
}
}
/*
@ -843,12 +872,14 @@ dlg_print_line(WINDOW *win,
* is less, and set wrap_ptr to the end of the last word in the line.
*/
for (n = 0; n < limit; ++n) {
test_ptr = prompt + indx[test_inx];
if (*test_ptr == '\n' || *test_ptr == '\0' || cur_x >= (rm + hidden))
int ch = *(test_ptr = prompt + indx[test_inx]);
if (ch == '\n' || ch == '\0' || cur_x >= (rm + hidden))
break;
if (*test_ptr == TAB && n == 0) {
if (ch == TAB && n == 0) {
tabbed = 8; /* workaround for leading tabs */
} else if (*test_ptr == ' ' && n != 0 && prompt[indx[n - 1]] != ' ') {
} else if (isblank(UCH(ch))
&& n != 0
&& !isblank(UCH(prompt[indx[n - 1]]))) {
wrap_inx = n;
*x = cur_x;
} else if (dialog_vars.colors && isOurEscape(test_ptr)) {
@ -867,9 +898,9 @@ dlg_print_line(WINDOW *win,
* we don't have to wrap it at the end of the previous word.
*/
test_ptr = prompt + indx[test_inx];
if (*test_ptr == '\n' || *test_ptr == ' ' || *test_ptr == '\0') {
if (*test_ptr == '\n' || isblank(UCH(*test_ptr)) || *test_ptr == '\0') {
wrap_inx = test_inx;
while (wrap_inx > 0 && prompt[indx[wrap_inx - 1]] == ' ') {
while (wrap_inx > 0 && isblank(UCH(prompt[indx[wrap_inx - 1]]))) {
wrap_inx--;
}
*x = lm + indx[wrap_inx];
@ -911,19 +942,20 @@ dlg_print_line(WINDOW *win,
* Print the line if we have a window pointer. Otherwise this routine
* is just being called for sizing the window.
*/
if (win) {
if (dialog_state.text_only || win) {
dlg_print_text(win, prompt, (cols[wrap_inx] - hidden), attr);
}
/* *x tells the calling function how long the line was */
if (*x == 1)
if (*x == 1) {
*x = rm;
}
*x -= hidden;
/* Find the start of the next line and return a pointer to it */
test_ptr = wrap_ptr;
while (*test_ptr == ' ')
while (isblank(UCH(*test_ptr)))
test_ptr++;
if (*test_ptr == '\n')
test_ptr++;
@ -947,7 +979,9 @@ justify_text(WINDOW *win,
int bm = limit_y; /* bottom margin */
int last_y = 0, last_x = 0;
if (win) {
dialog_state.text_height = 0;
dialog_state.text_width = 0;
if (dialog_state.text_only || win) {
rm -= (2 * MARGIN);
bm -= (2 * MARGIN);
}
@ -1050,12 +1084,12 @@ dlg_print_scrolled(WINDOW *win,
#endif
dummy = newwin(high, width, 0, 0);
if (dummy == 0) {
(void) wattrset(win, dialog_attr);
dlg_attrset(win, dialog_attr);
dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width);
last = 0;
} else {
wbkgdset(dummy, dialog_attr | ' ');
(void) wattrset(dummy, dialog_attr);
dlg_attrset(dummy, dialog_attr);
werase(dummy);
dlg_print_autowrap(dummy, prompt, high, width);
getyx(dummy, y, x);
@ -1081,12 +1115,12 @@ dlg_print_scrolled(WINDOW *win,
if (percent > 100)
percent = 100;
if (offset != 0 || percent != 100) {
(void) wattrset(win, position_indicator_attr);
dlg_attrset(win, position_indicator_attr);
(void) wmove(win, MARGIN + height, wide - 4);
(void) sprintf(buffer, "%d%%", percent);
(void) waddstr(win, buffer);
if ((len = (int) strlen(buffer)) < 4) {
(void) wattrset(win, border_attr);
dlg_attrset(win, border_attr);
whline(win, dlg_boxchar(ACS_HLINE), 4 - len);
}
}
@ -1097,7 +1131,7 @@ dlg_print_scrolled(WINDOW *win,
#endif
{
(void) offset;
(void) wattrset(win, dialog_attr);
dlg_attrset(win, dialog_attr);
dlg_print_autowrap(win, prompt, height + 1 + (3 * MARGIN), width);
last = 0;
}
@ -1243,11 +1277,12 @@ real_auto_size(const char *title,
int x = (dialog_vars.begin_set ? dialog_vars.begin_x : 2);
int y = (dialog_vars.begin_set ? dialog_vars.begin_y : 1);
int title_length = title ? dlg_count_columns(title) : 0;
int nc = 4;
int high;
int wide;
int save_high = *height;
int save_wide = *width;
int max_high;
int max_wide;
if (prompt == 0) {
if (*height == 0)
@ -1256,6 +1291,9 @@ real_auto_size(const char *title,
*width = -1;
}
max_high = (*height < 0);
max_wide = (*width < 0);
if (*height > 0) {
high = *height;
} else {
@ -1287,16 +1325,25 @@ real_auto_size(const char *title,
*width = title_length;
}
dialog_state.text_height = *height;
dialog_state.text_width = *width;
if (*width < mincols && save_wide == 0)
*width = mincols;
if (prompt != 0) {
*width += nc;
*height += boxlines + 2;
*width += ((2 * MARGIN) + SHADOW_COLS);
*height += boxlines + (2 * MARGIN);
}
if (save_high > 0)
*height = save_high;
if (save_wide > 0)
*width = save_wide;
if (max_high)
*height = SLINES - (dialog_vars.begin_set ? dialog_vars.begin_y : 0);
if (max_wide)
*width = SCOLS - (dialog_vars.begin_set ? dialog_vars.begin_x : 0);
}
/* End of real_auto_size() */
@ -1309,6 +1356,10 @@ dlg_auto_size(const char *title,
int boxlines,
int mincols)
{
DLG_TRACE(("# dlg_auto_size(%d,%d) limits %d,%d\n",
*height, *width,
boxlines, mincols));
real_auto_size(title, prompt, height, width, boxlines, mincols);
if (*width > SCOLS) {
@ -1316,8 +1367,12 @@ dlg_auto_size(const char *title,
*width = SCOLS;
}
if (*height > SLINES)
if (*height > SLINES) {
*height = SLINES;
}
DLG_TRACE(("# ...dlg_auto_size(%d,%d) also %d,%d\n",
*height, *width,
dialog_state.text_height, dialog_state.text_width));
}
/*
@ -1360,12 +1415,16 @@ dlg_auto_sizefile(const char *title,
}
while (!feof(fd)) {
if (ferror(fd))
break;
offset = 0;
while (((ch = getc(fd)) != '\n') && !feof(fd))
if ((ch == TAB) && (dialog_vars.tab_correct))
while (((ch = getc(fd)) != '\n') && !feof(fd)) {
if ((ch == TAB) && (dialog_vars.tab_correct)) {
offset += dialog_state.tab_len - (offset % dialog_state.tab_len);
else
} else {
offset++;
}
}
if (offset > len)
len = (int) offset;
@ -1384,27 +1443,6 @@ dlg_auto_sizefile(const char *title,
(void) fclose(fd);
}
static chtype
dlg_get_cell_attrs(WINDOW *win)
{
chtype result;
#ifdef USE_WIDE_CURSES
cchar_t wch;
wchar_t cc;
attr_t attrs;
short pair;
if (win_wch(win, &wch) == OK
&& getcchar(&wch, &cc, &attrs, &pair, NULL) == OK) {
result = attrs;
} else {
result = 0;
}
#else
result = winch(win) & (A_ATTRIBUTES & ~A_COLOR);
#endif
return result;
}
/*
* Draw a rectangular box with line drawing characters.
*
@ -1428,7 +1466,7 @@ dlg_draw_box2(WINDOW *win, int y, int x, int height, int width,
int i, j;
chtype save = dlg_get_attrs(win);
(void) wattrset(win, 0);
dlg_attrset(win, 0);
for (i = 0; i < height; i++) {
(void) wmove(win, y + i, x);
for (j = 0; j < width; j++)
@ -1451,7 +1489,7 @@ dlg_draw_box2(WINDOW *win, int y, int x, int height, int width,
else
(void) waddch(win, boxchar | ' ');
}
(void) wattrset(win, save);
dlg_attrset(win, save);
}
void
@ -1586,7 +1624,7 @@ repaint_cell(DIALOG_WINDOWS * dw, bool draw, int y, int x)
chtype the_cell = dlg_get_attrs(cellwin);
chtype the_attr = (draw ? shadow_attr : the_cell);
if (dlg_get_cell_attrs(cellwin) & A_ALTCHARSET) {
if (winch(cellwin) & A_ALTCHARSET) {
the_attr |= A_ALTCHARSET;
}
#if USE_WCHGAT
@ -1614,7 +1652,7 @@ repaint_shadow(DIALOG_WINDOWS * dw, bool draw, int y, int x, int height, int wid
if (UseShadow(dw)) {
#if !USE_WCHGAT
chtype save = dlg_get_attrs(dw->shadow);
(void) wattrset(dw->shadow, draw ? shadow_attr : screen_attr);
dlg_attrset(dw->shadow, draw ? shadow_attr : screen_attr);
#endif
for (i = 0; i < SHADOW_ROWS; ++i) {
for (j = 0; j < width; ++j) {
@ -1628,7 +1666,7 @@ repaint_shadow(DIALOG_WINDOWS * dw, bool draw, int y, int x, int height, int wid
}
(void) wnoutrefresh(dw->shadow);
#if !USE_WCHGAT
(void) wattrset(dw->shadow, save);
dlg_attrset(dw->shadow, save);
#endif
}
}
@ -1795,8 +1833,10 @@ dlg_beeping(void)
void
dlg_print_size(int height, int width)
{
if (dialog_vars.print_siz)
if (dialog_vars.print_siz) {
fprintf(dialog_state.output, "Size: %d, %d\n", height, width);
DLG_TRACE(("# print size: %dx%d\n", height, width));
}
}
void
@ -1904,9 +1944,12 @@ dlg_strempty(void)
char *
dlg_strclone(const char *cprompt)
{
char *prompt = dlg_malloc(char, strlen(cprompt) + 1);
assert_ptr(prompt, "dlg_strclone");
strcpy(prompt, cprompt);
char *prompt = 0;
if (cprompt != 0) {
prompt = dlg_malloc(char, strlen(cprompt) + 1);
assert_ptr(prompt, "dlg_strclone");
strcpy(prompt, cprompt);
}
return prompt;
}
@ -1989,10 +2032,10 @@ dlg_draw_title(WINDOW *win, const char *title)
chtype save = dlg_get_attrs(win);
int x = centered(getmaxx(win), title);
(void) wattrset(win, title_attr);
dlg_attrset(win, title_attr);
wmove(win, 0, x);
dlg_print_text(win, title, getmaxx(win) - x, &attr);
(void) wattrset(win, save);
dlg_attrset(win, save);
dlg_finish_string(title);
}
}
@ -2004,14 +2047,14 @@ dlg_draw_bottom_box2(WINDOW *win, chtype on_left, chtype on_right, chtype on_ins
int height = getmaxy(win);
int i;
(void) wattrset(win, on_left);
dlg_attrset(win, on_left);
(void) wmove(win, height - 3, 0);
(void) waddch(win, dlg_boxchar(ACS_LTEE));
for (i = 0; i < width - 2; i++)
(void) waddch(win, dlg_boxchar(ACS_HLINE));
(void) wattrset(win, on_right);
dlg_attrset(win, on_right);
(void) waddch(win, dlg_boxchar(ACS_RTEE));
(void) wattrset(win, on_inside);
dlg_attrset(win, on_inside);
(void) wmove(win, height - 2, 1);
for (i = 0; i < width - 2; i++)
(void) waddch(win, ' ');
@ -2147,6 +2190,34 @@ dlg_move_window(WINDOW *win, int height, int width, int y, int x)
}
}
}
/*
* Having just received a KEY_RESIZE, wait a short time to ignore followup
* KEY_RESIZE events.
*/
void
dlg_will_resize(WINDOW *win)
{
int n, ch, base;
int caught = 0;
dlg_trace_win(win);
wtimeout(win, 20);
for (n = base = 0; n < base + 10; ++n) {
if ((ch = wgetch(win)) != ERR) {
if (ch == KEY_RESIZE) {
base = n;
++caught;
} else {
ungetch(ch);
break;
}
}
}
dlg_trace_msg("# caught %d KEY_RESIZE key%s\n",
1 + caught,
caught == 1 ? "" : "s");
}
#endif /* KEY_RESIZE */
WINDOW *
@ -2213,7 +2284,7 @@ dlg_item_help(const char *txt)
chtype attr = A_NORMAL;
int y, x;
(void) wattrset(stdscr, itemhelp_attr);
dlg_attrset(stdscr, itemhelp_attr);
(void) wmove(stdscr, LINES - 1, 0);
(void) wclrtoeol(stdscr);
(void) addch(' ');
@ -2259,18 +2330,18 @@ dlg_strcmp(const char *a, const char *b)
static bool
trim_blank(char *base, char *dst)
{
int count = 0;
int count = isblank(UCH(*dst));
while (dst-- != base) {
if (*dst == '\n') {
return FALSE;
} else if (*dst != ' ') {
return (count > 1);
} else {
break;
} else if (isblank(UCH(*dst))) {
count++;
} else {
break;
}
}
return FALSE;
return (count > 1);
}
/*
@ -2301,7 +2372,7 @@ dlg_trim_string(char *s)
* then ignore the '\n'. This eliminates the need to escape
* the '\n' character (no need to use "\n\").
*/
while (*p1 == ' ')
while (isblank(UCH(*p1)))
p1++;
if (*p1 == '\n')
p = p1 + 1;
@ -2310,15 +2381,15 @@ dlg_trim_string(char *s)
*s++ = *p++;
else {
/* Replace the '\n' with a space if cr_wrap is not set */
if (!trim_blank(base, s))
if (!trim_blank(base, p))
*s++ = ' ';
p++;
}
} else /* If *p != '\n' */
*s++ = *p++;
} else if (dialog_vars.trim_whitespace) {
if (*p == ' ') {
if (*(s - 1) != ' ') {
if (isblank(UCH(*p))) {
if (!isblank(UCH(*(s - 1)))) {
*s++ = ' ';
p++;
} else
@ -2326,7 +2397,7 @@ dlg_trim_string(char *s)
} else if (*p == '\n') {
if (dialog_vars.cr_wrap)
*s++ = *p++;
else if (*(s - 1) != ' ') {
else if (!isblank(UCH(*(s - 1)))) {
/* Strip '\n's if cr_wrap is not set. */
*s++ = ' ';
p++;
@ -2335,8 +2406,8 @@ dlg_trim_string(char *s)
} else
*s++ = *p++;
} else { /* If there are no "\n" strings */
if (*p == ' ' && !dialog_vars.nocollapse) {
if (!trim_blank(base, s))
if (isblank(UCH(*p)) && !dialog_vars.nocollapse) {
if (!trim_blank(base, p))
*s++ = *p;
p++;
} else
@ -2510,7 +2581,7 @@ dlg_add_quoted(char *string)
dlg_add_result(my_quote);
while (*string != '\0') {
temp[0] = *string++;
if (strchr(my_quote, *temp) || strchr(must_fix, *temp))
if ((strchr) (my_quote, *temp) || (strchr) (must_fix, *temp))
dlg_add_result("\\");
dlg_add_result(temp);
}

24
yesno.c
View File

@ -1,9 +1,9 @@
/*
* $Id: yesno.c,v 1.57 2012/12/01 01:48:21 tom Exp $
* $Id: yesno.c,v 1.62 2018/06/19 22:57:01 tom Exp $
*
* yesno.c -- implements the yes/no box
*
* Copyright 1999-2011,2012 Thomas E. Dickey
* Copyright 1999-2012,2018 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
@ -37,8 +37,8 @@ dialog_yesno(const char *title, const char *cprompt, int height, int width)
static DLG_KEYS_BINDING binding[] = {
HELPKEY_BINDINGS,
ENTERKEY_BINDINGS,
TRAVERSE_BINDINGS,
SCROLLKEY_BINDINGS,
TRAVERSE_BINDINGS,
END_KEYS_BINDING
};
/* *INDENT-ON* */
@ -49,7 +49,7 @@ dialog_yesno(const char *title, const char *cprompt, int height, int width)
int button = dlg_default_button();
WINDOW *dialog = 0;
int result = DLG_EXIT_UNKNOWN;
char *prompt = dlg_strclone(cprompt);
char *prompt;
const char **buttons = dlg_yes_labels();
int min_width = 25;
bool show = TRUE;
@ -58,9 +58,18 @@ dialog_yesno(const char *title, const char *cprompt, int height, int width)
#ifdef KEY_RESIZE
int req_high = height;
int req_wide = width;
restart:
#endif
DLG_TRACE(("# yesno args:\n"));
DLG_TRACE2S("title", title);
DLG_TRACE2S("message", cprompt);
DLG_TRACE2N("height", height);
DLG_TRACE2N("width", width);
#ifdef KEY_RESIZE
restart:
#endif
prompt = dlg_strclone(cprompt);
dlg_tab_correct_str(prompt);
dlg_button_layout(buttons, &min_width);
dlg_auto_size(title, prompt, &height, &width, 2, min_width);
@ -86,7 +95,7 @@ dialog_yesno(const char *title, const char *cprompt, int height, int width)
dlg_draw_title(dialog, title);
dlg_draw_helpline(dialog, FALSE);
(void) wattrset(dialog, dialog_attr);
dlg_attrset(dialog, dialog_attr);
page = height - (1 + 3 * MARGIN);
dlg_draw_buttons(dialog,
@ -133,9 +142,12 @@ dialog_yesno(const char *title, const char *cprompt, int height, int width)
break;
#ifdef KEY_RESIZE
case KEY_RESIZE:
dlg_will_resize(dialog);
dlg_clear();
free(prompt);
height = req_high;
width = req_wide;
show = TRUE;
goto restart;
#endif
default: