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