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