debugVarTool/Src/VariableSelector.py

261 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import re
import xml.etree.ElementTree as ET
from PySide2.QtWidgets import (
QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton,
QLineEdit, QLabel, QHeaderView, QCompleter, QCheckBox, QHBoxLayout
)
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(600, 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_add = QPushButton("Добавить выбранные")
self.btn_delete = QPushButton("Удалить выбранные")
# Создаем экземпляр вашего готового виджета
self.vars_widget = selectTable.VariableSelectWidget(self)
# Собираем новую, более простую компоновку
search_layout = QHBoxLayout()
search_layout.addWidget(QLabel("Поиск:"))
search_layout.addStretch()
search_layout.addWidget(self.autocomplete_checkbox)
layout = QVBoxLayout(self)
layout.addLayout(search_layout)
layout.addWidget(self.vars_widget) # Добавляем ваш виджет целиком
button_layout = QHBoxLayout()
button_layout.addWidget(self.btn_add)
button_layout.addWidget(self.btn_delete)
layout.addLayout(button_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())
# --- Код в конце __init__ ---
self.expanded_vars = setupVars.expand_vars(self.all_vars, self.structs, self.typedefs)
# Передаем данные в виджет
self.vars_widget.set_data(self.expanded_vars)
def on_add_clicked(self):
# 5. Получаем имена из виджета
selected_items = self.vars_widget.get_selected_items()
if not selected_items:
return
for item in selected_items:
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
self.accept() # Используем accept() вместо done(QDialog.Accepted)
def on_delete_clicked(self):
# 5. Получаем имена из виджета
selected_names = self.vars_widget.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'
self.update_xml_vars(selected_names, 'false', 'false')
self.accept()
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:
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.filter_tree()
def _get_selected_var_names(self):
self.tree.setFocus()
return [item.text(0) for item in self.tree.selectedItems() if item.text(0)]
def save_checkbox_state(self):
self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked())