89498fdf41
This allows bsdconfig to -- like bsdinstall -- operate from read-only media. Reviewed by: adrian (co-mentor) Approved by: adrian (co-mentor)
1424 lines
39 KiB
Plaintext
1424 lines
39 KiB
Plaintext
if [ ! "$_DIALOG_SUBR" ]; then _DIALOG_SUBR=1
|
|
#
|
|
# Copyright (c) 2006-2012 Devin Teske
|
|
# All Rights Reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
# SUCH DAMAGE.
|
|
#
|
|
# $FreeBSD$
|
|
#
|
|
############################################################ INCLUDES
|
|
|
|
BSDCFG_SHARE="/usr/share/bsdconfig"
|
|
. $BSDCFG_SHARE/common.subr || exit 1
|
|
f_include $BSDCFG_SHARE/strings.subr
|
|
|
|
BSDCFG_LIBE="/usr/libexec/bsdconfig"
|
|
f_include_lang $BSDCFG_LIBE/include/messages.subr
|
|
|
|
############################################################ CONFIGURATION
|
|
|
|
#
|
|
# Default file descriptor to link to stdout for dialog(1) passthru allowing
|
|
# execution of dialog from within a sub-shell (so-long as its standard output
|
|
# is explicitly redirected to this file descriptor).
|
|
#
|
|
: ${DIALOG_TERMINAL_PASSTHRU_FD:=3}
|
|
|
|
############################################################ GLOBALS
|
|
|
|
#
|
|
# Default name of dialog(1) utility
|
|
# NOTE: This is changed to "Xdialog" by the optional `-X' argument
|
|
#
|
|
DIALOG="dialog"
|
|
|
|
#
|
|
# Default dialog(1) title and backtitle text
|
|
#
|
|
DIALOG_TITLE="$pgm"
|
|
DIALOG_BACKTITLE="bsdconfig"
|
|
|
|
#
|
|
# Settings used while interacting with dialog(1)
|
|
#
|
|
DIALOG_MENU_TAGS="123456789ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwxyz"
|
|
|
|
#
|
|
# Declare that we are fully-compliant with Xdialog(1) by unset'ing all
|
|
# compatibility settings.
|
|
#
|
|
unset XDIALOG_HIGH_DIALOG_COMPAT
|
|
unset XDIALOG_FORCE_AUTOSIZE
|
|
unset XDIALOG_INFOBOX_TIMEOUT
|
|
|
|
#
|
|
# Default behavior is to call f_dialog_init() automatically if not already
|
|
# called manually by the time the first f_dialog_*() function is used.
|
|
#
|
|
: ${DIALOG_SELF_INITIALIZE=1}
|
|
|
|
############################################################ GENERIC FUNCTIONS
|
|
|
|
# f_dialog_title [$new_title]
|
|
#
|
|
# Set the title of future dialog(1) ($DIALOG_TITLE) or backtitle of Xdialog(1)
|
|
# ($DIALOG_BACKTITLE) invocations. If no arguments are given or the first
|
|
# argument is NULL, the current title is returned.
|
|
#
|
|
# Each time this function is called, a backup of the current values is made
|
|
# allowing a one-time (single-level) restoration of the previous title using the
|
|
# f_dialog_title_restore() function (below).
|
|
#
|
|
f_dialog_title()
|
|
{
|
|
local new_title="$1"
|
|
|
|
if [ "$new_title" ]; then
|
|
if [ "$USE_XDIALOG" ]; then
|
|
_DIALOG_BACKTITLE="$DIALOG_BACKTITLE"
|
|
DIALOG_BACKTITLE="$new_title"
|
|
else
|
|
_DIALOG_TITLE="$DIALOG_TITLE"
|
|
DIALOG_TITLE="$new_title"
|
|
fi
|
|
else
|
|
if [ "$USE_XDIALOG" ]; then
|
|
echo "$DIALOG_BACKTITLE"
|
|
else
|
|
echo "$DIALOG_TITLE"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# f_dialog_title_restore
|
|
#
|
|
# Restore the previous title set by the last call to f_dialog_title().
|
|
# Restoration is non-recursive and only works to restore the most-recent title.
|
|
#
|
|
f_dialog_title_restore()
|
|
{
|
|
if [ "$USE_XDIALOG" ]; then
|
|
DIALOG_BACKTITLE="$_DIALOG_BACKTITLE"
|
|
else
|
|
DIALOG_TITLE="$_DIALOG_TITLE"
|
|
fi
|
|
}
|
|
|
|
# f_dialog_backtitle [$new_backtitle]
|
|
#
|
|
# Set the backtitle of future dialog(1) ($DIALOG_BACKTITLE) or title of
|
|
# Xdialog(1) ($DIALOG_TITLE) invocations. If no arguments are given or the
|
|
# first argument is NULL, the current backtitle is returned.
|
|
#
|
|
f_dialog_backtitle()
|
|
{
|
|
local new_backtitle="$1"
|
|
|
|
if [ "$new_backtitle" ]; then
|
|
if [ "$USE_XDIALOG" ]; then
|
|
_DIALOG_TITLE="$DIALOG_TITLE"
|
|
DIALOG_TITLE="$new_backtitle"
|
|
else
|
|
_DIALOG_BACKTITLE="$DIALOG_BACKTITLE"
|
|
DIALOG_BACKTITLE="$new_backtitle"
|
|
fi
|
|
else
|
|
if [ "$USE_XDIALOG" ]; then
|
|
echo "$DIALOG_TITLE"
|
|
else
|
|
echo "$DIALOG_BACKTITLE"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# f_dialog_backtitle_restore
|
|
#
|
|
# Restore the previous backtitle set by the last call to f_dialog_backtitle().
|
|
# Restoration is non-recursive and only works to restore the most-recent
|
|
# backtitle.
|
|
#
|
|
f_dialog_backtitle_restore()
|
|
{
|
|
if [ "$USE_XDIALOG" ]; then
|
|
DIALOG_TITLE="$_DIALOG_TITLE"
|
|
else
|
|
DIALOG_BACKTITLE="$_DIALOG_BACKTITLE"
|
|
fi
|
|
}
|
|
|
|
############################################################ SIZE FUNCTIONS
|
|
|
|
# f_dialog_infobox_size $title $backtitle $prompt [$hline]
|
|
#
|
|
# Not all versions of dialog(1) perform auto-sizing of the width and height of
|
|
# `--infobox' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, and [optionally] hline returning
|
|
# the optimal width and height for the box (not exceeding the actual terminal
|
|
# width or height).
|
|
#
|
|
# Newline character sequences (``\n'') in $prompt are expanded as-is done by
|
|
# dialog(1).
|
|
#
|
|
# Output is in the format of "height width".
|
|
#
|
|
f_dialog_infobox_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3" hline="$4" n=0
|
|
local min_width max_size
|
|
|
|
if [ "$USE_XDIALOG" ]; then
|
|
min_width=35
|
|
max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
else
|
|
min_width=24
|
|
max_size=$( stty size ) # usually "24 80"
|
|
fi
|
|
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
local max_width="${max_size##*[$IFS]}"
|
|
local height width=$min_width
|
|
|
|
#
|
|
# Bump width for long titles (but don't exceed terminal width).
|
|
#
|
|
n=$(( ${#title} + 4 ))
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
# Add 16.6% width for Xdialog(1)
|
|
[ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 ))
|
|
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# For Xdialog(1), bump width for long backtitles (which appear within
|
|
# the window; don't exceed maximum width).
|
|
#
|
|
if [ "$USE_XDIALOG" ]; then
|
|
n=$(( ${#btitle} + 4 ))
|
|
n=$(( $n + $n / 6 ))
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Bump width for long prompts (if not already at maximum width).
|
|
#
|
|
if [ $width -lt $max_width ]; then
|
|
n=$( echo "$prompt" | f_longest_line_length )
|
|
n=$(( $n + 4 ))
|
|
|
|
# Add 16.6% width for Xdialog(1)
|
|
[ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 ))
|
|
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Bump width for long hlines (if not already at maximum width).
|
|
# NOTE: Though Xdialog(1) supports `--hline', it's not currently used.
|
|
#
|
|
if [ ! "$USE_XDIALOG" ]; then
|
|
if [ $width -lt $max_width ]; then
|
|
n=$(( ${#hline} + 10 ))
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Set height based on number of rows in prompt
|
|
#
|
|
height=$( echo "$prompt" | f_number_of_lines )
|
|
height=$(( $height + 2 ))
|
|
|
|
#
|
|
# For Xdialog(1) bump height if backtitle is enabled (displayed in the
|
|
# X11 window with a separator line between the backtitle and msg text)
|
|
#
|
|
if [ "$USE_XDIALOG" -a "$btitle" ]; then
|
|
n=$( echo "$btitle" | f_number_of_lines )
|
|
height=$(( $height + $n + 2 ))
|
|
fi
|
|
|
|
# Make sure height is less than maximum screen size
|
|
[ $height -le $max_height ] || height=$max_height
|
|
|
|
# Return both
|
|
echo "$height $width"
|
|
}
|
|
|
|
# f_dialog_buttonbox_size $title $backtitle $prompt [$hline]
|
|
#
|
|
# Not all versions of dialog(1) perform auto-sizing of the width and height of
|
|
# `--msgbox' and `--yesno' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, and [optionally] hline returning
|
|
# the optimal width and height for the box (not exceeding the actual terminal
|
|
# width or height).
|
|
#
|
|
# Newline character sequences (``\n'') in $prompt are expanded as-is done by
|
|
# dialog(1).
|
|
#
|
|
# Output is in the format of "height width".
|
|
#
|
|
f_dialog_buttonbox_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3" hline="$4"
|
|
local size="$( f_dialog_infobox_size \
|
|
"$title" "$btitle" "$prompt" "$hline" )"
|
|
local height="${size%%[$IFS]*}"
|
|
local width="${size##*[$IFS]}"
|
|
|
|
# Add height to accomodate the buttons
|
|
height=$(( $height + 2 ))
|
|
|
|
# Adjust for clipping with Xdialog(1) on Linux/GTK2
|
|
[ "$USE_XDIALOG" ] && height=$(( $height + 3 ))
|
|
|
|
#
|
|
# Enforce maximum height regardless
|
|
#
|
|
local max_size
|
|
if [ "$USE_XDIALOG" ]; then
|
|
max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
else
|
|
max_size=$( stty size ) # usually "24 80"
|
|
fi
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
[ $height -le $max_height ] || height=$max_height
|
|
|
|
# Return both
|
|
echo "$height $width"
|
|
}
|
|
|
|
# f_dialog_inputbox_size $title $backtitle $prompt $init [$hline]
|
|
#
|
|
# Not all versions of dialog(1) perform auto-sizing of the width and height of
|
|
# `--inputbox' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, initial text, and [optionally]
|
|
# hline returning the optimal width and height for the box (not exceeding the
|
|
# actual terminal width and height).
|
|
#
|
|
# Newline character sequences (``\n'') in $prompt are expanded as-is done by
|
|
# dialog(1).
|
|
#
|
|
# Output is in the format of "height width".
|
|
#
|
|
f_dialog_inputbox_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3" init="$4" hline="$5" n
|
|
local size="$( f_dialog_buttonbox_size \
|
|
"$title" "$btitle" "$prompt" "$hline" )"
|
|
local height="${size%%[$IFS]*}"
|
|
local width="${size##*[$IFS]}"
|
|
|
|
local min_width max_size
|
|
if [ "$USE_XDIALOG" ]; then
|
|
min_width=35
|
|
max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
else
|
|
min_width=24
|
|
max_size=$( stty size ) # usually "24 80"
|
|
fi
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
local max_width="${max_size##*[$IFS]}"
|
|
|
|
#
|
|
# Add height to accomodate the input box
|
|
#
|
|
[ ! "$USE_XDIALOG" ] && height=$(( $height + 3 ))
|
|
[ $height -le $max_height ] || height=$max_height
|
|
|
|
#
|
|
# Bump width for initial text (if not already at maximum width).
|
|
# NOTE: Something neither dialog(1)/Xdialog(1) do, but worth it!
|
|
#
|
|
if [ $width -lt $max_width ]; then
|
|
n=$(( ${#init} + 7 ))
|
|
|
|
# Add 16.6% width for Xdialog(1)
|
|
[ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 ))
|
|
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Return both
|
|
echo "$height $width"
|
|
}
|
|
|
|
# f_xdialog_2inputsbox_size $title $backtitle $prompt \
|
|
# $label1 $init1 $label2 $init2
|
|
#
|
|
# Xdialog(1) does not perform auto-sizing of the width and height of
|
|
# `--2inputsbox' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, label for the first field, initial
|
|
# text for said field, label for the second field, and initial text for said
|
|
# field returning the optimal width and height for the box (not exceeding the
|
|
# actual terminal width and height).
|
|
#
|
|
# Newline character sequences (``\n'') in $prompt are expanded as-is done by
|
|
# Xdialog(1).
|
|
#
|
|
# Output is in the format of "height width".
|
|
#
|
|
f_xdialog_2inputsbox_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3"
|
|
local label1="$4" init1="$5" label2="$6" init2="$7" n
|
|
local size="$( f_dialog_inputbox_size \
|
|
"$title" "$btitle" "$prompt" "$init1" )"
|
|
local height="${size%%[$IFS]*}"
|
|
local width="${size##*[$IFS]}"
|
|
|
|
local min_width=35
|
|
local max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
local max_width="${max_size##*[$IFS]}"
|
|
|
|
# Add height for first label
|
|
height=$(( $height + 2 ))
|
|
|
|
#
|
|
# Bump width for first label text (if not already at maximum width).
|
|
#
|
|
if [ $width -lt $max_width ]; then
|
|
n=$(( ${#label1} + 7 ))
|
|
|
|
# Add 16.6% width for Xdialog(1)
|
|
n=$(( $n + $n / 6 ))
|
|
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Add height for second label
|
|
height=$(( $height + 2 ))
|
|
|
|
#
|
|
# Bump width for second label text (if not already at maximum width).
|
|
#
|
|
if [ $width -lt $max_width ]; then
|
|
n=$(( ${#label2} + 7 ))
|
|
|
|
# Add 16.6% width for Xdialog(1)
|
|
n=$(( $n + $n / 6 ))
|
|
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Add height for a second inputbox
|
|
height=$(( $height + 2 ))
|
|
|
|
#
|
|
# Bump width for second initial text (if not already at maximum width).
|
|
# NOTE: Something neither dialog(1)/Xdialog(1) do, but worth it!
|
|
#
|
|
if [ $width -lt $max_width ]; then
|
|
n=$(( ${#init2} + 7 ))
|
|
|
|
# Add 16.6% width for Xdialog(1)
|
|
n=$(( $n + $n / 6 ))
|
|
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Return both
|
|
echo "$height $width"
|
|
}
|
|
|
|
# f_dialog_menu_size $title $backtitle $prompt $hline \
|
|
# $tag1 $item1 $tag2 $item2 ...
|
|
#
|
|
# Not all versions of dialog(1) perform auto-sizing of the width and height of
|
|
# `--menu' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, hline and list of tag/item pairs,
|
|
# returning the optimal width and height for the menu (not exceeding the actual
|
|
# terminal width or height).
|
|
#
|
|
# Output is in the format of "height width rows".
|
|
#
|
|
f_dialog_menu_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3" hline="$4" n=0
|
|
local min_width min_rows max_size
|
|
|
|
if [ "$USE_XDIALOG" ]; then
|
|
min_width=35
|
|
min_rows=1
|
|
max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
else
|
|
min_width=24
|
|
min_rows=0
|
|
max_size=$( stty size ) # usually "24 80"
|
|
fi
|
|
|
|
local max_width="${max_size##*[$IFS]}"
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
local box_size="$( f_dialog_infobox_size \
|
|
"$title" "$btitle" "$prompt" "$hline" )"
|
|
local box_height="${box_size%%[$IFS]*}"
|
|
local box_width="${box_size##*[$IFS]}"
|
|
local max_rows=$(( $max_height - 8 ))
|
|
local height width=$box_width rows=$min_rows
|
|
|
|
shift 4 # title/btitle/prompt/hline
|
|
|
|
# If there's no prompt, bump the max-rows by 1
|
|
[ "$prompt" ] || max_rows=$(( $max_rows + 1 ))
|
|
|
|
#
|
|
# The sum total between the longest tag-length and longest item-length
|
|
# should be used for the menu width (not to exceed terminal width).
|
|
#
|
|
# Also, calculate the number of rows (not to exceed terminal height).
|
|
#
|
|
local longest_tag=0 longest_item=0
|
|
while [ $# -ge 2 ]; do
|
|
local tag="$1" item="$2"
|
|
shift 2 # tag/item
|
|
|
|
[ ${#tag} -gt $longest_tag ] && longest_tag=${#tag}
|
|
[ ${#item} -gt $longest_item ] && longest_item=${#item}
|
|
[ $rows -lt $max_rows ] && rows=$(( $rows + 1 ))
|
|
done
|
|
|
|
# Update width
|
|
n=$(( $longest_tag + $longest_item + 10 ))
|
|
[ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1)
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
|
|
# Fix rows and set height
|
|
[ $rows -gt 0 ] || rows=1
|
|
if [ "$USE_XDIALOG" ]; then
|
|
height=$(( $rows + $box_height + 7 ))
|
|
else
|
|
height=$(( $rows + $box_height + 4 ))
|
|
fi
|
|
[ $height -le $max_height ] || height=$max_height
|
|
|
|
# Return all three
|
|
echo "$height $width $rows"
|
|
}
|
|
|
|
# f_dialog_menu_with_help_size $title $backtitle $prompt $hline \
|
|
# $tag1 $item1 $help1 $tag2 $item2 $help2 ...
|
|
#
|
|
# Not all versions of dialog(1) perform auto-sizing of the width and height of
|
|
# `--menu' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, hline and list of tag/item/help
|
|
# triplets, returning the optimal width and height for the menu (not exceeding
|
|
# the actual terminal width or height).
|
|
#
|
|
# Output is in the format of "height width rows".
|
|
#
|
|
f_dialog_menu_with_help_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3" hline="$4" n=0
|
|
local min_width min_rows max_size
|
|
|
|
if [ "$USE_XDIALOG" ]; then
|
|
min_width=35
|
|
min_rows=1
|
|
max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
else
|
|
min_width=24
|
|
min_rows=0
|
|
max_size=$( stty size ) # usually "24 80"
|
|
fi
|
|
|
|
local max_width="${max_size##*[$IFS]}"
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
local box_size="$( f_dialog_infobox_size \
|
|
"$title" "$btitle" "$prompt" "$hline" )"
|
|
local box_height="${box_size%%[$IFS]*}"
|
|
local box_width="${box_size##*[$IFS]}"
|
|
local max_rows=$(( $max_height - 8 ))
|
|
local height width=$box_width rows=$min_rows
|
|
|
|
shift 4 # title/btitle/prompt/hline
|
|
|
|
# If there's no prompt, bump the max-rows by 1
|
|
[ "$prompt" ] || max_rows=$(( $max_rows + 1 ))
|
|
|
|
#
|
|
# The sum total between the longest tag-length and longest item-length
|
|
# should be used for the menu width (not to exceed terminal width).
|
|
#
|
|
# Also, calculate the number of rows (not to exceed terminal height).
|
|
#
|
|
# Also, calculate the longest help while we're here. This will be used
|
|
# to influence the width of the menu if (and only-if) using Xdialog(1).
|
|
#
|
|
local longest_tag=0 longest_item=0 longest_help=0
|
|
while [ $# -ge 3 ]; do
|
|
local tag="$1" item="$2" help="$3"
|
|
shift 3 # tag/item/help
|
|
|
|
[ ${#tag} -gt $longest_tag ] && longest_tag=${#tag}
|
|
[ ${#item} -gt $longest_item ] && longest_item=${#item}
|
|
[ ${#help} -gt $longest_help ] && longest_help=${#help}
|
|
[ $rows -lt $max_rows ] && rows=$(( $rows + 1 ))
|
|
done
|
|
|
|
# Update width
|
|
n=$(( $longest_tag + $longest_item + 10 ))
|
|
[ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1)
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
|
|
# Update width for help text if using Xdialog(1)
|
|
if [ "$USE_XDIALOG" ]; then
|
|
n=$(( $longest_help + 10 ))
|
|
n=$(( $n + $n / 6 )) # +16.6%
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Fix rows and set height
|
|
[ $rows -gt 0 ] || rows=1
|
|
if [ "$USE_XDIALOG" ]; then
|
|
height=$(( $rows + $box_height + 8 ))
|
|
else
|
|
height=$(( $rows + $box_height + 4 ))
|
|
fi
|
|
[ $height -le $max_height ] || height=$max_height
|
|
|
|
# Return all three
|
|
echo "$height $width $rows"
|
|
}
|
|
|
|
# f_dialog_radiolist_size $title $backtitle $prompt $hline \
|
|
# $tag1 $item1 $status1 $tag2 $item2 $status2 ...
|
|
#
|
|
# Not all versions of dialog(1) perform auto-sizing of the width and height of
|
|
# `--radiolist' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, hline and list of tag/item/status
|
|
# triplets, returning the optimal width and height for the radiolist (not
|
|
# exceeding the actual terminal width or height).
|
|
#
|
|
# Output is in the format of "height width rows".
|
|
#
|
|
f_dialog_radiolist_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3" hline="$4" n=0
|
|
local min_width min_rows max_size
|
|
|
|
if [ "$USE_XDIALOG" ]; then
|
|
min_width=35
|
|
min_rows=1
|
|
max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
else
|
|
min_width=24
|
|
min_rows=0
|
|
max_size=$( stty size ) # usually "24 80"
|
|
fi
|
|
|
|
local max_width="${max_size##*[$IFS]}"
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
local box_size="$( f_dialog_infobox_size \
|
|
"$title" "$btitle" "$prompt" "$hline" )"
|
|
local box_height="${box_size%%[$IFS]*}"
|
|
local box_width="${box_size##*[$IFS]}"
|
|
local max_rows=$(( $max_height - 8 ))
|
|
local height width=$box_width rows=$min_rows
|
|
|
|
shift 4 # title/btitle/prompt/hline
|
|
|
|
#
|
|
# The sum total between the longest tag-length, longest item-length,
|
|
# and radio-button width should be used for the menu width (not to
|
|
# exceed terminal width).
|
|
#
|
|
# Also, calculate the number of rows (not to exceed terminal height).
|
|
#
|
|
local longest_tag=0 longest_item=0
|
|
while [ $# -ge 2 ]; do
|
|
local tag="$1" item="$2" help="$3"
|
|
shift 3 # tag/item/status
|
|
|
|
[ ${#tag} -gt $longest_tag ] && longest_tag=${#tag}
|
|
[ ${#item} -gt $longest_item ] && longest_item=${#item}
|
|
[ $rows -lt $max_rows ] && rows=$(( $rows + 1 ))
|
|
done
|
|
|
|
# Update width
|
|
n=$(( $longest_tag + $longest_item + 13 ))
|
|
[ "$USE_XDIALOG" ] && n=$(( $n + $n / 6 )) # Add 16.6% for Xdialog(1)
|
|
if [ $n -gt $width -a $n -gt $min_width ]; then
|
|
if [ $n -lt $max_width ]; then
|
|
width=$n
|
|
else
|
|
width=$max_width
|
|
fi
|
|
fi
|
|
|
|
# Fix rows and set height
|
|
[ $rows -gt 0 ] || rows=1
|
|
if [ "$USE_XDIALOG" ]; then
|
|
height=$(( $rows + $box_height + 7 ))
|
|
else
|
|
height=$(( $rows + $box_height + 4 ))
|
|
fi
|
|
[ $height -le $max_height ] || height=$max_height
|
|
|
|
# Return all three
|
|
echo "$height $width $rows"
|
|
}
|
|
|
|
# f_dialog_calendar_size $title $backtitle $prompt [$hline]
|
|
#
|
|
# Not all versions of dialog(1) perform auto-sizing of the width and height of
|
|
# `--calendar' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, and [optionally] hline returning
|
|
# the optimal width and height for the box (not exceeding the actual terminal
|
|
# width and height).
|
|
#
|
|
# Newline character sequences (``\n'') in $prompt are expanded as-is done by
|
|
# dialog(1).
|
|
#
|
|
# Output is in the format of "height width".
|
|
#
|
|
f_dialog_calendar_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3" hline="$4" n
|
|
local size="$( f_dialog_infobox_size \
|
|
"$title" "$btitle" "$prompt" "$hline" )"
|
|
local height="${size%%[$IFS]*}"
|
|
local width="${size##*[$IFS]}"
|
|
|
|
local min_width min_height max_size
|
|
if [ "$USE_XDIALOG" ]; then
|
|
min_height=15
|
|
min_width=55
|
|
max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
else
|
|
min_height=0
|
|
min_width=40
|
|
max_size=$( stty size ) # usually "24 80"
|
|
fi
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
local max_width="${max_size##*[$IFS]}"
|
|
|
|
#
|
|
# Enforce the minimum width for displaying the calendar
|
|
#
|
|
[ $width -ge $min_width ] || width=$min_width
|
|
|
|
#
|
|
# When using dialog(1), the calendar box is unique from other dialog(1)
|
|
# boxes in-that the height passed should not accomodate the 15-lines
|
|
# required to display the calendar. This does not apply to Xdialog(1).
|
|
#
|
|
# When using Xdialog(1), the height must accomodate the 15-lines
|
|
# required to display the calendar.
|
|
#
|
|
# NOTE: Also under dialog(1), because we can't predict whether the user
|
|
# has disabled shadow's in their `$HOME/.dialogrc' file, we'll subtract
|
|
# 16 rather than 15. This does not apply to Xdialog(1).
|
|
#
|
|
max_height=$(( $max_height - 16 ))
|
|
height=$( echo "$prompt" | f_number_of_lines )
|
|
if [ "$USE_XDIALOG" ]; then
|
|
# Add height to accomodate for the embedded calendar widget
|
|
height=$(( $height + $min_height - 1 ))
|
|
|
|
# Also, bump height if backtitle is enabled
|
|
if [ "$btitle" ]; then
|
|
local n="$( echo "$btitle" | f_number_of_lines )"
|
|
height=$(( $height + $n + 2 ))
|
|
fi
|
|
else
|
|
[ "$prompt" ] && height=$(( $height + 1 ))
|
|
fi
|
|
[ $height -le $max_height ] || height=$max_height
|
|
|
|
#
|
|
# The calendar box refuses to display if too large.
|
|
#
|
|
max_width=$(( $max_width - 2 ))
|
|
[ $width -le $max_width ] || width=$max_width
|
|
|
|
# Return both
|
|
echo "$height $width"
|
|
}
|
|
|
|
# f_dialog_timebox_size $title $backtitle $prompt [$hline]
|
|
#
|
|
# Not all versions of dialog(1) perform auto-sizing of the width and height of
|
|
# `--timebox' boxes sensibly.
|
|
#
|
|
# This function helps solve this issue by taking as arguments (in order of
|
|
# appearance) the title, backtitle, prompt, and [optionally] hline returning
|
|
# the optimal width and height for the box (not exceeding the actual terminal
|
|
# width and height).
|
|
#
|
|
# Newline character sequences (``\n'') in $prompt are expanded as-is done by
|
|
# dialog(1).
|
|
#
|
|
# Output is in the format of "height width".
|
|
#
|
|
f_dialog_timebox_size()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local title="$1" btitle="$2" prompt="$3" hline="$4" n
|
|
local size="$( f_dialog_infobox_size \
|
|
"$title" "$btitle" "$prompt" "$hline" )"
|
|
local height="${size%%[$IFS]*}"
|
|
local width="${size##*[$IFS]}"
|
|
|
|
local min_width min_height max_size
|
|
if [ "$USE_XDIALOG" ]; then
|
|
min_width=40
|
|
max_size="$XDIALOG_MAXSIZE" # see CONFIGURATION
|
|
else
|
|
min_height=0
|
|
min_width=20
|
|
max_size=$( stty size ) # usually "24 80"
|
|
fi
|
|
local max_height="${max_size%%[$IFS]*}"
|
|
local max_width="${max_size##*[$IFS]}"
|
|
|
|
#
|
|
# Enforce the minimum width for displaying the timebox
|
|
#
|
|
[ $width -ge $min_width ] || width=$min_width
|
|
|
|
#
|
|
# When using dialog(1), the timebox box is unique from other dialog(1)
|
|
# boxes in-that the height passed should not accomodate the 6-lines
|
|
# required to display the timebox. This does not apply to Xdialog(1).
|
|
#
|
|
# When using Xdialog(1), the height seems to have no effect. All values
|
|
# provide the same results.
|
|
#
|
|
# NOTE: Also under dialog(1), because we can't predict whether the user
|
|
# has disabled shadow's in their `$HOME/.dialogrc' file, we'll subtract
|
|
# 7 rather than 6. This does not apply to Xdialog(1).
|
|
#
|
|
if [ "$USE_XDIALOG" ]; then
|
|
height=0 # Autosize; all values produce same results
|
|
else
|
|
max_height=$(( $max_height - 7 ))
|
|
height=$( echo "$prompt" | f_number_of_lines )
|
|
height=$(( $height + 1 ))
|
|
[ $height -le $max_height ] || height=$max_height
|
|
[ "$prompt" ] && height=$(( $height + 1 ))
|
|
fi
|
|
|
|
#
|
|
# The timebox box refuses to display if too large.
|
|
#
|
|
max_width=$(( $max_width - 2 ))
|
|
[ $width -le $max_width ] || width=$max_width
|
|
|
|
# Return both
|
|
echo "$height $width"
|
|
}
|
|
|
|
############################################################ CLEAR FUNCTIONS
|
|
|
|
# f_dialog_clear
|
|
#
|
|
# Clears any/all previous dialog(1) displays.
|
|
#
|
|
f_dialog_clear()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
$DIALOG --clear
|
|
}
|
|
|
|
############################################################ INFO FUNCTIONS
|
|
|
|
# f_dialog_info $info_text ...
|
|
#
|
|
# Throw up a dialog(1) infobox. The infobox remains until another dialog is
|
|
# displayed or `dialog --clear' (or dialog_clear) is called.
|
|
#
|
|
f_dialog_info()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local info_text="$*"
|
|
local size="$( f_dialog_infobox_size \
|
|
"$DIALOG_TITLE" \
|
|
"$DIALOG_BACKTITLE" \
|
|
"$info_text" )"
|
|
|
|
eval $DIALOG \
|
|
--title \"\$DIALOG_TITLE\" \
|
|
--backtitle \"\$DIALOG_BACKTITLE\" \
|
|
${USE_XDIALOG:+--ignore-eof} \
|
|
${USE_XDIALOG:+--no-buttons} \
|
|
--infobox \"\$info_text\" $size
|
|
}
|
|
|
|
# f_xdialog_info $info_text ...
|
|
#
|
|
# Throw up an Xdialog(1) infobox and do not dismiss it until stdin produces
|
|
# EOF. This implies that you must execute this either as an rvalue to a pipe,
|
|
# lvalue to indirection or in a sub-shell that provides data on stdin.
|
|
#
|
|
f_xdialog_info()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local info_text="$*"
|
|
local size="$( f_dialog_infobox_size \
|
|
"$DIALOG_TITLE" \
|
|
"$DIALOG_BACKTITLE" \
|
|
"$info_text" )"
|
|
|
|
eval $DIALOG \
|
|
--title \"\$DIALOG_TITLE\" \
|
|
--backtitle \"\$DIALOG_BACKTITLE\" \
|
|
--no-close --no-buttons \
|
|
--infobox \"\$info_text\" $size \
|
|
-1 # timeout of -1 means abort when EOF on stdin
|
|
}
|
|
|
|
############################################################ MSGBOX FUNCTIONS
|
|
|
|
# f_dialog_msgbox $msg_text ...
|
|
#
|
|
# Throw up a dialog(1) msgbox. The msgbox remains until the user presses ENTER
|
|
# or ESC, acknowledging the modal dialog.
|
|
#
|
|
# If the user presses ENTER, the exit status is zero (success), otherwise if
|
|
# the user presses ESC the exit status is 255.
|
|
#
|
|
f_dialog_msgbox()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local msg_text="$*"
|
|
local size="$( f_dialog_buttonbox_size \
|
|
"$DIALOG_TITLE" \
|
|
"$DIALOG_BACKTITLE" \
|
|
"$msg_text" )"
|
|
|
|
eval $DIALOG \
|
|
--title \"\$DIALOG_TITLE\" \
|
|
--backtitle \"\$DIALOG_BACKTITLE\" \
|
|
--ok-label \"\$msg_ok\" \
|
|
--msgbox \"\$msg_text\" $size
|
|
}
|
|
|
|
############################################################ YESNO FUNCTIONS
|
|
|
|
# f_dialog_yesno $msg_text ...
|
|
#
|
|
# Display a dialog(1) Yes/No prompt to allow the user to make some decision.
|
|
# The yesno prompt remains until the user presses ENTER or ESC, acknowledging
|
|
# the modal dialog.
|
|
#
|
|
# If the user chooses YES the exit status is zero, or chooses NO the exit
|
|
# status is one, or presses ESC the exit status is 255.
|
|
#
|
|
f_dialog_yesno()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local msg_text="$*"
|
|
local hline="$hline_arrows_tab_enter"
|
|
local size="$( f_dialog_buttonbox_size \
|
|
"$DIALOG_TITLE" \
|
|
"$DIALOG_BACKTITLE" \
|
|
"$msg_text" \
|
|
"$hline" )"
|
|
|
|
if [ "$USE_XDIALOG" ]; then
|
|
eval $DIALOG \
|
|
--title \"\$DIALOG_TITLE\" \
|
|
--backtitle \"\$DIALOG_BACKTITLE\" \
|
|
--hline \"\$hline\" \
|
|
--ok-label \"\$msg_yes\" \
|
|
--cancel-label \"\$msg_no\" \
|
|
--yesno \"\$msg_text\" $size
|
|
else
|
|
eval $DIALOG \
|
|
--title \"\$DIALOG_TITLE\" \
|
|
--backtitle \"\$DIALOG_BACKTITLE\" \
|
|
--hline \"\$hline\" \
|
|
--yes-label \"\$msg_yes\" \
|
|
--no-label \"\$msg_no\" \
|
|
--yesno \"\$msg_text\" $size
|
|
fi
|
|
}
|
|
|
|
# f_dialog_noyes $msg_text ...
|
|
#
|
|
# Display a dialog(1) No/Yes prompt to allow the user to make some decision.
|
|
# The noyes prompt remains until the user presses ENTER or ESC, acknowledging
|
|
# the modal dialog.
|
|
#
|
|
# If the user chooses YES the exit status is zero, or chooses NO the exit
|
|
# status is one, or presses ESC the exit status is 255.
|
|
#
|
|
# NOTE: This is just like the f_dialog_yesno function except "No" is default.
|
|
#
|
|
f_dialog_noyes()
|
|
{
|
|
[ "$DIALOG_SELF_INITIALIZE" ] && f_dialog_init
|
|
|
|
local msg_text="$*"
|
|
local hline="$hline_arrows_tab_enter"
|
|
local size="$( f_dialog_buttonbox_size \
|
|
"$DIALOG_TITLE" \
|
|
"$DIALOG_BACKTITLE" \
|
|
"$msg_text" \
|
|
"$hline" )"
|
|
|
|
if [ "$USE_XDIALOG" ]; then
|
|
eval $DIALOG \
|
|
--title \"\$DIALOG_TITLE\" \
|
|
--backtitle \"\$DIALOG_BACKTITLE\" \
|
|
--hline \"\$hline\" \
|
|
--default-no \
|
|
--ok-label \"\$msg_yes\" \
|
|
--cancel-label \"\$msg_no\" \
|
|
--yesno \"\$msg_text\" $size
|
|
else
|
|
eval $DIALOG \
|
|
--title \"\$DIALOG_TITLE\" \
|
|
--backtitle \"\$DIALOG_BACKTITLE\" \
|
|
--hline \"\$hline\" \
|
|
--defaultno \
|
|
--yes-label \"\$msg_yes\" \
|
|
--no-label \"\$msg_no\" \
|
|
--yesno \"\$msg_text\" $size
|
|
fi
|
|
}
|
|
|
|
############################################################ INPUT FUNCTIONS
|
|
|
|
# f_dialog_inputstr
|
|
#
|
|
# Obtain the inputstr entered by the user from the most recently displayed
|
|
# dialog(1) inputbox and clean up any temporary files.
|
|
#
|
|
f_dialog_inputstr()
|
|
{
|
|
# Skip warnings and trim leading/trailing whitespace from user input
|
|
eval echo \"\$DIALOG_INPUTBOX_$$\" | awk '
|
|
BEGIN { found = 0 }
|
|
{
|
|
if ( ! found )
|
|
{
|
|
if ( $0 ~ /^$/ ) next
|
|
if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next
|
|
found = 1
|
|
}
|
|
sub(/^[[:space:]]*/, "")
|
|
sub(/[[:space:]]*$/, "")
|
|
print
|
|
}
|
|
'
|
|
setvar DIALOG_INPUTBOX_$$ "" # scrub memory in case data was sensitive
|
|
return $SUCCESS
|
|
}
|
|
|
|
############################################################ MENU FUNCTIONS
|
|
|
|
# f_dialog_menutag
|
|
#
|
|
# Obtain the menutag chosen by the user from the most recently displayed
|
|
# dialog(1) menu and clean up any temporary files.
|
|
#
|
|
f_dialog_menutag()
|
|
{
|
|
# Skip warnings
|
|
eval echo \"\$DIALOG_MENU_$$\" | awk '
|
|
BEGIN { found = 0 }
|
|
{
|
|
if ( found ) # ... just spew
|
|
{
|
|
print
|
|
next
|
|
}
|
|
if ( $0 ~ /^$/ ) next
|
|
if ( $0 ~ /^Gdk-WARNING \*\*:/ ) next
|
|
found = 1
|
|
print
|
|
}
|
|
'
|
|
setvar DIALOG_MENU_$$ "" # scrub memory in case data was sensitive
|
|
return $SUCCESS
|
|
}
|
|
|
|
# f_dialog_menutag2item $tag_chosen $tag1 $item1 $tag2 $item2 ...
|
|
#
|
|
# To use the `--menu' option of dialog(1) you must pass an ordered list of
|
|
# tag/item pairs on the command-line. When the user selects a menu option the
|
|
# tag for that item is printed to stderr.
|
|
#
|
|
# This function allows you to dereference the tag chosen by the user back into
|
|
# the item associated with said tag.
|
|
#
|
|
# Pass the tag chosen by the user as the first argument, followed by the
|
|
# ordered list of tag/item pairs (HINT: use the same tag/item list as was
|
|
# passed to dialog(1) for consistency).
|
|
#
|
|
# If the tag cannot be found, NULL is returned.
|
|
#
|
|
f_dialog_menutag2item()
|
|
{
|
|
local tag="$1" tagn item
|
|
shift 1 # tag
|
|
|
|
while [ $# -gt 0 ]; do
|
|
tagn="$1"
|
|
item="$2"
|
|
shift 2 # tagn/item
|
|
|
|
if [ "$tag" = "$tagn" ]; then
|
|
echo "$item"
|
|
return $SUCCESS
|
|
fi
|
|
done
|
|
return $FAILURE
|
|
}
|
|
|
|
# f_dialog_menutag2item_with_help $tag_chosen $tag1 $item1 $help1 \
|
|
# $tag2 $item2 $help2 ...
|
|
#
|
|
# To use the `--menu' option of dialog(1) with the `--item-help' option, you
|
|
# must pass an ordered list of tag/item/help triplets on the command-line. When
|
|
# the user selects a menu option the tag for that item is printed to stderr.
|
|
#
|
|
# This function allows you to dereference the tag chosen by the user back into
|
|
# the item associated with said tag (help is discarded/ignored).
|
|
#
|
|
# Pass the tag chosen by the user as the first argument, followed by the
|
|
# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
|
|
# as was passed to dialog(1) for consistency).
|
|
#
|
|
# If the tag cannot be found, NULL is returned.
|
|
#
|
|
f_dialog_menutag2item_with_help()
|
|
{
|
|
local tag="$1" tagn item
|
|
shift 1 # tag
|
|
|
|
while [ $# -gt 0 ]; do
|
|
tagn="$1"
|
|
item="$2"
|
|
shift 3 # tagn/item/help
|
|
|
|
if [ "$tag" = "$tagn" ]; then
|
|
echo "$item"
|
|
return $SUCCESS
|
|
fi
|
|
done
|
|
return $FAILURE
|
|
}
|
|
|
|
# f_dialog_menutag2index $tag_chosen $tag1 $item1 $tag2 $item2 ...
|
|
#
|
|
# To use the `--menu' option of dialog(1) you must pass an ordered list of
|
|
# tag/item pairs on the command-line. When the user selects a menu option the
|
|
# tag for that item is printed to stderr.
|
|
#
|
|
# This function allows you to dereference the tag chosen by the user back into
|
|
# the index associated with said tag. The index is the one-based tag/item pair
|
|
# array position within the ordered list of tag/item pairs passed to dialog(1).
|
|
#
|
|
# Pass the tag chosen by the user as the first argument, followed by the
|
|
# ordered list of tag/item pairs (HINT: use the same tag/item list as was
|
|
# passed to dialog(1) for consistency).
|
|
#
|
|
# If the tag cannot be found, NULL is returned.
|
|
#
|
|
f_dialog_menutag2index()
|
|
{
|
|
local tag="$1" tagn n=1
|
|
shift 1 # tag
|
|
|
|
while [ $# -gt 0 ]; do
|
|
tagn="$1"
|
|
shift 2 # tagn/item
|
|
|
|
if [ "$tag" = "$tagn" ]; then
|
|
echo $n
|
|
return $SUCCESS
|
|
fi
|
|
n=$(( $n + 1 ))
|
|
done
|
|
return $FAILURE
|
|
}
|
|
|
|
# f_dialog_menutag2index_with_help $tag_chosen $tag1 $item1 $help1 \
|
|
# $tag2 $item2 $help2 ...
|
|
#
|
|
# To use the `--menu' option of dialog(1) with the `--item-help' option, you
|
|
# must pass an ordered list of tag/item/help triplets on the command-line. When
|
|
# the user selects a menu option the tag for that item is printed to stderr.
|
|
#
|
|
# This function allows you to dereference the tag chosen by the user back into
|
|
# the index associated with said tag. The index is the one-based tag/item/help
|
|
# triplet array position within the ordered list of tag/item/help triplets
|
|
# passed to dialog(1).
|
|
#
|
|
# Pass the tag chosen by the user as the first argument, followed by the
|
|
# ordered list of tag/item/help triplets (HINT: use the same tag/item/help list
|
|
# as was passed to dialog(1) for consistency).
|
|
#
|
|
# If the tag cannot be found, NULL is returned.
|
|
#
|
|
f_dialog_menutag2index_with_help()
|
|
{
|
|
local tag="$1" tagn n=1
|
|
shift 1 # tag
|
|
|
|
while [ $# -gt 0 ]; do
|
|
tagn="$1"
|
|
shift 3 # tagn/item/help
|
|
|
|
if [ "$tag" = "$tagn" ]; then
|
|
echo $n
|
|
return $SUCCESS
|
|
fi
|
|
n=$(( $n + 1 ))
|
|
done
|
|
return $FAILURE
|
|
}
|
|
|
|
############################################################ INIT FUNCTIONS
|
|
|
|
# f_dialog_init
|
|
#
|
|
# Initialize (or re-initialize) the dialog module after setting/changing any
|
|
# of the following environment variables:
|
|
#
|
|
# USE_XDIALOG Either NULL or Non-NULL. If given a value will indicate
|
|
# that Xdialog(1) should be used instead of dialog(1).
|
|
#
|
|
# SECURE Either NULL or Non-NULL. If given a value will indicate
|
|
# that (while running as root) sudo(8) authentication is
|
|
# required to proceed.
|
|
#
|
|
f_dialog_init()
|
|
{
|
|
DIALOG_SELF_INITIALIZE=
|
|
|
|
#
|
|
# Clone terminal stdout so we can redirect to it from within sub-shells
|
|
#
|
|
eval exec $DIALOG_TERMINAL_PASSTHRU_FD\>\&1
|
|
|
|
#
|
|
# Process stored command-line arguments
|
|
#
|
|
SECURE=$( set -- "$ARGV"
|
|
while getopts S flag > /dev/null; do
|
|
case "$flag" in
|
|
S) echo 1;;
|
|
\?) continue;;
|
|
esac
|
|
done
|
|
)
|
|
USE_XDIALOG=$( set -- "$ARGV"
|
|
while getopts SX flag > /dev/null; do
|
|
case "$flag" in
|
|
S|X) echo 1;;
|
|
\?) continue;;
|
|
esac
|
|
done
|
|
)
|
|
|
|
#
|
|
# Process `-X' command-line option
|
|
#
|
|
[ "$USE_XDIALOG" ] && DIALOG=Xdialog
|
|
|
|
#
|
|
# Sanity check, or die gracefully
|
|
#
|
|
if ! f_have $DIALOG; then
|
|
unset USE_XDIALOG
|
|
failed_dialog="$DIALOG"
|
|
DIALOG=dialog
|
|
f_die 1 "$msg_no_such_file_or_directory" "$pgm" "$failed_dialog"
|
|
fi
|
|
|
|
#
|
|
# If we're already running as root but we got there by way of sudo(8)
|
|
# and we have X11, we should merge the xauth(1) credentials from our
|
|
# original user.
|
|
#
|
|
if [ "$USE_XDIALOG" ] &&
|
|
[ "$( id -u )" = "0" ] &&
|
|
[ "$SUDO_USER" -a "$DISPLAY" ]
|
|
then
|
|
if ! f_have xauth; then
|
|
# Die gracefully, as we [likely] can't use Xdialog(1)
|
|
unset USE_XDIALOG
|
|
DIALOG=dialog
|
|
f_die 1 "$msg_no_such_file_or_directory" "$pgm" "xauth"
|
|
fi
|
|
HOSTNAME=$(hostname)
|
|
displaynum="${DISPLAY#*:}"
|
|
eval xauth -if \~$SUDO_USER/.Xauthority extract - \
|
|
\"\$HOSTNAME/unix:\$displaynum\" \
|
|
\"\$HOSTNAME:\$displaynum\" | sudo sh -c 'xauth -ivf \
|
|
~root/.Xauthority merge - > /dev/null 2>&1'
|
|
fi
|
|
|
|
#
|
|
# Probe Xdialog(1) for maximum height/width constraints, or die
|
|
# gracefully
|
|
#
|
|
if [ "$USE_XDIALOG" ]; then
|
|
if ! maxsize=$( LANG= LC_ALL= $DIALOG --print-maxsize 2>&1 )
|
|
then
|
|
# Xdialog(1) failed, fall back to dialog(1)
|
|
unset USE_XDIALOG
|
|
size=$( f_dialog_buttonbox_size "$DIALOG_TITLE" \
|
|
"$DIALOG_BACKTITLE" \
|
|
"$maxsize" "" )
|
|
eval dialog \
|
|
--title \"\$DIALOG_TITLE\" \
|
|
--backtitle \"\$DIALOG_BACKTITLE\" \
|
|
--ok-label \"\$msg_ok\" \
|
|
--msgbox \"\$maxsize\" $size
|
|
exit $FAILURE
|
|
fi
|
|
|
|
XDIALOG_MAXSIZE=$(
|
|
set -- ${maxsize##*:}
|
|
|
|
height=${1%,}
|
|
width=$2
|
|
|
|
echo $height $width
|
|
)
|
|
unset maxsize
|
|
fi
|
|
|
|
#
|
|
# If using Xdialog(1), swap DIALOG_TITLE with DIALOG_BACKTITLE.
|
|
# The reason for this is because many dialog(1) applications use
|
|
# --backtitle for the program name (which is better suited as
|
|
# --title with Xdialog(1)).
|
|
#
|
|
if [ "$USE_XDIALOG" ]; then
|
|
_DIALOG_TITLE="$DIALOG_TITLE"
|
|
DIALOG_TITLE="$DIALOG_BACKTITLE"
|
|
DIALOG_BACKTITLE="$_DIALOG_TITLE"
|
|
unset _DIALOG_TITLE
|
|
fi
|
|
}
|
|
|
|
fi # ! $_DIALOG_SUBR
|