базово разделены gui файлы и обработки xml базово работает, надо дорабатывать и тестить
168 lines
6.1 KiB
Python
168 lines
6.1 KiB
Python
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() |