import re import xml.etree.ElementTree as ET from PySide2.QtWidgets import ( QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton, QLineEdit, QLabel, QHeaderView, QCompleter, QCheckBox, QHBoxLayout, QSizePolicy ) from PySide2.QtGui import QKeySequence, QKeyEvent from PySide2.QtCore import Qt, QStringListModel, QSettings import VariableTable import setupVars import myXML import time import selectTable array_re = re.compile(r'^(\w+)\[(\d+)\]$') class VariableSelectorDialog(QDialog): def __init__(self, table, all_vars, structs, typedefs, xml_path=None, parent=None): super().__init__(parent) self.setWindowTitle("Выбор переменных") self.setAttribute(Qt.WA_DeleteOnClose) self.resize(1200, 500) self.selected_names = [] self._bckspc_pressed = False # флаг подавления добавления разделителя self.table = table self.all_vars = all_vars self.structs = structs self.typedefs = typedefs self.expanded_vars = [] self.var_map = {v['name']: v for v in all_vars} self.node_index = {} self.xml_path = xml_path # сохраняем путь к xml self.manual_completion_active = False # --- Добавляем чекбокс для автодополнения --- self.autocomplete_checkbox = QCheckBox("Включить автодополнение") self.autocomplete_checkbox.setChecked(True) # Инициализируем QSettings с именем организации и приложения self.settings = QSettings("SET", "DebugVarEdit_VarsSelector") # Восстанавливаем сохранённое состояние чекбокса, если есть checked = self.settings.value("autocomplete_enabled", True, type=bool) self.autocomplete_checkbox.setChecked(checked) # При изменении состояния чекбокса сохраняем его self.autocomplete_checkbox.stateChanged.connect(self.save_checkbox_state) # Кнопки между таблицами self.btn_right = QPushButton(">") self.btn_right.clicked.connect(self.on_move_right) self.btn_left = QPushButton("<") self.btn_left.clicked.connect(self.on_move_left) # Создаем кнопки, они остаются в диалоге self.btn_add = QPushButton("Добавить выбранные") self.btn_delete = QPushButton("Удалить выбранные") # Создаем экземпляр вашего готового виджета self.vars_widget = selectTable.VariableSelectWidget(self) self.selected_vars_widget = selectTable.VariableSelectWidget(self) # --- Лэйауты --- main_layout = QVBoxLayout(self) # главный вертикальный layout окна tables_layout = QHBoxLayout() # горизонтальный layout с таблицами и кнопками # Левая таблица self.vars_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) tables_layout.addWidget(self.vars_widget) # Кнопки ">" и "<" между таблицами middle_buttons_layout = QVBoxLayout() middle_buttons_layout.addStretch() middle_buttons_layout.addWidget(self.btn_right) middle_buttons_layout.addWidget(self.btn_left) middle_buttons_layout.addStretch() tables_layout.addLayout(middle_buttons_layout) # Правая таблица self.selected_vars_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) tables_layout.addWidget(self.selected_vars_widget) # Добавляем горизонтальный layout с таблицами в главный вертикальный main_layout.addLayout(tables_layout) # Кнопки "Добавить выбранные" и "Удалить выбранные" под таблицами buttons_layout = QVBoxLayout() buttons_layout.addWidget(self.btn_add) buttons_layout.addWidget(self.btn_delete) main_layout.addLayout(buttons_layout) # Важно, если окно — QDialog или QWidget, установи layout self.setLayout(main_layout) # Соединяем сигналы кнопок с методами диалога self.btn_add.clicked.connect(self.on_add_clicked) self.btn_delete.clicked.connect(self.on_delete_clicked) # Соединяем чекбокс с методом виджета self.autocomplete_checkbox.stateChanged.connect(self.vars_widget.set_autocomplete) # Устанавливаем начальное состояние автодополнения в виджете self.vars_widget.set_autocomplete(self.autocomplete_checkbox.isChecked()) self.selected_vars_widget.set_autocomplete(self.autocomplete_checkbox.isChecked()) # --- Код в конце __init__ --- self.expanded_vars = setupVars.expand_vars(self.all_vars, self.structs, self.typedefs) self.update_vars_widget() def on_move_right(self): # Устанавливаем show_var=True для всех выбранных переменных из ЛЕВОЙ таблицы selected = self.vars_widget._get_internal_selected_var_names() if not selected: return def mark_selected_show_var(data): for var in data: if var['name'] in selected: var['show_var'] = 'true' if 'children' in var: mark_selected_show_var(var['children']) mark_selected_show_var(self.expanded_vars) self.update_vars_widget() def on_move_left(self): # Сбрасываем show_var=False для всех выбранных переменных из ПРАВОЙ таблицы selected = self.selected_vars_widget._get_internal_selected_var_names() if not selected: return def mark_selected_hide_var(data): for var in data: if var['name'] in selected: var['show_var'] = 'false' if 'children' in var: mark_selected_hide_var(var['children']) mark_selected_hide_var(self.expanded_vars) self.update_vars_widget() def update_vars_widget(self): self.selected_vars, self.unselected_vars = setupVars.split_vars_by_show_flag(self.expanded_vars) self.vars_widget.set_data(self.unselected_vars) self.vars_widget.filter_tree() self.selected_vars_widget.set_data(self.selected_vars) self.selected_vars_widget.filter_tree() def on_add_clicked(self): # Получаем все переменные из правой таблицы (selected_vars_widget) var_names = self.selected_vars_widget.get_all_var_names() all_items = self.selected_vars_widget.get_all_items() if not all_items: return def add_to_var_map_recursively(item): name = item.text(0) type_str = item.text(1) if name in self.var_map: var = self.var_map[name] var['show_var'] = 'true' var['enable'] = 'true' else: file_val = item.data(0, Qt.UserRole + 1) extern_val = item.data(0, Qt.UserRole + 2) static_val = item.data(0, Qt.UserRole + 3) new_var = { 'name': name, 'type': type_str, 'show_var': 'true', 'enable': 'true', 'shortname': name, 'pt_type': '', 'iq_type': '', 'return_type': 'iq_none', 'file': file_val, 'extern': str(extern_val).lower() if extern_val else 'false', 'static': str(static_val).lower() if static_val else 'false', } self.all_vars.append(new_var) self.var_map[name] = new_var for item in all_items: add_to_var_map_recursively(item) self.accept() def on_delete_clicked(self): # Получаем все элементы (QTreeWidgetItem) из правой таблицы all_items = self.selected_vars_widget.get_all_items() if not all_items: return affected_names = [] def disable_var_recursively(item): name = item.text(0) if name in self.var_map: self.var_map[name]['show_var'] = 'false' self.var_map[name]['enable'] = 'false' affected_names.append(name) # Рекурсивно отключаем детей for i in range(item.childCount()): child = item.child(i) disable_var_recursively(child) for item in all_items: disable_var_recursively(item) # Обновляем XML и таблицу self.update_xml_vars(affected_names, 'false', 'false') self.update_vars_widget() def update_xml_vars(self, names, show, enable): """Обновляет флаги show_var и enable в XML файле, только если у переменной нет вложенных структур.""" if not self.xml_path: return root, tree = myXML.safe_parse_xml(self.xml_path) if root is None: return vars_section = root.find('variables') if vars_section is None: return for var_elem in vars_section.findall('var'): if var_elem.attrib.get('name') in names: # Проверяем наличие вложенных структур или объединений has_nested_structs = any( var_elem.find(tag) is not None for tag in ('struct', 'union') ) if not has_nested_structs: def set_text(tag, value): el = var_elem.find(tag) if el is None: el = ET.SubElement(var_elem, tag) el.text = value set_text('show_var', show) set_text('enable', enable) myXML.fwrite(root, self.xml_path) def save_checkbox_state(self): self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked()) def keyPressEvent(self, event): if event.key() == Qt.Key_Delete: self.delete_selected_vars() else: super().keyPressEvent(event) def delete_selected_vars(self): selected_names = self._get_selected_var_names() if not selected_names: print("nothing selected") return # Обновляем var_map и all_vars for name in selected_names: if name in self.var_map: self.var_map[name]['show_var'] = 'false' self.var_map[name]['enable'] = 'false' for v in self.all_vars: if v['name'] == name: v['show_var'] = 'false' v['enable'] = 'false' break # Проверка пути к XML if not hasattr(self, 'xml_path') or not self.xml_path: from PySide2.QtWidgets import QMessageBox QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно обновить переменные.") return root, tree = myXML.safe_parse_xml(self.xml_path) if root is None: return vars_section = root.find('variables') if vars_section is None: return for var_elem in vars_section.findall('var'): name = var_elem.attrib.get('name') if name in selected_names: def set_text(tag, value): el = var_elem.find(tag) if el is None: el = ET.SubElement(var_elem, tag) el.text = value set_text('show_var', 'false') set_text('enable', 'false') myXML.fwrite(root, self.xml_path) self.table.populate(self.all_vars, self.structs, None) # Проверка пути к XML if not hasattr(self, 'xml_path') or not self.xml_path: from PySide2.QtWidgets import QMessageBox QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно удалить переменные.") return import xml.etree.ElementTree as ET root, tree = myXML.safe_parse_xml(self.xml_path) if root is None: return vars_section = root.find('variables') if vars_section is None: return removed_any = False for var_elem in list(vars_section.findall('var')): name = var_elem.attrib.get('name') if name in selected_names: vars_section.remove(var_elem) removed_any = True self.var_map.pop(name, None) # Удаляем из all_vars (глобально) self.all_vars[:] = [v for v in self.all_vars if v['name'] not in selected_names] # Удаляем из expanded_vars (тоже глобально) def filter_out_selected(vars_list): filtered = [] for v in vars_list: if v['name'] not in selected_names: # Рекурсивно фильтруем детей, если есть if 'children' in v: v = v.copy() v['children'] = filter_out_selected(v['children']) filtered.append(v) return filtered self.expanded_vars[:] = filter_out_selected(self.expanded_vars) if removed_any: myXML.fwrite(root, self.xml_path) self.update_vars_widget() def _get_selected_var_names(self): focused = self.focusWidget() if focused and focused is self.vars_widget.tree: return self.vars_widget.get_selected_var_names() elif focused and focused is self.selected_vars_widget.tree: return self.selected_vars_widget.get_selected_var_names() else: return [] def save_checkbox_state(self): self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked())