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