Implements all new widgets and adds extensive error checking

This commit is contained in:
David Kramer 2018-06-19 22:07:58 -06:00
parent 65ce53b8af
commit 82542a6d1a

View File

@ -1,55 +1,254 @@
#!/data/data/com.termux/files/usr/bin/sh
#!/data/data/com.termux/files/usr/bin/bash
set -e -u
DEFAULT_WIDGET="text"
SCRIPTNAME=termux-dialog
show_usage () {
echo "Usage: $SCRIPTNAME [-i hint] [-m] [-p] [-t title] [-w widget]"
echo "Show a text entry dialog."
echo " -i hint the input hint to show when the input is empty"
echo " -m use a textarea with multiple lines instead of a single"
echo " -p enter the input as a password"
echo " -t title the title to show for the input prompt"
echo " -w widget widget type to use: confirm, text, date, time, spinner, or speech"
echo " -v values [,,,] values to use w/ spinner widget"
show_usage() {
echo "Usage: $SCRIPTNAME widget [options]"
echo "Get user input w/ different widgets! Default Widget: $DEFAULT_WIDGET"
echo " -h, help Show this help"
echo " -l, list Full list all available widgets and their options"
echo " -t, title Set title of input dialog"
exit 0
}
PARAMS=""
declare -a widgets=("confirm" "checkbox" "counter" "date" "radio" "sheet" "spinner" "text" "time")
# Descriptions for various options that multiple widgets can use
OPT_HINT_DESC="[-i hint] text hint (optional)"
OPT_MULTI_LINE_DESC="[-m multi-line] use a textarea with multiple lines instead of single (optional)"
OPT_PASS_DESC="[-p password] enter input as password (optional)"
OPT_TITLE_DESC="[-t title] dialog title (optional)"
OPT_RANGE_DESC="[-r range] min,max,start where each value is a number (optional)"
OPT_VALUES_DESC="[-v values] comma delimited string of values to use (required)"
# Widget hints
ARG_I=""
OPT_I=""
# Text widget multiline
ARG_M=""
# Counter range
ARG_R=""
OPT_R=""
# Text widget input as password
ARG_P=""
# Dialog title (supported by all widgets)
ARG_T=""
OPT_T=""
# Values for list-type widgets
OPT_V=""
ARG_V=""
# Use default values to preserve backwards compatibility w/ older dialog implementation
OPT_W="text"
# Widget type
ARG_W=""
WIDGET=""
# Flags for detecting invalid option combinations
HINT_FLAG=1
MULTI_LINE_FLAG=2
PASS_FLAG=4
RANGE_FLAG=8
VALUES_FLAG=16
FLAGS=0
# Show usage help for specific widget
widget_usage () {
echo -n -e "$1 \t"
case "$1" in
"confirm")
echo -e "Show confirmation dialog"
echo -e "\t\t$OPT_TITLE_DESC"
echo -e "\t\t$OPT_HINT_DESC"
;;
"checkbox")
echo -e "Select multiple values using checkboxes"
echo -e "\t\t$OPT_VALUES_DESC"
echo -e "\t\t$OPT_TITLE_DESC"
;;
"counter")
echo -e "Pick a number in specified range"
echo -e "\t\t$OPT_TITLE_DESC"
echo -e "\t\t$OPT_RANGE_DESC"
;;
"date")
echo -e "\tPick a date"
echo -e "\t\t$OPT_TITLE_DESC"
;;
"radio")
echo -e "\tPick a single value from radio buttons"
echo -e "\t\t$OPT_VALUES_DESC"
echo -e "\t\t$OPT_TITLE_DESC"
;;
"sheet")
echo -e "\tPick a value from a sliding bottom sheet interface"
echo -e "\t\t$OPT_VALUES_DESC"
echo -e "\t\t$OPT_TITLE_DESC"
;;
"spinner")
echo -e "Pick a single value from a dropdown spinner"
echo -e "\t\t$OPT_VALUES_DESC"
echo -e "\t\t$OPT_TITLE_DESC"
;;
"text")
echo -e "\tInput text (default if no widget specified)"
echo -e "\t\t$OPT_HINT_DESC"
echo -e "\t\t$OPT_PASS_DESC -- cannot use with -m"
echo -e "\t\t$OPT_TITLE_DESC"
echo -e "\t\t$OPT_MULTI_LINE_DESC -- cannot use with -p"
;;
"time")
echo -e "\tPick a time value"
echo -e "\t\t[-p title] dialog title (optional)"
;;
*)
echo -e "\tUnknown usage for '$1'"
;;
esac
}
# List all widgets
list_widgets() {
echo "Supported widgets:"
echo
for w in "${widgets[@]}"; do
widget_usage $w
echo
done
}
# Checks to see if widgets array contains specified widget
has_widget () {
for w in "${widgets[@]}"; do
[ "$w" == "$1" ] && return 0
done
return 1
}
set_flag () {
FLAGS=$((FLAGS | $1));
}
# Convenience method to get all supported options, regardless of specified widget
# NOTE: Option combination validation doesn't occur here
parse_options() {
while getopts :hlmpr:i:t:v: option
do
case "$option" in
h) show_usage ;;
l) list_widgets; exit 0;;
i) ARG_I="--es input_hint"; OPT_I="$OPTARG"; set_flag $HINT_FLAG; ;;
m) ARG_M="--ez multiple_lines true"; set_flag $MULTI_LINE_FLAG; ;;
p) ARG_P="--es input_type password"; set_flag $PASS_FLAG; ;;
t) ARG_T="--es input_title"; OPT_T="$OPTARG" ;;
v) ARG_V="--es input_values"; OPT_V="$OPTARG"; set_flag $VALUES_FLAG; ;;
r) ARG_R="--eia input_range"; OPT_R=$OPTARG; set_flag $RANGE_FLAG; ;;
?) echo "$SCRIPTNAME: illegal option -$OPTARG"; exit 1;
esac
done
}
options_error () {
echo -e "ERROR: Invalid option(s) detected for '$1'\n"
echo "Usage '$1'"
widget_usage $1
exit 1
}
if [ $# -eq 0 ]; then
WIDGET=$DEFAULT_WIDGET
# First argument wasn't a widget
elif ! has_widget $1; then
# we didn't receive a widget as an argument, check to see if we
# at least options (even if they're illegal)
if ! [[ $1 =~ -[a-z] ]]; then
echo -e "ERROR: Illegal argument $1\n"
show_usage
fi
WIDGET=$DEFAULT_WIDGET
else
WIDGET=$1
shift
fi
parse_options "$@"
shift $((OPTIND - 1))
# Ensure proper option combinations for the specific type of widget
case "$WIDGET" in
# Text (default) if no widget specified
"text")
if [ $((FLAGS & (RANGE_FLAG | VALUES_FLAG))) -ne 0 ]; then
options_error $WIDGET
fi
if [ $((FLAGS & MULTI_LINE_FLAG)) -ne 0 ] && [ $((FLAGS & PASS_FLAG)) -ne 0 ]; then
options_error $WIDGET
fi
;;
"confirm")
if [ $((FLAGS & (MULTI_LINE_FLAG | PASS_FLAG | RANGE_FLAG | VALUES_FLAG))) -ne 0 ]; then
options_error $WIDGET
fi
;;
"counter")
if [ $((FLAGS & (MULTI_LINE_FLAG | PASS_FLAG | VALUES_FLAG))) -ne 0 ]; then
options_error $WIDGET
fi
;;
"date" | "speech" | "time")
if [ $# -gt 0 ]; then
echo "ERROR: '$WIDGET' takes no arguments"; exit 1;
fi
if [ $((FLAGS & (HINT_FLAG | MULTI_LINE_FLAG | PASS_FLAG | RANGE_FLAG | VALUES_FLAG))) -ne 0 ]; then
options_error $WIDGET
fi
;;
"checkbox" | "radio" | "sheet" | "spinner")
if [ "$ARG_V" == "" ]; then
echo "ERROR: '$WIDGET' must be called with $OPT_VALUES_DESC"
exit 1
fi
if [ $((FLAGS & (HINT_FLAG | MULTI_LINE_FLAG | PASS_FLAG | RANGE_FLAG))) -ne 0 ]; then
options_error $WIDGET
fi
;;
*)
echo "$SCRIPTNAME: unsupported widget '$WIDGET'"; show_usage ;;
esac
# All valid args should be consumed by this point
if [ $# -gt 0 ]; then
echo "ERROR: Too many arguments!"
show_usage
fi
ARG_W="--es input_method"
while getopts :hi:mpt:v:w: option
do
case "$option" in
h) show_usage;;
i) ARG_I="--es input_hint"; OPT_I="$OPTARG";;
m) ARG_M="--ez multiple_lines true";;
p) ARG_P="--es input_type password";;
t) ARG_T="--es input_title"; OPT_T="$OPTARG";;
w) ARG_W="--es input_method"; OPT_W="$OPTARG";;
v) ARG_V="--es input_values"; OPT_V="$OPTARG";;
?) echo "$SCRIPTNAME: illegal option -$OPTARG"; exit 1;
esac
done
shift $(($OPTIND-1))
# if [ $# != 0 ]; then echo "$SCRIPTNAME: too many arguments"; exit 1; fi
set -- $ARG_M $ARG_P
# Set options, ensuring whitespace isn't lost
if [ -n "$ARG_W" ]; then set -- "$@" $ARG_W "$WIDGET"; fi
if [ -n "$ARG_I" ]; then set -- "$@" $ARG_I "$OPT_I"; fi
if [ -n "$ARG_T" ]; then set -- "$@" $ARG_T "$OPT_T"; fi
if [ -n "$ARG_R" ]; then set -- "$@" $ARG_R "$OPT_R"; fi
if [ -n "$ARG_V" ]; then set -- "$@" $ARG_V "$OPT_V"; fi
if [ -n "$ARG_W" ]; then set -- "$@" $ARG_W "$OPT_W"; fi
if [ -n "$ARG_M" ]; then set -- "$@" $ARG_M ""; fi
if [ -n "$ARG_P" ]; then set -- "$@" $ARG_P ""; fi
/data/data/com.termux/files/usr/libexec/termux-api Dialog "$@"