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