gui: Conform to $ret and $result conventions.
[gsu.git] / gui
1 #!/bin/bash
2
3 if [[ "$(type -t _gsu_setup)" != "function" ]]; then
4 gsu_dir=${gsu_dir:-${BASH_SOURCE[0]%/*}}
5 . $gsu_dir/common || exit 1
6 _gsu_setup
7 fi
8
9 _gsu_node_name_pattern='[a-zA-Z_]'
10
11 _get_geometry()
12 {
13 local x y
14 result="$(stty size)"
15 if (($? != 0)); then
16 gsu_msg "fatal: could not get terminal geometry"
17 exit 1
18 fi
19 x="${result#* }"
20 y="${result%% *}"
21 (($x > 190)) && x=190
22 result="$y $x"
23 }
24
25 gsu_inputbox()
26 {
27 local g text="$1" init="$2"
28
29 _get_geometry
30 g="$result"
31 result="$(dialog --inputbox "$text" $g "$init" 3>&1 1>&2 2>&3 3>&-)"
32 if (($? != 0)); then
33 ret=-$E_GSU_DIALOG
34 result='inputbox'
35 return
36 fi
37 ret=$GSU_SUCCESS
38 }
39
40 gsu_textbox()
41 {
42 local g file="$1"
43
44 _get_geometry
45 g="$result"
46
47 ret=-$E_GSU_DIALOG
48 result='textbox'
49 dialog --textbox "$file" $g || return
50 ret=$GSU_SUCCESS
51 }
52
53 # dialog segfaults if message is too long. Hence we always use a temporary file
54 gsu_msgbox()
55 {
56 local tmp="$(mktemp gsu_msgbox.XXXXXXXXXX)"
57
58 if (($? != 0)); then
59 ret=-$E_GSU_MKTEMP
60 result='temp file for textbox'
61 return
62 fi
63 echo "$1" > "$tmp"
64 gsu_textbox "$tmp"
65 rm -f "$tmp" # ignore errors
66 }
67
68 _gsu_menu()
69 {
70 local header="${1:-root}"
71 local items="$2"
72 local i state opts num=0
73
74 _get_geometry
75 opts="$result 16"
76 for i in $items; do
77 let num++
78 opts+=" $i $num"
79 done
80 result="$(dialog --menu "$gsu_banner_txt ($header)" $opts 3>&1 1>&2 2>&3 3>&-)"
81 case $? in
82 0) ret=$GSU_SUCCESS;;
83 1) ret=1;; # cancelled
84 *)
85 result="menu error $ret"
86 ret=-$E_GSU_DIALOG
87 esac
88 }
89
90 _get_level()
91 {
92 local tmp="${1%%$_gsu_node_name_pattern*}"
93 result="${#tmp}"
94 }
95
96 _get_subtree()
97 {
98 local tree="$1" root="${2%/}"
99 local first TAB=' '
100
101 ret=-$E_GSU_MENU_TREE
102 result="subtree grep failed"
103 first="$(grep -n "$TAB\{1,\}$root/" <<< "$tree")" || return
104 [[ -z "$first" ]] && return
105
106 line_num="${first%%:*}"
107 _get_level "${first#*:}"
108 level="$result"
109
110 #echo "line: $line_num, root: $root, indent level: $level"
111 result="$(sed -e "1,${line_num}d;" <<< "$tree" \
112 | sed -e "/^$TAB\{1,$level\}$_gsu_node_name_pattern/,\$d" \
113 | sed -e "/^$TAB\{$(($level + 2))\}/d")"
114 if (($? != 0)); then
115 ret=-$E_GSU_MENU_TREE
116 result="sed command for subtree $root failed"
117 return
118 fi
119 ret=$GSU_SUCCESS
120 }
121
122 _get_root_nodes()
123 {
124 local tree="$1" TAB=' '
125
126 result="$(grep "^${TAB}${_gsu_node_name_pattern}" <<< "$tree")"
127 if (($? != 0)); then
128 ret=-$E_GSU_MENU_TREE
129 result="root node grep failed"
130 return
131 fi
132 ret=$GSU_SUCCESS
133 }
134
135 _browse()
136 {
137 local header="$1" old_header
138 local tree="$2" subtree="$3"
139
140 while :; do
141 _gsu_menu "$header" "$subtree"
142 (($ret < 0)) && return
143 [[ -z "$result" ]] && return # menu was cancelled
144 if [[ "${result%/}" != "$result" ]]; then
145 old_header="$header"
146 header="$result"
147 _get_subtree "$tree" "$header"
148 (($ret < 0)) && return
149 _browse "$header" "$tree" "$result"
150 (($ret < 0)) && return
151 header="$old_header"
152 continue
153 fi
154 eval ${gsu_name}_$result
155 done
156 }
157
158 gsu_gui()
159 {
160 local tree="$1" subtree
161
162 type -t dialog &> /dev/null
163 if (($? != 0)); then
164 gsu_msg "dialog executable not found"
165 exit 1
166 fi
167 _get_root_nodes "$tree"
168 subtree="$result"
169 _browse "main menu" "$tree" "$subtree"
170 }