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