diff --git a/README.md b/README.md index 6e005c9..a2a4089 100644 --- a/README.md +++ b/README.md @@ -1619,6 +1619,9 @@ sudo ./scripts/cmk-manage.sh gui Bedienung: Pfeiltasten, **Leertaste** markiert in Auswahllisten (z. B. mehrere Sites für ein Backup), **Enter** bestätigt, **ESC/Cancel** geht zurück. +Die Fenstergröße richtet sich nach Terminalgröße, Textlänge und Anzahl der +Einträge – in einem größeren Terminal sind entsprechend mehr Einträge auf +einmal sichtbar. Es wird `dialog` bevorzugt; ist nur `whiptail` vorhanden, wird dieses genutzt. Eine Dateiauswahl mit Verzeichnisnavigation ist eingebaut. diff --git a/README_en.md b/README_en.md index b3460bf..e1b77b3 100644 --- a/README_en.md +++ b/README_en.md @@ -1623,6 +1623,8 @@ The menu labels are German; the command table in Operation: arrow keys, **space** toggles entries in selection lists (e.g. several sites for a backup), **Enter** confirms, **ESC/Cancel** goes back. +The window size adapts to the terminal size, the length of the text and the +number of entries – in a larger terminal more entries are visible at once. `dialog` is preferred; if only `whiptail` is present, that is used instead. A file chooser with directory navigation is built in. diff --git a/scripts/lib/common.sh b/scripts/lib/common.sh index a4af5b0..9356c17 100644 --- a/scripts/lib/common.sh +++ b/scripts/lib/common.sh @@ -224,6 +224,79 @@ primary_ip() { # ===================================================================== UI_BACKTITLE="Checkmk Stack Manager - Container-Runtime: ${RUNTIME:-?}" +# Groesse des Terminals ermitteln (mit Rueckfallwerten) +ui_term_size() { + UI_ROWS="$(tput lines 2>/dev/null || true)" + UI_COLS="$(tput cols 2>/dev/null || true)" + case "$UI_ROWS" in ''|*[!0-9]*) UI_ROWS=24 ;; esac + case "$UI_COLS" in ''|*[!0-9]*) UI_COLS=80 ;; esac + if [ "$UI_ROWS" -lt 10 ]; then UI_ROWS=24; fi + if [ "$UI_COLS" -lt 40 ]; then UI_COLS=80; fi + return 0 +} + +# Fenstergroesse aus Textlaenge, Anzahl der Eintraege und Terminalgroesse +# berechnen. Vorher waren die Werte fest - bei langem Text blieb dann nur +# eine Zeile fuer die Liste uebrig. +# +# ACHTUNG: hier bewusst mit if-Bloecken statt "[ ... ] && VAR=...". +# Letzteres liefert 1, wenn die Bedingung nicht zutrifft, und beendet +# unter "set -e" die Funktion bzw. das ganze Skript. +# +# ui_calc TEXT FELDER_JE_EINTRAG EINTRAEGE... +ui_calc() { + local text="$1" per="$2"; shift 2 + ui_term_size + + local tl maxw + tl="$(printf '%s\n' "$text" | wc -l)" + maxw="$(printf '%s\n' "$text" | awk '{ if (length($0) > m) m = length($0) } END { print m+0 }')" + + # breiteste Zeile der Liste (Kennung und Beschriftung stehen nebeneinander) + local -a args=("$@") + local i=0 w itemw=0 n=0 + while [ "$i" -lt "${#args[@]}" ]; do + w=$(( ${#args[$i]} + 4 )) + if [ $((i+1)) -lt "${#args[@]}" ]; then + w=$(( w + ${#args[$((i+1))]} )) + fi + if [ "$w" -gt "$itemw" ]; then itemw="$w"; fi + i=$(( i + per )); n=$(( n + 1 )) + done + + # Breite: der breitere von Text und Liste, plus Rahmen + if [ "$maxw" -gt "$itemw" ]; then UI_W=$(( maxw + 10 )); else UI_W=$(( itemw + 10 )); fi + if [ "$UI_W" -lt 60 ]; then UI_W=60; fi + if [ "$UI_W" -gt $(( UI_COLS - 4 )) ]; then UI_W=$(( UI_COLS - 4 )); fi + + # Listenhoehe: moeglichst alle Eintraege zeigen, ohne aus dem Bild zu laufen + local avail=$(( UI_ROWS - tl - 9 )) + if [ "$avail" -lt 3 ]; then avail=3; fi + if [ "$n" -lt "$avail" ]; then UI_MH="$n"; else UI_MH="$avail"; fi + if [ "$UI_MH" -lt 1 ]; then UI_MH=1; fi + + UI_H=$(( tl + UI_MH + 8 )) + if [ "$UI_H" -gt $(( UI_ROWS - 2 )) ]; then UI_H=$(( UI_ROWS - 2 )); fi + if [ "$UI_H" -lt 10 ]; then UI_H=10; fi + return 0 +} + +# Hoehe fuer Fenster ohne Liste (Meldung, Abfrage, Eingabe) +ui_calc_text() { # text zusatzzeilen + local text="$1" extra="${2:-7}" + ui_term_size + local tl maxw + tl="$(printf '%s\n' "$text" | wc -l)" + maxw="$(printf '%s\n' "$text" | awk '{ if (length($0) > m) m = length($0) } END { print m+0 }')" + UI_W=$(( maxw + 10 )) + if [ "$UI_W" -lt 60 ]; then UI_W=60; fi + if [ "$UI_W" -gt $(( UI_COLS - 4 )) ]; then UI_W=$(( UI_COLS - 4 )); fi + UI_H=$(( tl + extra )) + if [ "$UI_H" -gt $(( UI_ROWS - 2 )) ]; then UI_H=$(( UI_ROWS - 2 )); fi + if [ "$UI_H" -lt 8 ]; then UI_H=8; fi + return 0 +} + ui_init() { # Geometrie IMMER setzen - sonst laeuft das Skript unter "set -u" auf # eine unbound variable, wenn UI_BIN von aussen vorgegeben wurde. @@ -247,6 +320,7 @@ ui_require() { ui_menu() { # title text tag item [tag item ...] -> gewaehlter tag auf stdout ui_init local title="$1" text="$2"; shift 2 + ui_calc "$text" 2 "$@" "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \ --menu "$text" "$UI_H" "$UI_W" "$UI_MH" "$@" 3>&1 1>&2 2>&3 } @@ -254,6 +328,7 @@ ui_menu() { # title text tag item [tag item ...] -> gewaehlter tag auf stdout ui_checklist() { # title text tag item status ... ui_init local title="$1" text="$2"; shift 2 + ui_calc "$text" 3 "$@" "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \ --checklist "$text" "$UI_H" "$UI_W" "$UI_MH" "$@" 3>&1 1>&2 2>&3 } @@ -261,40 +336,48 @@ ui_checklist() { # title text tag item status ... ui_radiolist() { ui_init local title="$1" text="$2"; shift 2 + ui_calc "$text" 3 "$@" "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \ --radiolist "$text" "$UI_H" "$UI_W" "$UI_MH" "$@" 3>&1 1>&2 2>&3 } ui_input() { # title text default ui_init + ui_calc_text "$2" 10 "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" \ - --inputbox "$2" 10 "$UI_W" "${3:-}" 3>&1 1>&2 2>&3 + --inputbox "$2" "$UI_H" "$UI_W" "${3:-}" 3>&1 1>&2 2>&3 } ui_password() { ui_init + ui_calc_text "$2" 10 "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" \ - --passwordbox "$2" 10 "$UI_W" 3>&1 1>&2 2>&3 + --passwordbox "$2" "$UI_H" "$UI_W" 3>&1 1>&2 2>&3 } ui_msg() { # title text ui_init - "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --msgbox "$2" 16 "$UI_W" + ui_calc_text "$2" 7 + "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --msgbox "$2" "$UI_H" "$UI_W" } ui_yesno() { # title text -> exit 0 = ja ui_init - "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --yesno "$2" 14 "$UI_W" + ui_calc_text "$2" 8 + "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --yesno "$2" "$UI_H" "$UI_W" } -ui_text() { # title file +ui_text() { # title file - so gross wie das Terminal es zulaesst ui_init - "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --textbox "$2" "$UI_H" "$UI_W" + ui_term_size + "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --textbox "$2" \ + $(( UI_ROWS - 2 )) $(( UI_COLS - 4 )) } ui_info() { # title text (ohne OK-Button) ui_init - "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --infobox "$2" 8 "$UI_W" + ui_calc_text "$2" 5 + "$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --infobox "$2" "$UI_H" "$UI_W" } # Kommando ausfuehren, Ausgabe live in Datei, danach in Textbox anzeigen