Deleted Added
full compact
dialog.subr (298884) dialog.subr (300050)
1if [ ! "$_DIALOG_SUBR" ]; then _DIALOG_SUBR=1
2#
3# Copyright (c) 2006-2015 Devin Teske
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
1if [ ! "$_DIALOG_SUBR" ]; then _DIALOG_SUBR=1
2#
3# Copyright (c) 2006-2015 Devin Teske
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26#
27# $FreeBSD: head/usr.sbin/bsdconfig/share/dialog.subr 298884 2016-05-01 16:38:12Z pfg $
27# $FreeBSD: head/usr.sbin/bsdconfig/share/dialog.subr 300050 2016-05-17 12:52:31Z eadler $
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." dialog.subr
34f_include $BSDCFG_SHARE/strings.subr
35f_include $BSDCFG_SHARE/variable.subr
36
37BSDCFG_LIBE="/usr/libexec/bsdconfig"
38f_include_lang $BSDCFG_LIBE/include/messages.subr
39
40############################################################ CONFIGURATION
41
42#
43# Default file descriptor to link to stdout for dialog(1) passthru allowing
44# execution of dialog from within a sub-shell (so-long as its standard output
45# is explicitly redirected to this file descriptor).
46#
47: ${DIALOG_TERMINAL_PASSTHRU_FD:=${TERMINAL_STDOUT_PASSTHRU:-3}}
48
49############################################################ GLOBALS
50
51#
52# Default name of dialog(1) utility
53# NOTE: This is changed to "Xdialog" by the optional `-X' argument
54#
55DIALOG="dialog"
56
57#
58# Default dialog(1) title and backtitle text
59#
60DIALOG_TITLE="$pgm"
61DIALOG_BACKTITLE="bsdconfig"
62
63#
64# Settings used while interacting with dialog(1)
65#
66DIALOG_MENU_TAGS="123456789ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwxyz"
67
68#
69# Declare that we are fully-compliant with Xdialog(1) by unset'ing all
70# compatibility settings.
71#
72unset XDIALOG_HIGH_DIALOG_COMPAT
73unset XDIALOG_FORCE_AUTOSIZE
74unset XDIALOG_INFOBOX_TIMEOUT
75
76#
77# Exit codes for [X]dialog(1)
78#
79DIALOG_OK=${SUCCESS:-0}
80DIALOG_CANCEL=${FAILURE:-1}
81DIALOG_HELP=2
82DIALOG_ITEM_HELP=2
83DIALOG_EXTRA=3
84DIALOG_ITEM_HELP=4
85export DIALOG_ERROR=254 # sh(1) can't handle the default of `-1'
86DIALOG_ESC=255
87
88#
89# Default behavior is to call f_dialog_init() automatically when loaded.
90#
91: ${DIALOG_SELF_INITIALIZE=1}
92
93#
94# Default terminal size (used if/when running without a controlling terminal)
95#
96: ${DEFAULT_TERMINAL_SIZE:=24 80}
97
98#
99# Minimum width(s) for various dialog(1) implementations (sensible global
100# default(s) for all widgets of a given variant)
101#
102: ${DIALOG_MIN_WIDTH:=24}
103: ${XDIALOG_MIN_WIDTH:=35}
104
105#
106# When manually sizing Xdialog(1) widgets such as calendar and timebox, you'll
107# need to know the size of the embedded GUI objects because the height passed
108# to Xdialog(1) for these widgets has to be tall enough to accommodate them.
109#
110# These values are helpful when manually sizing with dialog(1) too, but in a
111# different way. dialog(1) does not make you accommodate the custom items in the
112# height (but does for width) -- a height of 3 will display three lines and a
113# full calendar, for example (whereas Xdialog will truncate the calendar if
114# given a height of 3). For dialog(1), use these values for making sure that
115# the height does not exceed max_height (obtained by f_dialog_max_size()).
116#
117DIALOG_CALENDAR_HEIGHT=15
118DIALOG_TIMEBOX_HEIGHT=6
119
120############################################################ GENERIC FUNCTIONS
121
122# f_dialog_data_sanitize $var_to_edit ...
123#
124# When using dialog(1) or Xdialog(1) sometimes unintended warnings or errors
125# are generated from underlying libraries. For example, if $LANG is set to an
126# invalid or unknown locale, the warnings from the Xdialog(1) libraries will
127# clutter the output. This function helps by providing a centralied function
128# that removes spurious warnings from the dialog(1) (or Xdialog(1)) response.
129#
130# Simply pass the name of one or more variables that need to be sanitized.
131# After execution, the variables will hold their newly-sanitized data.
132#
133f_dialog_data_sanitize()
134{
135 if [ "$#" -eq 0 ]; then
136 f_dprintf "%s: called with zero arguments" \
137 f_dialog_response_sanitize
138 return $FAILURE
139 fi
140
141 local __var_to_edit
142 for __var_to_edit in $*; do
143 # Skip warnings and trim leading/trailing whitespace
144 setvar $__var_to_edit "$( f_getvar $__var_to_edit | awk '
145 BEGIN { data = 0 }
146 {
147 if ( ! data )
148 {
149 if ( $0 ~ /^$/ ) next
150 if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next
151 data = 1
152 }
153 print
154 }
155 ' )"
156 done
157}
158
159# f_dialog_line_sanitize $var_to_edit ...
160#
161# When using dialog(1) or Xdialog(1) sometimes unintended warnings or errors
162# are generated from underlying libraries. For example, if $LANG is set to an
163# invalid or unknown locale, the warnings from the Xdialog(1) libraries will
164# clutter the output. This function helps by providing a centralied function
165# that removes spurious warnings from the dialog(1) (or Xdialog(1)) response.
166#
167# Simply pass the name of one or more variables that need to be sanitized.
168# After execution, the variables will hold their newly-sanitized data.
169#
170# This function, unlike f_dialog_data_sanitize(), also removes leading/trailing
171# whitespace from each line.
172#
173f_dialog_line_sanitize()
174{
175 if [ "$#" -eq 0 ]; then
176 f_dprintf "%s: called with zero arguments" \
177 f_dialog_response_sanitize
178 return $FAILURE
179 fi
180
181 local __var_to_edit
182 for __var_to_edit in $*; do
183 # Skip warnings and trim leading/trailing whitespace
184 setvar $__var_to_edit "$( f_getvar $__var_to_edit | awk '
185 BEGIN { data = 0 }
186 {
187 if ( ! data )
188 {
189 if ( $0 ~ /^$/ ) next
190 if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next
191 data = 1
192 }
193 sub(/^[[:space:]]*/, "")
194 sub(/[[:space:]]*$/, "")
195 print
196 }
197 ' )"
198 done
199}
200
201############################################################ TITLE FUNCTIONS
202
203# f_dialog_title [$new_title]
204#
205# Set the title of future dialog(1) ($DIALOG_TITLE) or backtitle of Xdialog(1)
206# ($DIALOG_BACKTITLE) invocations. If no arguments are given or the first
207# argument is NULL, the current title is returned.
208#
209# Each time this function is called, a backup of the current values is made
210# allowing a one-time (single-level) restoration of the previous title using
211# the f_dialog_title_restore() function (below).
212#
213f_dialog_title()
214{
215 local new_title="$1"
216
217 if [ "${1+set}" ]; then
218 if [ "$USE_XDIALOG" ]; then
219 _DIALOG_BACKTITLE="$DIALOG_BACKTITLE"
220 DIALOG_BACKTITLE="$new_title"
221 else
222 _DIALOG_TITLE="$DIALOG_TITLE"
223 DIALOG_TITLE="$new_title"
224 fi
225 else
226 if [ "$USE_XDIALOG" ]; then
227 echo "$DIALOG_BACKTITLE"
228 else
229 echo "$DIALOG_TITLE"
230 fi
231 fi
232}
233
234# f_dialog_title_restore
235#
236# Restore the previous title set by the last call to f_dialog_title().
237# Restoration is non-recursive and only works to restore the most-recent title.
238#
239f_dialog_title_restore()
240{
241 if [ "$USE_XDIALOG" ]; then
242 DIALOG_BACKTITLE="$_DIALOG_BACKTITLE"
243 else
244 DIALOG_TITLE="$_DIALOG_TITLE"
245 fi
246}
247
248# f_dialog_backtitle [$new_backtitle]
249#
250# Set the backtitle of future dialog(1) ($DIALOG_BACKTITLE) or title of
251# Xdialog(1) ($DIALOG_TITLE) invocations. If no arguments are given or the
252# first argument is NULL, the current backtitle is returned.
253#
254f_dialog_backtitle()
255{
256 local new_backtitle="$1"
257
258 if [ "${1+set}" ]; then
259 if [ "$USE_XDIALOG" ]; then
260 _DIALOG_TITLE="$DIALOG_TITLE"
261 DIALOG_TITLE="$new_backtitle"
262 else
263 _DIALOG_BACKTITLE="$DIALOG_BACKTITLE"
264 DIALOG_BACKTITLE="$new_backtitle"
265 fi
266 else
267 if [ "$USE_XDIALOG" ]; then
268 echo "$DIALOG_TITLE"
269 else
270 echo "$DIALOG_BACKTITLE"
271 fi
272 fi
273}
274
275# f_dialog_backtitle_restore
276#
277# Restore the previous backtitle set by the last call to f_dialog_backtitle().
278# Restoration is non-recursive and only works to restore the most-recent
279# backtitle.
280#
281f_dialog_backtitle_restore()
282{
283 if [ "$USE_XDIALOG" ]; then
284 DIALOG_TITLE="$_DIALOG_TITLE"
285 else
286 DIALOG_BACKTITLE="$_DIALOG_BACKTITLE"
287 fi
288}
289
290############################################################ SIZE FUNCTIONS
291
292# f_dialog_max_size $var_height $var_width
293#
294# Get the maximum height and width for a dialog widget and store the values in
295# $var_height and $var_width (respectively).
296#
297f_dialog_max_size()
298{
299 local funcname=f_dialog_max_size
300 local __var_height="$1" __var_width="$2" __max_size
301 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
302 if [ "$USE_XDIALOG" ]; then
303 __max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
304 else
305 if __max_size=$( $DIALOG --print-maxsize \
306 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD )
307 then
308 f_dprintf "$funcname: %s --print-maxsize = [%s]" \
309 "$DIALOG" "$__max_size"
310 # usually "MaxSize: 24, 80"
311 __max_size="${__max_size#*: }"
312 f_replaceall "$__max_size" "," "" __max_size
313 else
314 f_eval_catch -dk __max_size $funcname stty \
315 'stty size' || __max_size=
316 # usually "24 80"
317 fi
318 : ${__max_size:=$DEFAULT_TERMINAL_SIZE}
319 fi
320 if [ "$__var_height" ]; then
321 local __height="${__max_size%%[$IFS]*}"
322 #
323 # If we're not using Xdialog(1), we should assume that $DIALOG
324 # will render --backtitle behind the widget. In such a case, we
325 # should prevent a widget from obscuring the backtitle (unless
326 # $NO_BACKTITLE is set and non-NULL, allowing a trap-door).
327 #
328 if [ ! "$USE_XDIALOG" ] && [ ! "$NO_BACKTITLE" ]; then
329 #
330 # If use_shadow (in ~/.dialogrc) is OFF, we need to
331 # subtract 4, otherwise 5. However, don't check this
332 # every time, rely on an initialization variable set
333 # by f_dialog_init().
334 #
335 local __adjust=5
336 [ "$NO_SHADOW" ] && __adjust=4
337
338 # Don't adjust height if already too small (allowing
339 # obscured backtitle for small values of __height).
340 [ ${__height:-0} -gt 11 ] &&
341 __height=$(( $__height - $__adjust ))
342 fi
343 setvar "$__var_height" "$__height"
344 fi
345 [ "$__var_width" ] && setvar "$__var_width" "${__max_size##*[$IFS]}"
346}
347
348# f_dialog_size_constrain $var_height $var_width [$min_height [$min_width]]
349#
350# Modify $var_height to be no-less-than $min_height (if given; zero otherwise)
351# and no-greater-than terminal height (or screen height if $USE_XDIALOG is
352# set).
353#
354# Also modify $var_width to be no-less-than $XDIALOG_MIN_WIDTH (or
355# $XDIALOG_MIN_WIDTH if $_USE_XDIALOG is set) and no-greater-than terminal
356# or screen width. The use of $[X]DIALOG_MIN_WIDTH can be overridden by
357# passing $min_width.
358#
359# Return status is success unless one of the passed arguments is invalid
360# or all of the $var_* arguments are either NULL or missing.
361#
362f_dialog_size_constrain()
363{
364 local __var_height="$1" __var_width="$2"
365 local __min_height="$3" __min_width="$4"
366 local __retval=$SUCCESS
367
368 # Return failure unless at least one var_* argument is passed
369 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
370
371 #
372 # Print debug warnings if any given (non-NULL) argument are invalid
373 # NOTE: Don't change the name of $__{var,min,}{height,width}
374 #
375 local __height __width
376 local __arg __cp __fname=f_dialog_size_constrain
377 for __arg in height width; do
378 debug= f_getvar __var_$__arg __cp
379 [ "$__cp" ] || continue
380 if ! debug= f_getvar "$__cp" __$__arg; then
381 f_dprintf "%s: var_%s variable \`%s' not set" \
382 $__fname $__arg "$__cp"
383 __retval=$FAILURE
384 elif ! eval f_isinteger \$__$__arg; then
385 f_dprintf "%s: var_%s variable value not a number" \
386 $__fname $__arg
387 __retval=$FAILURE
388 fi
389 done
390 for __arg in height width; do
391 debug= f_getvar __min_$__arg __cp
392 [ "$__cp" ] || continue
393 f_isinteger "$__cp" && continue
394 f_dprintf "%s: min_%s value not a number" $__fname $__arg
395 __retval=$FAILURE
396 setvar __min_$__arg ""
397 done
398
399 # Obtain maximum height and width values
400 # NOTE: Function name appended to prevent __var_{height,width} values
401 # from becoming local (and thus preventing setvar from working).
402 local __max_height_size_constain __max_width_size_constrain
403 f_dialog_max_size \
404 __max_height_size_constrain __max_width_size_constrain
405
406 # Adjust height if desired
407 if [ "$__var_height" ]; then
408 if [ $__height -lt ${__min_height:-0} ]; then
409 setvar "$__var_height" $__min_height
410 elif [ $__height -gt $__max_height_size_constrain ]; then
411 setvar "$__var_height" $__max_height_size_constrain
412 fi
413 fi
414
415 # Adjust width if desired
416 if [ "$__var_width" ]; then
417 if [ "$USE_XDIALOG" ]; then
418 : ${__min_width:=${XDIALOG_MIN_WIDTH:-35}}
419 else
420 : ${__min_width:=${DIALOG_MIN_WIDTH:-24}}
421 fi
422 if [ $__width -lt $__min_width ]; then
423 setvar "$__var_width" $__min_width
424 elif [ $__width -gt $__max_width_size_constrain ]; then
425 setvar "$__var_width" $__max_width_size_constrain
426 fi
427 fi
428
429 if [ "$debug" ]; then
430 # Print final constrained values to debugging
431 [ "$__var_height" ] && f_quietly f_getvar "$__var_height"
432 [ "$__var_width" ] && f_quietly f_getvar "$__var_width"
433 fi
434
435 return $__retval # success if no debug warnings were printed
436}
437
438# f_dialog_menu_constrain $var_height $var_width $var_rows "$prompt" \
439# [$min_height [$min_width [$min_rows]]]
440#
441# Modify $var_height to be no-less-than $min_height (if given; zero otherwise)
442# and no-greater-than terminal height (or screen height if $USE_XDIALOG is
443# set).
444#
445# Also modify $var_width to be no-less-than $XDIALOG_MIN_WIDTH (or
446# $XDIALOG_MIN_WIDTH if $_USE_XDIALOG is set) and no-greater-than terminal
447# or screen width. The use of $[X]DIALOG_MIN_WIDTH can be overridden by
448# passing $min_width.
449#
450# Last, modify $var_rows to be no-less-than $min_rows (if specified; zero
451# otherwise) and no-greater-than (max_height - 8) where max_height is the
452# terminal height (or screen height if $USE_XDIALOG is set). If $prompt is NULL
453# or missing, dialog(1) allows $var_rows to be (max_height - 7), maximizing the
454# number of visible rows.
455#
456# Return status is success unless one of the passed arguments is invalid
457# or all of the $var_* arguments are either NULL or missing.
458#
459f_dialog_menu_constrain()
460{
461 local __var_height="$1" __var_width="$2" __var_rows="$3" __prompt="$4"
462 local __min_height="$5" __min_width="$6" __min_rows="$7"
463
464 # Return failure unless at least one var_* argument is passed
465 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
466 return $FAILURE
467
468 #
469 # Print debug warnings if any given (non-NULL) argument are invalid
470 # NOTE: Don't change the name of $__{var,min,}{height,width,rows}
471 #
472 local __height_menu_constrain __width_menu_constrain
473 local __rows_menu_constrain
474 local __arg __cp __fname=f_dialog_menu_constrain
475 for __arg in height width rows; do
476 debug= f_getvar __var_$__arg __cp
477 [ "$__cp" ] || continue
478 if ! debug= f_getvar "$__cp" __${__arg}_menu_constrain; then
479 f_dprintf "%s: var_%s variable \`%s' not set" \
480 $__fname $__arg "$__cp"
481 __retval=$FAILURE
482 elif ! eval f_isinteger \$__${__arg}_menu_constrain; then
483 f_dprintf "%s: var_%s variable value not a number" \
484 $__fname $__arg
485 __retval=$FAILURE
486 fi
487 done
488 for __arg in height width rows; do
489 debug= f_getvar __min_$__arg __cp
490 [ "$__cp" ] || continue
491 f_isinteger "$__cp" && continue
492 f_dprintf "%s: min_%s value not a number" $__fname $__arg
493 __retval=$FAILURE
494 setvar __min_$__arg ""
495 done
496
497 # Obtain maximum height and width values
498 # NOTE: Function name appended to prevent __var_{height,width} values
499 # from becoming local (and thus preventing setvar from working).
500 local __max_height_menu_constrain __max_width_menu_constrain
501 f_dialog_max_size \
502 __max_height_menu_constrain __max_width_menu_constrain
503
504 # Adjust height if desired
505 if [ "$__var_height" ]; then
506 if [ $__height_menu_constrain -lt ${__min_height:-0} ]; then
507 setvar "$__var_height" $__min_height
508 elif [ $__height_menu_constrain -gt \
509 $__max_height_menu_constrain ]
510 then
511 setvar "$__var_height" $__max_height_menu_constrain
512 fi
513 fi
514
515 # Adjust width if desired
516 if [ "$__var_width" ]; then
517 if [ "$USE_XDIALOG" ]; then
518 : ${__min_width:=${XDIALOG_MIN_WIDTH:-35}}
519 else
520 : ${__min_width:=${DIALOG_MIN_WIDTH:-24}}
521 fi
522 if [ $__width_menu_constrain -lt $__min_width ]; then
523 setvar "$__var_width" $__min_width
524 elif [ $__width_menu_constrain -gt \
525 $__max_width_menu_constrain ]
526 then
527 setvar "$__var_width" $__max_width_menu_constrain
528 fi
529 fi
530
531 # Adjust rows if desired
532 if [ "$__var_rows" ]; then
533 if [ "$USE_XDIALOG" ]; then
534 : ${__min_rows:=1}
535 else
536 : ${__min_rows:=0}
537 fi
538
539 local __max_rows_menu_constrain=$((
540 $__max_height_menu_constrain - 7
541 ))
542 # If prompt_len is zero (no prompt), bump the max-rows by 1
543 # Default assumption is (if no argument) that there's no prompt
544 [ ${__prompt_len:-0} -gt 0 ] || __max_rows_menu_constrain=$((
545 $__max_rows_menu_constrain + 1
546 ))
547
548 if [ $__rows_menu_constrain -lt $__min_rows ]; then
549 setvar "$__var_rows" $__min_rows
550 elif [ $__rows_menu_constrain -gt $__max_rows_menu_constrain ]
551 then
552 setvar "$__var_rows" $__max_rows_menu_constrain
553 fi
554 fi
555
556 if [ "$debug" ]; then
557 # Print final constrained values to debugging
558 [ "$__var_height" ] && f_quietly f_getvar "$__var_height"
559 [ "$__var_width" ] && f_quietly f_getvar "$__var_width"
560 [ "$__var_rows" ] && f_quietly f_getvar "$__var_rows"
561 fi
562
563 return $__retval # success if no debug warnings were printed
564}
565
566# f_dialog_infobox_size [-n] $var_height $var_width \
567# $title $backtitle $prompt [$hline]
568#
569# Not all versions of dialog(1) perform auto-sizing of the width and height of
570# `--infobox' boxes sensibly.
571#
572# This function helps solve this issue by taking two sets of sequential
573# arguments. The first set of arguments are the variable names to use when
574# storing the calculated height and width. The second set of arguments are the
575# title, backtitle, prompt, and [optionally] hline. The optimal height and
576# width for the described widget (not exceeding the actual terminal height or
577# width) is stored in $var_height and $var_width (respectively).
578#
579# If the first argument is `-n', the calculated sizes ($var_height and
580# $var_width) are not constrained to minimum/maximum values.
581#
582# Newline character sequences (``\n'') in $prompt are expanded as-is done by
583# dialog(1).
584#
585f_dialog_infobox_size()
586{
587 local __constrain=1
588 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
589 local __var_height="$1" __var_width="$2"
590 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6"
591
592 # Return unless at least one size aspect has been requested
593 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
594
595 # Default height/width of zero for auto-sizing
596 local __height=0 __width=0 __n
597
598 # Adjust height if desired
599 if [ "$__var_height" ]; then
600 #
601 # Set height based on number of rows in prompt
602 #
603 __n=$( echo -n "$__prompt" | f_number_of_lines )
604 __n=$(( $__n + 2 ))
605 [ $__n -gt $__height ] && __height=$__n
606
607 #
608 # For Xdialog(1) bump height if backtitle is enabled (displayed
609 # in the X11 window with a separator line between the backtitle
610 # and msg text).
611 #
612 if [ "$USE_XDIALOG" -a "$__btitle" ]; then
613 __n=$( echo "$__btitle" | f_number_of_lines )
614 __height=$(( $__height + $__n + 2 ))
615 fi
616
617 setvar "$__var_height" $__height
618 fi
619
620 # Adjust width if desired
621 if [ "$__var_width" ]; then
622 #
623 # Bump width for long titles
624 #
625 __n=$(( ${#__title} + 4 ))
626 [ $__n -gt $__width ] && __width=$__n
627
628 #
629 # If using Xdialog(1), bump width for long backtitles (which
630 # appear within the window).
631 #
632 if [ "$USE_XDIALOG" ]; then
633 __n=$(( ${#__btitle} + 4 ))
634 [ $__n -gt $__width ] && __width=$__n
635 fi
636
637 #
638 # Bump width for long prompts
639 #
640 __n=$( echo "$__prompt" | f_longest_line_length )
641 __n=$(( $__n + 4 )) # add width for border
642 [ $__n -gt $__width ] && __width=$__n
643
644 #
645 # Bump width for long hlines. Xdialog(1) supports `--hline' but
646 # it's currently not used (so don't do anything here if using
647 # Xdialog(1)).
648 #
649 if [ ! "$USE_XDIALOG" ]; then
650 __n=$(( ${#__hline} + 10 ))
651 [ $__n -gt $__width ] && __width=$__n
652 fi
653
654 # Bump width by 16.6% if using Xdialog(1)
655 [ "$USE_XDIALOG" ] && __width=$(( $__width + $__width / 6 ))
656
657 setvar "$__var_width" $__width
658 fi
659
660 # Constrain values to sensible minimums/maximums unless `-n' was passed
661 # Return success if no-constrain, else return status from constrain
662 [ ! "$__constrain" ] ||
663 f_dialog_size_constrain "$__var_height" "$__var_width"
664}
665
666# f_dialog_buttonbox_size [-n] $var_height $var_width \
667# $title $backtitle $prompt [$hline]
668#
669# Not all versions of dialog(1) perform auto-sizing of the width and height of
670# `--msgbox' and `--yesno' boxes sensibly.
671#
672# This function helps solve this issue by taking two sets of sequential
673# arguments. The first set of arguments are the variable names to use when
674# storing the calculated height and width. The second set of arguments are the
675# title, backtitle, prompt, and [optionally] hline. The optimal height and
676# width for the described widget (not exceeding the actual terminal height or
677# width) is stored in $var_height and $var_width (respectively).
678#
679# If the first argument is `-n', the calculated sizes ($var_height and
680# $var_width) are not constrained to minimum/maximum values.
681#
682# Newline character sequences (``\n'') in $prompt are expanded as-is done by
683# dialog(1).
684#
685f_dialog_buttonbox_size()
686{
687 local __constrain=1
688 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
689 local __var_height="$1" __var_width="$2"
690 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6"
691
692 # Return unless at least one size aspect has been requested
693 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
694
695 # Calculate height/width of infobox (adjusted/constrained below)
696 # NOTE: Function name appended to prevent __var_{height,width} values
697 # from becoming local (and thus preventing setvar from working).
698 local __height_bbox_size __width_bbox_size
699 f_dialog_infobox_size -n \
700 "${__var_height:+__height_bbox_size}" \
701 "${__var_width:+__width_bbox_size}" \
702 "$__title" "$__btitle" "$__prompt" "$__hline"
703
704 # Adjust height if desired
705 if [ "$__var_height" ]; then
706 # Add height to accommodate the buttons
707 __height_bbox_size=$(( $__height_bbox_size + 2 ))
708
709 # Adjust for clipping with Xdialog(1) on Linux/GTK2
710 [ "$USE_XDIALOG" ] &&
711 __height_bbox_size=$(( $__height_bbox_size + 3 ))
712
713 setvar "$__var_height" $__height_bbox_size
714 fi
715
716 # No adjustemnts to width, just pass-thru the infobox width
717 if [ "$__var_width" ]; then
718 setvar "$__var_width" $__width_bbox_size
719 fi
720
721 # Constrain values to sensible minimums/maximums unless `-n' was passed
722 # Return success if no-constrain, else return status from constrain
723 [ ! "$__constrain" ] ||
724 f_dialog_size_constrain "$__var_height" "$__var_width"
725}
726
727# f_dialog_inputbox_size [-n] $var_height $var_width \
728# $title $backtitle $prompt $init [$hline]
729#
730# Not all versions of dialog(1) perform auto-sizing of the width and height of
731# `--inputbox' boxes sensibly.
732#
733# This function helps solve this issue by taking two sets of sequential
734# arguments. The first set of arguments are the variable names to use when
735# storing the calculated height and width. The second set of arguments are the
736# title, backtitle, prompt, and [optionally] hline. The optimal height and
737# width for the described widget (not exceeding the actual terminal height or
738# width) is stored in $var_height and $var_width (respectively).
739#
740# If the first argument is `-n', the calculated sizes ($var_height and
741# $var_width) are not constrained to minimum/maximum values.
742#
743# Newline character sequences (``\n'') in $prompt are expanded as-is done by
744# dialog(1).
745#
746f_dialog_inputbox_size()
747{
748 local __constrain=1
749 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
750 local __var_height="$1" __var_width="$2"
751 local __title="$3" __btitle="$4" __prompt="$5" __init="$6" __hline="$7"
752
753 # Return unless at least one size aspect has been requested
754 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
755
756 # Calculate height/width of buttonbox (adjusted/constrained below)
757 # NOTE: Function name appended to prevent __var_{height,width} values
758 # from becoming local (and thus preventing setvar from working).
759 local __height_ibox_size __width_ibox_size
760 f_dialog_buttonbox_size -n \
761 "${__var_height:+__height_ibox_size}" \
762 "${__var_width:+__width_ibox_size}" \
763 "$__title" "$__btitle" "$__prompt" "$__hline"
764
765 # Adjust height if desired
766 if [ "$__var_height" ]; then
767 # Add height for input box (not needed for Xdialog(1))
768 [ ! "$USE_XDIALOG" ] &&
769 __height_ibox_size=$(( $__height_ibox_size + 3 ))
770
771 setvar "$__var_height" $__height_ibox_size
772 fi
773
774 # Adjust width if desired
775 if [ "$__var_width" ]; then
776 # Bump width for initial text (something neither dialog(1) nor
777 # Xdialog(1) do, but worth it!; add 16.6% if using Xdialog(1))
778 local __n=$(( ${#__init} + 7 ))
779 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 ))
780 [ $__n -gt $__width_ibox_size ] && __width_ibox_size=$__n
781
782 setvar "$__var_width" $__width_ibox_size
783 fi
784
785 # Constrain values to sensible minimums/maximums unless `-n' was passed
786 # Return success if no-constrain, else return status from constrain
787 [ ! "$__constrain" ] ||
788 f_dialog_size_constrain "$__var_height" "$__var_width"
789}
790
791# f_xdialog_2inputsbox_size [-n] $var_height $var_width \
792# $title $backtitle $prompt \
793# $label1 $init1 $label2 $init2
794#
795# Xdialog(1) does not perform auto-sizing of the width and height of
796# `--2inputsbox' boxes sensibly.
797#
798# This function helps solve this issue by taking two sets of sequential
799# arguments. The first set of arguments are the variable names to use when
800# storing the calculated height and width. The second set of arguments are the
801# title, backtitle, prompt, label for the first field, initial text for said
802# field, label for the second field, and initial text for said field. The
803# optimal height and width for the described widget (not exceeding the actual
804# terminal height or width) is stored in $var_height and $var_width
805# (respectively).
806#
807# If the first argument is `-n', the calculated sizes ($var_height and
808# $var_width) are not constrained to minimum/maximum values.
809#
810# Newline character sequences (``\n'') in $prompt are expanded as-is done by
811# Xdialog(1).
812#
813f_xdialog_2inputsbox_size()
814{
815 local __constrain=1
816 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
817 local __var_height="$1" __var_width="$2"
818 local __title="$3" __btitle="$4" __prompt="$5"
819 local __label1="$6" __init1="$7" __label2="$8" __init2="$9"
820
821 # Return unless at least one size aspect has been requested
822 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
823
824 # Calculate height/width of inputbox (adjusted/constrained below)
825 # NOTE: Function name appended to prevent __var_{height,width} values
826 # from becoming local (and thus preventing setvar from working).
827 local __height_2ibox_size __width_2ibox_size
828 f_dialog_inputbox_size -n \
829 "${__var_height:+__height_2ibox_size}" \
830 "${__var_width:+__width_2ibox_size}" \
831 "$__title" "$__btitle" "$__prompt" "$__hline" "$__init1"
832
833 # Adjust height if desired
834 if [ "$__var_height" ]; then
835 # Add height for 1st label, 2nd label, and 2nd input box
836 __height_2ibox_size=$(( $__height_2ibox_size + 2 + 2 + 2 ))
837 setvar "$__var_height" $__height_2ibox_size
838 fi
839
840 # Adjust width if desired
841 if [ "$__var_width" ]; then
842 local __n
843
844 # Bump width for first label text (+16.6% since Xdialog(1))
845 __n=$(( ${#__label1} + 7 ))
846 __n=$(( $__n + $__n / 6 ))
847 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n
848
849 # Bump width for second label text (+16.6% since Xdialog(1))
850 __n=$(( ${#__label2} + 7 ))
851 __n=$(( $__n + $__n / 6 ))
852 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n
853
854 # Bump width for 2nd initial text (something neither dialog(1)
855 # nor Xdialog(1) do, but worth it!; +16.6% since Xdialog(1))
856 __n=$(( ${#__init2} + 7 ))
857 __n=$(( $__n + $__n / 6 ))
858 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n
859
860 setvar "$__var_width" $__width_2ibox_size
861 fi
862
863 # Constrain values to sensible minimums/maximums unless `-n' was passed
864 # Return success if no-constrain, else return status from constrain
865 [ ! "$__constrain" ] ||
866 f_dialog_size_constrain "$__var_height" "$__var_width"
867}
868
869# f_dialog_menu_size [-n] $var_height $var_width $var_rows \
870# $title $backtitle $prompt $hline \
871# $tag1 $item1 $tag2 $item2 ...
872#
873# Not all versions of dialog(1) perform auto-sizing of the width and height of
874# `--menu' boxes sensibly.
875#
876# This function helps solve this issue by taking three sets of sequential
877# arguments. The first set of arguments are the variable names to use when
878# storing the calculated height, width, and rows. The second set of arguments
879# are the title, backtitle, prompt, and hline. The [optional] third set of
880# arguments are the menu list itself (comprised of tag/item couplets). The
881# optimal height, width, and rows for the described widget (not exceeding the
882# actual terminal height or width) is stored in $var_height, $var_width, and
883# $var_rows (respectively).
884#
885# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
886# and $var_rows) are not constrained to minimum/maximum values.
887#
888f_dialog_menu_size()
889{
890 local __constrain=1
891 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
892 local __var_height="$1" __var_width="$2" __var_rows="$3"
893 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7"
894 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline
895
896 # Return unless at least one size aspect has been requested
897 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
898 return $FAILURE
899
900 # Calculate height/width of infobox (adjusted/constrained below)
901 # NOTE: Function name appended to prevent __var_{height,width} values
902 # from becoming local (and thus preventing setvar from working).
903 local __height_menu_size __width_menu_size
904 f_dialog_infobox_size -n \
905 "${__var_height:+__height_menu_size}" \
906 "${__var_width:+__width_menu_size}" \
907 "$__title" "$__btitle" "$__prompt" "$__hline"
908
909 #
910 # Always process the menu-item arguments to get the longest tag-length,
911 # longest item-length (both used to bump the width), and the number of
912 # rows (used to bump the height).
913 #
914 local __longest_tag=0 __longest_item=0 __rows=0
915 while [ $# -ge 2 ]; do
916 local __tag="$1" __item="$2"
917 shift 2 # tag/item
918 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
919 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
920 __rows=$(( $__rows + 1 ))
921 done
922
923 # Adjust rows early (for up-comning height calculation)
924 if [ "$__var_height" -o "$__var_rows" ]; then
925 # Add a row for visual aid if using Xdialog(1)
926 [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 ))
927 fi
928
929 # Adjust height if desired
930 if [ "$__var_height" ]; then
931 # Add rows to height
932 if [ "$USE_XDIALOG" ]; then
933 __height_menu_size=$((
934 $__height_menu_size + $__rows + 7 ))
935 else
936 __height_menu_size=$((
937 $__height_menu_size + $__rows + 4 ))
938 fi
939 setvar "$__var_height" $__height_menu_size
940 fi
941
942 # Adjust width if desired
943 if [ "$__var_width" ]; then
944 # The sum total between the longest tag-length and the
945 # longest item-length should be used to bump menu width
946 local __n=$(( $__longest_tag + $__longest_item + 10 ))
947 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6%
948 [ $__n -gt $__width_menu_size ] && __width_menu_size=$__n
949
950 setvar "$__var_width" $__width_menu_size
951 fi
952
953 # Store adjusted rows if desired
954 [ "$__var_rows" ] && setvar "$__var_rows" $__rows
955
956 # Constrain height, width, and rows to sensible minimum/maximum values
957 # Return success if no-constrain, else return status from constrain
958 [ ! "$__constrain" ] || f_dialog_menu_constrain \
959 "$__var_height" "$__var_width" "$__var_rows" "$__prompt"
960}
961
962# f_dialog_menu_with_help_size [-n] $var_height $var_width $var_rows \
963# $title $backtitle $prompt $hline \
964# $tag1 $item1 $help1 $tag2 $item2 $help2 ...
965#
966# Not all versions of dialog(1) perform auto-sizing of the width and height of
967# `--menu' boxes sensibly.
968#
969# This function helps solve this issue by taking three sets of sequential
970# arguments. The first set of arguments are the variable names to use when
971# storing the calculated height, width, and rows. The second set of arguments
972# are the title, backtitle, prompt, and hline. The [optional] third set of
973# arguments are the menu list itself (comprised of tag/item/help triplets). The
974# optimal height, width, and rows for the described widget (not exceeding the
975# actual terminal height or width) is stored in $var_height, $var_width, and
976# $var_rows (respectively).
977#
978# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
979# and $var_rows) are not constrained to minimum/maximum values.
980#
981f_dialog_menu_with_help_size()
982{
983 local __constrain=1
984 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
985 local __var_height="$1" __var_width="$2" __var_rows="$3"
986 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7"
987 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline
988
989 # Return unless at least one size aspect has been requested
990 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
991 return $FAILURE
992
993 # Calculate height/width of infobox (adjusted/constrained below)
994 # NOTE: Function name appended to prevent __var_{height,width} values
995 # from becoming local (and thus preventing setvar from working).
996 local __height_menu_with_help_size __width_menu_with_help_size
997 f_dialog_infobox_size -n \
998 "${__var_height:+__height_menu_with_help_size}" \
999 "${__var_width:+__width_menu_with_help_size}" \
1000 "$__title" "$__btitle" "$__prompt" "$__hline"
1001
1002 #
1003 # Always process the menu-item arguments to get the longest tag-length,
1004 # longest item-length, longest help-length (help-length only considered
1005 # if using Xdialog(1), as it places the help string in the widget) --
1006 # all used to bump the width -- and the number of rows (used to bump
1007 # the height).
1008 #
1009 local __longest_tag=0 __longest_item=0 __longest_help=0 __rows=0
1010 while [ $# -ge 3 ]; do
1011 local __tag="$1" __item="$2" __help="$3"
1012 shift 3 # tag/item/help
1013 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
1014 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
1015 [ ${#__help} -gt $__longest_help ] && __longest_help=${#__help}
1016 __rows=$(( $__rows + 1 ))
1017 done
1018
1019 # Adjust rows early (for up-coming height calculation)
1020 if [ "$__var_height" -o "$__var_rows" ]; then
1021 # Add a row for visual aid if using Xdialog(1)
1022 [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 ))
1023 fi
1024
1025 # Adjust height if desired
1026 if [ "$__var_height" ]; then
1027 # Add rows to height
1028 if [ "$USE_XDIALOG" ]; then
1029 __height_menu_with_help_size=$((
1030 $__height_menu_with_help_size + $__rows + 8 ))
1031 else
1032 __height_menu_with_help_size=$((
1033 $__height_menu_with_help_size + $__rows + 4 ))
1034 fi
1035 setvar "$__var_height" $__height_menu_with_help_size
1036 fi
1037
1038 # Adjust width if desired
1039 if [ "$__var_width" ]; then
1040 # The sum total between the longest tag-length and the
1041 # longest item-length should be used to bump menu width
1042 local __n=$(( $__longest_tag + $__longest_item + 10 ))
1043 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6%
1044 [ $__n -gt $__width_menu_with_help_size ] &&
1045 __width_menu_with_help_size=$__n
1046
1047 # Update width for help text if using Xdialog(1)
1048 if [ "$USE_XDIALOG" ]; then
1049 __n=$(( $__longest_help + 10 ))
1050 __n=$(( $__n + $__n / 6 )) # plus 16.6%
1051 [ $__n -gt $__width_menu_with_help_size ] &&
1052 __width_menu_with_help_size=$__n
1053 fi
1054
1055 setvar "$__var_width" $__width_menu_with_help_size
1056 fi
1057
1058 # Store adjusted rows if desired
1059 [ "$__var_rows" ] && setvar "$__var_rows" $__rows
1060
1061 # Constrain height, width, and rows to sensible minimum/maximum values
1062 # Return success if no-constrain, else return status from constrain
1063 [ ! "$__constrain" ] || f_dialog_menu_constrain \
1064 "$__var_height" "$__var_width" "$__var_rows" "$__prompt"
1065}
1066
1067# f_dialog_radiolist_size [-n] $var_height $var_width $var_rows \
1068# $title $backtitle $prompt $hline \
1069# $tag1 $item1 $status1 $tag2 $item2 $status2 ...
1070#
1071# Not all versions of dialog(1) perform auto-sizing of the width and height of
1072# `--radiolist' boxes sensibly.
1073#
1074# This function helps solve this issue by taking three sets of sequential
1075# arguments. The first set of arguments are the variable names to use when
1076# storing the calculated height, width, and rows. The second set of arguments
1077# are the title, backtitle, prompt, and hline. The [optional] third set of
1078# arguments are the radio list itself (comprised of tag/item/status triplets).
1079# The optimal height, width, and rows for the described widget (not exceeding
1080# the actual terminal height or width) is stored in $var_height, $var_width,
1081# and $var_rows (respectively).
1082#
1083# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
1084# and $var_rows) are not constrained to minimum/maximum values.
1085#
1086f_dialog_radiolist_size()
1087{
1088 local __constrain=1
1089 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
1090 local __var_height="$1" __var_width="$2" __var_rows="$3"
1091 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7"
1092 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline
1093
1094 # Return unless at least one size aspect has been requested
1095 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
1096 return $FAILURE
1097
1098 # Calculate height/width of infobox (adjusted/constrained below)
1099 # NOTE: Function name appended to prevent __var_{height,width} values
1100 # from becoming local (and thus preventing setvar from working).
1101 local __height_rlist_size __width_rlist_size
1102 f_dialog_infobox_size -n \
1103 "${__var_height:+__height_rlist_size}" \
1104 "${__var_width:+__width_rlist_size}" \
1105 "$__title" "$__btitle" "$__prompt" "$__hline"
1106
1107 #
1108 # Always process the menu-item arguments to get the longest tag-length,
1109 # longest item-length (both used to bump the width), and the number of
1110 # rows (used to bump the height).
1111 #
1112 local __longest_tag=0 __longest_item=0 __rows_rlist_size=0
1113 while [ $# -ge 3 ]; do
1114 local __tag="$1" __item="$2"
1115 shift 3 # tag/item/status
1116 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
1117 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
1118 __rows_rlist_size=$(( $__rows_rlist_size + 1 ))
1119 done
1120
1121 # Adjust rows early (for up-coming height calculation)
1122 if [ "$__var_height" -o "$__var_rows" ]; then
1123 # Add a row for visual aid if using Xdialog(1)
1124 [ "$USE_XDIALOG" ] &&
1125 __rows_rlist_size=$(( $__rows_rlist_size + 1 ))
1126 fi
1127
1128 # Adjust height if desired
1129 if [ "$__var_height" ]; then
1130 # Add rows to height
1131 if [ "$USE_XDIALOG" ]; then
1132 __height_rlist_size=$((
1133 $__height_rlist_size + $__rows_rlist_size + 7
1134 ))
1135 else
1136 __height_rlist_size=$((
1137 $__height_rlist_size + $__rows_rlist_size + 4
1138 ))
1139 fi
1140 setvar "$__var_height" $__height_rlist_size
1141 fi
1142
1143 # Adjust width if desired
1144 if [ "$__var_width" ]; then
1145 # Sum total between longest tag-length, longest item-length,
1146 # and radio-button width should be used to bump menu width
1147 local __n=$(( $__longest_tag + $__longest_item + 13 ))
1148 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6%
1149 [ $__n -gt $__width_rlist_size ] && __width_rlist_size=$__n
1150
1151 setvar "$__var_width" $__width_rlist_size
1152 fi
1153
1154 # Store adjusted rows if desired
1155 [ "$__var_rows" ] && setvar "$__var_rows" $__rows_rlist_size
1156
1157 # Constrain height, width, and rows to sensible minimum/maximum values
1158 # Return success if no-constrain, else return status from constrain
1159 [ ! "$__constrain" ] || f_dialog_menu_constrain \
1160 "$__var_height" "$__var_width" "$__var_rows" "$__prompt"
1161}
1162
1163# f_dialog_checklist_size [-n] $var_height $var_width $var_rows \
1164# $title $backtitle $prompt $hline \
1165# $tag1 $item1 $status1 $tag2 $item2 $status2 ...
1166#
1167# Not all versions of dialog(1) perform auto-sizing of the width and height of
1168# `--checklist' boxes sensibly.
1169#
1170# This function helps solve this issue by taking three sets of sequential
1171# arguments. The first set of arguments are the variable names to use when
1172# storing the calculated height, width, and rows. The second set of arguments
1173# are the title, backtitle, prompt, and hline. The [optional] third set of
1174# arguments are the check list itself (comprised of tag/item/status triplets).
1175# The optimal height, width, and rows for the described widget (not exceeding
1176# the actual terminal height or width) is stored in $var_height, $var_width,
1177# and $var_rows (respectively).
1178#
1179# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
1180# and $var_rows) are not constrained to minimum/maximum values.
1181#
1182f_dialog_checklist_size()
1183{
1184 f_dialog_radiolist_size "$@"
1185}
1186
1187# f_dialog_radiolist_with_help_size [-n] $var_height $var_width $var_rows \
1188# $title $backtitle $prompt $hline \
1189# $tag1 $item1 $status1 $help1 \
1190# $tag2 $item2 $status2 $help2 ...
1191#
1192# Not all versions of dialog(1) perform auto-sizing of the width and height of
1193# `--radiolist' boxes sensibly.
1194#
1195# This function helps solve this issue by taking three sets of sequential
1196# arguments. The first set of arguments are the variable names to use when
1197# storing the calculated height, width, and rows. The second set of arguments
1198# are the title, backtitle, prompt, and hline. The [optional] third set of
1199# arguments are the radio list itself (comprised of tag/item/status/help
1200# quadruplets). The optimal height, width, and rows for the described widget
1201# (not exceeding the actual terminal height or width) is stored in $var_height,
1202# $var_width, and $var_rows (respectively).
1203#
1204# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
1205# and $var_rows) are not constrained to minimum/maximum values.
1206#
1207f_dialog_radiolist_with_help_size()
1208{
1209 local __constrain=1
1210 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
1211 local __var_height="$1" __var_width="$2" __var_rows="$3"
1212 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7"
1213 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline
1214
1215 # Return unless at least one size aspect has been requested
1216 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
1217 return $FAILURE
1218
1219 # Calculate height/width of infobox (adjusted/constrained below)
1220 # NOTE: Function name appended to prevent __var_{height,width} values
1221 # from becoming local (and thus preventing setvar from working).
1222 local __height_rlist_with_help_size __width_rlist_with_help_size
1223 f_dialog_infobox_size -n \
1224 "${__var_height:+__height_rlist_with_help_size}" \
1225 "${__var_width:+__width_rlist_with_help_size}" \
1226 "$__title" "$__btitle" "$__prompt" "$__hline"
1227
1228 #
1229 # Always process the menu-item arguments to get the longest tag-length,
1230 # longest item-length, longest help-length (help-length only considered
1231 # if using Xdialog(1), as it places the help string in the widget) --
1232 # all used to bump the width -- and the number of rows (used to bump
1233 # the height).
1234 #
1235 local __longest_tag=0 __longest_item=0 __longest_help=0
1236 local __rows_rlist_with_help_size=0
1237 while [ $# -ge 4 ]; do
1238 local __tag="$1" __item="$2" __status="$3" __help="$4"
1239 shift 4 # tag/item/status/help
1240 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
1241 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
1242 [ ${#__help} -gt $__longest_help ] && __longest_help=${#__help}
1243 __rows_rlist_with_help_size=$((
1244 $__rows_rlist_with_help_size + 1
1245 ))
1246 done
1247
1248 # Adjust rows early (for up-coming height calculation)
1249 if [ "$__var_height" -o "$__var_rows" ]; then
1250 # Add a row for visual aid if using Xdialog(1)
1251 [ "$USE_XDIALOG" ] &&
1252 __rows_rlist_with_help_size=$((
1253 $__rows_rlist_with_help_size + 1
1254 ))
1255 fi
1256
1257 # Adjust height if desired
1258 if [ "$__var_height" ]; then
1259 # Add rows to height
1260 if [ "$USE_XDIALOG" ]; then
1261 __height_rlist_with_help_size=$((
1262 $__height_rlist_with_help_size +
1263 $__rows_rlist_with_help_size + 7
1264 ))
1265 else
1266 __height_rlist_with_help_size=$((
1267 $__height_rlist_with_help_size +
1268 $__rows_rlist_with_help_size + 4
1269 ))
1270 fi
1271 setvar "$__var_height" $__height
1272 fi
1273
1274 # Adjust width if desired
1275 if [ "$__var_width" ]; then
1276 # Sum total between longest tag-length, longest item-length,
1277 # and radio-button width should be used to bump menu width
1278 local __n=$(( $__longest_tag + $__longest_item + 13 ))
1279 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6%
1280 [ $__n -gt $__width_rlist_with_help_size ] &&
1281 __width_rlist_with_help_size=$__n
1282
1283 # Update width for help text if using Xdialog(1)
1284 if [ "$USE_XDIALOG" ]; then
1285 __n=$(( $__longest_help + 10 ))
1286 __n=$(( $__n + $__n / 6 )) # plus 16.6%
1287 [ $__n -gt $__width_rlist_with_help_size ] &&
1288 __width_rlist_with_help_size=$__n
1289 fi
1290
1291 setvar "$__var_width" $__width_rlist_with_help_size
1292 fi
1293
1294 # Store adjusted rows if desired
1295 [ "$__var_rows" ] && setvar "$__var_rows" $__rows_rlist_with_help_size
1296
1297 # Constrain height, width, and rows to sensible minimum/maximum values
1298 # Return success if no-constrain, else return status from constrain
1299 [ ! "$__constrain" ] || f_dialog_menu_constrain \
1300 "$__var_height" "$__var_width" "$__var_rows" "$__prompt"
1301}
1302
1303# f_dialog_checklist_with_help_size [-n] $var_height $var_width $var_rows \
1304# $title $backtitle $prompt $hline \
1305# $tag1 $item1 $status1 $help1 \
1306# $tag2 $item2 $status2 $help2 ...
1307#
1308# Not all versions of dialog(1) perform auto-sizing of the width and height of
1309# `--checklist' boxes sensibly.
1310#
1311# This function helps solve this issue by taking three sets of sequential
1312# arguments. The first set of arguments are the variable names to use when
1313# storing the calculated height, width, and rows. The second set of arguments
1314# are the title, backtitle, prompt, and hline. The [optional] third set of
1315# arguments are the check list itself (comprised of tag/item/status/help
1316# quadruplets). The optimal height, width, and rows for the described widget
1317# (not exceeding the actual terminal height or width) is stored in $var_height,
1318# $var_width, and $var_rows (respectively).
1319#
1320# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
1321# and $var_rows) are not constrained to minimum/maximum values.
1322#
1323f_dialog_checklist_with_help_size()
1324{
1325 f_dialog_radiolist_with_help_size "$@"
1326}
1327
1328# f_dialog_calendar_size [-n] $var_height $var_width \
1329# $title $backtitle $prompt [$hline]
1330#
1331# Not all versions of dialog(1) perform auto-sizing of the width and height of
1332# `--calendar' boxes sensibly.
1333#
1334# This function helps solve this issue by taking two sets of sequential
1335# arguments. The first set of arguments are the variable names to use when
1336# storing the calculated height and width. The second set of arguments are the
1337# title, backtitle, prompt, and [optionally] hline. The optimal height and
1338# width for the described widget (not exceeding the actual terminal height or
1339# width) is stored in $var_height and $var_width (respectively).
1340#
1341# If the first argument is `-n', the calculated sizes ($var_height and
1342# $var_width) are not constrained to minimum/maximum values.
1343#
1344# Newline character sequences (``\n'') in $prompt are expanded as-is done by
1345# dialog(1).
1346#
1347f_dialog_calendar_size()
1348{
1349 local __constrain=1
1350 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
1351 local __var_height="$1" __var_width="$2"
1352 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6"
1353
1354 # Return unless at least one size aspect has been requested
1355 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
1356
1357 #
1358 # Obtain/Adjust minimum and maximum thresholds
1359 # NOTE: Function name appended to prevent __var_{height,width} values
1360 # from becoming local (and thus preventing setvar from working).
1361 #
1362 local __max_height_cal_size __max_width_cal_size
1363 f_dialog_max_size __max_height_cal_size __max_width_cal_size
1364 __max_width_cal_size=$(( $__max_width_cal_size - 2 ))
1365 # the calendar box will refuse to display if too wide
1366 local __min_width
1367 if [ "$USE_XDIALOG" ]; then
1368 __min_width=55
1369 else
1370 __min_width=40
1371 __max_height_cal_size=$((
1372 $__max_height_cal_size - $DIALOG_CALENDAR_HEIGHT ))
1373 # When using dialog(1), we can't predict whether the user has
1374 # disabled shadow's in their `$HOME/.dialogrc' file, so we'll
1375 # subtract one for the potential shadow around the widget
1376 __max_height_cal_size=$(( $__max_height_cal_size - 1 ))
1377 fi
1378
1379 # Calculate height if desired
1380 if [ "$__var_height" ]; then
1381 local __height
1382 __height=$( echo "$__prompt" | f_number_of_lines )
1383
1384 if [ "$USE_XDIALOG" ]; then
1385 # Add height to accommodate for embedded calendar widget
1386 __height=$(( $__height + $DIALOG_CALENDAR_HEIGHT - 1 ))
1387
1388 # Also, bump height if backtitle is enabled
1389 if [ "$__btitle" ]; then
1390 local __n
1391 __n=$( echo "$__btitle" | f_number_of_lines )
1392 __height=$(( $__height + $__n + 2 ))
1393 fi
1394 else
1395 [ "$__prompt" ] && __height=$(( $__height + 1 ))
1396 fi
1397
1398 # Enforce maximum height, unless `-n' was passed
1399 [ "$__constrain" -a $__height -gt $__max_height_cal_size ] &&
1400 __height=$__max_height_cal_size
1401
1402 setvar "$__var_height" $__height
1403 fi
1404
1405 # Calculate width if desired
1406 if [ "$__var_width" ]; then
1407 # NOTE: Function name appended to prevent __var_{height,width}
1408 # values from becoming local (and thus preventing setvar
1409 # from working).
1410 local __width_cal_size
1411 f_dialog_infobox_size -n "" __width_cal_size \
1412 "$__title" "$__btitle" "$__prompt" "$__hline"
1413
1414 # Enforce minimum/maximum width, unless `-n' was passed
1415 if [ "$__constrain" ]; then
1416 if [ $__width_cal_size -lt $__min_width ]; then
1417 __width_cal_size=$__min_width
1418 elif [ $__width_cal_size -gt $__max_width_cal_size ]
1419 then
1420 __width_cal_size=$__max_width_size
1421 fi
1422 fi
1423
1424 setvar "$__var_width" $__width_cal_size
1425 fi
1426
1427 return $SUCCESS
1428}
1429
1430# f_dialog_timebox_size [-n] $var_height $var_width \
1431# $title $backtitle $prompt [$hline]
1432#
1433# Not all versions of dialog(1) perform auto-sizing of the width and height of
1434# `--timebox' boxes sensibly.
1435#
1436# This function helps solve this issue by taking two sets of sequential
1437# arguments. The first set of arguments are the variable names to use when
1438# storing the calculated height and width. The second set of arguments are the
1439# title, backtitle, prompt, and [optionally] hline. The optional height and
1440# width for the described widget (not exceeding the actual terminal height or
1441# width) is stored in $var_height and $var_width (respectively).
1442#
1443# If the first argument is `-n', the calculated sizes ($var_height and
1444# $var_width) are not constrained to minimum/maximum values.
1445#
1446# Newline character sequences (``\n'') in $prompt are expanded as-is done by
1447# dialog(1).
1448#
1449f_dialog_timebox_size()
1450{
1451 local __constrain=1
1452 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
1453 local __var_height="$1" __var_width="$2"
1454 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6"
1455
1456 # Return unless at least one size aspect has been requested
1457 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
1458
1459 #
1460 # Obtain/Adjust minimum and maximum thresholds
1461 # NOTE: Function name appended to prevent __var_{height,width} values
1462 # from becoming local (and thus preventing setvar from working).
1463 #
1464 local __max_height_tbox_size __max_width_tbox_size
1465 f_dialog_max_size __max_height_tbox_size __max_width_tbox_size
1466 __max_width_tbox_size=$(( $__max_width_tbox_size - 2 ))
1467 # the timebox widget refuses to display if too wide
1468 local __min_width
1469 if [ "$USE_XDIALOG" ]; then
1470 __min_width=40
1471 else
1472 __min_width=20
1473 __max_height_tbox_size=$(( \
1474 $__max_height_tbox_size - $DIALOG_TIMEBOX_HEIGHT ))
1475 # When using dialog(1), we can't predict whether the user has
1476 # disabled shadow's in their `$HOME/.dialogrc' file, so we'll
1477 # subtract one for the potential shadow around the widget
1478 __max_height_tbox_size=$(( $__max_height_tbox_size - 1 ))
1479 fi
1480
1481 # Calculate height if desired
1482 if [ "$__var_height" -a "$USE_XDIALOG" ]; then
1483 # When using Xdialog(1), the height seems to have
1484 # no effect. All values provide the same results.
1485 setvar "$__var_height" 0 # autosize
1486 elif [ "$__var_height" ]; then
1487 local __height
1488 __height=$( echo "$__prompt" | f_number_of_lines )
1489 __height=$(( $__height ${__prompt:++1} + 1 ))
1490
1491 # Enforce maximum height, unless `-n' was passed
1492 [ "$__constrain" -a $__height -gt $__max_height_tbox_size ] &&
1493 __height=$__max_height_tbox_size
1494
1495 setvar "$__var_height" $__height
1496 fi
1497
1498 # Calculate width if desired
1499 if [ "$__var_width" ]; then
1500 # NOTE: Function name appended to prevent __var_{height,width}
1501 # values from becoming local (and thus preventing setvar
1502 # from working).
1503 local __width_tbox_size
1504 f_dialog_infobox_size -n "" __width_tbox_size \
1505 "$__title" "$__btitle" "$__prompt" "$__hline"
1506
1507 # Enforce the minimum width for displaying the timebox
1508 if [ "$__constrain" ]; then
1509 if [ $__width_tbox_size -lt $__min_width ]; then
1510 __width_tbox_size=$__min_width
1511 elif [ $__width_tbox_size -ge $__max_width_tbox_size ]
1512 then
1513 __width_tbox_size=$__max_width_tbox_size
1514 fi
1515 fi
1516
1517 setvar "$__var_width" $__width_tbox_size
1518 fi
1519
1520 return $SUCCESS
1521}
1522
1523############################################################ CLEAR FUNCTIONS
1524
1525# f_dialog_clear
1526#
1527# Clears any/all previous dialog(1) displays.
1528#
1529f_dialog_clear()
1530{
1531 $DIALOG --clear
1532}
1533
1534############################################################ INFO FUNCTIONS
1535
1536# f_dialog_info $info_text ...
1537#
1538# Throw up a dialog(1) infobox. The infobox remains until another dialog is
1539# displayed or `dialog --clear' (or f_dialog_clear) is called.
1540#
1541f_dialog_info()
1542{
1543 local info_text="$*" height width
1544 f_dialog_infobox_size height width \
1545 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$info_text"
1546 $DIALOG \
1547 --title "$DIALOG_TITLE" \
1548 --backtitle "$DIALOG_BACKTITLE" \
1549 ${USE_XDIALOG:+--ignore-eof} \
1550 ${USE_XDIALOG:+--no-buttons} \
1551 --infobox "$info_text" $height $width
1552}
1553
1554# f_xdialog_info $info_text ...
1555#
1556# Throw up an Xdialog(1) infobox and do not dismiss it until stdin produces
1557# EOF. This implies that you must execute this either as an rvalue to a pipe,
1558# lvalue to indirection or in a sub-shell that provides data on stdin.
1559#
1560# To open an Xdialog(1) infobox that does not disappear until expeclitly dis-
1561# missed, use the following:
1562#
1563# f_xdialog_info "$info_text" < /dev/tty &
1564# pid=$!
1565# # Perform some lengthy actions
1566# kill $pid
1567#
1568# NB: Check $USE_XDIALOG if you need to support both dialog(1) and Xdialog(1).
1569#
1570f_xdialog_info()
1571{
1572 local info_text="$*" height width
1573 f_dialog_infobox_size height width \
1574 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$info_text"
1575 exec $DIALOG \
1576 --title "$DIALOG_TITLE" \
1577 --backtitle "$DIALOG_BACKTITLE" \
1578 --no-close --no-buttons \
1579 --infobox "$info_text" $height $width \
1580 -1 # timeout of -1 means abort when EOF on stdin
1581}
1582
1583############################################################ PAUSE FUNCTIONS
1584
1585# f_dialog_pause $msg_text $duration [$hline]
1586#
1587# Display a message in a widget with a progress bar that runs backward for
1588# $duration seconds.
1589#
1590f_dialog_pause()
1591{
1592 local pause_text="$1" duration="$2" hline="$3" height width
1593 f_isinteger "$duration" || return $FAILURE
1594 f_dialog_buttonbox_size height width \
1595 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$pause_text" "$hline"
1596 if [ "$USE_XDIALOG" ]; then
1597 $DIALOG \
1598 --title "$DIALOG_TITLE" \
1599 --backtitle "$DIALOG_BACKTITLE" \
1600 --ok-label "$msg_skip" \
1601 --cancel-label "$msg_cancel" \
1602 ${noCancel:+--no-cancel} \
1603 --timeout "$duration" \
1604 --yesno "$pause_text" \
1605 $height $width
1606 else
1607 [ $duration -gt 0 ] && duration=$(( $duration - 1 ))
1608 height=$(( $height + 3 )) # Add height for progress bar
1609 $DIALOG \
1610 --title "$DIALOG_TITLE" \
1611 --backtitle "$DIALOG_BACKTITLE" \
1612 --hline "$hline" \
1613 --ok-label "$msg_skip" \
1614 --cancel-label "$msg_cancel" \
1615 ${noCancel:+--no-cancel} \
1616 --pause "$pause_text" \
1617 $height $width "$duration"
1618 fi
1619}
1620
1621# f_dialog_pause_no_cancel $msg_text $duration [$hline]
1622#
1623# Display a message in a widget with a progress bar that runs backward for
1624# $duration seconds. No cancel button is provided. Always returns success.
1625#
1626f_dialog_pause_no_cancel()
1627{
1628 noCancel=1 f_dialog_pause "$@"
1629 return $SUCCESS
1630}
1631
1632############################################################ MSGBOX FUNCTIONS
1633
1634# f_dialog_msgbox $msg_text [$hline]
1635#
1636# Throw up a dialog(1) msgbox. The msgbox remains until the user presses ENTER
1637# or ESC, acknowledging the modal dialog.
1638#
1639# If the user presses ENTER, the exit status is zero (success), otherwise if
1640# the user presses ESC the exit status is 255.
1641#
1642f_dialog_msgbox()
1643{
1644 local msg_text="$1" hline="$2" height width
1645 f_dialog_buttonbox_size height width \
1646 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline"
1647 $DIALOG \
1648 --title "$DIALOG_TITLE" \
1649 --backtitle "$DIALOG_BACKTITLE" \
1650 --hline "$hline" \
1651 --ok-label "$msg_ok" \
1652 --msgbox "$msg_text" $height $width
1653}
1654
1655############################################################ TEXTBOX FUNCTIONS
1656
1657# f_dialog_textbox $file
1658#
1659# Display the contents of $file (or an error if $file does not exist, etc.) in
1660# a dialog(1) textbox (which has a scrollable region for the text). The textbox
1661# remains until the user presses ENTER or ESC, acknowledging the modal dialog.
1662#
1663# If the user presses ENTER, the exit status is zero (success), otherwise if
1664# the user presses ESC the exit status is 255.
1665#
1666f_dialog_textbox()
1667{
1668 local file="$1"
1669 local contents height width retval
1670
1671 contents=$( cat "$file" 2>&1 )
1672 retval=$?
1673
1674 f_dialog_buttonbox_size height width \
1675 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$contents"
1676
1677 if [ $retval -eq $SUCCESS ]; then
1678 $DIALOG \
1679 --title "$DIALOG_TITLE" \
1680 --backtitle "$DIALOG_BACKTITLE" \
1681 --exit-label "$msg_ok" \
1682 --no-cancel \
1683 --textbox "$file" $height $width
1684 else
1685 $DIALOG \
1686 --title "$DIALOG_TITLE" \
1687 --backtitle "$DIALOG_BACKTITLE" \
1688 --ok-label "$msg_ok" \
1689 --msgbox "$contents" $height $width
1690 fi
1691}
1692
1693############################################################ YESNO FUNCTIONS
1694
1695# f_dialog_yesno $msg_text [$hline]
1696#
1697# Display a dialog(1) Yes/No prompt to allow the user to make some decision.
1698# The yesno prompt remains until the user presses ENTER or ESC, acknowledging
1699# the modal dialog.
1700#
1701# If the user chooses YES the exit status is zero, or chooses NO the exit
1702# status is one, or presses ESC the exit status is 255.
1703#
1704f_dialog_yesno()
1705{
1706 local msg_text="$1" height width
1707 local hline="${2-$hline_arrows_tab_enter}"
1708
1709 f_interactive || return 0 # If non-interactive, return YES all the time
1710
1711 f_dialog_buttonbox_size height width \
1712 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline"
1713
1714 if [ "$USE_XDIALOG" ]; then
1715 $DIALOG \
1716 --title "$DIALOG_TITLE" \
1717 --backtitle "$DIALOG_BACKTITLE" \
1718 --hline "$hline" \
1719 --ok-label "$msg_yes" \
1720 --cancel-label "$msg_no" \
1721 --yesno "$msg_text" $height $width
1722 else
1723 $DIALOG \
1724 --title "$DIALOG_TITLE" \
1725 --backtitle "$DIALOG_BACKTITLE" \
1726 --hline "$hline" \
1727 --yes-label "$msg_yes" \
1728 --no-label "$msg_no" \
1729 --yesno "$msg_text" $height $width
1730 fi
1731}
1732
1733# f_dialog_noyes $msg_text [$hline]
1734#
1735# Display a dialog(1) No/Yes prompt to allow the user to make some decision.
1736# The noyes prompt remains until the user presses ENTER or ESC, acknowledging
1737# the modal dialog.
1738#
1739# If the user chooses YES the exit status is zero, or chooses NO the exit
1740# status is one, or presses ESC the exit status is 255.
1741#
1742# NOTE: This is just like the f_dialog_yesno function except "No" is default.
1743#
1744f_dialog_noyes()
1745{
1746 local msg_text="$1" height width
1747 local hline="${2-$hline_arrows_tab_enter}"
1748
1749 f_interactive || return 1 # If non-interactive, return NO all the time
1750
1751 f_dialog_buttonbox_size height width \
1752 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline"
1753
1754 if [ "$USE_XDIALOG" ]; then
1755 $DIALOG \
1756 --title "$DIALOG_TITLE" \
1757 --backtitle "$DIALOG_BACKTITLE" \
1758 --hline "$hline" \
1759 --default-no \
1760 --ok-label "$msg_yes" \
1761 --cancel-label "$msg_no" \
1762 --yesno "$msg_text" $height $width
1763 else
1764 $DIALOG \
1765 --title "$DIALOG_TITLE" \
1766 --backtitle "$DIALOG_BACKTITLE" \
1767 --hline "$hline" \
1768 --defaultno \
1769 --yes-label "$msg_yes" \
1770 --no-label "$msg_no" \
1771 --yesno "$msg_text" $height $width
1772 fi
1773}
1774
1775############################################################ INPUT FUNCTIONS
1776
1777# f_dialog_inputstr_store [-s] $text
1778#
1779# Store some text from a dialog(1) inputbox to be retrieved later by
1780# f_dialog_inputstr_fetch(). If the first argument is `-s', the text is
1781# sanitized before being stored.
1782#
1783f_dialog_inputstr_store()
1784{
1785 local sanitize=
1786 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s
1787 local text="$1"
1788
1789 # Sanitize the line before storing it if desired
1790 [ "$sanitize" ] && f_dialog_line_sanitize text
1791
1792 setvar DIALOG_INPUTBOX_$$ "$text"
1793}
1794
1795# f_dialog_inputstr_fetch [$var_to_set]
1796#
1797# Obtain the inputstr entered by the user from the most recently displayed
1798# dialog(1) inputbox (previously stored with f_dialog_inputstr_store() above).
1799# If $var_to_set is NULL or missing, output is printed to stdout (which is less
1800# recommended due to performance degradation; in a loop for example).
1801#
1802f_dialog_inputstr_fetch()
1803{
1804 local __var_to_set="$1" __cp
1805
1806 debug= f_getvar DIALOG_INPUTBOX_$$ "${__var_to_set:-__cp}" # get data
1807 setvar DIALOG_INPUTBOX_$$ "" # scrub memory in case data was sensitive
1808
1809 # Return the line on standard-out if desired
1810 [ "$__var_to_set" ] || echo "$__cp"
1811
1812 return $SUCCESS
1813}
1814
1815# f_dialog_input $var_to_set $prompt [$init [$hline]]
1816#
1817# Prompt the user with a dialog(1) inputbox to enter some value. The inputbox
28#
29############################################################ INCLUDES
30
31BSDCFG_SHARE="/usr/share/bsdconfig"
32. $BSDCFG_SHARE/common.subr || exit 1
33f_dprintf "%s: loading includes..." dialog.subr
34f_include $BSDCFG_SHARE/strings.subr
35f_include $BSDCFG_SHARE/variable.subr
36
37BSDCFG_LIBE="/usr/libexec/bsdconfig"
38f_include_lang $BSDCFG_LIBE/include/messages.subr
39
40############################################################ CONFIGURATION
41
42#
43# Default file descriptor to link to stdout for dialog(1) passthru allowing
44# execution of dialog from within a sub-shell (so-long as its standard output
45# is explicitly redirected to this file descriptor).
46#
47: ${DIALOG_TERMINAL_PASSTHRU_FD:=${TERMINAL_STDOUT_PASSTHRU:-3}}
48
49############################################################ GLOBALS
50
51#
52# Default name of dialog(1) utility
53# NOTE: This is changed to "Xdialog" by the optional `-X' argument
54#
55DIALOG="dialog"
56
57#
58# Default dialog(1) title and backtitle text
59#
60DIALOG_TITLE="$pgm"
61DIALOG_BACKTITLE="bsdconfig"
62
63#
64# Settings used while interacting with dialog(1)
65#
66DIALOG_MENU_TAGS="123456789ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwxyz"
67
68#
69# Declare that we are fully-compliant with Xdialog(1) by unset'ing all
70# compatibility settings.
71#
72unset XDIALOG_HIGH_DIALOG_COMPAT
73unset XDIALOG_FORCE_AUTOSIZE
74unset XDIALOG_INFOBOX_TIMEOUT
75
76#
77# Exit codes for [X]dialog(1)
78#
79DIALOG_OK=${SUCCESS:-0}
80DIALOG_CANCEL=${FAILURE:-1}
81DIALOG_HELP=2
82DIALOG_ITEM_HELP=2
83DIALOG_EXTRA=3
84DIALOG_ITEM_HELP=4
85export DIALOG_ERROR=254 # sh(1) can't handle the default of `-1'
86DIALOG_ESC=255
87
88#
89# Default behavior is to call f_dialog_init() automatically when loaded.
90#
91: ${DIALOG_SELF_INITIALIZE=1}
92
93#
94# Default terminal size (used if/when running without a controlling terminal)
95#
96: ${DEFAULT_TERMINAL_SIZE:=24 80}
97
98#
99# Minimum width(s) for various dialog(1) implementations (sensible global
100# default(s) for all widgets of a given variant)
101#
102: ${DIALOG_MIN_WIDTH:=24}
103: ${XDIALOG_MIN_WIDTH:=35}
104
105#
106# When manually sizing Xdialog(1) widgets such as calendar and timebox, you'll
107# need to know the size of the embedded GUI objects because the height passed
108# to Xdialog(1) for these widgets has to be tall enough to accommodate them.
109#
110# These values are helpful when manually sizing with dialog(1) too, but in a
111# different way. dialog(1) does not make you accommodate the custom items in the
112# height (but does for width) -- a height of 3 will display three lines and a
113# full calendar, for example (whereas Xdialog will truncate the calendar if
114# given a height of 3). For dialog(1), use these values for making sure that
115# the height does not exceed max_height (obtained by f_dialog_max_size()).
116#
117DIALOG_CALENDAR_HEIGHT=15
118DIALOG_TIMEBOX_HEIGHT=6
119
120############################################################ GENERIC FUNCTIONS
121
122# f_dialog_data_sanitize $var_to_edit ...
123#
124# When using dialog(1) or Xdialog(1) sometimes unintended warnings or errors
125# are generated from underlying libraries. For example, if $LANG is set to an
126# invalid or unknown locale, the warnings from the Xdialog(1) libraries will
127# clutter the output. This function helps by providing a centralied function
128# that removes spurious warnings from the dialog(1) (or Xdialog(1)) response.
129#
130# Simply pass the name of one or more variables that need to be sanitized.
131# After execution, the variables will hold their newly-sanitized data.
132#
133f_dialog_data_sanitize()
134{
135 if [ "$#" -eq 0 ]; then
136 f_dprintf "%s: called with zero arguments" \
137 f_dialog_response_sanitize
138 return $FAILURE
139 fi
140
141 local __var_to_edit
142 for __var_to_edit in $*; do
143 # Skip warnings and trim leading/trailing whitespace
144 setvar $__var_to_edit "$( f_getvar $__var_to_edit | awk '
145 BEGIN { data = 0 }
146 {
147 if ( ! data )
148 {
149 if ( $0 ~ /^$/ ) next
150 if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next
151 data = 1
152 }
153 print
154 }
155 ' )"
156 done
157}
158
159# f_dialog_line_sanitize $var_to_edit ...
160#
161# When using dialog(1) or Xdialog(1) sometimes unintended warnings or errors
162# are generated from underlying libraries. For example, if $LANG is set to an
163# invalid or unknown locale, the warnings from the Xdialog(1) libraries will
164# clutter the output. This function helps by providing a centralied function
165# that removes spurious warnings from the dialog(1) (or Xdialog(1)) response.
166#
167# Simply pass the name of one or more variables that need to be sanitized.
168# After execution, the variables will hold their newly-sanitized data.
169#
170# This function, unlike f_dialog_data_sanitize(), also removes leading/trailing
171# whitespace from each line.
172#
173f_dialog_line_sanitize()
174{
175 if [ "$#" -eq 0 ]; then
176 f_dprintf "%s: called with zero arguments" \
177 f_dialog_response_sanitize
178 return $FAILURE
179 fi
180
181 local __var_to_edit
182 for __var_to_edit in $*; do
183 # Skip warnings and trim leading/trailing whitespace
184 setvar $__var_to_edit "$( f_getvar $__var_to_edit | awk '
185 BEGIN { data = 0 }
186 {
187 if ( ! data )
188 {
189 if ( $0 ~ /^$/ ) next
190 if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next
191 data = 1
192 }
193 sub(/^[[:space:]]*/, "")
194 sub(/[[:space:]]*$/, "")
195 print
196 }
197 ' )"
198 done
199}
200
201############################################################ TITLE FUNCTIONS
202
203# f_dialog_title [$new_title]
204#
205# Set the title of future dialog(1) ($DIALOG_TITLE) or backtitle of Xdialog(1)
206# ($DIALOG_BACKTITLE) invocations. If no arguments are given or the first
207# argument is NULL, the current title is returned.
208#
209# Each time this function is called, a backup of the current values is made
210# allowing a one-time (single-level) restoration of the previous title using
211# the f_dialog_title_restore() function (below).
212#
213f_dialog_title()
214{
215 local new_title="$1"
216
217 if [ "${1+set}" ]; then
218 if [ "$USE_XDIALOG" ]; then
219 _DIALOG_BACKTITLE="$DIALOG_BACKTITLE"
220 DIALOG_BACKTITLE="$new_title"
221 else
222 _DIALOG_TITLE="$DIALOG_TITLE"
223 DIALOG_TITLE="$new_title"
224 fi
225 else
226 if [ "$USE_XDIALOG" ]; then
227 echo "$DIALOG_BACKTITLE"
228 else
229 echo "$DIALOG_TITLE"
230 fi
231 fi
232}
233
234# f_dialog_title_restore
235#
236# Restore the previous title set by the last call to f_dialog_title().
237# Restoration is non-recursive and only works to restore the most-recent title.
238#
239f_dialog_title_restore()
240{
241 if [ "$USE_XDIALOG" ]; then
242 DIALOG_BACKTITLE="$_DIALOG_BACKTITLE"
243 else
244 DIALOG_TITLE="$_DIALOG_TITLE"
245 fi
246}
247
248# f_dialog_backtitle [$new_backtitle]
249#
250# Set the backtitle of future dialog(1) ($DIALOG_BACKTITLE) or title of
251# Xdialog(1) ($DIALOG_TITLE) invocations. If no arguments are given or the
252# first argument is NULL, the current backtitle is returned.
253#
254f_dialog_backtitle()
255{
256 local new_backtitle="$1"
257
258 if [ "${1+set}" ]; then
259 if [ "$USE_XDIALOG" ]; then
260 _DIALOG_TITLE="$DIALOG_TITLE"
261 DIALOG_TITLE="$new_backtitle"
262 else
263 _DIALOG_BACKTITLE="$DIALOG_BACKTITLE"
264 DIALOG_BACKTITLE="$new_backtitle"
265 fi
266 else
267 if [ "$USE_XDIALOG" ]; then
268 echo "$DIALOG_TITLE"
269 else
270 echo "$DIALOG_BACKTITLE"
271 fi
272 fi
273}
274
275# f_dialog_backtitle_restore
276#
277# Restore the previous backtitle set by the last call to f_dialog_backtitle().
278# Restoration is non-recursive and only works to restore the most-recent
279# backtitle.
280#
281f_dialog_backtitle_restore()
282{
283 if [ "$USE_XDIALOG" ]; then
284 DIALOG_TITLE="$_DIALOG_TITLE"
285 else
286 DIALOG_BACKTITLE="$_DIALOG_BACKTITLE"
287 fi
288}
289
290############################################################ SIZE FUNCTIONS
291
292# f_dialog_max_size $var_height $var_width
293#
294# Get the maximum height and width for a dialog widget and store the values in
295# $var_height and $var_width (respectively).
296#
297f_dialog_max_size()
298{
299 local funcname=f_dialog_max_size
300 local __var_height="$1" __var_width="$2" __max_size
301 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
302 if [ "$USE_XDIALOG" ]; then
303 __max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
304 else
305 if __max_size=$( $DIALOG --print-maxsize \
306 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD )
307 then
308 f_dprintf "$funcname: %s --print-maxsize = [%s]" \
309 "$DIALOG" "$__max_size"
310 # usually "MaxSize: 24, 80"
311 __max_size="${__max_size#*: }"
312 f_replaceall "$__max_size" "," "" __max_size
313 else
314 f_eval_catch -dk __max_size $funcname stty \
315 'stty size' || __max_size=
316 # usually "24 80"
317 fi
318 : ${__max_size:=$DEFAULT_TERMINAL_SIZE}
319 fi
320 if [ "$__var_height" ]; then
321 local __height="${__max_size%%[$IFS]*}"
322 #
323 # If we're not using Xdialog(1), we should assume that $DIALOG
324 # will render --backtitle behind the widget. In such a case, we
325 # should prevent a widget from obscuring the backtitle (unless
326 # $NO_BACKTITLE is set and non-NULL, allowing a trap-door).
327 #
328 if [ ! "$USE_XDIALOG" ] && [ ! "$NO_BACKTITLE" ]; then
329 #
330 # If use_shadow (in ~/.dialogrc) is OFF, we need to
331 # subtract 4, otherwise 5. However, don't check this
332 # every time, rely on an initialization variable set
333 # by f_dialog_init().
334 #
335 local __adjust=5
336 [ "$NO_SHADOW" ] && __adjust=4
337
338 # Don't adjust height if already too small (allowing
339 # obscured backtitle for small values of __height).
340 [ ${__height:-0} -gt 11 ] &&
341 __height=$(( $__height - $__adjust ))
342 fi
343 setvar "$__var_height" "$__height"
344 fi
345 [ "$__var_width" ] && setvar "$__var_width" "${__max_size##*[$IFS]}"
346}
347
348# f_dialog_size_constrain $var_height $var_width [$min_height [$min_width]]
349#
350# Modify $var_height to be no-less-than $min_height (if given; zero otherwise)
351# and no-greater-than terminal height (or screen height if $USE_XDIALOG is
352# set).
353#
354# Also modify $var_width to be no-less-than $XDIALOG_MIN_WIDTH (or
355# $XDIALOG_MIN_WIDTH if $_USE_XDIALOG is set) and no-greater-than terminal
356# or screen width. The use of $[X]DIALOG_MIN_WIDTH can be overridden by
357# passing $min_width.
358#
359# Return status is success unless one of the passed arguments is invalid
360# or all of the $var_* arguments are either NULL or missing.
361#
362f_dialog_size_constrain()
363{
364 local __var_height="$1" __var_width="$2"
365 local __min_height="$3" __min_width="$4"
366 local __retval=$SUCCESS
367
368 # Return failure unless at least one var_* argument is passed
369 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
370
371 #
372 # Print debug warnings if any given (non-NULL) argument are invalid
373 # NOTE: Don't change the name of $__{var,min,}{height,width}
374 #
375 local __height __width
376 local __arg __cp __fname=f_dialog_size_constrain
377 for __arg in height width; do
378 debug= f_getvar __var_$__arg __cp
379 [ "$__cp" ] || continue
380 if ! debug= f_getvar "$__cp" __$__arg; then
381 f_dprintf "%s: var_%s variable \`%s' not set" \
382 $__fname $__arg "$__cp"
383 __retval=$FAILURE
384 elif ! eval f_isinteger \$__$__arg; then
385 f_dprintf "%s: var_%s variable value not a number" \
386 $__fname $__arg
387 __retval=$FAILURE
388 fi
389 done
390 for __arg in height width; do
391 debug= f_getvar __min_$__arg __cp
392 [ "$__cp" ] || continue
393 f_isinteger "$__cp" && continue
394 f_dprintf "%s: min_%s value not a number" $__fname $__arg
395 __retval=$FAILURE
396 setvar __min_$__arg ""
397 done
398
399 # Obtain maximum height and width values
400 # NOTE: Function name appended to prevent __var_{height,width} values
401 # from becoming local (and thus preventing setvar from working).
402 local __max_height_size_constain __max_width_size_constrain
403 f_dialog_max_size \
404 __max_height_size_constrain __max_width_size_constrain
405
406 # Adjust height if desired
407 if [ "$__var_height" ]; then
408 if [ $__height -lt ${__min_height:-0} ]; then
409 setvar "$__var_height" $__min_height
410 elif [ $__height -gt $__max_height_size_constrain ]; then
411 setvar "$__var_height" $__max_height_size_constrain
412 fi
413 fi
414
415 # Adjust width if desired
416 if [ "$__var_width" ]; then
417 if [ "$USE_XDIALOG" ]; then
418 : ${__min_width:=${XDIALOG_MIN_WIDTH:-35}}
419 else
420 : ${__min_width:=${DIALOG_MIN_WIDTH:-24}}
421 fi
422 if [ $__width -lt $__min_width ]; then
423 setvar "$__var_width" $__min_width
424 elif [ $__width -gt $__max_width_size_constrain ]; then
425 setvar "$__var_width" $__max_width_size_constrain
426 fi
427 fi
428
429 if [ "$debug" ]; then
430 # Print final constrained values to debugging
431 [ "$__var_height" ] && f_quietly f_getvar "$__var_height"
432 [ "$__var_width" ] && f_quietly f_getvar "$__var_width"
433 fi
434
435 return $__retval # success if no debug warnings were printed
436}
437
438# f_dialog_menu_constrain $var_height $var_width $var_rows "$prompt" \
439# [$min_height [$min_width [$min_rows]]]
440#
441# Modify $var_height to be no-less-than $min_height (if given; zero otherwise)
442# and no-greater-than terminal height (or screen height if $USE_XDIALOG is
443# set).
444#
445# Also modify $var_width to be no-less-than $XDIALOG_MIN_WIDTH (or
446# $XDIALOG_MIN_WIDTH if $_USE_XDIALOG is set) and no-greater-than terminal
447# or screen width. The use of $[X]DIALOG_MIN_WIDTH can be overridden by
448# passing $min_width.
449#
450# Last, modify $var_rows to be no-less-than $min_rows (if specified; zero
451# otherwise) and no-greater-than (max_height - 8) where max_height is the
452# terminal height (or screen height if $USE_XDIALOG is set). If $prompt is NULL
453# or missing, dialog(1) allows $var_rows to be (max_height - 7), maximizing the
454# number of visible rows.
455#
456# Return status is success unless one of the passed arguments is invalid
457# or all of the $var_* arguments are either NULL or missing.
458#
459f_dialog_menu_constrain()
460{
461 local __var_height="$1" __var_width="$2" __var_rows="$3" __prompt="$4"
462 local __min_height="$5" __min_width="$6" __min_rows="$7"
463
464 # Return failure unless at least one var_* argument is passed
465 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
466 return $FAILURE
467
468 #
469 # Print debug warnings if any given (non-NULL) argument are invalid
470 # NOTE: Don't change the name of $__{var,min,}{height,width,rows}
471 #
472 local __height_menu_constrain __width_menu_constrain
473 local __rows_menu_constrain
474 local __arg __cp __fname=f_dialog_menu_constrain
475 for __arg in height width rows; do
476 debug= f_getvar __var_$__arg __cp
477 [ "$__cp" ] || continue
478 if ! debug= f_getvar "$__cp" __${__arg}_menu_constrain; then
479 f_dprintf "%s: var_%s variable \`%s' not set" \
480 $__fname $__arg "$__cp"
481 __retval=$FAILURE
482 elif ! eval f_isinteger \$__${__arg}_menu_constrain; then
483 f_dprintf "%s: var_%s variable value not a number" \
484 $__fname $__arg
485 __retval=$FAILURE
486 fi
487 done
488 for __arg in height width rows; do
489 debug= f_getvar __min_$__arg __cp
490 [ "$__cp" ] || continue
491 f_isinteger "$__cp" && continue
492 f_dprintf "%s: min_%s value not a number" $__fname $__arg
493 __retval=$FAILURE
494 setvar __min_$__arg ""
495 done
496
497 # Obtain maximum height and width values
498 # NOTE: Function name appended to prevent __var_{height,width} values
499 # from becoming local (and thus preventing setvar from working).
500 local __max_height_menu_constrain __max_width_menu_constrain
501 f_dialog_max_size \
502 __max_height_menu_constrain __max_width_menu_constrain
503
504 # Adjust height if desired
505 if [ "$__var_height" ]; then
506 if [ $__height_menu_constrain -lt ${__min_height:-0} ]; then
507 setvar "$__var_height" $__min_height
508 elif [ $__height_menu_constrain -gt \
509 $__max_height_menu_constrain ]
510 then
511 setvar "$__var_height" $__max_height_menu_constrain
512 fi
513 fi
514
515 # Adjust width if desired
516 if [ "$__var_width" ]; then
517 if [ "$USE_XDIALOG" ]; then
518 : ${__min_width:=${XDIALOG_MIN_WIDTH:-35}}
519 else
520 : ${__min_width:=${DIALOG_MIN_WIDTH:-24}}
521 fi
522 if [ $__width_menu_constrain -lt $__min_width ]; then
523 setvar "$__var_width" $__min_width
524 elif [ $__width_menu_constrain -gt \
525 $__max_width_menu_constrain ]
526 then
527 setvar "$__var_width" $__max_width_menu_constrain
528 fi
529 fi
530
531 # Adjust rows if desired
532 if [ "$__var_rows" ]; then
533 if [ "$USE_XDIALOG" ]; then
534 : ${__min_rows:=1}
535 else
536 : ${__min_rows:=0}
537 fi
538
539 local __max_rows_menu_constrain=$((
540 $__max_height_menu_constrain - 7
541 ))
542 # If prompt_len is zero (no prompt), bump the max-rows by 1
543 # Default assumption is (if no argument) that there's no prompt
544 [ ${__prompt_len:-0} -gt 0 ] || __max_rows_menu_constrain=$((
545 $__max_rows_menu_constrain + 1
546 ))
547
548 if [ $__rows_menu_constrain -lt $__min_rows ]; then
549 setvar "$__var_rows" $__min_rows
550 elif [ $__rows_menu_constrain -gt $__max_rows_menu_constrain ]
551 then
552 setvar "$__var_rows" $__max_rows_menu_constrain
553 fi
554 fi
555
556 if [ "$debug" ]; then
557 # Print final constrained values to debugging
558 [ "$__var_height" ] && f_quietly f_getvar "$__var_height"
559 [ "$__var_width" ] && f_quietly f_getvar "$__var_width"
560 [ "$__var_rows" ] && f_quietly f_getvar "$__var_rows"
561 fi
562
563 return $__retval # success if no debug warnings were printed
564}
565
566# f_dialog_infobox_size [-n] $var_height $var_width \
567# $title $backtitle $prompt [$hline]
568#
569# Not all versions of dialog(1) perform auto-sizing of the width and height of
570# `--infobox' boxes sensibly.
571#
572# This function helps solve this issue by taking two sets of sequential
573# arguments. The first set of arguments are the variable names to use when
574# storing the calculated height and width. The second set of arguments are the
575# title, backtitle, prompt, and [optionally] hline. The optimal height and
576# width for the described widget (not exceeding the actual terminal height or
577# width) is stored in $var_height and $var_width (respectively).
578#
579# If the first argument is `-n', the calculated sizes ($var_height and
580# $var_width) are not constrained to minimum/maximum values.
581#
582# Newline character sequences (``\n'') in $prompt are expanded as-is done by
583# dialog(1).
584#
585f_dialog_infobox_size()
586{
587 local __constrain=1
588 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
589 local __var_height="$1" __var_width="$2"
590 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6"
591
592 # Return unless at least one size aspect has been requested
593 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
594
595 # Default height/width of zero for auto-sizing
596 local __height=0 __width=0 __n
597
598 # Adjust height if desired
599 if [ "$__var_height" ]; then
600 #
601 # Set height based on number of rows in prompt
602 #
603 __n=$( echo -n "$__prompt" | f_number_of_lines )
604 __n=$(( $__n + 2 ))
605 [ $__n -gt $__height ] && __height=$__n
606
607 #
608 # For Xdialog(1) bump height if backtitle is enabled (displayed
609 # in the X11 window with a separator line between the backtitle
610 # and msg text).
611 #
612 if [ "$USE_XDIALOG" -a "$__btitle" ]; then
613 __n=$( echo "$__btitle" | f_number_of_lines )
614 __height=$(( $__height + $__n + 2 ))
615 fi
616
617 setvar "$__var_height" $__height
618 fi
619
620 # Adjust width if desired
621 if [ "$__var_width" ]; then
622 #
623 # Bump width for long titles
624 #
625 __n=$(( ${#__title} + 4 ))
626 [ $__n -gt $__width ] && __width=$__n
627
628 #
629 # If using Xdialog(1), bump width for long backtitles (which
630 # appear within the window).
631 #
632 if [ "$USE_XDIALOG" ]; then
633 __n=$(( ${#__btitle} + 4 ))
634 [ $__n -gt $__width ] && __width=$__n
635 fi
636
637 #
638 # Bump width for long prompts
639 #
640 __n=$( echo "$__prompt" | f_longest_line_length )
641 __n=$(( $__n + 4 )) # add width for border
642 [ $__n -gt $__width ] && __width=$__n
643
644 #
645 # Bump width for long hlines. Xdialog(1) supports `--hline' but
646 # it's currently not used (so don't do anything here if using
647 # Xdialog(1)).
648 #
649 if [ ! "$USE_XDIALOG" ]; then
650 __n=$(( ${#__hline} + 10 ))
651 [ $__n -gt $__width ] && __width=$__n
652 fi
653
654 # Bump width by 16.6% if using Xdialog(1)
655 [ "$USE_XDIALOG" ] && __width=$(( $__width + $__width / 6 ))
656
657 setvar "$__var_width" $__width
658 fi
659
660 # Constrain values to sensible minimums/maximums unless `-n' was passed
661 # Return success if no-constrain, else return status from constrain
662 [ ! "$__constrain" ] ||
663 f_dialog_size_constrain "$__var_height" "$__var_width"
664}
665
666# f_dialog_buttonbox_size [-n] $var_height $var_width \
667# $title $backtitle $prompt [$hline]
668#
669# Not all versions of dialog(1) perform auto-sizing of the width and height of
670# `--msgbox' and `--yesno' boxes sensibly.
671#
672# This function helps solve this issue by taking two sets of sequential
673# arguments. The first set of arguments are the variable names to use when
674# storing the calculated height and width. The second set of arguments are the
675# title, backtitle, prompt, and [optionally] hline. The optimal height and
676# width for the described widget (not exceeding the actual terminal height or
677# width) is stored in $var_height and $var_width (respectively).
678#
679# If the first argument is `-n', the calculated sizes ($var_height and
680# $var_width) are not constrained to minimum/maximum values.
681#
682# Newline character sequences (``\n'') in $prompt are expanded as-is done by
683# dialog(1).
684#
685f_dialog_buttonbox_size()
686{
687 local __constrain=1
688 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
689 local __var_height="$1" __var_width="$2"
690 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6"
691
692 # Return unless at least one size aspect has been requested
693 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
694
695 # Calculate height/width of infobox (adjusted/constrained below)
696 # NOTE: Function name appended to prevent __var_{height,width} values
697 # from becoming local (and thus preventing setvar from working).
698 local __height_bbox_size __width_bbox_size
699 f_dialog_infobox_size -n \
700 "${__var_height:+__height_bbox_size}" \
701 "${__var_width:+__width_bbox_size}" \
702 "$__title" "$__btitle" "$__prompt" "$__hline"
703
704 # Adjust height if desired
705 if [ "$__var_height" ]; then
706 # Add height to accommodate the buttons
707 __height_bbox_size=$(( $__height_bbox_size + 2 ))
708
709 # Adjust for clipping with Xdialog(1) on Linux/GTK2
710 [ "$USE_XDIALOG" ] &&
711 __height_bbox_size=$(( $__height_bbox_size + 3 ))
712
713 setvar "$__var_height" $__height_bbox_size
714 fi
715
716 # No adjustemnts to width, just pass-thru the infobox width
717 if [ "$__var_width" ]; then
718 setvar "$__var_width" $__width_bbox_size
719 fi
720
721 # Constrain values to sensible minimums/maximums unless `-n' was passed
722 # Return success if no-constrain, else return status from constrain
723 [ ! "$__constrain" ] ||
724 f_dialog_size_constrain "$__var_height" "$__var_width"
725}
726
727# f_dialog_inputbox_size [-n] $var_height $var_width \
728# $title $backtitle $prompt $init [$hline]
729#
730# Not all versions of dialog(1) perform auto-sizing of the width and height of
731# `--inputbox' boxes sensibly.
732#
733# This function helps solve this issue by taking two sets of sequential
734# arguments. The first set of arguments are the variable names to use when
735# storing the calculated height and width. The second set of arguments are the
736# title, backtitle, prompt, and [optionally] hline. The optimal height and
737# width for the described widget (not exceeding the actual terminal height or
738# width) is stored in $var_height and $var_width (respectively).
739#
740# If the first argument is `-n', the calculated sizes ($var_height and
741# $var_width) are not constrained to minimum/maximum values.
742#
743# Newline character sequences (``\n'') in $prompt are expanded as-is done by
744# dialog(1).
745#
746f_dialog_inputbox_size()
747{
748 local __constrain=1
749 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
750 local __var_height="$1" __var_width="$2"
751 local __title="$3" __btitle="$4" __prompt="$5" __init="$6" __hline="$7"
752
753 # Return unless at least one size aspect has been requested
754 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
755
756 # Calculate height/width of buttonbox (adjusted/constrained below)
757 # NOTE: Function name appended to prevent __var_{height,width} values
758 # from becoming local (and thus preventing setvar from working).
759 local __height_ibox_size __width_ibox_size
760 f_dialog_buttonbox_size -n \
761 "${__var_height:+__height_ibox_size}" \
762 "${__var_width:+__width_ibox_size}" \
763 "$__title" "$__btitle" "$__prompt" "$__hline"
764
765 # Adjust height if desired
766 if [ "$__var_height" ]; then
767 # Add height for input box (not needed for Xdialog(1))
768 [ ! "$USE_XDIALOG" ] &&
769 __height_ibox_size=$(( $__height_ibox_size + 3 ))
770
771 setvar "$__var_height" $__height_ibox_size
772 fi
773
774 # Adjust width if desired
775 if [ "$__var_width" ]; then
776 # Bump width for initial text (something neither dialog(1) nor
777 # Xdialog(1) do, but worth it!; add 16.6% if using Xdialog(1))
778 local __n=$(( ${#__init} + 7 ))
779 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 ))
780 [ $__n -gt $__width_ibox_size ] && __width_ibox_size=$__n
781
782 setvar "$__var_width" $__width_ibox_size
783 fi
784
785 # Constrain values to sensible minimums/maximums unless `-n' was passed
786 # Return success if no-constrain, else return status from constrain
787 [ ! "$__constrain" ] ||
788 f_dialog_size_constrain "$__var_height" "$__var_width"
789}
790
791# f_xdialog_2inputsbox_size [-n] $var_height $var_width \
792# $title $backtitle $prompt \
793# $label1 $init1 $label2 $init2
794#
795# Xdialog(1) does not perform auto-sizing of the width and height of
796# `--2inputsbox' boxes sensibly.
797#
798# This function helps solve this issue by taking two sets of sequential
799# arguments. The first set of arguments are the variable names to use when
800# storing the calculated height and width. The second set of arguments are the
801# title, backtitle, prompt, label for the first field, initial text for said
802# field, label for the second field, and initial text for said field. The
803# optimal height and width for the described widget (not exceeding the actual
804# terminal height or width) is stored in $var_height and $var_width
805# (respectively).
806#
807# If the first argument is `-n', the calculated sizes ($var_height and
808# $var_width) are not constrained to minimum/maximum values.
809#
810# Newline character sequences (``\n'') in $prompt are expanded as-is done by
811# Xdialog(1).
812#
813f_xdialog_2inputsbox_size()
814{
815 local __constrain=1
816 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
817 local __var_height="$1" __var_width="$2"
818 local __title="$3" __btitle="$4" __prompt="$5"
819 local __label1="$6" __init1="$7" __label2="$8" __init2="$9"
820
821 # Return unless at least one size aspect has been requested
822 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
823
824 # Calculate height/width of inputbox (adjusted/constrained below)
825 # NOTE: Function name appended to prevent __var_{height,width} values
826 # from becoming local (and thus preventing setvar from working).
827 local __height_2ibox_size __width_2ibox_size
828 f_dialog_inputbox_size -n \
829 "${__var_height:+__height_2ibox_size}" \
830 "${__var_width:+__width_2ibox_size}" \
831 "$__title" "$__btitle" "$__prompt" "$__hline" "$__init1"
832
833 # Adjust height if desired
834 if [ "$__var_height" ]; then
835 # Add height for 1st label, 2nd label, and 2nd input box
836 __height_2ibox_size=$(( $__height_2ibox_size + 2 + 2 + 2 ))
837 setvar "$__var_height" $__height_2ibox_size
838 fi
839
840 # Adjust width if desired
841 if [ "$__var_width" ]; then
842 local __n
843
844 # Bump width for first label text (+16.6% since Xdialog(1))
845 __n=$(( ${#__label1} + 7 ))
846 __n=$(( $__n + $__n / 6 ))
847 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n
848
849 # Bump width for second label text (+16.6% since Xdialog(1))
850 __n=$(( ${#__label2} + 7 ))
851 __n=$(( $__n + $__n / 6 ))
852 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n
853
854 # Bump width for 2nd initial text (something neither dialog(1)
855 # nor Xdialog(1) do, but worth it!; +16.6% since Xdialog(1))
856 __n=$(( ${#__init2} + 7 ))
857 __n=$(( $__n + $__n / 6 ))
858 [ $__n -gt $__width_2ibox_size ] && __width_2ibox_size=$__n
859
860 setvar "$__var_width" $__width_2ibox_size
861 fi
862
863 # Constrain values to sensible minimums/maximums unless `-n' was passed
864 # Return success if no-constrain, else return status from constrain
865 [ ! "$__constrain" ] ||
866 f_dialog_size_constrain "$__var_height" "$__var_width"
867}
868
869# f_dialog_menu_size [-n] $var_height $var_width $var_rows \
870# $title $backtitle $prompt $hline \
871# $tag1 $item1 $tag2 $item2 ...
872#
873# Not all versions of dialog(1) perform auto-sizing of the width and height of
874# `--menu' boxes sensibly.
875#
876# This function helps solve this issue by taking three sets of sequential
877# arguments. The first set of arguments are the variable names to use when
878# storing the calculated height, width, and rows. The second set of arguments
879# are the title, backtitle, prompt, and hline. The [optional] third set of
880# arguments are the menu list itself (comprised of tag/item couplets). The
881# optimal height, width, and rows for the described widget (not exceeding the
882# actual terminal height or width) is stored in $var_height, $var_width, and
883# $var_rows (respectively).
884#
885# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
886# and $var_rows) are not constrained to minimum/maximum values.
887#
888f_dialog_menu_size()
889{
890 local __constrain=1
891 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
892 local __var_height="$1" __var_width="$2" __var_rows="$3"
893 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7"
894 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline
895
896 # Return unless at least one size aspect has been requested
897 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
898 return $FAILURE
899
900 # Calculate height/width of infobox (adjusted/constrained below)
901 # NOTE: Function name appended to prevent __var_{height,width} values
902 # from becoming local (and thus preventing setvar from working).
903 local __height_menu_size __width_menu_size
904 f_dialog_infobox_size -n \
905 "${__var_height:+__height_menu_size}" \
906 "${__var_width:+__width_menu_size}" \
907 "$__title" "$__btitle" "$__prompt" "$__hline"
908
909 #
910 # Always process the menu-item arguments to get the longest tag-length,
911 # longest item-length (both used to bump the width), and the number of
912 # rows (used to bump the height).
913 #
914 local __longest_tag=0 __longest_item=0 __rows=0
915 while [ $# -ge 2 ]; do
916 local __tag="$1" __item="$2"
917 shift 2 # tag/item
918 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
919 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
920 __rows=$(( $__rows + 1 ))
921 done
922
923 # Adjust rows early (for up-comning height calculation)
924 if [ "$__var_height" -o "$__var_rows" ]; then
925 # Add a row for visual aid if using Xdialog(1)
926 [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 ))
927 fi
928
929 # Adjust height if desired
930 if [ "$__var_height" ]; then
931 # Add rows to height
932 if [ "$USE_XDIALOG" ]; then
933 __height_menu_size=$((
934 $__height_menu_size + $__rows + 7 ))
935 else
936 __height_menu_size=$((
937 $__height_menu_size + $__rows + 4 ))
938 fi
939 setvar "$__var_height" $__height_menu_size
940 fi
941
942 # Adjust width if desired
943 if [ "$__var_width" ]; then
944 # The sum total between the longest tag-length and the
945 # longest item-length should be used to bump menu width
946 local __n=$(( $__longest_tag + $__longest_item + 10 ))
947 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6%
948 [ $__n -gt $__width_menu_size ] && __width_menu_size=$__n
949
950 setvar "$__var_width" $__width_menu_size
951 fi
952
953 # Store adjusted rows if desired
954 [ "$__var_rows" ] && setvar "$__var_rows" $__rows
955
956 # Constrain height, width, and rows to sensible minimum/maximum values
957 # Return success if no-constrain, else return status from constrain
958 [ ! "$__constrain" ] || f_dialog_menu_constrain \
959 "$__var_height" "$__var_width" "$__var_rows" "$__prompt"
960}
961
962# f_dialog_menu_with_help_size [-n] $var_height $var_width $var_rows \
963# $title $backtitle $prompt $hline \
964# $tag1 $item1 $help1 $tag2 $item2 $help2 ...
965#
966# Not all versions of dialog(1) perform auto-sizing of the width and height of
967# `--menu' boxes sensibly.
968#
969# This function helps solve this issue by taking three sets of sequential
970# arguments. The first set of arguments are the variable names to use when
971# storing the calculated height, width, and rows. The second set of arguments
972# are the title, backtitle, prompt, and hline. The [optional] third set of
973# arguments are the menu list itself (comprised of tag/item/help triplets). The
974# optimal height, width, and rows for the described widget (not exceeding the
975# actual terminal height or width) is stored in $var_height, $var_width, and
976# $var_rows (respectively).
977#
978# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
979# and $var_rows) are not constrained to minimum/maximum values.
980#
981f_dialog_menu_with_help_size()
982{
983 local __constrain=1
984 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
985 local __var_height="$1" __var_width="$2" __var_rows="$3"
986 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7"
987 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline
988
989 # Return unless at least one size aspect has been requested
990 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
991 return $FAILURE
992
993 # Calculate height/width of infobox (adjusted/constrained below)
994 # NOTE: Function name appended to prevent __var_{height,width} values
995 # from becoming local (and thus preventing setvar from working).
996 local __height_menu_with_help_size __width_menu_with_help_size
997 f_dialog_infobox_size -n \
998 "${__var_height:+__height_menu_with_help_size}" \
999 "${__var_width:+__width_menu_with_help_size}" \
1000 "$__title" "$__btitle" "$__prompt" "$__hline"
1001
1002 #
1003 # Always process the menu-item arguments to get the longest tag-length,
1004 # longest item-length, longest help-length (help-length only considered
1005 # if using Xdialog(1), as it places the help string in the widget) --
1006 # all used to bump the width -- and the number of rows (used to bump
1007 # the height).
1008 #
1009 local __longest_tag=0 __longest_item=0 __longest_help=0 __rows=0
1010 while [ $# -ge 3 ]; do
1011 local __tag="$1" __item="$2" __help="$3"
1012 shift 3 # tag/item/help
1013 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
1014 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
1015 [ ${#__help} -gt $__longest_help ] && __longest_help=${#__help}
1016 __rows=$(( $__rows + 1 ))
1017 done
1018
1019 # Adjust rows early (for up-coming height calculation)
1020 if [ "$__var_height" -o "$__var_rows" ]; then
1021 # Add a row for visual aid if using Xdialog(1)
1022 [ "$USE_XDIALOG" ] && __rows=$(( $__rows + 1 ))
1023 fi
1024
1025 # Adjust height if desired
1026 if [ "$__var_height" ]; then
1027 # Add rows to height
1028 if [ "$USE_XDIALOG" ]; then
1029 __height_menu_with_help_size=$((
1030 $__height_menu_with_help_size + $__rows + 8 ))
1031 else
1032 __height_menu_with_help_size=$((
1033 $__height_menu_with_help_size + $__rows + 4 ))
1034 fi
1035 setvar "$__var_height" $__height_menu_with_help_size
1036 fi
1037
1038 # Adjust width if desired
1039 if [ "$__var_width" ]; then
1040 # The sum total between the longest tag-length and the
1041 # longest item-length should be used to bump menu width
1042 local __n=$(( $__longest_tag + $__longest_item + 10 ))
1043 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6%
1044 [ $__n -gt $__width_menu_with_help_size ] &&
1045 __width_menu_with_help_size=$__n
1046
1047 # Update width for help text if using Xdialog(1)
1048 if [ "$USE_XDIALOG" ]; then
1049 __n=$(( $__longest_help + 10 ))
1050 __n=$(( $__n + $__n / 6 )) # plus 16.6%
1051 [ $__n -gt $__width_menu_with_help_size ] &&
1052 __width_menu_with_help_size=$__n
1053 fi
1054
1055 setvar "$__var_width" $__width_menu_with_help_size
1056 fi
1057
1058 # Store adjusted rows if desired
1059 [ "$__var_rows" ] && setvar "$__var_rows" $__rows
1060
1061 # Constrain height, width, and rows to sensible minimum/maximum values
1062 # Return success if no-constrain, else return status from constrain
1063 [ ! "$__constrain" ] || f_dialog_menu_constrain \
1064 "$__var_height" "$__var_width" "$__var_rows" "$__prompt"
1065}
1066
1067# f_dialog_radiolist_size [-n] $var_height $var_width $var_rows \
1068# $title $backtitle $prompt $hline \
1069# $tag1 $item1 $status1 $tag2 $item2 $status2 ...
1070#
1071# Not all versions of dialog(1) perform auto-sizing of the width and height of
1072# `--radiolist' boxes sensibly.
1073#
1074# This function helps solve this issue by taking three sets of sequential
1075# arguments. The first set of arguments are the variable names to use when
1076# storing the calculated height, width, and rows. The second set of arguments
1077# are the title, backtitle, prompt, and hline. The [optional] third set of
1078# arguments are the radio list itself (comprised of tag/item/status triplets).
1079# The optimal height, width, and rows for the described widget (not exceeding
1080# the actual terminal height or width) is stored in $var_height, $var_width,
1081# and $var_rows (respectively).
1082#
1083# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
1084# and $var_rows) are not constrained to minimum/maximum values.
1085#
1086f_dialog_radiolist_size()
1087{
1088 local __constrain=1
1089 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
1090 local __var_height="$1" __var_width="$2" __var_rows="$3"
1091 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7"
1092 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline
1093
1094 # Return unless at least one size aspect has been requested
1095 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
1096 return $FAILURE
1097
1098 # Calculate height/width of infobox (adjusted/constrained below)
1099 # NOTE: Function name appended to prevent __var_{height,width} values
1100 # from becoming local (and thus preventing setvar from working).
1101 local __height_rlist_size __width_rlist_size
1102 f_dialog_infobox_size -n \
1103 "${__var_height:+__height_rlist_size}" \
1104 "${__var_width:+__width_rlist_size}" \
1105 "$__title" "$__btitle" "$__prompt" "$__hline"
1106
1107 #
1108 # Always process the menu-item arguments to get the longest tag-length,
1109 # longest item-length (both used to bump the width), and the number of
1110 # rows (used to bump the height).
1111 #
1112 local __longest_tag=0 __longest_item=0 __rows_rlist_size=0
1113 while [ $# -ge 3 ]; do
1114 local __tag="$1" __item="$2"
1115 shift 3 # tag/item/status
1116 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
1117 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
1118 __rows_rlist_size=$(( $__rows_rlist_size + 1 ))
1119 done
1120
1121 # Adjust rows early (for up-coming height calculation)
1122 if [ "$__var_height" -o "$__var_rows" ]; then
1123 # Add a row for visual aid if using Xdialog(1)
1124 [ "$USE_XDIALOG" ] &&
1125 __rows_rlist_size=$(( $__rows_rlist_size + 1 ))
1126 fi
1127
1128 # Adjust height if desired
1129 if [ "$__var_height" ]; then
1130 # Add rows to height
1131 if [ "$USE_XDIALOG" ]; then
1132 __height_rlist_size=$((
1133 $__height_rlist_size + $__rows_rlist_size + 7
1134 ))
1135 else
1136 __height_rlist_size=$((
1137 $__height_rlist_size + $__rows_rlist_size + 4
1138 ))
1139 fi
1140 setvar "$__var_height" $__height_rlist_size
1141 fi
1142
1143 # Adjust width if desired
1144 if [ "$__var_width" ]; then
1145 # Sum total between longest tag-length, longest item-length,
1146 # and radio-button width should be used to bump menu width
1147 local __n=$(( $__longest_tag + $__longest_item + 13 ))
1148 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6%
1149 [ $__n -gt $__width_rlist_size ] && __width_rlist_size=$__n
1150
1151 setvar "$__var_width" $__width_rlist_size
1152 fi
1153
1154 # Store adjusted rows if desired
1155 [ "$__var_rows" ] && setvar "$__var_rows" $__rows_rlist_size
1156
1157 # Constrain height, width, and rows to sensible minimum/maximum values
1158 # Return success if no-constrain, else return status from constrain
1159 [ ! "$__constrain" ] || f_dialog_menu_constrain \
1160 "$__var_height" "$__var_width" "$__var_rows" "$__prompt"
1161}
1162
1163# f_dialog_checklist_size [-n] $var_height $var_width $var_rows \
1164# $title $backtitle $prompt $hline \
1165# $tag1 $item1 $status1 $tag2 $item2 $status2 ...
1166#
1167# Not all versions of dialog(1) perform auto-sizing of the width and height of
1168# `--checklist' boxes sensibly.
1169#
1170# This function helps solve this issue by taking three sets of sequential
1171# arguments. The first set of arguments are the variable names to use when
1172# storing the calculated height, width, and rows. The second set of arguments
1173# are the title, backtitle, prompt, and hline. The [optional] third set of
1174# arguments are the check list itself (comprised of tag/item/status triplets).
1175# The optimal height, width, and rows for the described widget (not exceeding
1176# the actual terminal height or width) is stored in $var_height, $var_width,
1177# and $var_rows (respectively).
1178#
1179# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
1180# and $var_rows) are not constrained to minimum/maximum values.
1181#
1182f_dialog_checklist_size()
1183{
1184 f_dialog_radiolist_size "$@"
1185}
1186
1187# f_dialog_radiolist_with_help_size [-n] $var_height $var_width $var_rows \
1188# $title $backtitle $prompt $hline \
1189# $tag1 $item1 $status1 $help1 \
1190# $tag2 $item2 $status2 $help2 ...
1191#
1192# Not all versions of dialog(1) perform auto-sizing of the width and height of
1193# `--radiolist' boxes sensibly.
1194#
1195# This function helps solve this issue by taking three sets of sequential
1196# arguments. The first set of arguments are the variable names to use when
1197# storing the calculated height, width, and rows. The second set of arguments
1198# are the title, backtitle, prompt, and hline. The [optional] third set of
1199# arguments are the radio list itself (comprised of tag/item/status/help
1200# quadruplets). The optimal height, width, and rows for the described widget
1201# (not exceeding the actual terminal height or width) is stored in $var_height,
1202# $var_width, and $var_rows (respectively).
1203#
1204# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
1205# and $var_rows) are not constrained to minimum/maximum values.
1206#
1207f_dialog_radiolist_with_help_size()
1208{
1209 local __constrain=1
1210 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
1211 local __var_height="$1" __var_width="$2" __var_rows="$3"
1212 local __title="$4" __btitle="$5" __prompt="$6" __hline="$7"
1213 shift 7 # var_height/var_width/var_rows/title/btitle/prompt/hline
1214
1215 # Return unless at least one size aspect has been requested
1216 [ "$__var_height" -o "$__var_width" -o "$__var_rows" ] ||
1217 return $FAILURE
1218
1219 # Calculate height/width of infobox (adjusted/constrained below)
1220 # NOTE: Function name appended to prevent __var_{height,width} values
1221 # from becoming local (and thus preventing setvar from working).
1222 local __height_rlist_with_help_size __width_rlist_with_help_size
1223 f_dialog_infobox_size -n \
1224 "${__var_height:+__height_rlist_with_help_size}" \
1225 "${__var_width:+__width_rlist_with_help_size}" \
1226 "$__title" "$__btitle" "$__prompt" "$__hline"
1227
1228 #
1229 # Always process the menu-item arguments to get the longest tag-length,
1230 # longest item-length, longest help-length (help-length only considered
1231 # if using Xdialog(1), as it places the help string in the widget) --
1232 # all used to bump the width -- and the number of rows (used to bump
1233 # the height).
1234 #
1235 local __longest_tag=0 __longest_item=0 __longest_help=0
1236 local __rows_rlist_with_help_size=0
1237 while [ $# -ge 4 ]; do
1238 local __tag="$1" __item="$2" __status="$3" __help="$4"
1239 shift 4 # tag/item/status/help
1240 [ ${#__tag} -gt $__longest_tag ] && __longest_tag=${#__tag}
1241 [ ${#__item} -gt $__longest_item ] && __longest_item=${#__item}
1242 [ ${#__help} -gt $__longest_help ] && __longest_help=${#__help}
1243 __rows_rlist_with_help_size=$((
1244 $__rows_rlist_with_help_size + 1
1245 ))
1246 done
1247
1248 # Adjust rows early (for up-coming height calculation)
1249 if [ "$__var_height" -o "$__var_rows" ]; then
1250 # Add a row for visual aid if using Xdialog(1)
1251 [ "$USE_XDIALOG" ] &&
1252 __rows_rlist_with_help_size=$((
1253 $__rows_rlist_with_help_size + 1
1254 ))
1255 fi
1256
1257 # Adjust height if desired
1258 if [ "$__var_height" ]; then
1259 # Add rows to height
1260 if [ "$USE_XDIALOG" ]; then
1261 __height_rlist_with_help_size=$((
1262 $__height_rlist_with_help_size +
1263 $__rows_rlist_with_help_size + 7
1264 ))
1265 else
1266 __height_rlist_with_help_size=$((
1267 $__height_rlist_with_help_size +
1268 $__rows_rlist_with_help_size + 4
1269 ))
1270 fi
1271 setvar "$__var_height" $__height
1272 fi
1273
1274 # Adjust width if desired
1275 if [ "$__var_width" ]; then
1276 # Sum total between longest tag-length, longest item-length,
1277 # and radio-button width should be used to bump menu width
1278 local __n=$(( $__longest_tag + $__longest_item + 13 ))
1279 [ "$USE_XDIALOG" ] && __n=$(( $__n + $__n / 6 )) # plus 16.6%
1280 [ $__n -gt $__width_rlist_with_help_size ] &&
1281 __width_rlist_with_help_size=$__n
1282
1283 # Update width for help text if using Xdialog(1)
1284 if [ "$USE_XDIALOG" ]; then
1285 __n=$(( $__longest_help + 10 ))
1286 __n=$(( $__n + $__n / 6 )) # plus 16.6%
1287 [ $__n -gt $__width_rlist_with_help_size ] &&
1288 __width_rlist_with_help_size=$__n
1289 fi
1290
1291 setvar "$__var_width" $__width_rlist_with_help_size
1292 fi
1293
1294 # Store adjusted rows if desired
1295 [ "$__var_rows" ] && setvar "$__var_rows" $__rows_rlist_with_help_size
1296
1297 # Constrain height, width, and rows to sensible minimum/maximum values
1298 # Return success if no-constrain, else return status from constrain
1299 [ ! "$__constrain" ] || f_dialog_menu_constrain \
1300 "$__var_height" "$__var_width" "$__var_rows" "$__prompt"
1301}
1302
1303# f_dialog_checklist_with_help_size [-n] $var_height $var_width $var_rows \
1304# $title $backtitle $prompt $hline \
1305# $tag1 $item1 $status1 $help1 \
1306# $tag2 $item2 $status2 $help2 ...
1307#
1308# Not all versions of dialog(1) perform auto-sizing of the width and height of
1309# `--checklist' boxes sensibly.
1310#
1311# This function helps solve this issue by taking three sets of sequential
1312# arguments. The first set of arguments are the variable names to use when
1313# storing the calculated height, width, and rows. The second set of arguments
1314# are the title, backtitle, prompt, and hline. The [optional] third set of
1315# arguments are the check list itself (comprised of tag/item/status/help
1316# quadruplets). The optimal height, width, and rows for the described widget
1317# (not exceeding the actual terminal height or width) is stored in $var_height,
1318# $var_width, and $var_rows (respectively).
1319#
1320# If the first argument is `-n', the calculated sizes ($var_height, $var_width,
1321# and $var_rows) are not constrained to minimum/maximum values.
1322#
1323f_dialog_checklist_with_help_size()
1324{
1325 f_dialog_radiolist_with_help_size "$@"
1326}
1327
1328# f_dialog_calendar_size [-n] $var_height $var_width \
1329# $title $backtitle $prompt [$hline]
1330#
1331# Not all versions of dialog(1) perform auto-sizing of the width and height of
1332# `--calendar' boxes sensibly.
1333#
1334# This function helps solve this issue by taking two sets of sequential
1335# arguments. The first set of arguments are the variable names to use when
1336# storing the calculated height and width. The second set of arguments are the
1337# title, backtitle, prompt, and [optionally] hline. The optimal height and
1338# width for the described widget (not exceeding the actual terminal height or
1339# width) is stored in $var_height and $var_width (respectively).
1340#
1341# If the first argument is `-n', the calculated sizes ($var_height and
1342# $var_width) are not constrained to minimum/maximum values.
1343#
1344# Newline character sequences (``\n'') in $prompt are expanded as-is done by
1345# dialog(1).
1346#
1347f_dialog_calendar_size()
1348{
1349 local __constrain=1
1350 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
1351 local __var_height="$1" __var_width="$2"
1352 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6"
1353
1354 # Return unless at least one size aspect has been requested
1355 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
1356
1357 #
1358 # Obtain/Adjust minimum and maximum thresholds
1359 # NOTE: Function name appended to prevent __var_{height,width} values
1360 # from becoming local (and thus preventing setvar from working).
1361 #
1362 local __max_height_cal_size __max_width_cal_size
1363 f_dialog_max_size __max_height_cal_size __max_width_cal_size
1364 __max_width_cal_size=$(( $__max_width_cal_size - 2 ))
1365 # the calendar box will refuse to display if too wide
1366 local __min_width
1367 if [ "$USE_XDIALOG" ]; then
1368 __min_width=55
1369 else
1370 __min_width=40
1371 __max_height_cal_size=$((
1372 $__max_height_cal_size - $DIALOG_CALENDAR_HEIGHT ))
1373 # When using dialog(1), we can't predict whether the user has
1374 # disabled shadow's in their `$HOME/.dialogrc' file, so we'll
1375 # subtract one for the potential shadow around the widget
1376 __max_height_cal_size=$(( $__max_height_cal_size - 1 ))
1377 fi
1378
1379 # Calculate height if desired
1380 if [ "$__var_height" ]; then
1381 local __height
1382 __height=$( echo "$__prompt" | f_number_of_lines )
1383
1384 if [ "$USE_XDIALOG" ]; then
1385 # Add height to accommodate for embedded calendar widget
1386 __height=$(( $__height + $DIALOG_CALENDAR_HEIGHT - 1 ))
1387
1388 # Also, bump height if backtitle is enabled
1389 if [ "$__btitle" ]; then
1390 local __n
1391 __n=$( echo "$__btitle" | f_number_of_lines )
1392 __height=$(( $__height + $__n + 2 ))
1393 fi
1394 else
1395 [ "$__prompt" ] && __height=$(( $__height + 1 ))
1396 fi
1397
1398 # Enforce maximum height, unless `-n' was passed
1399 [ "$__constrain" -a $__height -gt $__max_height_cal_size ] &&
1400 __height=$__max_height_cal_size
1401
1402 setvar "$__var_height" $__height
1403 fi
1404
1405 # Calculate width if desired
1406 if [ "$__var_width" ]; then
1407 # NOTE: Function name appended to prevent __var_{height,width}
1408 # values from becoming local (and thus preventing setvar
1409 # from working).
1410 local __width_cal_size
1411 f_dialog_infobox_size -n "" __width_cal_size \
1412 "$__title" "$__btitle" "$__prompt" "$__hline"
1413
1414 # Enforce minimum/maximum width, unless `-n' was passed
1415 if [ "$__constrain" ]; then
1416 if [ $__width_cal_size -lt $__min_width ]; then
1417 __width_cal_size=$__min_width
1418 elif [ $__width_cal_size -gt $__max_width_cal_size ]
1419 then
1420 __width_cal_size=$__max_width_size
1421 fi
1422 fi
1423
1424 setvar "$__var_width" $__width_cal_size
1425 fi
1426
1427 return $SUCCESS
1428}
1429
1430# f_dialog_timebox_size [-n] $var_height $var_width \
1431# $title $backtitle $prompt [$hline]
1432#
1433# Not all versions of dialog(1) perform auto-sizing of the width and height of
1434# `--timebox' boxes sensibly.
1435#
1436# This function helps solve this issue by taking two sets of sequential
1437# arguments. The first set of arguments are the variable names to use when
1438# storing the calculated height and width. The second set of arguments are the
1439# title, backtitle, prompt, and [optionally] hline. The optional height and
1440# width for the described widget (not exceeding the actual terminal height or
1441# width) is stored in $var_height and $var_width (respectively).
1442#
1443# If the first argument is `-n', the calculated sizes ($var_height and
1444# $var_width) are not constrained to minimum/maximum values.
1445#
1446# Newline character sequences (``\n'') in $prompt are expanded as-is done by
1447# dialog(1).
1448#
1449f_dialog_timebox_size()
1450{
1451 local __constrain=1
1452 [ "$1" = "-n" ] && __constrain= && shift 1 # -n
1453 local __var_height="$1" __var_width="$2"
1454 local __title="$3" __btitle="$4" __prompt="$5" __hline="$6"
1455
1456 # Return unless at least one size aspect has been requested
1457 [ "$__var_height" -o "$__var_width" ] || return $FAILURE
1458
1459 #
1460 # Obtain/Adjust minimum and maximum thresholds
1461 # NOTE: Function name appended to prevent __var_{height,width} values
1462 # from becoming local (and thus preventing setvar from working).
1463 #
1464 local __max_height_tbox_size __max_width_tbox_size
1465 f_dialog_max_size __max_height_tbox_size __max_width_tbox_size
1466 __max_width_tbox_size=$(( $__max_width_tbox_size - 2 ))
1467 # the timebox widget refuses to display if too wide
1468 local __min_width
1469 if [ "$USE_XDIALOG" ]; then
1470 __min_width=40
1471 else
1472 __min_width=20
1473 __max_height_tbox_size=$(( \
1474 $__max_height_tbox_size - $DIALOG_TIMEBOX_HEIGHT ))
1475 # When using dialog(1), we can't predict whether the user has
1476 # disabled shadow's in their `$HOME/.dialogrc' file, so we'll
1477 # subtract one for the potential shadow around the widget
1478 __max_height_tbox_size=$(( $__max_height_tbox_size - 1 ))
1479 fi
1480
1481 # Calculate height if desired
1482 if [ "$__var_height" -a "$USE_XDIALOG" ]; then
1483 # When using Xdialog(1), the height seems to have
1484 # no effect. All values provide the same results.
1485 setvar "$__var_height" 0 # autosize
1486 elif [ "$__var_height" ]; then
1487 local __height
1488 __height=$( echo "$__prompt" | f_number_of_lines )
1489 __height=$(( $__height ${__prompt:++1} + 1 ))
1490
1491 # Enforce maximum height, unless `-n' was passed
1492 [ "$__constrain" -a $__height -gt $__max_height_tbox_size ] &&
1493 __height=$__max_height_tbox_size
1494
1495 setvar "$__var_height" $__height
1496 fi
1497
1498 # Calculate width if desired
1499 if [ "$__var_width" ]; then
1500 # NOTE: Function name appended to prevent __var_{height,width}
1501 # values from becoming local (and thus preventing setvar
1502 # from working).
1503 local __width_tbox_size
1504 f_dialog_infobox_size -n "" __width_tbox_size \
1505 "$__title" "$__btitle" "$__prompt" "$__hline"
1506
1507 # Enforce the minimum width for displaying the timebox
1508 if [ "$__constrain" ]; then
1509 if [ $__width_tbox_size -lt $__min_width ]; then
1510 __width_tbox_size=$__min_width
1511 elif [ $__width_tbox_size -ge $__max_width_tbox_size ]
1512 then
1513 __width_tbox_size=$__max_width_tbox_size
1514 fi
1515 fi
1516
1517 setvar "$__var_width" $__width_tbox_size
1518 fi
1519
1520 return $SUCCESS
1521}
1522
1523############################################################ CLEAR FUNCTIONS
1524
1525# f_dialog_clear
1526#
1527# Clears any/all previous dialog(1) displays.
1528#
1529f_dialog_clear()
1530{
1531 $DIALOG --clear
1532}
1533
1534############################################################ INFO FUNCTIONS
1535
1536# f_dialog_info $info_text ...
1537#
1538# Throw up a dialog(1) infobox. The infobox remains until another dialog is
1539# displayed or `dialog --clear' (or f_dialog_clear) is called.
1540#
1541f_dialog_info()
1542{
1543 local info_text="$*" height width
1544 f_dialog_infobox_size height width \
1545 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$info_text"
1546 $DIALOG \
1547 --title "$DIALOG_TITLE" \
1548 --backtitle "$DIALOG_BACKTITLE" \
1549 ${USE_XDIALOG:+--ignore-eof} \
1550 ${USE_XDIALOG:+--no-buttons} \
1551 --infobox "$info_text" $height $width
1552}
1553
1554# f_xdialog_info $info_text ...
1555#
1556# Throw up an Xdialog(1) infobox and do not dismiss it until stdin produces
1557# EOF. This implies that you must execute this either as an rvalue to a pipe,
1558# lvalue to indirection or in a sub-shell that provides data on stdin.
1559#
1560# To open an Xdialog(1) infobox that does not disappear until expeclitly dis-
1561# missed, use the following:
1562#
1563# f_xdialog_info "$info_text" < /dev/tty &
1564# pid=$!
1565# # Perform some lengthy actions
1566# kill $pid
1567#
1568# NB: Check $USE_XDIALOG if you need to support both dialog(1) and Xdialog(1).
1569#
1570f_xdialog_info()
1571{
1572 local info_text="$*" height width
1573 f_dialog_infobox_size height width \
1574 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$info_text"
1575 exec $DIALOG \
1576 --title "$DIALOG_TITLE" \
1577 --backtitle "$DIALOG_BACKTITLE" \
1578 --no-close --no-buttons \
1579 --infobox "$info_text" $height $width \
1580 -1 # timeout of -1 means abort when EOF on stdin
1581}
1582
1583############################################################ PAUSE FUNCTIONS
1584
1585# f_dialog_pause $msg_text $duration [$hline]
1586#
1587# Display a message in a widget with a progress bar that runs backward for
1588# $duration seconds.
1589#
1590f_dialog_pause()
1591{
1592 local pause_text="$1" duration="$2" hline="$3" height width
1593 f_isinteger "$duration" || return $FAILURE
1594 f_dialog_buttonbox_size height width \
1595 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$pause_text" "$hline"
1596 if [ "$USE_XDIALOG" ]; then
1597 $DIALOG \
1598 --title "$DIALOG_TITLE" \
1599 --backtitle "$DIALOG_BACKTITLE" \
1600 --ok-label "$msg_skip" \
1601 --cancel-label "$msg_cancel" \
1602 ${noCancel:+--no-cancel} \
1603 --timeout "$duration" \
1604 --yesno "$pause_text" \
1605 $height $width
1606 else
1607 [ $duration -gt 0 ] && duration=$(( $duration - 1 ))
1608 height=$(( $height + 3 )) # Add height for progress bar
1609 $DIALOG \
1610 --title "$DIALOG_TITLE" \
1611 --backtitle "$DIALOG_BACKTITLE" \
1612 --hline "$hline" \
1613 --ok-label "$msg_skip" \
1614 --cancel-label "$msg_cancel" \
1615 ${noCancel:+--no-cancel} \
1616 --pause "$pause_text" \
1617 $height $width "$duration"
1618 fi
1619}
1620
1621# f_dialog_pause_no_cancel $msg_text $duration [$hline]
1622#
1623# Display a message in a widget with a progress bar that runs backward for
1624# $duration seconds. No cancel button is provided. Always returns success.
1625#
1626f_dialog_pause_no_cancel()
1627{
1628 noCancel=1 f_dialog_pause "$@"
1629 return $SUCCESS
1630}
1631
1632############################################################ MSGBOX FUNCTIONS
1633
1634# f_dialog_msgbox $msg_text [$hline]
1635#
1636# Throw up a dialog(1) msgbox. The msgbox remains until the user presses ENTER
1637# or ESC, acknowledging the modal dialog.
1638#
1639# If the user presses ENTER, the exit status is zero (success), otherwise if
1640# the user presses ESC the exit status is 255.
1641#
1642f_dialog_msgbox()
1643{
1644 local msg_text="$1" hline="$2" height width
1645 f_dialog_buttonbox_size height width \
1646 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline"
1647 $DIALOG \
1648 --title "$DIALOG_TITLE" \
1649 --backtitle "$DIALOG_BACKTITLE" \
1650 --hline "$hline" \
1651 --ok-label "$msg_ok" \
1652 --msgbox "$msg_text" $height $width
1653}
1654
1655############################################################ TEXTBOX FUNCTIONS
1656
1657# f_dialog_textbox $file
1658#
1659# Display the contents of $file (or an error if $file does not exist, etc.) in
1660# a dialog(1) textbox (which has a scrollable region for the text). The textbox
1661# remains until the user presses ENTER or ESC, acknowledging the modal dialog.
1662#
1663# If the user presses ENTER, the exit status is zero (success), otherwise if
1664# the user presses ESC the exit status is 255.
1665#
1666f_dialog_textbox()
1667{
1668 local file="$1"
1669 local contents height width retval
1670
1671 contents=$( cat "$file" 2>&1 )
1672 retval=$?
1673
1674 f_dialog_buttonbox_size height width \
1675 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$contents"
1676
1677 if [ $retval -eq $SUCCESS ]; then
1678 $DIALOG \
1679 --title "$DIALOG_TITLE" \
1680 --backtitle "$DIALOG_BACKTITLE" \
1681 --exit-label "$msg_ok" \
1682 --no-cancel \
1683 --textbox "$file" $height $width
1684 else
1685 $DIALOG \
1686 --title "$DIALOG_TITLE" \
1687 --backtitle "$DIALOG_BACKTITLE" \
1688 --ok-label "$msg_ok" \
1689 --msgbox "$contents" $height $width
1690 fi
1691}
1692
1693############################################################ YESNO FUNCTIONS
1694
1695# f_dialog_yesno $msg_text [$hline]
1696#
1697# Display a dialog(1) Yes/No prompt to allow the user to make some decision.
1698# The yesno prompt remains until the user presses ENTER or ESC, acknowledging
1699# the modal dialog.
1700#
1701# If the user chooses YES the exit status is zero, or chooses NO the exit
1702# status is one, or presses ESC the exit status is 255.
1703#
1704f_dialog_yesno()
1705{
1706 local msg_text="$1" height width
1707 local hline="${2-$hline_arrows_tab_enter}"
1708
1709 f_interactive || return 0 # If non-interactive, return YES all the time
1710
1711 f_dialog_buttonbox_size height width \
1712 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline"
1713
1714 if [ "$USE_XDIALOG" ]; then
1715 $DIALOG \
1716 --title "$DIALOG_TITLE" \
1717 --backtitle "$DIALOG_BACKTITLE" \
1718 --hline "$hline" \
1719 --ok-label "$msg_yes" \
1720 --cancel-label "$msg_no" \
1721 --yesno "$msg_text" $height $width
1722 else
1723 $DIALOG \
1724 --title "$DIALOG_TITLE" \
1725 --backtitle "$DIALOG_BACKTITLE" \
1726 --hline "$hline" \
1727 --yes-label "$msg_yes" \
1728 --no-label "$msg_no" \
1729 --yesno "$msg_text" $height $width
1730 fi
1731}
1732
1733# f_dialog_noyes $msg_text [$hline]
1734#
1735# Display a dialog(1) No/Yes prompt to allow the user to make some decision.
1736# The noyes prompt remains until the user presses ENTER or ESC, acknowledging
1737# the modal dialog.
1738#
1739# If the user chooses YES the exit status is zero, or chooses NO the exit
1740# status is one, or presses ESC the exit status is 255.
1741#
1742# NOTE: This is just like the f_dialog_yesno function except "No" is default.
1743#
1744f_dialog_noyes()
1745{
1746 local msg_text="$1" height width
1747 local hline="${2-$hline_arrows_tab_enter}"
1748
1749 f_interactive || return 1 # If non-interactive, return NO all the time
1750
1751 f_dialog_buttonbox_size height width \
1752 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$msg_text" "$hline"
1753
1754 if [ "$USE_XDIALOG" ]; then
1755 $DIALOG \
1756 --title "$DIALOG_TITLE" \
1757 --backtitle "$DIALOG_BACKTITLE" \
1758 --hline "$hline" \
1759 --default-no \
1760 --ok-label "$msg_yes" \
1761 --cancel-label "$msg_no" \
1762 --yesno "$msg_text" $height $width
1763 else
1764 $DIALOG \
1765 --title "$DIALOG_TITLE" \
1766 --backtitle "$DIALOG_BACKTITLE" \
1767 --hline "$hline" \
1768 --defaultno \
1769 --yes-label "$msg_yes" \
1770 --no-label "$msg_no" \
1771 --yesno "$msg_text" $height $width
1772 fi
1773}
1774
1775############################################################ INPUT FUNCTIONS
1776
1777# f_dialog_inputstr_store [-s] $text
1778#
1779# Store some text from a dialog(1) inputbox to be retrieved later by
1780# f_dialog_inputstr_fetch(). If the first argument is `-s', the text is
1781# sanitized before being stored.
1782#
1783f_dialog_inputstr_store()
1784{
1785 local sanitize=
1786 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s
1787 local text="$1"
1788
1789 # Sanitize the line before storing it if desired
1790 [ "$sanitize" ] && f_dialog_line_sanitize text
1791
1792 setvar DIALOG_INPUTBOX_$$ "$text"
1793}
1794
1795# f_dialog_inputstr_fetch [$var_to_set]
1796#
1797# Obtain the inputstr entered by the user from the most recently displayed
1798# dialog(1) inputbox (previously stored with f_dialog_inputstr_store() above).
1799# If $var_to_set is NULL or missing, output is printed to stdout (which is less
1800# recommended due to performance degradation; in a loop for example).
1801#
1802f_dialog_inputstr_fetch()
1803{
1804 local __var_to_set="$1" __cp
1805
1806 debug= f_getvar DIALOG_INPUTBOX_$$ "${__var_to_set:-__cp}" # get data
1807 setvar DIALOG_INPUTBOX_$$ "" # scrub memory in case data was sensitive
1808
1809 # Return the line on standard-out if desired
1810 [ "$__var_to_set" ] || echo "$__cp"
1811
1812 return $SUCCESS
1813}
1814
1815# f_dialog_input $var_to_set $prompt [$init [$hline]]
1816#
1817# Prompt the user with a dialog(1) inputbox to enter some value. The inputbox
1818# remains until the the user presses ENTER or ESC, or otherwise ends the
1818# remains until the user presses ENTER or ESC, or otherwise ends the
1819# editing session (by selecting `Cancel' for example).
1820#
1821# If the user presses ENTER, the exit status is zero (success), otherwise if
1822# the user presses ESC the exit status is 255, or if the user chose Cancel, the
1823# exit status is instead 1.
1824#
1825# NOTE: The hline should correspond to the type of data you want from the user.
1826# NOTE: Should not be used to edit multiline values.
1827#
1828f_dialog_input()
1829{
1830 local __var_to_set="$1" __prompt="$2" __init="$3" __hline="$4"
1831
1832 # NOTE: Function name appended to prevent __var_{height,width} values
1833 # from becoming local (and thus preventing setvar from working).
1834 local __height_input __width_input
1835 f_dialog_inputbox_size __height_input __width_input \
1836 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" \
1837 "$__prompt" "$__init" "$__hline"
1838
1839 local __opterm="--"
1840 [ "$USE_XDIALOG" ] && __opterm=
1841
1842 local __dialog_input
1843 __dialog_input=$(
1844 $DIALOG \
1845 --title "$DIALOG_TITLE" \
1846 --backtitle "$DIALOG_BACKTITLE" \
1847 --hline "$__hline" \
1848 --ok-label "$msg_ok" \
1849 --cancel-label "$msg_cancel" \
1850 --inputbox "$__prompt" \
1851 $__height_input $__width_input \
1852 $__opterm "$__init" \
1853 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
1854 )
1855 local __retval=$?
1856
1857 # Remove warnings and leading/trailing whitespace from user input
1858 f_dialog_line_sanitize __dialog_input
1859
1860 setvar "$__var_to_set" "$__dialog_input"
1861 return $__retval
1862}
1863
1864############################################################ MENU FUNCTIONS
1865
1866# f_dialog_menutag_store [-s] $text
1867#
1868# Store some text from a dialog(1) menu to be retrieved later by
1869# f_dialog_menutag_fetch(). If the first argument is `-s', the text is
1870# sanitized before being stored.
1871#
1872f_dialog_menutag_store()
1873{
1874 local sanitize=
1875 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s
1876 local text="$1"
1877
1878 # Sanitize the menutag before storing it if desired
1879 [ "$sanitize" ] && f_dialog_data_sanitize text
1880
1881 setvar DIALOG_MENU_$$ "$text"
1882}
1883
1884# f_dialog_menutag_fetch [$var_to_set]
1885#
1886# Obtain the menutag chosen by the user from the most recently displayed
1887# dialog(1) menu (previously stored with f_dialog_menutag_store() above). If
1888# $var_to_set is NULL or missing, output is printed to stdout (which is less
1889# recommended due to performance degradation; in a loop for example).
1890#
1891f_dialog_menutag_fetch()
1892{
1893 local __var_to_set="$1" __cp
1894
1895 debug= f_getvar DIALOG_MENU_$$ "${__var_to_set:-__cp}" # get the data
1896 setvar DIALOG_MENU_$$ "" # scrub memory in case data was sensitive
1897
1898 # Return the data on standard-out if desired
1899 [ "$__var_to_set" ] || echo "$__cp"
1900
1901 return $SUCCESS
1902}
1903
1904# f_dialog_menuitem_store [-s] $text
1905#
1906# Store the item from a dialog(1) menu (see f_dialog_menutag2item()) to be
1907# retrieved later by f_dialog_menuitem_fetch(). If the first argument is `-s',
1908# the text is sanitized before being stored.
1909#
1910f_dialog_menuitem_store()
1911{
1912 local sanitize=
1913 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s
1914 local text="$1"
1915
1916 # Sanitize the menuitem before storing it if desired
1917 [ "$sanitize" ] && f_dialog_data_sanitize text
1918
1919 setvar DIALOG_MENUITEM_$$ "$text"
1920}
1921
1922# f_dialog_menuitem_fetch [$var_to_set]
1923#
1924# Obtain the menuitem chosen by the user from the most recently displayed
1925# dialog(1) menu (previously stored with f_dialog_menuitem_store() above). If
1926# $var_to_set is NULL or missing, output is printed to stdout (which is less
1927# recommended due to performance degradation; in a loop for example).
1928#
1929f_dialog_menuitem_fetch()
1930{
1931 local __var_to_set="$1" __cp
1932
1933 debug= f_getvar DIALOG_MENUITEM_$$ "${__var_to_set:-__cp}" # get data
1934 setvar DIALOG_MENUITEM_$$ "" # scrub memory in case data was sensitive
1935
1936 # Return the data on standard-out if desired
1937 [ "$__var_to_set" ] || echo "$__cp"
1938
1939 return $SUCCESS
1940}
1941
1942# f_dialog_default_store [-s] $text
1943#
1944# Store some text to be used later as the --default-item argument to dialog(1)
1945# (or Xdialog(1)) for --menu, --checklist, and --radiolist widgets. Retrieve
1946# the text later with f_dialog_menutag_fetch(). If the first argument is `-s',
1947# the text is sanitized before being stored.
1948#
1949f_dialog_default_store()
1950{
1951 local sanitize=
1952 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s
1953 local text="$1"
1954
1955 # Sanitize the defaulitem before storing it if desired
1956 [ "$sanitize" ] && f_dialog_data_sanitize text
1957
1958 setvar DEFAULTITEM_$$ "$text"
1959}
1960
1961# f_dialog_default_fetch [$var_to_set]
1962#
1963# Obtain text to be used with the --default-item argument of dialog(1) (or
1964# Xdialog(1)) (previously stored with f_dialog_default_store() above). If
1965# $var_to_set is NULL or missing, output is printed to stdout (which is less
1966# recommended due to performance degradation; in a loop for example).
1967#
1968f_dialog_default_fetch()
1969{
1970 local __var_to_set="$1" __cp
1971
1972 debug= f_getvar DEFAULTITEM_$$ "${__var_to_set:-__cp}" # get the data
1973 setvar DEFAULTITEM_$$ "" # scrub memory in case data was sensitive
1974
1975 # Return the data on standard-out if desired
1976 [ "$__var_to_set" ] || echo "$__cp"
1977
1978 return $SUCCESS
1979}
1980
1981# f_dialog_menutag2item $tag_chosen $tag1 $item1 $tag2 $item2 ...
1982#
1983# To use the `--menu' option of dialog(1) you must pass an ordered list of
1984# tag/item pairs on the command-line. When the user selects a menu option the
1985# tag for that item is printed to stderr.
1986#
1987# This function allows you to dereference the tag chosen by the user back into
1988# the item associated with said tag.
1989#
1990# Pass the tag chosen by the user as the first argument, followed by the
1991# ordered list of tag/item pairs (HINT: use the same tag/item list as was
1992# passed to dialog(1) for consistency).
1993#
1994# If the tag cannot be found, NULL is returned.
1995#
1996f_dialog_menutag2item()
1997{
1998 local tag="$1" tagn item
1999 shift 1 # tag
2000
2001 while [ $# -gt 0 ]; do
2002 tagn="$1"
2003 item="$2"
2004 shift 2 # tagn/item
2005
2006 if [ "$tag" = "$tagn" ]; then
2007 echo "$item"
2008 return $SUCCESS
2009 fi
2010 done
2011 return $FAILURE
2012}
2013
2014# f_dialog_menutag2item_with_help $tag_chosen $tag1 $item1 $help1 \
2015# $tag2 $item2 $help2 ...
2016#
2017# To use the `--menu' option of dialog(1) with the `--item-help' option, you
2018# must pass an ordered list of tag/item/help triplets on the command-line. When
2019# the user selects a menu option the tag for that item is printed to stderr.
2020#
2021# This function allows you to dereference the tag chosen by the user back into
2022# the item associated with said tag (help is discarded/ignored).
2023#
2024# Pass the tag chosen by the user as the first argument, followed by the
2025# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
2026# as was passed to dialog(1) for consistency).
2027#
2028# If the tag cannot be found, NULL is returned.
2029#
2030f_dialog_menutag2item_with_help()
2031{
2032 local tag="$1" tagn item
2033 shift 1 # tag
2034
2035 while [ $# -gt 0 ]; do
2036 tagn="$1"
2037 item="$2"
2038 shift 3 # tagn/item/help
2039
2040 if [ "$tag" = "$tagn" ]; then
2041 echo "$item"
2042 return $SUCCESS
2043 fi
2044 done
2045 return $FAILURE
2046}
2047
2048# f_dialog_menutag2index $tag_chosen $tag1 $item1 $tag2 $item2 ...
2049#
2050# To use the `--menu' option of dialog(1) you must pass an ordered list of
2051# tag/item pairs on the command-line. When the user selects a menu option the
2052# tag for that item is printed to stderr.
2053#
2054# This function allows you to dereference the tag chosen by the user back into
2055# the index associated with said tag. The index is the one-based tag/item pair
2056# array position within the ordered list of tag/item pairs passed to dialog(1).
2057#
2058# Pass the tag chosen by the user as the first argument, followed by the
2059# ordered list of tag/item pairs (HINT: use the same tag/item list as was
2060# passed to dialog(1) for consistency).
2061#
2062# If the tag cannot be found, NULL is returned.
2063#
2064f_dialog_menutag2index()
2065{
2066 local tag="$1" tagn n=1
2067 shift 1 # tag
2068
2069 while [ $# -gt 0 ]; do
2070 tagn="$1"
2071 shift 2 # tagn/item
2072
2073 if [ "$tag" = "$tagn" ]; then
2074 echo $n
2075 return $SUCCESS
2076 fi
2077 n=$(( $n + 1 ))
2078 done
2079 return $FAILURE
2080}
2081
2082# f_dialog_menutag2index_with_help $tag_chosen $tag1 $item1 $help1 \
2083# $tag2 $item2 $help2 ...
2084#
2085# To use the `--menu' option of dialog(1) with the `--item-help' option, you
2086# must pass an ordered list of tag/item/help triplets on the command-line. When
2087# the user selects a menu option the tag for that item is printed to stderr.
2088#
2089# This function allows you to dereference the tag chosen by the user back into
2090# the index associated with said tag. The index is the one-based tag/item/help
2091# triplet array position within the ordered list of tag/item/help triplets
2092# passed to dialog(1).
2093#
2094# Pass the tag chosen by the user as the first argument, followed by the
2095# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
2096# as was passed to dialog(1) for consistency).
2097#
2098# If the tag cannot be found, NULL is returned.
2099#
2100f_dialog_menutag2index_with_help()
2101{
2102 local tag="$1" tagn n=1
2103 shift 1 # tag
2104
2105 while [ $# -gt 0 ]; do
2106 tagn="$1"
2107 shift 3 # tagn/item/help
2108
2109 if [ "$tag" = "$tagn" ]; then
2110 echo $n
2111 return $SUCCESS
2112 fi
2113 n=$(( $n + 1 ))
2114 done
2115 return $FAILURE
2116}
2117
2118# f_dialog_menutag2help $tag_chosen $tag1 $item1 $help1 $tag2 $item2 $help2 ...
2119#
2120# To use the `--menu' option of dialog(1) with the `--item-help' option, you
2121# must pass an ordered list of tag/item/help triplets on the command-line. When
2122# the user selects a menu option the tag for that item is printed to stderr.
2123#
2124# This function allows you to dereference the tag chosen by the user back into
2125# the help associated with said tag (item is discarded/ignored).
2126#
2127# Pass the tag chosen by the user as the first argument, followed by the
2128# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
2129# as was passed to dialog(1) for consistency).
2130#
2131# If the tag cannot be found, NULL is returned.
2132#
2133f_dialog_menutag2help()
2134{
2135 local tag="$1" tagn help
2136 shift 1 # tag
2137
2138 while [ $# -gt 0 ]; do
2139 tagn="$1"
2140 help="$3"
2141 shift 3 # tagn/item/help
2142
2143 if [ "$tag" = "$tagn" ]; then
2144 echo "$help"
2145 return $SUCCESS
2146 fi
2147 done
2148 return $FAILURE
2149}
2150
2151############################################################ INIT FUNCTIONS
2152
2153# f_dialog_init
2154#
2155# Initialize (or re-initialize) the dialog module after setting/changing any
2156# of the following environment variables:
2157#
2158# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate
2159# that Xdialog(1) should be used instead of dialog(1).
2160#
2161# SECURE Either NULL or Non-NULL. If given a value will indicate
2162# that (while running as root) sudo(8) authentication is
2163# required to proceed.
2164#
2165# Also reads ~/.dialogrc for the following information:
2166#
2167# NO_SHADOW Either NULL or Non-NULL. If use_shadow is OFF (case-
2168# insensitive) in ~/.dialogrc this is set to "1" (otherwise
2169# unset).
2170#
2171f_dialog_init()
2172{
2173 local funcname=f_dialog_init
2174
2175 DIALOG_SELF_INITIALIZE=
2176 USE_DIALOG=1
2177
2178 #
2179 # Clone terminal stdout so we can redirect to it from within sub-shells
2180 #
2181 eval exec $DIALOG_TERMINAL_PASSTHRU_FD\>\&1
2182
2183 #
2184 # Add `-S' and `-X' to the list of standard arguments supported by all
2185 #
2186 case "$GETOPTS_STDARGS" in
2187 *SX*) : good ;; # already present
2188 *) GETOPTS_STDARGS="${GETOPTS_STDARGS}SX"
2189 esac
2190
2191 #
2192 # Process stored command-line arguments
2193 #
2194 # NB: Using backticks instead of $(...) for portability since Linux
2195 # bash(1) balks at the right parentheses encountered in the case-
2196 # statement (incorrectly interpreting it as the close of $(...)).
2197 #
2198 f_dprintf "f_dialog_init: ARGV=[%s] GETOPTS_STDARGS=[%s]" \
2199 "$ARGV" "$GETOPTS_STDARGS"
2200 SECURE=`set -- $ARGV
2201 OPTIND=1
2202 while getopts \
2203 "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" \
2204 flag > /dev/null; do
2205 case "$flag" in
2206 S) echo 1 ;;
2207 esac
2208 done
2209 ` # END-BACKTICK
2210 USE_XDIALOG=`set -- $ARGV
2211 OPTIND=1
2212 while getopts \
2213 "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" \
2214 flag > /dev/null; do
2215 case "$flag" in
2216 S|X) echo 1 ;;
2217 esac
2218 done
2219 ` # END-BACKTICK
2220 f_dprintf "f_dialog_init: SECURE=[%s] USE_XDIALOG=[%s]" \
2221 "$SECURE" "$USE_XDIALOG"
2222
2223 #
2224 # Process `-X' command-line option
2225 #
2226 [ "$USE_XDIALOG" ] && DIALOG=Xdialog USE_DIALOG=
2227
2228 #
2229 # Sanity check, or die gracefully
2230 #
2231 if ! f_have $DIALOG; then
2232 unset USE_XDIALOG
2233 local failed_dialog="$DIALOG"
2234 DIALOG=dialog
2235 f_die 1 "$msg_no_such_file_or_directory" "$pgm" "$failed_dialog"
2236 fi
2237
2238 #
2239 # Read ~/.dialogrc (unless using Xdialog(1)) for properties
2240 #
2241 if [ -f ~/.dialogrc -a ! "$USE_XDIALOG" ]; then
2242 eval "$(
2243 awk -v param=use_shadow -v expect=OFF \
2244 -v set="NO_SHADOW=1" '
2245 !/^[[:space:]]*(#|$)/ && \
2246 tolower($1) ~ "^"param"(=|$)" && \
2247 /[^#]*=/ {
2248 sub(/^[^=]*=[[:space:]]*/, "")
2249 if ( toupper($1) == expect ) print set";"
2250 }' ~/.dialogrc
2251 )"
2252 fi
2253
2254 #
2255 # If we're already running as root but we got there by way of sudo(8)
2256 # and we have X11, we should merge the xauth(1) credentials from our
2257 # original user.
2258 #
2259 if [ "$USE_XDIALOG" ] &&
2260 [ "$( id -u )" = "0" ] &&
2261 [ "$SUDO_USER" -a "$DISPLAY" ]
2262 then
2263 if ! f_have xauth; then
2264 # Die gracefully, as we [likely] can't use Xdialog(1)
2265 unset USE_XDIALOG
2266 DIALOG=dialog
2267 f_die 1 "$msg_no_such_file_or_directory" "$pgm" "xauth"
2268 fi
2269 HOSTNAME=$( hostname )
2270 local displaynum="${DISPLAY#*:}"
2271 eval xauth -if \~$SUDO_USER/.Xauthority extract - \
2272 \"\$HOSTNAME/unix:\$displaynum\" \
2273 \"\$HOSTNAME:\$displaynum\" | sudo sh -c 'xauth -ivf \
2274 ~root/.Xauthority merge - > /dev/null 2>&1'
2275 fi
2276
2277 #
2278 # Probe Xdialog(1) for maximum height/width constraints, or die
2279 # gracefully
2280 #
2281 if [ "$USE_XDIALOG" ]; then
2282 local maxsize
2283 if ! f_eval_catch -dk maxsize $funcname "$DIALOG" \
2284 'LANG= LC_ALL= %s --print-maxsize' "$DIALOG"
2285 then
2286 # Xdialog(1) failed, fall back to dialog(1)
2287 unset USE_XDIALOG
2288
2289 # Display the error message produced by Xdialog(1)
2290 local height width
2291 f_dialog_buttonbox_size height width \
2292 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$maxsize"
2293 dialog \
2294 --title "$DIALOG_TITLE" \
2295 --backtitle "$DIALOG_BACKTITLE" \
2296 --ok-label "$msg_ok" \
2297 --msgbox "$maxsize" $height $width
2298 exit $FAILURE
2299 fi
2300
2301 XDIALOG_MAXSIZE=$(
2302 set -- ${maxsize##*:}
2303
2304 height=${1%,}
2305 width=$2
2306
2307 echo $height $width
2308 )
2309 fi
2310
2311 #
2312 # If using Xdialog(1), swap DIALOG_TITLE with DIALOG_BACKTITLE.
2313 # The reason for this is because many dialog(1) applications use
2314 # --backtitle for the program name (which is better suited as
2315 # --title with Xdialog(1)).
2316 #
2317 if [ "$USE_XDIALOG" ]; then
2318 local _DIALOG_TITLE="$DIALOG_TITLE"
2319 DIALOG_TITLE="$DIALOG_BACKTITLE"
2320 DIALOG_BACKTITLE="$_DIALOG_TITLE"
2321 fi
2322
2323 f_dprintf "f_dialog_init: dialog(1) API initialized."
2324}
2325
2326############################################################ MAIN
2327
2328#
2329# Self-initialize unless requested otherwise
2330#
2331f_dprintf "%s: DIALOG_SELF_INITIALIZE=[%s]" \
2332 dialog.subr "$DIALOG_SELF_INITIALIZE"
2333case "$DIALOG_SELF_INITIALIZE" in
2334""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;;
2335*) f_dialog_init
2336esac
2337
2338f_dprintf "%s: Successfully loaded." dialog.subr
2339
2340fi # ! $_DIALOG_SUBR
1819# editing session (by selecting `Cancel' for example).
1820#
1821# If the user presses ENTER, the exit status is zero (success), otherwise if
1822# the user presses ESC the exit status is 255, or if the user chose Cancel, the
1823# exit status is instead 1.
1824#
1825# NOTE: The hline should correspond to the type of data you want from the user.
1826# NOTE: Should not be used to edit multiline values.
1827#
1828f_dialog_input()
1829{
1830 local __var_to_set="$1" __prompt="$2" __init="$3" __hline="$4"
1831
1832 # NOTE: Function name appended to prevent __var_{height,width} values
1833 # from becoming local (and thus preventing setvar from working).
1834 local __height_input __width_input
1835 f_dialog_inputbox_size __height_input __width_input \
1836 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" \
1837 "$__prompt" "$__init" "$__hline"
1838
1839 local __opterm="--"
1840 [ "$USE_XDIALOG" ] && __opterm=
1841
1842 local __dialog_input
1843 __dialog_input=$(
1844 $DIALOG \
1845 --title "$DIALOG_TITLE" \
1846 --backtitle "$DIALOG_BACKTITLE" \
1847 --hline "$__hline" \
1848 --ok-label "$msg_ok" \
1849 --cancel-label "$msg_cancel" \
1850 --inputbox "$__prompt" \
1851 $__height_input $__width_input \
1852 $__opterm "$__init" \
1853 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
1854 )
1855 local __retval=$?
1856
1857 # Remove warnings and leading/trailing whitespace from user input
1858 f_dialog_line_sanitize __dialog_input
1859
1860 setvar "$__var_to_set" "$__dialog_input"
1861 return $__retval
1862}
1863
1864############################################################ MENU FUNCTIONS
1865
1866# f_dialog_menutag_store [-s] $text
1867#
1868# Store some text from a dialog(1) menu to be retrieved later by
1869# f_dialog_menutag_fetch(). If the first argument is `-s', the text is
1870# sanitized before being stored.
1871#
1872f_dialog_menutag_store()
1873{
1874 local sanitize=
1875 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s
1876 local text="$1"
1877
1878 # Sanitize the menutag before storing it if desired
1879 [ "$sanitize" ] && f_dialog_data_sanitize text
1880
1881 setvar DIALOG_MENU_$$ "$text"
1882}
1883
1884# f_dialog_menutag_fetch [$var_to_set]
1885#
1886# Obtain the menutag chosen by the user from the most recently displayed
1887# dialog(1) menu (previously stored with f_dialog_menutag_store() above). If
1888# $var_to_set is NULL or missing, output is printed to stdout (which is less
1889# recommended due to performance degradation; in a loop for example).
1890#
1891f_dialog_menutag_fetch()
1892{
1893 local __var_to_set="$1" __cp
1894
1895 debug= f_getvar DIALOG_MENU_$$ "${__var_to_set:-__cp}" # get the data
1896 setvar DIALOG_MENU_$$ "" # scrub memory in case data was sensitive
1897
1898 # Return the data on standard-out if desired
1899 [ "$__var_to_set" ] || echo "$__cp"
1900
1901 return $SUCCESS
1902}
1903
1904# f_dialog_menuitem_store [-s] $text
1905#
1906# Store the item from a dialog(1) menu (see f_dialog_menutag2item()) to be
1907# retrieved later by f_dialog_menuitem_fetch(). If the first argument is `-s',
1908# the text is sanitized before being stored.
1909#
1910f_dialog_menuitem_store()
1911{
1912 local sanitize=
1913 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s
1914 local text="$1"
1915
1916 # Sanitize the menuitem before storing it if desired
1917 [ "$sanitize" ] && f_dialog_data_sanitize text
1918
1919 setvar DIALOG_MENUITEM_$$ "$text"
1920}
1921
1922# f_dialog_menuitem_fetch [$var_to_set]
1923#
1924# Obtain the menuitem chosen by the user from the most recently displayed
1925# dialog(1) menu (previously stored with f_dialog_menuitem_store() above). If
1926# $var_to_set is NULL or missing, output is printed to stdout (which is less
1927# recommended due to performance degradation; in a loop for example).
1928#
1929f_dialog_menuitem_fetch()
1930{
1931 local __var_to_set="$1" __cp
1932
1933 debug= f_getvar DIALOG_MENUITEM_$$ "${__var_to_set:-__cp}" # get data
1934 setvar DIALOG_MENUITEM_$$ "" # scrub memory in case data was sensitive
1935
1936 # Return the data on standard-out if desired
1937 [ "$__var_to_set" ] || echo "$__cp"
1938
1939 return $SUCCESS
1940}
1941
1942# f_dialog_default_store [-s] $text
1943#
1944# Store some text to be used later as the --default-item argument to dialog(1)
1945# (or Xdialog(1)) for --menu, --checklist, and --radiolist widgets. Retrieve
1946# the text later with f_dialog_menutag_fetch(). If the first argument is `-s',
1947# the text is sanitized before being stored.
1948#
1949f_dialog_default_store()
1950{
1951 local sanitize=
1952 [ "$1" = "-s" ] && sanitize=1 && shift 1 # -s
1953 local text="$1"
1954
1955 # Sanitize the defaulitem before storing it if desired
1956 [ "$sanitize" ] && f_dialog_data_sanitize text
1957
1958 setvar DEFAULTITEM_$$ "$text"
1959}
1960
1961# f_dialog_default_fetch [$var_to_set]
1962#
1963# Obtain text to be used with the --default-item argument of dialog(1) (or
1964# Xdialog(1)) (previously stored with f_dialog_default_store() above). If
1965# $var_to_set is NULL or missing, output is printed to stdout (which is less
1966# recommended due to performance degradation; in a loop for example).
1967#
1968f_dialog_default_fetch()
1969{
1970 local __var_to_set="$1" __cp
1971
1972 debug= f_getvar DEFAULTITEM_$$ "${__var_to_set:-__cp}" # get the data
1973 setvar DEFAULTITEM_$$ "" # scrub memory in case data was sensitive
1974
1975 # Return the data on standard-out if desired
1976 [ "$__var_to_set" ] || echo "$__cp"
1977
1978 return $SUCCESS
1979}
1980
1981# f_dialog_menutag2item $tag_chosen $tag1 $item1 $tag2 $item2 ...
1982#
1983# To use the `--menu' option of dialog(1) you must pass an ordered list of
1984# tag/item pairs on the command-line. When the user selects a menu option the
1985# tag for that item is printed to stderr.
1986#
1987# This function allows you to dereference the tag chosen by the user back into
1988# the item associated with said tag.
1989#
1990# Pass the tag chosen by the user as the first argument, followed by the
1991# ordered list of tag/item pairs (HINT: use the same tag/item list as was
1992# passed to dialog(1) for consistency).
1993#
1994# If the tag cannot be found, NULL is returned.
1995#
1996f_dialog_menutag2item()
1997{
1998 local tag="$1" tagn item
1999 shift 1 # tag
2000
2001 while [ $# -gt 0 ]; do
2002 tagn="$1"
2003 item="$2"
2004 shift 2 # tagn/item
2005
2006 if [ "$tag" = "$tagn" ]; then
2007 echo "$item"
2008 return $SUCCESS
2009 fi
2010 done
2011 return $FAILURE
2012}
2013
2014# f_dialog_menutag2item_with_help $tag_chosen $tag1 $item1 $help1 \
2015# $tag2 $item2 $help2 ...
2016#
2017# To use the `--menu' option of dialog(1) with the `--item-help' option, you
2018# must pass an ordered list of tag/item/help triplets on the command-line. When
2019# the user selects a menu option the tag for that item is printed to stderr.
2020#
2021# This function allows you to dereference the tag chosen by the user back into
2022# the item associated with said tag (help is discarded/ignored).
2023#
2024# Pass the tag chosen by the user as the first argument, followed by the
2025# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
2026# as was passed to dialog(1) for consistency).
2027#
2028# If the tag cannot be found, NULL is returned.
2029#
2030f_dialog_menutag2item_with_help()
2031{
2032 local tag="$1" tagn item
2033 shift 1 # tag
2034
2035 while [ $# -gt 0 ]; do
2036 tagn="$1"
2037 item="$2"
2038 shift 3 # tagn/item/help
2039
2040 if [ "$tag" = "$tagn" ]; then
2041 echo "$item"
2042 return $SUCCESS
2043 fi
2044 done
2045 return $FAILURE
2046}
2047
2048# f_dialog_menutag2index $tag_chosen $tag1 $item1 $tag2 $item2 ...
2049#
2050# To use the `--menu' option of dialog(1) you must pass an ordered list of
2051# tag/item pairs on the command-line. When the user selects a menu option the
2052# tag for that item is printed to stderr.
2053#
2054# This function allows you to dereference the tag chosen by the user back into
2055# the index associated with said tag. The index is the one-based tag/item pair
2056# array position within the ordered list of tag/item pairs passed to dialog(1).
2057#
2058# Pass the tag chosen by the user as the first argument, followed by the
2059# ordered list of tag/item pairs (HINT: use the same tag/item list as was
2060# passed to dialog(1) for consistency).
2061#
2062# If the tag cannot be found, NULL is returned.
2063#
2064f_dialog_menutag2index()
2065{
2066 local tag="$1" tagn n=1
2067 shift 1 # tag
2068
2069 while [ $# -gt 0 ]; do
2070 tagn="$1"
2071 shift 2 # tagn/item
2072
2073 if [ "$tag" = "$tagn" ]; then
2074 echo $n
2075 return $SUCCESS
2076 fi
2077 n=$(( $n + 1 ))
2078 done
2079 return $FAILURE
2080}
2081
2082# f_dialog_menutag2index_with_help $tag_chosen $tag1 $item1 $help1 \
2083# $tag2 $item2 $help2 ...
2084#
2085# To use the `--menu' option of dialog(1) with the `--item-help' option, you
2086# must pass an ordered list of tag/item/help triplets on the command-line. When
2087# the user selects a menu option the tag for that item is printed to stderr.
2088#
2089# This function allows you to dereference the tag chosen by the user back into
2090# the index associated with said tag. The index is the one-based tag/item/help
2091# triplet array position within the ordered list of tag/item/help triplets
2092# passed to dialog(1).
2093#
2094# Pass the tag chosen by the user as the first argument, followed by the
2095# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
2096# as was passed to dialog(1) for consistency).
2097#
2098# If the tag cannot be found, NULL is returned.
2099#
2100f_dialog_menutag2index_with_help()
2101{
2102 local tag="$1" tagn n=1
2103 shift 1 # tag
2104
2105 while [ $# -gt 0 ]; do
2106 tagn="$1"
2107 shift 3 # tagn/item/help
2108
2109 if [ "$tag" = "$tagn" ]; then
2110 echo $n
2111 return $SUCCESS
2112 fi
2113 n=$(( $n + 1 ))
2114 done
2115 return $FAILURE
2116}
2117
2118# f_dialog_menutag2help $tag_chosen $tag1 $item1 $help1 $tag2 $item2 $help2 ...
2119#
2120# To use the `--menu' option of dialog(1) with the `--item-help' option, you
2121# must pass an ordered list of tag/item/help triplets on the command-line. When
2122# the user selects a menu option the tag for that item is printed to stderr.
2123#
2124# This function allows you to dereference the tag chosen by the user back into
2125# the help associated with said tag (item is discarded/ignored).
2126#
2127# Pass the tag chosen by the user as the first argument, followed by the
2128# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
2129# as was passed to dialog(1) for consistency).
2130#
2131# If the tag cannot be found, NULL is returned.
2132#
2133f_dialog_menutag2help()
2134{
2135 local tag="$1" tagn help
2136 shift 1 # tag
2137
2138 while [ $# -gt 0 ]; do
2139 tagn="$1"
2140 help="$3"
2141 shift 3 # tagn/item/help
2142
2143 if [ "$tag" = "$tagn" ]; then
2144 echo "$help"
2145 return $SUCCESS
2146 fi
2147 done
2148 return $FAILURE
2149}
2150
2151############################################################ INIT FUNCTIONS
2152
2153# f_dialog_init
2154#
2155# Initialize (or re-initialize) the dialog module after setting/changing any
2156# of the following environment variables:
2157#
2158# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate
2159# that Xdialog(1) should be used instead of dialog(1).
2160#
2161# SECURE Either NULL or Non-NULL. If given a value will indicate
2162# that (while running as root) sudo(8) authentication is
2163# required to proceed.
2164#
2165# Also reads ~/.dialogrc for the following information:
2166#
2167# NO_SHADOW Either NULL or Non-NULL. If use_shadow is OFF (case-
2168# insensitive) in ~/.dialogrc this is set to "1" (otherwise
2169# unset).
2170#
2171f_dialog_init()
2172{
2173 local funcname=f_dialog_init
2174
2175 DIALOG_SELF_INITIALIZE=
2176 USE_DIALOG=1
2177
2178 #
2179 # Clone terminal stdout so we can redirect to it from within sub-shells
2180 #
2181 eval exec $DIALOG_TERMINAL_PASSTHRU_FD\>\&1
2182
2183 #
2184 # Add `-S' and `-X' to the list of standard arguments supported by all
2185 #
2186 case "$GETOPTS_STDARGS" in
2187 *SX*) : good ;; # already present
2188 *) GETOPTS_STDARGS="${GETOPTS_STDARGS}SX"
2189 esac
2190
2191 #
2192 # Process stored command-line arguments
2193 #
2194 # NB: Using backticks instead of $(...) for portability since Linux
2195 # bash(1) balks at the right parentheses encountered in the case-
2196 # statement (incorrectly interpreting it as the close of $(...)).
2197 #
2198 f_dprintf "f_dialog_init: ARGV=[%s] GETOPTS_STDARGS=[%s]" \
2199 "$ARGV" "$GETOPTS_STDARGS"
2200 SECURE=`set -- $ARGV
2201 OPTIND=1
2202 while getopts \
2203 "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" \
2204 flag > /dev/null; do
2205 case "$flag" in
2206 S) echo 1 ;;
2207 esac
2208 done
2209 ` # END-BACKTICK
2210 USE_XDIALOG=`set -- $ARGV
2211 OPTIND=1
2212 while getopts \
2213 "$GETOPTS_STDARGS$GETOPTS_EXTRA$GETOPTS_ALLFLAGS" \
2214 flag > /dev/null; do
2215 case "$flag" in
2216 S|X) echo 1 ;;
2217 esac
2218 done
2219 ` # END-BACKTICK
2220 f_dprintf "f_dialog_init: SECURE=[%s] USE_XDIALOG=[%s]" \
2221 "$SECURE" "$USE_XDIALOG"
2222
2223 #
2224 # Process `-X' command-line option
2225 #
2226 [ "$USE_XDIALOG" ] && DIALOG=Xdialog USE_DIALOG=
2227
2228 #
2229 # Sanity check, or die gracefully
2230 #
2231 if ! f_have $DIALOG; then
2232 unset USE_XDIALOG
2233 local failed_dialog="$DIALOG"
2234 DIALOG=dialog
2235 f_die 1 "$msg_no_such_file_or_directory" "$pgm" "$failed_dialog"
2236 fi
2237
2238 #
2239 # Read ~/.dialogrc (unless using Xdialog(1)) for properties
2240 #
2241 if [ -f ~/.dialogrc -a ! "$USE_XDIALOG" ]; then
2242 eval "$(
2243 awk -v param=use_shadow -v expect=OFF \
2244 -v set="NO_SHADOW=1" '
2245 !/^[[:space:]]*(#|$)/ && \
2246 tolower($1) ~ "^"param"(=|$)" && \
2247 /[^#]*=/ {
2248 sub(/^[^=]*=[[:space:]]*/, "")
2249 if ( toupper($1) == expect ) print set";"
2250 }' ~/.dialogrc
2251 )"
2252 fi
2253
2254 #
2255 # If we're already running as root but we got there by way of sudo(8)
2256 # and we have X11, we should merge the xauth(1) credentials from our
2257 # original user.
2258 #
2259 if [ "$USE_XDIALOG" ] &&
2260 [ "$( id -u )" = "0" ] &&
2261 [ "$SUDO_USER" -a "$DISPLAY" ]
2262 then
2263 if ! f_have xauth; then
2264 # Die gracefully, as we [likely] can't use Xdialog(1)
2265 unset USE_XDIALOG
2266 DIALOG=dialog
2267 f_die 1 "$msg_no_such_file_or_directory" "$pgm" "xauth"
2268 fi
2269 HOSTNAME=$( hostname )
2270 local displaynum="${DISPLAY#*:}"
2271 eval xauth -if \~$SUDO_USER/.Xauthority extract - \
2272 \"\$HOSTNAME/unix:\$displaynum\" \
2273 \"\$HOSTNAME:\$displaynum\" | sudo sh -c 'xauth -ivf \
2274 ~root/.Xauthority merge - > /dev/null 2>&1'
2275 fi
2276
2277 #
2278 # Probe Xdialog(1) for maximum height/width constraints, or die
2279 # gracefully
2280 #
2281 if [ "$USE_XDIALOG" ]; then
2282 local maxsize
2283 if ! f_eval_catch -dk maxsize $funcname "$DIALOG" \
2284 'LANG= LC_ALL= %s --print-maxsize' "$DIALOG"
2285 then
2286 # Xdialog(1) failed, fall back to dialog(1)
2287 unset USE_XDIALOG
2288
2289 # Display the error message produced by Xdialog(1)
2290 local height width
2291 f_dialog_buttonbox_size height width \
2292 "$DIALOG_TITLE" "$DIALOG_BACKTITLE" "$maxsize"
2293 dialog \
2294 --title "$DIALOG_TITLE" \
2295 --backtitle "$DIALOG_BACKTITLE" \
2296 --ok-label "$msg_ok" \
2297 --msgbox "$maxsize" $height $width
2298 exit $FAILURE
2299 fi
2300
2301 XDIALOG_MAXSIZE=$(
2302 set -- ${maxsize##*:}
2303
2304 height=${1%,}
2305 width=$2
2306
2307 echo $height $width
2308 )
2309 fi
2310
2311 #
2312 # If using Xdialog(1), swap DIALOG_TITLE with DIALOG_BACKTITLE.
2313 # The reason for this is because many dialog(1) applications use
2314 # --backtitle for the program name (which is better suited as
2315 # --title with Xdialog(1)).
2316 #
2317 if [ "$USE_XDIALOG" ]; then
2318 local _DIALOG_TITLE="$DIALOG_TITLE"
2319 DIALOG_TITLE="$DIALOG_BACKTITLE"
2320 DIALOG_BACKTITLE="$_DIALOG_TITLE"
2321 fi
2322
2323 f_dprintf "f_dialog_init: dialog(1) API initialized."
2324}
2325
2326############################################################ MAIN
2327
2328#
2329# Self-initialize unless requested otherwise
2330#
2331f_dprintf "%s: DIALOG_SELF_INITIALIZE=[%s]" \
2332 dialog.subr "$DIALOG_SELF_INITIALIZE"
2333case "$DIALOG_SELF_INITIALIZE" in
2334""|0|[Nn][Oo]|[Oo][Ff][Ff]|[Ff][Aa][Ll][Ss][Ee]) : do nothing ;;
2335*) f_dialog_init
2336esac
2337
2338f_dprintf "%s: Successfully loaded." dialog.subr
2339
2340fi # ! $_DIALOG_SUBR