gui: Add documentation of public functions.
[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 # Open a dialog box which asks the user to input a text
26 #
27 # Usage: gsu_input_box <text> <init>
28 #
29 # <text> is displayed above of the input field, which is is preset to <init>.
30 # The entered text is returned in $result. On success (user pressed OK)
31 # the function returns zero. If the user selected Cancel, the return value is
32 # one. On dialog errors, a negative error code is returned.
33 gsu_inputbox()
34 {
35 local g text="$1" init="$2"
36
37 _get_geometry
38 g="$result"
39 result="$(dialog --inputbox "$text" $g "$init" 3>&1 1>&2 2>&3 3>&-)"
40 if (($? != 0)); then
41 ret=-$E_GSU_DIALOG
42 result='inputbox'
43 return
44 fi
45 ret=$GSU_SUCCESS
46 }
47
48 # Show the given file in a text box
49 #
50 # Usage: gsu_textbox <path>
51 #
52 # The box has an OK button which closes the box when activated.
53 gsu_textbox()
54 {
55 local g file="$1"
56
57 _get_geometry
58 g="$result"
59
60 ret=-$E_GSU_DIALOG
61 result='textbox'
62 dialog --textbox "$file" $g || return
63 ret=$GSU_SUCCESS
64 }
65
66 # Show a message in a text box
67 #
68 # Usage: gsu_msgbox <text>
69 #
70 # This is like gsu_textbox() but the text is passed as a string.
71 gsu_msgbox()
72 {
73 # Some versions of dialog segfault if the text is too long. Hence we
74 # always use a temporary file.
75 local tmp="$(mktemp gsu_msgbox.XXXXXXXXXX)"
76
77 if (($? != 0)); then
78 ret=-$E_GSU_MKTEMP
79 result='temp file for textbox'
80 return
81 fi
82 echo "$1" > "$tmp"
83 gsu_textbox "$tmp"
84 rm -f "$tmp" # ignore errors
85 }
86
87 _gsu_menu()
88 {
89 local header="${1:-root}"
90 local items="$2"
91 local i state opts num=0
92
93 _get_geometry
94 opts="$result 16"
95 for i in $items; do
96 let num++
97 opts+=" $i $num"
98 done
99 result="$(dialog --menu "$gsu_banner_txt ($header)" $opts 3>&1 1>&2 2>&3 3>&-)"
100 case $? in
101 0) ret=$GSU_SUCCESS;;
102 1) ret=1;; # cancelled
103 *)
104 result="menu error $ret"
105 ret=-$E_GSU_DIALOG
106 esac
107 }
108
109 _get_level()
110 {
111 local tmp="${1%%$_gsu_node_name_pattern*}"
112 result="${#tmp}"
113 }
114
115 _get_subtree()
116 {
117 local tree="$1" root="${2%/}"
118 local first TAB=' '
119
120 ret=-$E_GSU_MENU_TREE
121 result="subtree grep failed"
122 first="$(grep -n "$TAB\{1,\}$root/" <<< "$tree")" || return
123 [[ -z "$first" ]] && return
124
125 line_num="${first%%:*}"
126 _get_level "${first#*:}"
127 level="$result"
128
129 #echo "line: $line_num, root: $root, indent level: $level"
130 result="$(sed -e "1,${line_num}d;" <<< "$tree" \
131 | sed -e "/^$TAB\{1,$level\}$_gsu_node_name_pattern/,\$d" \
132 | sed -e "/^$TAB\{$(($level + 2))\}/d")"
133 if (($? != 0)); then
134 ret=-$E_GSU_MENU_TREE
135 result="sed command for subtree $root failed"
136 return
137 fi
138 ret=$GSU_SUCCESS
139 }
140
141 _get_root_nodes()
142 {
143 local tree="$1" TAB=' '
144
145 result="$(grep "^${TAB}${_gsu_node_name_pattern}" <<< "$tree")"
146 if (($? != 0)); then
147 ret=-$E_GSU_MENU_TREE
148 result="root node grep failed"
149 return
150 fi
151 ret=$GSU_SUCCESS
152 }
153
154 _browse()
155 {
156 local header="$1" old_header
157 local tree="$2" subtree="$3"
158
159 while :; do
160 _gsu_menu "$header" "$subtree"
161 (($ret < 0)) && return
162 [[ -z "$result" ]] && return # menu was cancelled
163 if [[ "${result%/}" != "$result" ]]; then
164 old_header="$header"
165 header="$result"
166 _get_subtree "$tree" "$header"
167 (($ret < 0)) && return
168 _browse "$header" "$tree" "$result"
169 (($ret < 0)) && return
170 header="$old_header"
171 continue
172 fi
173 eval ${gsu_name}_$result
174 done
175 }
176
177 gsu_gui()
178 {
179 local tree="$1" subtree
180
181 type -t dialog &> /dev/null
182 if (($? != 0)); then
183 gsu_msg "dialog executable not found"
184 exit 1
185 fi
186 _get_root_nodes "$tree"
187 subtree="$result"
188 _browse "main menu" "$tree" "$subtree"
189 }