From 21e4e136e4fa35916c8dbe35b40518aae0845a26 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Tue, 24 Oct 2023 23:55:27 +0200 Subject: [PATCH] gui: Implement descriptive tree items. A restriction of the current gui module is that the text shown in the menu items must also be a valid identifier for the corresponding bash function. In particular no whitespace is allowed there. To overcome this restriction we introduce the concept of a menu item identifier and an optional menu item description. If the description is absent, the identifier is used as the description, providing backward compatibility. --- README.md | 58 +++++++++++++++++++++++++++++-------------------------- gui | 55 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index ff00e29..bd4bf13 100644 --- a/README.md +++ b/README.md @@ -431,23 +431,27 @@ contents of the kernel log buffer. Bash code which defines the menu tree could look like this: menu_tree=' - load_average - processes - hardware/ - cpu - scsi - storage/ - df - mdstat - log/ - syslog - dmesg + load_average System load + processes Running processes of a user + hardware/ Hardware related information + cpu Show prozessor type and features + scsi Show SCSI devices + storage/ Filesystems and software raid + df List of mounted filesystems + mdstat Status of software raid arrays + log/ System and kernel logs + syslog System log + dmesg Kernel log ' -In this tree, `hardware/`, `storage/` and `log/` are the only -internal nodes. Note that these are written with a trailing slash -character while the leaf nodes have no slash at the end. All entries -of the menu tree must be indented by tab characters. +Each line of the menu tree consists of an identifier, suffixed with an +optional slash, and a description. The identifier becomes part of the +name of a bash function and should only contain alphabetic characters +and underscores. The description becomes the text shown as the menu +item. Identifiers suffixed with a slash are regarded as internal nodes +which represent submenus. In the above tree, `hardware/`, `storage/` +and `log/` are internal nodes. All entries of the menu tree must be +properly indented by tab characters. ___Action handlers___ @@ -463,7 +467,7 @@ handler for the `df` node: } The function name `lsi_df` is derived from the name of the script -(`lsi`) and the name of the leaf node (`df`). The function simply +(`lsi`) and the identifier of the leaf node (`df`). The function simply passes the output of the `df(1)` command as the first argument to the public gsu function `gsu_msgbox()` which runs dialog(1) to display a message box that shows the given text. @@ -503,17 +507,17 @@ tab characters into space characters. The script must be named "lsi". #!/bin/bash menu_tree=' - load_average - processes - hardware/ - cpu - scsi - storage/ - df - mdstat - log/ - syslog - dmesg + load_average System load + processes Running processes of a user + hardware/ Hardware related information + cpu Show prozessor type and features + scsi Show SCSI devices + storage/ Filesystems and software raid + df List of mounted filesystems + mdstat Status of software raid arrays + log/ System and kernel logs + syslog System log + dmesg Kernel log ' lsi_load_average() diff --git a/gui b/gui index fbcbb01..83da0cd 100644 --- a/gui +++ b/gui @@ -95,15 +95,16 @@ gsu_msgbox() _gsu_menu() { - local header=${1:-root} dflt_item=$2 items=$3 + local header=$1 dflt_item=$2 local geom + shift 2 _get_geometry geom=$result result="$(dialog --no-lines --no-items \ --default-item "$dflt_item" \ - --menu "$gsu_banner_txt ($header)" \ - $geom 16 $items 3>&1 1>&2 2>&3 3>&-)" + --menu "$gsu_banner_txt"$'\n'"Current location: $header" \ + $geom 16 "$@" 3>&1 1>&2 2>&3 3>&-)" _set_dialog_ret $? } @@ -154,26 +155,46 @@ _get_root_nodes() _browse() { - local header=$1 tree=$2 - local -a subtree=($3) - local old_header dflt_item=${subtree[0]} - + local root_item=$1 tree=$2 subtree=$3 + local -a items arr + local -A ids + local old_root dflt_item + local item id OIFS + local -i i=0 + + while read -a arr; do + ((${#arr[@]} == 0)) && continue + id=${arr[0]} + if ((${#arr[@]} > 1)); then + unset arr[0]; + item=${arr[*]} + if [[ "${id:$((${#id} - 1)):1}" == '/' ]]; then + item+=/ + else + item="• $item" + fi + else + item=$id + fi + items[$i]=$item + ids["$item"]=$id + let i++ + done <<< "$subtree" + dflt_item=${items[0]} while :; do - _gsu_menu "$header" "$dflt_item" "${subtree[*]}" + _gsu_menu "$root_item" "$dflt_item" "${items[@]}" ((ret < 0)) && return - dflt_item=$result [[ -z "$result" ]] && return # menu was cancelled - if [[ "${result%/}" != "$result" ]]; then - old_header="$header" - header="$result" - _get_subtree "$tree" "$header" + dflt_item=$result + id=${ids["$result"]} + if [[ "${id:$((${#id} - 1)):1}" == '/' ]]; then + _get_subtree "$tree" "$id" ((ret < 0)) && return - _browse "$header" "$tree" "$result" + _browse "${dflt_item%/}" "$tree" "$result" ((ret < 0)) && return - header="$old_header" continue fi - eval ${gsu_name}_$result + eval ${gsu_name}_${id} done } @@ -188,5 +209,5 @@ gsu_gui() fi _get_root_nodes "$tree" subtree="$result" - _browse "main menu" "$tree" "$subtree" + _browse 'Main menu' "$tree" "$subtree" } -- 2.39.5