]> git.tuebingen.mpg.de Git - gsu.git/blob - gui
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 }