исправлен поиск и фильтрация

плюс делание всякого по коду для мк
This commit is contained in:
2025-07-11 17:57:29 +03:00
parent e4fcfd11d7
commit 0d54031dd5
8 changed files with 341 additions and 340 deletions

View File

@@ -228,7 +228,7 @@ class VariableSelectorDialog(QDialog):
text = self.search_input.text().strip()
else:
text = text.strip()
parts = self.split_path(text)
path_parts = parts[:-1] if parts else []
prefix = parts[-1].lower() if parts else ''
@@ -238,8 +238,6 @@ class VariableSelectorDialog(QDialog):
completions = []
def find_exact_node(parts):
# Ищем точный узел по полному пути, используя node_index
# Постепенно собираем fullname из parts
if not parts:
return None
fullname = parts[0]
@@ -251,7 +249,6 @@ class VariableSelectorDialog(QDialog):
base_text = text[:-1] # убираем '['
parent_node = self.find_node_by_fullname(base_text)
if not parent_node:
# если base_text может содержать индекс типа foo[12], попробуем очистить
base_text_clean = re.sub(r'\[\d+\]$', '', base_text)
parent_node = self.find_node_by_fullname(base_text_clean)
if parent_node:
@@ -267,24 +264,22 @@ class VariableSelectorDialog(QDialog):
return completions
if ends_with_sep:
# Путь завершен, показываем детей узла
node = self.find_node_by_fullname(text[:-1])
if node:
completions.extend(node.child(i).text(0) for i in range(node.childCount()))
elif not path_parts:
# Первый уровень — по вхождению
# Первый уровень — только если имя начинается с prefix
for i in range(self.tree.topLevelItemCount()):
item = self.tree.topLevelItem(i)
name = item.text(0).lower()
if prefix in name:
completions.append(item.text(0))
name = item.text(0)
if name.lower().startswith(prefix):
completions.append(name)
else:
node = find_exact_node(path_parts)
if node:
for i in range(node.childCount()):
child = node.child(i)
name = child.text(0)
# Оптимизируем split_path - кэширование
name_parts = child.data(0, Qt.UserRole + 10)
if name_parts is None:
name_parts = self.split_path(name)
@@ -292,16 +287,17 @@ class VariableSelectorDialog(QDialog):
if not name_parts:
continue
last_part = name_parts[-1].lower()
if prefix == '' or prefix in last_part: # здесь изменено
if prefix == '' or last_part.startswith(prefix): # ← строго startswith
completions.append(name)
self.completer.setModel(QStringListModel(completions))
self.completer.complete()
return completions
# Функция для поиска узла с полным именем
def find_node_by_fullname(self, name):
return self.node_index.get(name.lower())
@@ -665,29 +661,27 @@ class VariableSelectorDialog(QDialog):
def filter_vars(vars_list, path_parts):
"""Рекурсивно фильтруем vars_list по path_parts и возвращаем только подходящие."""
"""Рекурсивно фильтруем vars_list по path_parts по вхождению на любом уровне."""
filtered = []
def matches_path(name, search_parts):
name_parts = name.lower().split('.')
if len(name_parts) < len(search_parts):
return False
for sp, np in zip(search_parts, name_parts):
if not np.startswith(sp):
if sp not in np:
return False
return True
for var in vars_list:
fullname = var.get('fullname', var['name']) # желательно иметь полное имя
# Если фильтра нет — берем всё
if not path_parts or matches_path(fullname, path_parts):
# Копируем узел с рекурсией по детям
new_var = var.copy()
if 'children' in var:
new_var['children'] = filter_vars(var['children'], path_parts)
filtered.append(new_var)
else:
# Но даже если этот узел не подходит, может подойти его потомок
if 'children' in var:
child_filtered = filter_vars(var['children'], path_parts)
if child_filtered:
@@ -696,3 +690,5 @@ def filter_vars(vars_list, path_parts):
filtered.append(new_var)
return filtered

View File

@@ -147,13 +147,14 @@ def add_new_vars_to_xml(proj_path, xml_rel_path, output_path):
for line in f:
# {(char *)&some.deep.var.name , pt_uint16 , t_iq15 , "ShortName"},
m = re.match(
r'{\s*\(char\s*\*\)\s*&([a-zA-Z_][a-zA-Z0-9_]*)\s*,\s*(pt_\w+)\s*,\s*(t?iq_\w+)\s*,\s*"([^"]+)"',
line)
r'{\s*\(char\s*\*\)\s*&([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)\s*,\s*(pt_\w+)\s*,\s*(t?iq_\w+)\s*,\s*"([^"]+)"',
line)
if m:
full_varname = m.group(1) # e.g., some.deep.var.name
pt_type = m.group(2)
iq_type = m.group(3)
shortname = m.group(4)
return_type = m.group(4)
shortname = m.group(5)
parsed_vars[full_varname] = {
'pt_type': pt_type,
@@ -161,7 +162,7 @@ def add_new_vars_to_xml(proj_path, xml_rel_path, output_path):
'enable': True,
'show_var': True,
'shortname': shortname,
'return_type': 'int',
'return_type': return_type,
'type': '', # Можешь дополнить из externs
'file': '', # Можешь дополнить из externs
'extern': False,
@@ -330,8 +331,7 @@ def generate_vars_file(proj_path, xml_path, output_dir):
if not pt_type:
pt_type = map_type_to_pt(vtype, vname)
ret_type = info.get('pt_type')
ret_type = info.get('return_type')
if not ret_type:
pt_type = 't_iq_none'

View File

@@ -86,7 +86,7 @@ def parse_vars(filename, typedef_map=None):
'shortname': var.findtext('shortname', name),
'pt_type': pt_type,
'iq_type': iq_type,
'return_type': var.findtext('return_type', 'int'),
'return_type': var.findtext('return_type', ''),
'type': var_type,
'file': var.findtext('file', ''),
'extern': var.findtext('extern', 'false') == 'true',