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