Add gsu_make_tempfile() and fix bug in gui module.
[gsu.git] / gui
diff --git a/gui b/gui
index 72717a1ecd30750990073c86ceb47bc8f65604e6..34f732e27bacc9646710efb0c11eef09659a2ce4 100644 (file)
--- a/gui
+++ b/gui
@@ -1,4 +1,6 @@
 #!/bin/bash
+# Copyright (C) 2006 Andre Noll
+# Licensed under the LGPL, version 3. See COPYING and COPYING.LESSER.
 
 if [[ "$(type -t _gsu_setup)" != "function" ]]; then
        gsu_dir=${gsu_dir:-${BASH_SOURCE[0]%/*}}
@@ -6,7 +8,7 @@ if [[ "$(type -t _gsu_setup)" != "function" ]]; then
        _gsu_setup
 fi
 
-export GSU_NODE_NAME_PATTERN='[a-zA-Z_]'
+_gsu_node_name_pattern='[a-zA-Z_]'
 
 _get_geometry()
 {
@@ -22,50 +24,27 @@ _get_geometry()
        result="$y $x"
 }
 
-gsu_infobox()
+_set_dialog_ret()
 {
-       _get_geometry
-       dialog --infobox "$1" $result
-}
-
-gsu_checklist_all_on()
-{
-       local header="$1"
-       local items="$2"
-       local i state opts num=0
-
-       _get_geometry
-       ops="$result 16"
-       for i in $items; do
-               let num++
-               opts+=" $i $num on"
-       done
-       result=$(dialog --checklist "$header" $opts 3>&1 1>&2 2>&3 3>&-)
-       ret="$?"
-}
-
-gsu_radiolist()
-{
-       local header="$1"
-       local selected_item="$2"
-       local items="$3"
-       local i state ops num=0
-
-       _get_geometry
-       ops="$result 16"
-       for i in $items; do
-               let num++
-               if [[ "$i" == "$selected_item" ]]; then
-                       state="on"
-               else
-                       state="off"
-               fi
-               ops+=" $i $num $state"
-       done
-       result=$(dialog --radiolist "$header" $ops 3>&1 1>&2 2>&3 3>&-)
-       ret="$?"
+       local ec="$1"
+
+       case "$ec" in
+       0) ret=$GSU_SUCCESS;;
+       1) ret=1;; # cancelled
+       *)
+               result="dialog exit code $ec"
+               ret=-$E_GSU_DIALOG
+       esac
 }
 
+# Open a dialog box which asks the user to input a text
+#
+# Usage: gsu_input_box <text> <init>
+#
+# <text> is displayed above of the input field, which is is preset to <init>.
+# The entered text is returned in $result. On success (user pressed OK)
+# the function returns zero. If the user selected Cancel, the return value is
+# one. On dialog errors, a negative error code is returned.
 gsu_inputbox()
 {
        local g text="$1" init="$2"
@@ -73,62 +52,48 @@ gsu_inputbox()
        _get_geometry
        g="$result"
        result="$(dialog --inputbox "$text" $g "$init" 3>&1 1>&2 2>&3 3>&-)"
-       ret="$?"
+       _set_dialog_ret $?
 }
 
+# Show the given file in a text box
+#
+# Usage: gsu_textbox <path>
+#
+# The box has an OK button which closes the box when activated.
 gsu_textbox()
 {
-       local file="$1"
+       local file="$1"
 
        _get_geometry
-       dialog --textbox "$file" $result
+       g="$result"
+
+       ret=-$E_GSU_DIALOG
+       result='textbox'
+       dialog --textbox "$file" $g
+       _set_dialog_ret $?
 }
 
-# dialog segfaults if message is too long. Hence we always use a temporary file
+# Show a message in a text box
+#
+# Usage: gsu_msgbox <text>
+#
+# This is like gsu_textbox() but the text is passed as a string.
 gsu_msgbox()
 {
-       local tmp="$(mktemp gsu_msgbox.XXXXXXXXXX)"
-
-       if (($? != 0)); then
-               dialog --msgbox "mktemp error" 0 0
-               return
-       fi
+       local tmp
+
+       # Some versions of dialog segfault if the text is too long. Hence we
+       # always use a temporary file.
+       gsu_make_tempfile 'gsu_msgbox.XXXXXXXXXX'
+       (($ret < 0)) && return
+       tmp="$result"
+       trap "rm -f $tmp" EXIT
        echo "$1" > "$tmp"
        gsu_textbox "$tmp"
-       rm -f "$tmp"
-}
-
-gsu_cmd_output_box()
-{
-       local tmp="$(mktemp)"
-
-       if (($? != 0)); then
-               dialog --msgbox "mktemp error" 0 0
-               return
-       fi
-       $@ > "$tmp" 2>&1
-       echo "exit code: $?" >> "$tmp"
-       gsu_textbox "$tmp"
-       rm -f "$tmp"
+       rm -f "$tmp" # ignore errors
 }
 
-gsu_yesno()
-{
-       local text="$1"
-
-       _get_geometry
-       dialog --yesno "$text" $result
-       ret=$?
-       if (($ret == 0)); then
-               result="yes"
-       elif (($ret == 1)); then
-               result="no"
-       else
-               result=
-       fi
-}
-
-gsu_menu()
+_gsu_menu()
 {
        local header="${1:-root}"
        local items="$2"
@@ -141,21 +106,23 @@ gsu_menu()
                opts+=" $i $num"
        done
        result="$(dialog --menu "$gsu_banner_txt ($header)" $opts 3>&1 1>&2 2>&3 3>&-)"
-       ret="$?"
+       _set_dialog_ret $?
 }
 
 _get_level()
 {
-       local tmp="${1%%$GSU_NODE_NAME_PATTERN*}"
+       local tmp="${1%%$_gsu_node_name_pattern*}"
        result="${#tmp}"
 }
 
 _get_subtree()
 {
        local tree="$1" root="${2%/}"
-       local TAB='     '
+       local first TAB='       '
 
-       first="$(grep -n "$TAB\{1,\}$root/" <<< "$tree")"
+       ret=-$E_GSU_MENU_TREE
+       result="subtree grep failed"
+       first="$(grep -n "$TAB\{1,\}$root/" <<< "$tree")" || return
        [[ -z "$first" ]] && return
 
        line_num="${first%%:*}"
@@ -164,16 +131,27 @@ _get_subtree()
 
        #echo "line: $line_num, root: $root, indent level: $level"
        result="$(sed -e "1,${line_num}d;" <<< "$tree" \
-               | sed -e "/^$TAB\{1,$level\}$GSU_NODE_NAME_PATTERN/,\$d" \
+               | sed -e "/^$TAB\{1,$level\}$_gsu_node_name_pattern/,\$d" \
                | sed -e "/^$TAB\{$(($level + 2))\}/d")"
-       ret="$level"
+       if (($? != 0)); then
+               ret=-$E_GSU_MENU_TREE
+               result="sed command for subtree $root failed"
+               return
+       fi
+       ret=$GSU_SUCCESS
 }
 
 _get_root_nodes()
 {
        local tree="$1" TAB='   '
 
-       result="$(grep "^${TAB}${GSU_NODE_NAME_PATTERN}" <<< "$tree")"
+       result="$(grep "^${TAB}${_gsu_node_name_pattern}" <<< "$tree")"
+       if (($? != 0)); then
+               ret=-$E_GSU_MENU_TREE
+               result="root node grep failed"
+               return
+       fi
+       ret=$GSU_SUCCESS
 }
 
 _browse()
@@ -182,14 +160,16 @@ _browse()
        local tree="$2" subtree="$3"
 
        while :; do
-               gsu_menu "$header" "$subtree"
-               (($ret != 0)) && return
-               [[ -z "$result" ]] && return
+               _gsu_menu "$header" "$subtree"
+               (($ret < 0)) && return
+               [[ -z "$result" ]] && return # menu was cancelled
                if [[ "${result%/}" != "$result" ]]; then
                        old_header="$header"
                        header="$result"
                        _get_subtree "$tree" "$header"
+                       (($ret < 0)) && return
                        _browse "$header" "$tree" "$result"
+                       (($ret < 0)) && return
                        header="$old_header"
                        continue
                fi