X-Git-Url: http://git.tuebingen.mpg.de/?p=gsu.git;a=blobdiff_plain;f=gui;h=42975647e6900bb67c900c8108cc9925e4022739;hp=eb9f29f37c9e1d7aef03c96f08b4838285931f1a;hb=refs%2Fheads%2Fpu;hpb=f31cc416b1acdbb8f5703b208d943ce500a5b840 diff --git a/gui b/gui index eb9f29f..83da0cd 100644 --- a/gui +++ b/gui @@ -1,11 +1,14 @@ #!/bin/bash +# Copyright (C) 2006 Andre Noll +# Licensed under the LGPL, version 3. See COPYING and COPYING.LESSER. -if [[ $(type -t gsu_is_a_number) != "function" ]]; then - GSU_DIR=${GSU_DIR:=${HOME:-}/.gsu} - . $GSU_DIR/common || exit 1 +if [[ "$(type -t _gsu_setup)" != "function" ]]; then + gsu_dir=${gsu_dir:-${BASH_SOURCE[0]%/*}} + . "$gsu_dir/common" || exit 1 + _gsu_setup fi -export GSU_NODE_NAME_PATTERN='[a-zA-Z_]' +_gsu_node_name_pattern='[a-zA-Z_]' _get_geometry() { @@ -17,54 +20,31 @@ _get_geometry() fi x="${result#* }" y="${result%% *}" - (($x > 190)) && x=190 + ((x > 190)) && x=190 result="$y $x" } -gsu_infobox() -{ - _get_geometry - dialog --infobox "$1" $result -} - -gsu_checklist_all_on() -{ - local header="$1" - local items="$2" - local i state opts num=0 - - _get_geometry - ops="$result 16" - for i in $items; do - let num++ - opts+=" $i $num on" - done - result=$(dialog --checklist "$header" $opts 3>&1 1>&2 2>&3 3>&-) - ret="$?" -} - -gsu_radiolist() +_set_dialog_ret() { - local header="$1" - local selected_item="$2" - local items="$3" - local i state ops num=0 - - _get_geometry - ops="$result 16" - for i in $items; do - let num++ - if [[ "$i" == "$selected_item" ]]; then - state="on" - else - state="off" - fi - ops+=" $i $num $state" - done - result=$(dialog --radiolist "$header" $ops 3>&1 1>&2 2>&3 3>&-) - ret="$?" + local ec="$1" + + case "$ec" in + 0) ret=$GSU_SUCCESS;; + 1|255) ret=1;; # cancelled + *) + result="dialog exit code $ec" + ret=-$E_GSU_DIALOG + esac } +# Open a dialog box which asks the user to input a text +# +# Usage: gsu_input_box +# +# is displayed above of the input field, which is is preset to . +# The entered text is returned in $result. On success (user pressed OK) +# the function returns zero. If the user selected Cancel, the return value is +# one. On dialog errors, a negative error code is returned. gsu_inputbox() { local g text="$1" init="$2" @@ -72,89 +52,76 @@ gsu_inputbox() _get_geometry g="$result" result="$(dialog --inputbox "$text" $g "$init" 3>&1 1>&2 2>&3 3>&-)" - ret="$?" + _set_dialog_ret $? } +# Show the given file in a text box +# +# Usage: gsu_textbox +# +# The box has an OK button which closes the box when activated. gsu_textbox() { - local file="$1" + local g file="$1" _get_geometry - dialog --textbox "$file" $result + g="$result" + + ret=-$E_GSU_DIALOG + result='textbox' + dialog --textbox "$file" $g + _set_dialog_ret $? } -# dialog segfaults if message is too long. Hence we always use a temporary file +# Show a message in a text box +# +# Usage: gsu_msgbox +# +# This is like gsu_textbox() but the text is passed as a string. gsu_msgbox() { - local tmp="$(mktemp gsu_msgbox.XXXXXXXXXX)" - - if (($? != 0)); then - dialog --msgbox "mktemp error" 0 0 - return - fi + local tmp + + # Some versions of dialog segfault if the text is too long. Hence we + # always use a temporary file. + gsu_make_tempfile 'gsu_msgbox.XXXXXXXXXX' + ((ret < 0)) && return + tmp="$result" + trap "rm -f $tmp" EXIT echo "$1" > "$tmp" gsu_textbox "$tmp" - rm -f "$tmp" + rm -f "$tmp" # ignore errors } -gsu_cmd_output_box() +_gsu_menu() { - local tmp="$(mktemp)" - - if (($? != 0)); then - dialog --msgbox "mktemp error" 0 0 - return - fi - $@ > "$tmp" 2>&1 - echo "exit code: $?" >> "$tmp" - gsu_textbox "$tmp" - rm -f "$tmp" -} - -gsu_yesno() -{ - local text="$1" + local header=$1 dflt_item=$2 + local geom + shift 2 _get_geometry - dialog --yesno "$text" $result - ret=$? - if (($ret == 0)); then - result="yes" - elif (($ret == 1)); then - result="no" - else - result= - fi -} - -gsu_menu() -{ - local header="${1:-root}" - local items="$2" - local i state opts num=0 - - _get_geometry - opts="$result 16" - for i in $items; do - let num++ - opts+=" $i $num" - done - result="$(dialog --menu "$gsu_banner_txt ($header)" $opts 3>&1 1>&2 2>&3 3>&-)" - ret="$?" + geom=$result + result="$(dialog --no-lines --no-items \ + --default-item "$dflt_item" \ + --menu "$gsu_banner_txt"$'\n'"Current location: $header" \ + $geom 16 "$@" 3>&1 1>&2 2>&3 3>&-)" + _set_dialog_ret $? } _get_level() { - local tmp="${1%%$GSU_NODE_NAME_PATTERN*}" + local tmp="${1%%$_gsu_node_name_pattern*}" result="${#tmp}" } _get_subtree() { local tree="$1" root="${2%/}" - local TAB=' ' + local first TAB=' ' - first="$(grep -n "$TAB\{1,\}$root/" <<< "$tree")" + ret=-$E_GSU_MENU_TREE + result="subtree grep failed" + first="$(grep -n "$TAB\{1,\}$root/" <<< "$tree")" || return [[ -z "$first" ]] && return line_num="${first%%:*}" @@ -163,36 +130,71 @@ _get_subtree() #echo "line: $line_num, root: $root, indent level: $level" result="$(sed -e "1,${line_num}d;" <<< "$tree" \ - | sed -e "/^$TAB\{1,$level\}$GSU_NODE_NAME_PATTERN/,\$d" \ - | sed -e "/^$TAB\{$(($level + 2))\}/d")" - ret="$level" + | sed -e "/^$TAB\{1,$level\}$_gsu_node_name_pattern/,\$d" \ + | sed -e "/^$TAB\{$((level + 2))\}/d")" + if (($? != 0)); then + ret=-$E_GSU_MENU_TREE + result="sed command for subtree $root failed" + return + fi + ret=$GSU_SUCCESS } _get_root_nodes() { local tree="$1" TAB=' ' - result="$(grep "^${TAB}${GSU_NODE_NAME_PATTERN}" <<< "$tree")" + result="$(grep "^${TAB}${_gsu_node_name_pattern}" <<< "$tree")" + if (($? != 0)); then + ret=-$E_GSU_MENU_TREE + result="root node grep failed" + return + fi + ret=$GSU_SUCCESS } _browse() { - local header="$1" old_header - local tree="$2" subtree="$3" - + local root_item=$1 tree=$2 subtree=$3 + local -a items arr + local -A ids + local old_root dflt_item + local item id OIFS + local -i i=0 + + while read -a arr; do + ((${#arr[@]} == 0)) && continue + id=${arr[0]} + if ((${#arr[@]} > 1)); then + unset arr[0]; + item=${arr[*]} + if [[ "${id:$((${#id} - 1)):1}" == '/' ]]; then + item+=/ + else + item="• $item" + fi + else + item=$id + fi + items[$i]=$item + ids["$item"]=$id + let i++ + done <<< "$subtree" + dflt_item=${items[0]} while :; do - gsu_menu "$header" "$subtree" - (($ret != 0)) && return - [[ -z "$result" ]] && return - if [[ "${result%/}" != "$result" ]]; then - old_header="$header" - header="$result" - _get_subtree "$tree" "$header" - _browse "$header" "$tree" "$result" - header="$old_header" + _gsu_menu "$root_item" "$dflt_item" "${items[@]}" + ((ret < 0)) && return + [[ -z "$result" ]] && return # menu was cancelled + dflt_item=$result + id=${ids["$result"]} + if [[ "${id:$((${#id} - 1)):1}" == '/' ]]; then + _get_subtree "$tree" "$id" + ((ret < 0)) && return + _browse "${dflt_item%/}" "$tree" "$result" + ((ret < 0)) && return continue fi - eval ${gsu_name}_$result + eval ${gsu_name}_${id} done } @@ -200,7 +202,6 @@ gsu_gui() { local tree="$1" subtree - _gsu_setup type -t dialog &> /dev/null if (($? != 0)); then gsu_msg "dialog executable not found" @@ -208,5 +209,5 @@ gsu_gui() fi _get_root_nodes "$tree" subtree="$result" - _browse "main menu" "$tree" "$subtree" + _browse 'Main menu' "$tree" "$subtree" }