feat: вкладка «ПО» — словари ОС/аппаратных средств/прикладных программ + большое окно редактирования

- словари: hw_sw.json, os_sw.json, app_sw.json
- кнопка «📚 Из словаря» у каждого списка ПО (мультивыбор)
- большое окно добавления/редактирования позиции (560x220, многострочное)
This commit is contained in:
2026-08-04 16:56:51 +04:00
parent ba2a02d1cd
commit aae66dcca1
4 changed files with 109 additions and 11 deletions
+62 -11
View File
@@ -916,11 +916,11 @@ class DokoGenApp:
sw_frame.pack(fill=tk.BOTH, expand=True)
sw_fields = [
("ПО и аппаратные средства (модели, производители, количество):", "is_hw_sw_listbox"),
("Операционные системы:", "is_os_sw_listbox"),
("Прикладные программы (MS Office, OpenOffice и пр.):", "is_app_sw_listbox"),
("ПО и аппаратные средства (модели, производители, количество):", "is_hw_sw_listbox", "hw_sw.json"),
("Операционные системы:", "is_os_sw_listbox", "os_sw.json"),
("Прикладные программы (MS Office, OpenOffice и пр.):", "is_app_sw_listbox", "app_sw.json"),
]
for i, (label, attr) in enumerate(sw_fields):
for i, (label, attr, dict_name) in enumerate(sw_fields):
row = i * 2
ttk.Label(sw_frame, text=label).grid(row=row, column=0, sticky=tk.W, pady=(4, 0))
box = tk.Listbox(sw_frame, height=4, exportselection=False)
@@ -936,6 +936,8 @@ class DokoGenApp:
command=lambda a=attr: self._del_sw_item(getattr(self, a))).pack(fill=tk.X, pady=1)
ttk.Button(btn, text="✏️ Редактировать",
command=lambda a=attr: self._edit_sw_item(getattr(self, a))).pack(fill=tk.X, pady=1)
ttk.Button(btn, text="📚 Из словаря",
command=lambda a=attr, d=dict_name: self._select_sw_from_dict(getattr(self, a), d)).pack(fill=tk.X, pady=1)
setattr(self, attr, box)
sw_frame.columnconfigure(0, weight=1)
@@ -1564,11 +1566,61 @@ class DokoGenApp:
if item:
self.defense_tools_listbox.insert(tk.END, item)
def _select_sw_from_dict(self, listbox, dict_name):
"""Выбор позиций из словаря (JSON) — можно несколько."""
import json
dict_path = os.path.join(os.path.dirname(__file__), 'dictionaries', dict_name)
try:
with open(dict_path, 'r', encoding='utf-8') as f:
items = json.load(f)
title = "Выбор из словаря"
self._select_from_dialog(title, items, listbox)
except Exception as e:
messagebox.showerror("Ошибка", f"Не удалось загрузить словарь: {e}")
def _sw_dialog(self, title, initial=""):
"""Большое окно для ввода/редактирования позиции ПО."""
dialog = tk.Toplevel(self.root)
dialog.title(title)
dialog.geometry("560x220")
dialog.transient(self.root)
dialog.grab_set()
dialog.resizable(True, True)
frame = ttk.Frame(dialog, padding=10)
frame.pack(fill=tk.BOTH, expand=True)
ttk.Label(frame, text="Текст позиции:").pack(anchor=tk.W)
txt = tk.Text(frame, width=70, height=6, wrap=tk.WORD)
txt.pack(fill=tk.BOTH, expand=True, pady=5)
txt.insert('1.0', initial)
txt.focus_set()
result = {}
def _ok():
result['val'] = txt.get('1.0', 'end-1c').strip()
dialog.destroy()
def _cancel():
result['val'] = None
dialog.destroy()
btn_frame = ttk.Frame(frame)
btn_frame.pack(fill=tk.X)
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 _add_sw_item(self, listbox):
"""Добавить строку в список ПО."""
item = simpledialog.askstring("Добавить", "Введите позицию:")
"""Добавить строку в список ПО (большое окно)."""
item = self._sw_dialog("Добавить позицию")
if item:
listbox.insert(tk.END, item.strip())
listbox.insert(tk.END, item)
def _del_sw_item(self, listbox):
"""Удалить выбранную строку из списка ПО."""
@@ -1577,17 +1629,16 @@ class DokoGenApp:
listbox.delete(sel[0])
def _edit_sw_item(self, listbox):
"""Редактировать выбранную строку списка ПО."""
"""Редактировать выбранную строку списка ПО (большое окно)."""
sel = listbox.curselection()
if not sel:
messagebox.showinfo("Редактировать", "Сначала выберите позицию в списке")
return
current = listbox.get(sel[0])
item = simpledialog.askstring("Редактировать", "Измените позицию:",
initialvalue=current)
item = self._sw_dialog("Редактировать позицию", initial=current)
if item is not None:
listbox.delete(sel[0])
listbox.insert(sel[0], item.strip())
listbox.insert(sel[0], item)
def _add_user_to_is(self):
user = simpledialog.askstring("Добавить пользователя", "Введите ФИО или должность:")