[UPD] tui qemu: pick the VM by number for its state
Changing state meant retyping the name, on a single comma-separated line. Names are long and alike -- two of them sometimes differ by a suffix only -- and a typo here decided whether a machine started or shut down. The screen now reuses the numbered list from the delete screen, "all" included, and its parser, which already accepts names: nothing is lost for those who typed them. The warning on an unknown entry is kept, that parser otherwise dropping it without a word. --- FR --- Changer l'état demandait de retaper le nom, sur une seule ligne séparée par des virgules. Les noms sont longs et se ressemblent — deux d'entre eux ne diffèrent parfois que par un suffixe — et une faute de frappe portait ici sur le démarrage ou l'extinction d'une machine. L'écran reprend donc la liste numérotée de la suppression, « all » compris, et son analyseur, qui accepte déjà les noms : rien n'est perdu pour qui les tapait. L'avertissement sur une entrée inconnue est conservé, cet analyseur l'écartant autrement sans un mot. Assisted-by: Claude Opus 5
This commit is contained in:
parent
c7b9d2396d
commit
891d412aa2
1 changed files with 34 additions and 12 deletions
|
|
@ -2137,20 +2137,34 @@ class TODO:
|
|||
if not names:
|
||||
print(f"\n{t('No VM found.')}")
|
||||
return
|
||||
print(f"\n{t('Available VMs:')} {', '.join(names)}")
|
||||
raw = input(t("VMs to change (comma-separated): ")).strip()
|
||||
targets = [n.strip() for n in raw.split(",") if n.strip()]
|
||||
if not targets:
|
||||
# Liste NUMÉROTÉE, comme l'écran de suppression : les noms de VM sont
|
||||
# longs et se ressemblent, les retaper invite à la faute de frappe sur
|
||||
# une commande qui change l'état d'une machine.
|
||||
print(f"\n{t('Available VMs:')}")
|
||||
for i, n in enumerate(names, 1):
|
||||
print(f" [{i}] {n}")
|
||||
print(f" [all] {t('select all')}")
|
||||
raw = input(t("Selection (numbers, or 'all'): ")).strip()
|
||||
if not raw:
|
||||
print(t("Nothing selected."))
|
||||
return
|
||||
# Résoudre les ID -> noms et valider l'existence.
|
||||
resolved, unknown = [], []
|
||||
known = set(names)
|
||||
for tgt in targets:
|
||||
real = self._qemu_domname(tgt)
|
||||
(resolved if real in known else unknown).append(real)
|
||||
if unknown:
|
||||
print(f"{t('Unknown VM(s):')} {', '.join(unknown)}")
|
||||
if raw.lower() in ("all", "*"):
|
||||
resolved = list(names)
|
||||
else:
|
||||
resolved = self._parse_index_selection(raw.lower(), names)
|
||||
# Le parseur ignore en silence ce qu'il ne reconnaît pas. Sur une
|
||||
# sélection qui va démarrer ou éteindre des VM, un numéro hors
|
||||
# liste doit être dit, pas escamoté.
|
||||
unknown = [
|
||||
tok
|
||||
for tok in re.split(r"[\s,]+", raw.strip())
|
||||
if tok and tok not in names and not self._is_index(tok, names)
|
||||
]
|
||||
if unknown:
|
||||
print(f"{t('Unknown VM(s):')} {', '.join(unknown)}")
|
||||
return
|
||||
if not resolved:
|
||||
print(t("Nothing selected."))
|
||||
return
|
||||
# Choix de l'état cible : ouvrir (démarrer) ou fermer (éteindre).
|
||||
print(f"\n{t('Target state:')}")
|
||||
|
|
@ -3812,6 +3826,14 @@ class TODO:
|
|||
pass
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def _is_index(token, options):
|
||||
"""Vrai si le jeton est un numéro valide dans la liste (1-based)."""
|
||||
try:
|
||||
return 1 <= int(token) <= len(options)
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _parse_index_selection(raw, options):
|
||||
"""« 1 3 » ou « 1,3 » -> sous-liste d'options (indices 1-based)."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue