Merge branch 't/arithmetic_eval'
[gsu.git] / gui
1 #!/bin/bash
2
3 if [[ $(type -t gsu_is_a_number) != "function" ]]; then
4 GSU_DIR=${GSU_DIR:=${HOME:-}/.gsu}
5 . $GSU_DIR/common || exit 1
6 fi
7
8 export GSU_NODE_NAME_PATTERN='[a-zA-Z_]'
9
10 _get_geometry()
11 {
12 local x y
13 result="$(stty size)"
14 if (($? != 0)); then
15 gsu_msg "fatal: could not get terminal geometry"
16 exit 1
17 fi
18 x="${result#* }"
19 y="${result%% *}"
20 (($x > 190)) && x=190
21 result="$y $x"
22 }
23
24 gsu_infobox()
25 {
26 _get_geometry
27 dialog --infobox "$1" $result
28 }
29
30 gsu_checklist_all_on()
31 {
32 local header="$1"
33 local items="$2"
34 local i state opts num=0
35
36 _get_geometry
37 ops="$result 16"
38 for i in $items; do
39 let num++
40 opts+=" $i $num on"
41 done
42 result=$(dialog --checklist "$header" $opts 3>&1 1>&2 2>&3 3>&-)
43 ret="$?"
44 }
45
46 gsu_radiolist()
47 {
48 local header="$1"
49 local selected_item="$2"
50 local items="$3"
51 local i state ops num=0
52
53 _get_geometry
54 ops="$result 16"
55 for i in $items; do
56 let num++
57 if [[ "$i" == "$selected_item" ]]; then
58 state="on"
59 else
60 state="off"
61 fi
62 ops+=" $i $num $state"
63 done
64 result=$(dialog --radiolist "$header" $ops 3>&1 1>&2 2>&3 3>&-)
65 ret="$?"
66 }
67
68 gsu_inputbox()
69 {
70 local g text="$1" init="$2"
71
72 _get_geometry
73 g="$result"
74 result="$(dialog --inputbox "$text" $g "$init" 3>&1 1>&2 2>&3 3>&-)"
75 ret="$?"
76 }
77
78 gsu_textbox()
79 {
80 local file="$1"
81
82 _get_geometry
83 dialog --textbox "$file" $result
84 }
85
86 # dialog segfaults if message is too long. Hence we always use a temporary file
87 gsu_msgbox()
88 {
89 local tmp="$(mktemp gsu_msgbox.XXXXXXXXXX)"
90
91 if (($? != 0)); then
92 dialog --msgbox "mktemp error" 0 0
93 return
94 fi
95 echo "$1" > "$tmp"
96 gsu_textbox "$tmp"
97 rm -f "$tmp"
98 }
99
100 gsu_cmd_output_box()
101 {
102 local tmp="$(mktemp)"
103
104 if (($? != 0)); then
105 dialog --msgbox "mktemp error" 0 0
106 return
107 fi
108 $@ > "$tmp" 2>&1
109 echo "exit code: $?" >> "$tmp"
110 gsu_textbox "$tmp"
111 rm -f "$tmp"
112 }
113
114 gsu_yesno()
115 {
116 local text="$1"
117
118 _get_geometry
119 dialog --yesno "$text" $result
120 ret=$?
121 if (($ret == 0)); then
122 result="yes"
123 elif (($ret == 1)); then
124 result="no"
125 else
126 result=
127 fi
128 }
129
130 gsu_menu()
131 {
132 local header="${1:-root}"
133 local items="$2"
134 local i state opts num=0
135
136 _get_geometry
137 opts="$result 16"
138 for i in $items; do
139 let num++
140 opts+=" $i $num"
141 done
142 result="$(dialog --menu "$gsu_banner_txt ($header)" $opts 3>&1 1>&2 2>&3 3>&-)"
143 ret="$?"
144 }
145
146 _get_level()
147 {
148 local tmp="${1%%$GSU_NODE_NAME_PATTERN*}"
149 result="${#tmp}"
150 }
151
152 _get_subtree()
153 {
154 local tree="$1" root="${2%/}"
155 local TAB=' '
156
157 first="$(grep -n "$TAB\{1,\}$root/" <<< "$tree")"
158 [[ -z "$first" ]] && return
159
160 line_num="${first%%:*}"
161 _get_level "${first#*:}"
162 level="$result"
163
164 #echo "line: $line_num, root: $root, indent level: $level"
165 result="$(sed -e "1,${line_num}d;" <<< "$tree" \
166 | sed -e "/^$TAB\{1,$level\}$GSU_NODE_NAME_PATTERN/,\$d" \
167 | sed -e "/^$TAB\{$(($level + 2))\}/d")"
168 ret="$level"
169 }
170
171 _get_root_nodes()
172 {
173 local tree="$1" TAB=' '
174
175 result="$(grep "^${TAB}${GSU_NODE_NAME_PATTERN}" <<< "$tree")"
176 }
177
178 _browse()
179 {
180 local header="$1" old_header
181 local tree="$2" subtree="$3"
182
183 while :; do
184 gsu_menu "$header" "$subtree"
185 (($ret != 0)) && return
186 [[ -z "$result" ]] && return
187 if [[ "${result%/}" != "$result" ]]; then
188 old_header="$header"
189 header="$result"
190 _get_subtree "$tree" "$header"
191 _browse "$header" "$tree" "$result"
192 header="$old_header"
193 continue
194 fi
195 eval ${gsu_name}_$result
196 done
197 }
198
199 gsu_gui()
200 {
201 local tree="$1" subtree
202
203 _gsu_setup
204 type -t dialog &> /dev/null
205 if (($? != 0)); then
206 gsu_msg "dialog executable not found"
207 exit 1
208 fi
209 _get_root_nodes "$tree"
210 subtree="$result"
211 _browse "main menu" "$tree" "$subtree"
212 }