261 lines
10 KiB
Python
261 lines
10 KiB
Python
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())
|