feat: вкладка «ПО» — списки с кнопками (как «Средства защиты»)
3 списка: ПО и аппаратные средства, Операционные системы, Прикладные программы.
У каждого кнопки «+ Добавить», «- Удалить», «✏️ Редактировать».
Данные хранятся построчно (\n), импорт и генератор сохраняют переносы.
This commit is contained in:
+60
-19
@@ -906,25 +906,34 @@ class DokoGenApp:
|
|||||||
|
|
||||||
net_frame.columnconfigure(1, weight=1)
|
net_frame.columnconfigure(1, weight=1)
|
||||||
|
|
||||||
# ===== Вкладка «ПО» =====
|
# ===== Вкладка «ПО» (списки, как «Средства защиты») =====
|
||||||
sw_tab = ttk.Frame(nb2)
|
sw_tab = ttk.Frame(nb2)
|
||||||
nb2.add(sw_tab, text="ПО")
|
nb2.add(sw_tab, text="ПО")
|
||||||
sw_frame = ttk.Frame(sw_tab, padding=8)
|
sw_frame = ttk.Frame(sw_tab, padding=8)
|
||||||
sw_frame.pack(fill=tk.BOTH, expand=True)
|
sw_frame.pack(fill=tk.BOTH, expand=True)
|
||||||
|
|
||||||
sw_fields = [
|
sw_fields = [
|
||||||
("ПО и аппаратные средства (модели, производители, количество):", "is_hw_sw_entry", 5),
|
("ПО и аппаратные средства (модели, производители, количество):", "is_hw_sw_listbox"),
|
||||||
("Операционные системы:", "is_os_sw_entry", 3),
|
("Операционные системы:", "is_os_sw_listbox"),
|
||||||
("Прикладные программы (MS Office, OpenOffice и пр.):", "is_app_sw_entry", 4),
|
("Прикладные программы (MS Office, OpenOffice и пр.):", "is_app_sw_listbox"),
|
||||||
]
|
]
|
||||||
for i, (label, attr, height) in enumerate(sw_fields):
|
for i, (label, attr) in enumerate(sw_fields):
|
||||||
ttk.Label(sw_frame, text=label).grid(row=i * 2, column=0, sticky=tk.W, pady=(4, 0))
|
row = i * 2
|
||||||
txt = tk.Text(sw_frame, width=70, height=height, wrap=tk.WORD)
|
ttk.Label(sw_frame, text=label).grid(row=row, column=0, sticky=tk.W, pady=(4, 0))
|
||||||
txt.grid(row=i * 2 + 1, column=0, columnspan=2, padx=8, sticky=tk.EW, pady=1)
|
box = tk.Listbox(sw_frame, height=4, exportselection=False)
|
||||||
sb = ttk.Scrollbar(sw_frame, orient=tk.VERTICAL, command=txt.yview)
|
box.grid(row=row + 1, column=0, sticky=tk.EW, padx=(0, 4), pady=1)
|
||||||
sb.grid(row=i * 2 + 1, column=2, sticky=tk.NS)
|
sb = ttk.Scrollbar(sw_frame, orient=tk.VERTICAL, command=box.yview)
|
||||||
txt.configure(yscrollcommand=sb.set)
|
sb.grid(row=row + 1, column=1, sticky=tk.NS)
|
||||||
setattr(self, attr, txt)
|
box.configure(yscrollcommand=sb.set)
|
||||||
|
btn = ttk.Frame(sw_frame)
|
||||||
|
btn.grid(row=row + 1, column=2, sticky=tk.N, padx=(4, 0))
|
||||||
|
ttk.Button(btn, text="+ Добавить",
|
||||||
|
command=lambda a=attr: self._add_sw_item(getattr(self, a))).pack(fill=tk.X, pady=1)
|
||||||
|
ttk.Button(btn, text="- Удалить",
|
||||||
|
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)
|
||||||
|
setattr(self, attr, box)
|
||||||
sw_frame.columnconfigure(0, weight=1)
|
sw_frame.columnconfigure(0, weight=1)
|
||||||
|
|
||||||
# ===== Вкладка «Безопасность (236)» =====
|
# ===== Вкладка «Безопасность (236)» =====
|
||||||
@@ -1211,9 +1220,9 @@ class DokoGenApp:
|
|||||||
('is_net_operator_entry', 'net_operator'),
|
('is_net_operator_entry', 'net_operator'),
|
||||||
('is_net_purpose_combo', 'net_purpose'),
|
('is_net_purpose_combo', 'net_purpose'),
|
||||||
('is_net_method_combo', 'net_method'),
|
('is_net_method_combo', 'net_method'),
|
||||||
('is_hw_sw_entry', 'hw_sw'),
|
('is_hw_sw_listbox', 'hw_sw'),
|
||||||
('is_os_sw_entry', 'os_sw'),
|
('is_os_sw_listbox', 'os_sw'),
|
||||||
('is_app_sw_entry', 'app_sw'),
|
('is_app_sw_listbox', 'app_sw'),
|
||||||
('is_attacker_category_entry', 'attacker_category'),
|
('is_attacker_category_entry', 'attacker_category'),
|
||||||
('is_threats_entry', 'threats'),
|
('is_threats_entry', 'threats'),
|
||||||
('is_incidents_entry', 'incidents'),
|
('is_incidents_entry', 'incidents'),
|
||||||
@@ -1224,7 +1233,9 @@ class DokoGenApp:
|
|||||||
]:
|
]:
|
||||||
w = getattr(self, attr, None)
|
w = getattr(self, attr, None)
|
||||||
if w is not None:
|
if w is not None:
|
||||||
if isinstance(w, tk.Text):
|
if isinstance(w, tk.Listbox):
|
||||||
|
setattr(isys, model_field, '\n'.join(w.get(0, tk.END)))
|
||||||
|
elif isinstance(w, tk.Text):
|
||||||
setattr(isys, model_field, w.get('1.0', 'end-1c').strip())
|
setattr(isys, model_field, w.get('1.0', 'end-1c').strip())
|
||||||
else:
|
else:
|
||||||
setattr(isys, model_field, w.get().strip())
|
setattr(isys, model_field, w.get().strip())
|
||||||
@@ -1443,9 +1454,9 @@ class DokoGenApp:
|
|||||||
('is_net_operator_entry', 'net_operator'),
|
('is_net_operator_entry', 'net_operator'),
|
||||||
('is_net_purpose_combo', 'net_purpose'),
|
('is_net_purpose_combo', 'net_purpose'),
|
||||||
('is_net_method_combo', 'net_method'),
|
('is_net_method_combo', 'net_method'),
|
||||||
('is_hw_sw_entry', 'hw_sw'),
|
('is_hw_sw_listbox', 'hw_sw'),
|
||||||
('is_os_sw_entry', 'os_sw'),
|
('is_os_sw_listbox', 'os_sw'),
|
||||||
('is_app_sw_entry', 'app_sw'),
|
('is_app_sw_listbox', 'app_sw'),
|
||||||
('is_attacker_category_entry', 'attacker_category'),
|
('is_attacker_category_entry', 'attacker_category'),
|
||||||
('is_threats_entry', 'threats'),
|
('is_threats_entry', 'threats'),
|
||||||
('is_incidents_entry', 'incidents'),
|
('is_incidents_entry', 'incidents'),
|
||||||
@@ -1459,6 +1470,11 @@ class DokoGenApp:
|
|||||||
val = getattr(isys, model_field, '') or ''
|
val = getattr(isys, model_field, '') or ''
|
||||||
if isinstance(w, ttk.Combobox):
|
if isinstance(w, ttk.Combobox):
|
||||||
w.set(val)
|
w.set(val)
|
||||||
|
elif isinstance(w, tk.Listbox):
|
||||||
|
w.delete(0, tk.END)
|
||||||
|
for line in str(val).split('\n'):
|
||||||
|
if line.strip():
|
||||||
|
w.insert(tk.END, line.strip())
|
||||||
elif isinstance(w, tk.Text):
|
elif isinstance(w, tk.Text):
|
||||||
w.delete('1.0', tk.END)
|
w.delete('1.0', tk.END)
|
||||||
w.insert('1.0', val)
|
w.insert('1.0', val)
|
||||||
@@ -1545,6 +1561,31 @@ class DokoGenApp:
|
|||||||
if item:
|
if item:
|
||||||
self.defense_tools_listbox.insert(tk.END, item)
|
self.defense_tools_listbox.insert(tk.END, item)
|
||||||
|
|
||||||
|
def _add_sw_item(self, listbox):
|
||||||
|
"""Добавить строку в список ПО."""
|
||||||
|
item = simpledialog.askstring("Добавить", "Введите позицию:")
|
||||||
|
if item:
|
||||||
|
listbox.insert(tk.END, item.strip())
|
||||||
|
|
||||||
|
def _del_sw_item(self, listbox):
|
||||||
|
"""Удалить выбранную строку из списка ПО."""
|
||||||
|
sel = listbox.curselection()
|
||||||
|
if sel:
|
||||||
|
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)
|
||||||
|
if item is not None:
|
||||||
|
listbox.delete(sel[0])
|
||||||
|
listbox.insert(sel[0], item.strip())
|
||||||
|
|
||||||
def _add_user_to_is(self):
|
def _add_user_to_is(self):
|
||||||
user = simpledialog.askstring("Добавить пользователя", "Введите ФИО или должность:")
|
user = simpledialog.askstring("Добавить пользователя", "Введите ФИО или должность:")
|
||||||
if user:
|
if user:
|
||||||
|
|||||||
Reference in New Issue
Block a user