import re from PySide6.QtWidgets import ( QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton, QLineEdit, QLabel, QHeaderView ) from PySide6.QtCore import Qt from setupVars import * from scanVars import * array_re = re.compile(r'^(\w+)\[(\d+)\]$') class VariableSelectorDialog(QDialog): def __init__(self, all_vars, structs, typedefs, parent=None): super().__init__(parent) self.setWindowTitle("Выбор переменных") self.resize(600, 500) self.selected_names = [] 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.search_input = QLineEdit() self.search_input.setPlaceholderText("Поиск по имени переменной...") self.search_input.textChanged.connect(self.filter_tree) self.tree = QTreeWidget() self.tree.setHeaderLabels(["Имя переменной", "Тип"]) self.tree.setSelectionMode(QTreeWidget.ExtendedSelection) self.tree.setRootIsDecorated(False) # без иконки "вложенность" self.tree.setUniformRowHeights(True) # --- Автоматическая ширина колонок self.tree.setStyleSheet(""" QTreeWidget::item:selected { background-color: #87CEFA; color: black; } QTreeWidget::item:hover { background-color: #D3D3D3; } """) self.btn_add = QPushButton("Добавить выбранные") self.btn_add.clicked.connect(self.on_add_clicked) layout = QVBoxLayout() layout.addWidget(QLabel("Поиск:")) layout.addWidget(self.search_input) layout.addWidget(self.tree) layout.addWidget(self.btn_add) self.setLayout(layout) self.populate_tree() def add_tree_item_recursively(self, parent, var): """ Рекурсивно добавляет переменную и её дочерние поля в дерево. Если parent == None, добавляет на верхний уровень. """ name = var['name'] type_str = var.get('type', '') show_var = var.get('show_var', 'false') == 'true' item = QTreeWidgetItem([name, type_str]) item.setData(0, Qt.UserRole, name) for i, attr in enumerate(['file', 'extern', 'static']): item.setData(0, Qt.UserRole + 1 + i, var.get(attr)) if show_var: item.setForeground(0, Qt.gray) item.setForeground(1, Qt.gray) item.setToolTip(0, "Уже добавлена") item.setToolTip(1, "Уже добавлена") if parent is None: self.tree.addTopLevelItem(item) else: parent.addChild(item) for child in var.get('children', []): self.add_tree_item_recursively(item, child) def populate_tree(self): self.tree.clear() expanded_vars = expand_vars(self.all_vars, self.structs, self.typedefs) for var in expanded_vars: self.add_tree_item_recursively(None, var) header = self.tree.header() header.setSectionResizeMode(0, QHeaderView.Stretch) header.setSectionResizeMode(1, QHeaderView.ResizeToContents) def filter_tree(self): text = self.search_input.text().strip().lower() def match_recursive(item): matched = False for i in range(item.childCount()): child = item.child(i) if match_recursive(child): matched = True # Проверяем текущий элемент name = item.text(0).lower() typ = item.text(1).lower() if text in name or text in typ: matched = True item.setHidden(not matched) # Открываем только те элементы, у которых есть совпадение в потомках или в себе item.setExpanded(matched) return matched for i in range(self.tree.topLevelItemCount()): match_recursive(self.tree.topLevelItem(i)) def on_add_clicked(self): self.selected_names = [] for item in self.tree.selectedItems(): name = item.text(0) # имя переменной (в колонке 1) type_str = item.text(1) # тип переменной (в колонке 2) if not name or not type_str: continue self.selected_names.append((name, type_str)) 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 # Чтобы в будущем не добавлялось повторно self.accept()