feat: кнопка «✏️ Уточнить модель/кол-во» в окне выбора из словаря
- если в словаре есть позиции с «(уточнить …)» — в окне выбора появляется кнопка - отмечаешь галочкой, например «Сервер (уточнить модель)» — жмёшь кнопку, программа запрашивает модель/версию/конфигурацию и количество - в список добавляется полная строка: «Сервер Supermicro SSG-2027R -E1R24N, 2 шт.» - работает для всех словарей: ПО (hw_sw, os_sw, app_sw), СЗИ и т.д.
This commit is contained in:
@@ -1965,11 +1965,13 @@ class DokoGenApp:
|
|||||||
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
||||||
|
|
||||||
vars = {}
|
vars = {}
|
||||||
|
items_map = {}
|
||||||
for item in items:
|
for item in items:
|
||||||
var = tk.BooleanVar(value=item in existing)
|
var = tk.BooleanVar(value=item in existing)
|
||||||
cb = ttk.Checkbutton(check_frame, text=item, variable=var)
|
cb = ttk.Checkbutton(check_frame, text=item, variable=var)
|
||||||
cb.pack(anchor=tk.W, pady=1)
|
cb.pack(anchor=tk.W, pady=1)
|
||||||
vars[item] = var
|
vars[item] = var
|
||||||
|
items_map[item] = (var, cb)
|
||||||
|
|
||||||
btn_frame = ttk.Frame(dialog, padding=10)
|
btn_frame = ttk.Frame(dialog, padding=10)
|
||||||
btn_frame.pack(fill=tk.X)
|
btn_frame.pack(fill=tk.X)
|
||||||
@@ -1989,12 +1991,87 @@ class DokoGenApp:
|
|||||||
for var in vars.values():
|
for var in vars.values():
|
||||||
var.set(False)
|
var.set(False)
|
||||||
|
|
||||||
|
has_refinable = any('уточн' in str(item).lower() for item in items)
|
||||||
|
|
||||||
|
def _refine_selected():
|
||||||
|
"""Для отмеченных позиций с «(уточнить …)» запросить модель и количество."""
|
||||||
|
for item, (var, cb) in list(items_map.items()):
|
||||||
|
if not var.get():
|
||||||
|
continue
|
||||||
|
if 'уточн' not in item.lower():
|
||||||
|
continue
|
||||||
|
new_text = self._refine_dict_item_dialog(item)
|
||||||
|
if new_text is None or new_text == item:
|
||||||
|
continue
|
||||||
|
# Обновляем текст чекбокса и ключ в словаре
|
||||||
|
cb.config(text=new_text)
|
||||||
|
vars.pop(item, None)
|
||||||
|
items_map.pop(item, None)
|
||||||
|
vars[new_text] = var
|
||||||
|
items_map[new_text] = (var, cb)
|
||||||
|
|
||||||
|
if has_refinable:
|
||||||
|
ttk.Button(btn_frame, text="✏️ Уточнить модель/кол-во",
|
||||||
|
command=_refine_selected).pack(side=tk.LEFT, padx=2)
|
||||||
ttk.Button(btn_frame, text="Выбрать всё", command=_select_all).pack(side=tk.LEFT, padx=2)
|
ttk.Button(btn_frame, text="Выбрать всё", command=_select_all).pack(side=tk.LEFT, padx=2)
|
||||||
ttk.Button(btn_frame, text="Снять всё", command=_clear_all).pack(side=tk.LEFT, padx=2)
|
ttk.Button(btn_frame, text="Снять всё", command=_clear_all).pack(side=tk.LEFT, padx=2)
|
||||||
ttk.Button(btn_frame, text="✅ Применить", command=_apply).pack(side=tk.RIGHT, padx=2)
|
ttk.Button(btn_frame, text="✅ Применить", command=_apply).pack(side=tk.RIGHT, padx=2)
|
||||||
|
|
||||||
dialog.wait_window()
|
dialog.wait_window()
|
||||||
|
|
||||||
|
def _refine_dict_item_dialog(self, base_item):
|
||||||
|
"""Окно уточнения модели и количества для позиции из словаря.
|
||||||
|
|
||||||
|
Возвращает полную строку вида «Сервер <модель>, <N> шт.» или None.
|
||||||
|
"""
|
||||||
|
dialog = tk.Toplevel(self.root)
|
||||||
|
dialog.title("Уточнить модель и количество")
|
||||||
|
dialog.geometry("500x180")
|
||||||
|
dialog.transient(self.root)
|
||||||
|
dialog.grab_set()
|
||||||
|
|
||||||
|
frame = ttk.Frame(dialog, padding=10)
|
||||||
|
frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
|
ttk.Label(frame, text=f"Позиция: {base_item}", wraplength=470,
|
||||||
|
font=('Arial', 9, 'bold')).pack(anchor=tk.W, pady=(0, 8))
|
||||||
|
|
||||||
|
ttk.Label(frame, text="Модель / версия / конфигурация:").pack(anchor=tk.W)
|
||||||
|
model_entry = ttk.Entry(frame, width=60)
|
||||||
|
model_entry.pack(fill=tk.X, pady=(2, 6))
|
||||||
|
model_entry.focus_set()
|
||||||
|
|
||||||
|
ttk.Label(frame, text="Количество (необязательно):").pack(anchor=tk.W)
|
||||||
|
count_entry = ttk.Entry(frame, width=20)
|
||||||
|
count_entry.pack(anchor=tk.W, pady=(2, 6))
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
def _ok():
|
||||||
|
model = model_entry.get().strip()
|
||||||
|
count = count_entry.get().strip()
|
||||||
|
text = base_item
|
||||||
|
if model:
|
||||||
|
text = f"{text} {model}"
|
||||||
|
if count:
|
||||||
|
text = f"{text}, {count} шт."
|
||||||
|
result['val'] = text
|
||||||
|
dialog.destroy()
|
||||||
|
|
||||||
|
def _cancel():
|
||||||
|
result['val'] = None
|
||||||
|
dialog.destroy()
|
||||||
|
|
||||||
|
btn_frame = ttk.Frame(frame)
|
||||||
|
btn_frame.pack(fill=tk.X, pady=(6, 0))
|
||||||
|
ttk.Button(btn_frame, text="✅ ОК", command=_ok).pack(side=tk.RIGHT, padx=2)
|
||||||
|
ttk.Button(btn_frame, text="Отмена", command=_cancel).pack(side=tk.RIGHT, padx=2)
|
||||||
|
|
||||||
|
dialog.bind('<Return>', lambda e: _ok())
|
||||||
|
dialog.bind('<Escape>', lambda e: _cancel())
|
||||||
|
dialog.wait_window()
|
||||||
|
return result.get('val')
|
||||||
|
|
||||||
def _select_from_defense_list(self):
|
def _select_from_defense_list(self):
|
||||||
"""Выбор СЗИ из JSON словаря."""
|
"""Выбор СЗИ из JSON словаря."""
|
||||||
import json
|
import json
|
||||||
|
|||||||
Reference in New Issue
Block a user