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