From 4b7c23d095258a0c50844f9af84926a917011656 Mon Sep 17 00:00:00 2001 From: HelioGuilherme66 Date: Mon, 16 Dec 2024 02:36:12 +0000 Subject: [PATCH] WIP but already changes from step to resource. Problems with non prefixed --- src/robotide/controller/ctrlcommands.py | 16 ++- src/robotide/controller/macrocontrollers.py | 10 +- src/robotide/controller/settingcontrollers.py | 4 +- src/robotide/controller/stepcontrollers.py | 28 +++-- src/robotide/editor/macroeditors.py | 2 + src/robotide/ui/treeplugin.py | 106 ++++++++++++++++-- src/robotide/usages/UsageRunner.py | 6 +- 7 files changed, 145 insertions(+), 27 deletions(-) diff --git a/src/robotide/controller/ctrlcommands.py b/src/robotide/controller/ctrlcommands.py index 40612d7ad..077f77c94 100644 --- a/src/robotide/controller/ctrlcommands.py +++ b/src/robotide/controller/ctrlcommands.py @@ -93,7 +93,8 @@ def _in_for_loop(self): return isinstance(self._item.parent, ForLoopStepController) def replace_keyword(self, new_name): - # print(f"DEBUG: ctrlcommands.py replace_keyword new_name={new_name}") + print(f"DEBUG: ctrlcommands.py Occurrence replace_keyword BEFORE new_name={new_name} value={self._value}" + f" self._replaced={self._replaced} item={self._item}") self._item.replace_keyword(*self._get_replace_values(new_name)) self._replaced = not self._replaced @@ -284,8 +285,9 @@ def __init__(self, original_name, new_name, observer, keyword_info=None): self._original_name, self._new_name = self._check_gherkin(new_name, original_name ) - # print(f"DEBUG: ctrlcommands.py RenameKeywordOccurrences ENTER after check_gherkin\n" - # f"self._original_name={self._original_name} self._new_name={self._new_name} ") + print(f"DEBUG: ctrlcommands.py RenameKeywordOccurrences ENTER after check_gherkin\n" + f"{original_name=}, {new_name=}, self._original_name={self._original_name} " + f"self._new_name={self._new_name} ") self._observer = observer self._keyword_info = keyword_info self._occurrences = None @@ -341,6 +343,12 @@ def _replace_keywords_in(self, occurrences): def _notify_values_changed(self, occurrences, old_name=None): for oc in occurrences: + try: + print(f"DEBUG: ctlcommands.py RenameKeywordOccurrences _notify_values_changed: " + f"oc= {oc.source} {oc.item} {oc.usage} {oc._value}") + except AttributeError: + print(f"DEBUG: ctlcommands.py RenameKeywordOccurrences _notify_values_changed: " + f" in AttributeError oc= {oc.item} {oc.usage} {oc._value}") oc.notify_value_changed(old_name) self._observer.notify() @@ -721,7 +729,7 @@ def _find_occurrences_in(self, items): from .tablecontrollers import VariableTableController print(f"DEBUG: ctrlcommands _find_occurrences_in NORMALIZED NAME {self.normalized_name}") for item in items: - print(f"DEBUG: ctrlcommands _find_occurrences_in searching item={item}") + # print(f"DEBUG: ctrlcommands _find_occurrences_in searching item={item}") if self._contains_item(item) or (not isinstance(item, VariableTableController) and (item.contains_keyword(self.normalized_name) or item.contains_keyword(self.normalized_name.replace(' ', '_')))): diff --git a/src/robotide/controller/macrocontrollers.py b/src/robotide/controller/macrocontrollers.py index 54e38cc6f..1c3c6b054 100644 --- a/src/robotide/controller/macrocontrollers.py +++ b/src/robotide/controller/macrocontrollers.py @@ -43,8 +43,8 @@ def __init__(self, item): self._item = item def contains_keyword(self, name): - print(f"DEBUG: macrocontrollers.py ItemNameController contains_keyword: item={self._item.name} search=" - f"{name}") + # print(f"DEBUG: macrocontrollers.py ItemNameController contains_keyword: item={self._item.name} search=" + # f"{name}") if isinstance(name, str): return self._item.name == name return name.match(self._item.name) @@ -60,6 +60,7 @@ def rename(self, new_name): self._item.rename(new_name) def notify_value_changed(self, old_name=None): + print(f"DEBUG: macrocontrollers.py notify_value_changed item={self._item.name} old_name={old_name}") self._item.notify_name_changed(old_name) @property @@ -187,6 +188,7 @@ def delete(self): self.notify_keyword_removed() def rename(self, new_name): + print(f"DEBUG: macrocontrollers.py WithStepsController rename BEFORE new_name={new_name} old_name={self.data.name}") self.data.name = new_name.strip() self.mark_dirty() @@ -299,8 +301,10 @@ def notify_settings_changed(self): self.update_namespace() self._notify(RideItemSettingsChanged) - def notify_steps_changed(self): + def notify_steps_changed(self, old_name=None): self._has_steps_changed = True + print(f"DEBUG: macrocontrollers.py WithStepsController notify_steps_changed: ENTER old_name={old_name}" + f" {self.parent} {self.source} {self} call self._notify") self._notify(RideItemStepsChanged) def _notify(self, messageclass): diff --git a/src/robotide/controller/settingcontrollers.py b/src/robotide/controller/settingcontrollers.py index 9c34b8b45..fedd623dc 100644 --- a/src/robotide/controller/settingcontrollers.py +++ b/src/robotide/controller/settingcontrollers.py @@ -70,8 +70,8 @@ def keyword_name(self): def contains_keyword(self, name): istring = isinstance(name, str) - print(f"DEBUG: settingcontrollers.py _SettingController contains_keyword: item={self} search=" - f"{name}") + # print(f"DEBUG: settingcontrollers.py _SettingController contains_keyword: item={self} search=" + # f"{name}") matcher = name.match if not istring else lambda i: utils.eq(i, name) return self._contains_keyword(matcher) diff --git a/src/robotide/controller/stepcontrollers.py b/src/robotide/controller/stepcontrollers.py index 41f53fc03..a162c1c43 100644 --- a/src/robotide/controller/stepcontrollers.py +++ b/src/robotide/controller/stepcontrollers.py @@ -18,6 +18,7 @@ from .. import robotapi, utils from .basecontroller import _BaseController from .cellinfo import CellPosition, CellType, CellInfo, CellContent, ContentType, UPPERCASE_KWS +from ..publish.messages import RideItemNameChanged from ..namespace.local_namespace import local_namespace from ..utils import variablematcher @@ -285,24 +286,34 @@ def contains_keyword(self, name): for item in [self.keyword or ''] + self.args) def _kw_name_match(self, item, expected): - print(f"DEBUG: stepcontrollers.py StepController kw_name_match: item={item} expected={expected}") if isinstance(expected, str): return utils.eq(item, expected) or (self._GIVEN_WHEN_THEN_MATCHER.match(item) and utils.eq(self._GIVEN_WHEN_THEN_MATCHER.sub('', item), expected)) - return expected.match(item) + matcher = expected.match(item) + if matcher: + old_prefix = matcher.group(1) + print(f"DEBUG: stepcontrollers.py StepController kw_name_match: RE expected={expected}" + f" matcher={matcher} old_prefix={old_prefix}") + return matcher def replace_keyword(self, new_name, old_name): # DEBUG: Create setters for Step.name and Step.args - if self._kw_name_match(self.keyword or '', old_name): - self.step_controller_step.name = self.step_controller_step.cells[self.step_controller_step.inner_kw_pos] =\ + new_match = self._kw_name_match(self.keyword or '', old_name) + if new_match: + print(f"DEBUG: stepcontrollers.py StepController replace_keyword: ACTUAL CHANGE old_name={old_name}" + f" new_name={new_name} new_match={new_match}") + self.step_controller_step.name = self.step_controller_step.cells[self.step_controller_step.inner_kw_pos] = \ self._kw_name_replace(self.keyword, new_name, old_name) for index, value in enumerate(self.args): if self._kw_name_match(value, old_name): self.step_controller_step.args[index] = self.step_controller_step.cells[ - self.step_controller_step.inner_kw_pos + 1 + index] =\ + self.step_controller_step.inner_kw_pos + 1 + index] = \ self._kw_name_replace(value, new_name, old_name) def _kw_name_replace(self, old_value, new_match, old_match): + # Here we should have a match for keywords prefixed with resource name + print(f"DEBUG: stepcontrollers.py StepController _kw_name_replace: ENTER old_value={old_value}" + f" old_match={old_match} new_match={new_match}") old_prefix_matcher = self._GIVEN_WHEN_THEN_MATCHER.match(old_value) if not old_prefix_matcher: return new_match @@ -552,8 +563,11 @@ def _recreate_next_step(self, index): next_step.recreate(next_step.as_list()) def notify_value_changed(self, old_name=None): - _ = old_name - self.parent.notify_steps_changed() + print(f"DEBUG: stepcontrollers.py StepController notify_value_changed: ENTER old_name={old_name}" + f" parent={self.parent.name} calling self.parent.notify_steps_changed()") + if old_name is not None: + RideItemNameChanged(item=self, old_name=old_name).publish() + self.parent.notify_steps_changed(old_name) def increase_indent(self): self.indent.append('') diff --git a/src/robotide/editor/macroeditors.py b/src/robotide/editor/macroeditors.py index dbb2e11fc..1a7a45188 100644 --- a/src/robotide/editor/macroeditors.py +++ b/src/robotide/editor/macroeditors.py @@ -39,6 +39,8 @@ def _create_kweditor(self): self._editors.append(self.kweditor) def _name_changed(self, message): + print(f"DEBUG: macroeditors.py TestCaseEditor _name_changed ENTER {message}\n" + f" {message.item.name=} {self.controller}") if message.item == self.controller: self.header.SetLabel(message.item.name) diff --git a/src/robotide/ui/treeplugin.py b/src/robotide/ui/treeplugin.py index 7be8abde0..d7b990ce5 100644 --- a/src/robotide/ui/treeplugin.py +++ b/src/robotide/ui/treeplugin.py @@ -31,10 +31,10 @@ SKIPPED_IMAGE_INDEX, ROBOT_IMAGE_INDEX) from ..ui.treenodehandlers import TestCaseHandler, TestDataDirectoryHandler, TestCaseFileHandler from ..publish import (PUBLISHER, RideTreeSelection, RideFileNameChanged, RideItem, RideUserKeywordAdded, - RideTestCaseAdded, RideUserKeywordRemoved, RideTestCaseRemoved, RideDataFileRemoved, - RideDataChangedToDirty, RideDataDirtyCleared, RideVariableRemoved, RideVariableAdded, - RideVariableMovedUp, RideVariableMovedDown, RideVariableUpdated, RideOpenResource, - RideSuiteAdded, RideSelectResource, RideDataFileSet, RideItemNameChanged) + RideTestCaseAdded, RideUserKeywordRemoved, RideUserKeywordRenamed, RideTestCaseRemoved, + RideDataFileRemoved, RideDataChangedToDirty, RideDataDirtyCleared, RideVariableRemoved, + RideVariableAdded, RideVariableMovedUp, RideVariableMovedDown, RideVariableUpdated, + RideOpenResource, RideSuiteAdded, RideSelectResource, RideDataFileSet, RideItemNameChanged) from ..controller.ctrlcommands import MoveTo from ..pluginapi import Plugin from ..action import ActionInfo @@ -305,8 +305,8 @@ def unregister_context_menu_hook(self, callable_m): def _subscribe_to_messages(self): subscriptions = [ + (self._item_renamed, RideItemNameChanged), (self._item_changed, RideItem), - (self._item_changed, RideItemNameChanged), (self._resource_added, RideOpenResource), (self._select_resource, RideSelectResource), (self._suite_added, RideSuiteAdded), @@ -720,12 +720,13 @@ def select_node_by_data(self, controller): Controller can be any of the controllers that are represented in the tree.""" parent_node = self._get_datafile_node(controller.datafile) + print(f"DEBUG: treeplugin.py Tree select_node_by_data parent_node={parent_node}") if not parent_node: return None if not self.IsExpanded(parent_node): self._expand_and_render_children(parent_node) node = self.controller.find_node_by_controller(controller) - if node != self.GetSelection(): + if node and node != self.GetSelection(): self.SelectItem(node) return node @@ -1085,10 +1086,10 @@ def on_move_down(self, event): handler.on_move_down(event) def _item_changed(self, message): + if isinstance(message, RideItemNameChanged): + return controller = message.item node = self.controller.find_node_by_controller(controller) - if hasattr(message, 'old_name'): - print(f"DEBUG: treeplugin.py Tree _item_changed RENAMED node={node}, old_name={message.old_name}") if node: self.SetItemText(node, message.item.name) @@ -1096,6 +1097,95 @@ def _item_changed(self, message): self.controller.mark_node_dirty( self._get_datafile_node(controller.datafile)) + def _item_renamed(self, message): + from ..lib.robot.parsing.settings import Resource + if not isinstance(message, RideItemNameChanged): + return + controller = message.item + print(f"DEBUG: treeplugin.py Tree _item_renamed ENTER controller={controller.display_name}") + node = self.controller.find_node_by_controller(controller) + if hasattr(controller.datafile, 'setting_table'): + imports = controller.datafile.setting_table.imports + print(f"DEBUG: treeplugin.py Tree _item_renamed HAS IMPORTS imports={imports}") + for imp in imports: + if isinstance(imp, Resource): + print(f"DEBUG: treeplugin.py Tree _item_renamed IMPORT message.item.name={message.item.keyword}," + f" old_name={message.old_name} resource name={imp.name}") + # print(f"DEBUG: treeplugin.py Tree _item_renamed IMPORT message.item.name={message}," + # f" old_name={message.old_name} import={imp}") + self._rename_resource_kw(new_name=message.item.keyword, old_name=message.old_name, resource=imp) + # if node and hasattr(message, 'old_name'): + # print(f"DEBUG: treeplugin.py Tree _item_renamed RENAMED node={node}, old_name={message.old_name}") + self.Refresh() + if node: + self.EnsureVisible(node) + self.SelectItem(node) + self.SetItemText(node, message.item.name) + new_name=self.GetItemText(node) + print(f"DEBUG: treeplugin.py Tree _item_renamed AFTER RENAMED new_name={new_name}" + f" controller={controller.datafile}") + else: + return + if controller.dirty: + self.controller.mark_node_dirty( + self._get_datafile_node(controller.datafile)) + + def _rename_resource_kw(self, new_name, old_name, resource): + prefix_new = new_name.split('.')[0] + prefix_old = old_name.split('.')[0] + prefix_res = os.path.basename(resource.name).split('.')[0] + if not prefix_new == prefix_old == prefix_res: + return + keyword_name = old_name.split('.')[-1] + new_keyword_name = new_name.split('.')[-1] + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw {prefix_res=} {keyword_name=}") + res_name=os.path.basename(resource.name) + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw {res_name=}") + res_node=self.FindItem(self._resource_root, res_name) + if res_node: + self.EnsureVisible(res_node) + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw root node {res_node=}") + # node = self.controller.find_node_with_label(res_node, keyword_name) + self._expand_and_render_children(res_node) + node = self.FindItem(res_node, keyword_name) + if node: + from ..controller.ctrlcommands import RenameKeywordOccurrences + from ..ui.progress import RenameProgressObserver + nlabel = node.GetText() + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw node label {nlabel} {keyword_name}") + if nlabel == keyword_name: + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw {node=} {nlabel} change to {new_keyword_name=}") + self.EnsureVisible(node) + # self.SetItemText(node, new_keyword_name) + self.SelectItem(node) + controller = self.get_selected_datafile_controller() + keywords = controller.keywords + keyword_names = controller.get_keyword_names() + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw already changed to {new_keyword_name=}" + f" controller={controller} keywords={keywords} \n" + f"{keyword_names=}") + for k in keywords.items: + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw keywords: {k=}") + if k.name == keyword_name: + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw CHANGING: {k.name=}") + if controller.validate_keyword_name(new_keyword_name): + k.name = new_keyword_name + RideUserKeywordRenamed(datafile=controller.datafile, item=k, + old_name=keyword_name).publish() + controller.mark_dirty() + print(f"DEBUG: treeplugin.py Tree _rename_resource_kw DONE CHANGING: {k.name=}") + # self.controller.mark_node_dirty(self._get_datafile_node(controller.datafile)) + self.observer = RenameProgressObserver(self.GetParent()) + RenameKeywordOccurrences(keyword_name, new_keyword_name, self.observer) + self.observer.finish() + self.Collapse(res_node) + self.Expand(res_node) + self.SelectItem(res_node) + else: + wx.MessageBox(f"Invalid keyword name: {new_keyword_name}", + "Failed Keyword Name Validation") + return + def _variable_moved_up(self, message): if self._should_update_variable_positions(message): self._do_action_if_datafile_node_is_expanded(self.move_up, message) diff --git a/src/robotide/usages/UsageRunner.py b/src/robotide/usages/UsageRunner.py index 525568d8b..a03125f6f 100644 --- a/src/robotide/usages/UsageRunner.py +++ b/src/robotide/usages/UsageRunner.py @@ -57,9 +57,9 @@ def show(self): def _run(self): wx.CallAfter(self._begin_search) names = [ self._name ] - if self.prefix != '' and '.' not in self._name: - names.append(f'{self.prefix}.{self._name}') - print(f"DEBUG: UsageRunner.py Usages _run before loop with _find_usages names={names}") + # if self.prefix != '' and '.' not in self._name: + # names.append(f'{self.prefix}.{self._name}') + # print(f"DEBUG: UsageRunner.py Usages _run before loop with _find_usages names={names}") for name in names: # DEBUG for usage in self._find_usages(name): time.sleep(0) # GIVE SPACE TO OTHER THREADS -- Thread.yield in Java