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