def find(self, selected, item_type, entry_type, find): if not selected.IsOk(): self.status_bar.SetStatusText('No matches found') return # Get next item item = get_next_item(self.part_sets_list, selected) if not item.IsOk(): item, _ = get_first_item(self.part_sets_list) # Loop over while item != selected: data = self.part_sets_list.GetItemData(item) if (type(data) == item_type and (find is None or (isinstance(find, int) and data[entry_type] == find) or (isinstance(find, str) and find.lower() in data[entry_type].lower()))): self.select_found(item, entry_type) break item = get_next_item(self.part_sets_list, item) if not item.IsOk(): item, _ = get_first_item(self.part_sets_list) else: self.status_bar.SetStatusText('No matches found')
def reindex(self): # Set indexes first item, _ = get_first_item(self.entry_list) index = 1 mappings = {} while item.IsOk(): entry = self.entry_list.GetItemData(item) old_address, entry.address = entry.address, index_to_address(index) mappings[old_address] = entry.address self.entry_list.SetItemText(item, f'Entry {index}') item = get_next_item(self.entry_list, item) index += 1 # Set parent/child/sibling/root item, _ = get_first_item(self.entry_list) root = 0 entries = [self.entry_list.GetItemData(self.entry_list.GetRootItem())] while item.IsOk(): entry = self.entry_list.GetItemData(item) text = self.entry_list.GetItemText(item) sibling = self.entry_list.GetNextSibling(item) child, _ = self.entry_list.GetFirstChild(item) parent = self.entry_list.GetItemParent(item) sibling_address = self.entry_list.GetItemData( sibling).address if sibling.IsOk() else 0 child_address = self.entry_list.GetItemData( child).address if child.IsOk() else 0 # Root will always be one of the immediate childs to Entry 0 if parent == self.entry_list.GetRootItem(): root = entry.address # If the mapping for the sibling/child has been deleted, reset it if entry.sibling: entry.sibling = mappings.get(entry.sibling, 0) if not entry.sibling: entry.sibling = sibling_address if entry.child: entry.child = mappings.get(entry.child, 0) if not entry.child: entry.child = child_address entry.parent = self.entry_list.GetItemData( parent ).address if parent != self.entry_list.GetRootItem() else 0 entry.root = root if sibling_address != entry.sibling: text += f", Sibling: {address_to_index(entry.sibling)}" if child_address != entry.child: text += f", Child: {address_to_index(entry.child)}" self.entry_list.SetItemText(item, text) entries.append(entry) item = get_next_item(self.entry_list, item) self.parent.bcm.entries = entries
def on_find(self, _): # Get Item Type selection = self.items.GetSelection() item_type = ITEM_TYPES[selection] if selection < len( ITEM_TYPES) else None # Get Entry Type if item_type: bac_record = item_type.bac_record selection = self.entry.GetSelection() entry_type = bac_record.__fields__[selection] if selection < len( bac_record.__fields__) else None else: entry_type = None # Get Find value value = None try: value = self.get_value(self.find_ctrl) except ValueError: self.status_bar.SetStatusText("Invalid Value") if item_type is None or entry_type is None: self.status_bar.SetStatusText("Need a value to search for") return selected = self.entry_list.GetSelections() if len(selected) == 1: selected = selected[0] else: selected, _ = get_first_item(self.entry_list) self.find(selected, item_type, entry_type, value)
def add_bac_entry(self, append, bac_entry=None): bac_entry, data = self.get_parent_bac_entry(bac_entry) if not bac_entry or not data: return # Check if append or insert new_index = data.index if append: new_index += 1 # Add Entry new_entry = Entry(self.bac, new_index) self.bac.entries.insert(new_index, new_entry) # Insert into Treelist root = self.entry_list.GetRootItem() tree_index = 0 item, _ = get_first_item(self.entry_list) while item.IsOk(): text = self.entry_list.GetItemText(item) item_index = int(text.split(':')[0]) if new_index <= item_index: break tree_index += 1 item = self.entry_list.GetNextSibling(item) new_item = self.entry_list.InsertItem(root, tree_index, f'{new_index}: Entry', data=new_entry) return new_item, new_entry
def on_find(self, _): if not color_db.bcs: self.status_bar.SetStatusText("BCS not loaded") return # Get Item Type selection = self.items.GetSelection() item_type, fields = FIND_ITEM_TYPES[selection] # Get Entry Type selection = self.entry.GetSelection() entry_type = fields[selection] # Get Find value find = self.find_ctrl.GetValue() if "name" not in entry_type: try: find = int(find, 0) except ValueError: self.status_bar.SetStatusText("Invalid Value") return selected = self.part_sets_list.GetSelections() if len(selected) == 1: selected = selected[0] else: selected, _ = get_first_item(self.part_sets_list) self.find(selected, item_type, entry_type, find)
def find(self, item_type, entry_type, value): item = get_first_item(self.entry_list)[0] while item.IsOk(): data = self.entry_list.GetItemData(item) if self.entry == data: item = self.entry_list.GetNextSibling(item) continue elif isinstance(data, item_type) and data[entry_type] == value: return 'Conflict Found!' item = get_next_item(self.entry_list, item) return ''
def convert_for_skill_creator(self): if not self.bac: with wx.MessageDialog(self, "No BAC loaded!", "Error") as dlg: dlg.ShowModal() return # Get Choices choices = set() item, _ = get_first_item(self.entry_list) while item.IsOk(): data = self.entry_list.GetItemData(item) item = get_next_item(self.entry_list, item) if 'skill_id' not in data.__fields__: continue if data.skill_id != 0 and data.skill_id != 0xFFFF and data.skill_id != 0xBACA: choices.update([str(data.skill_id)]) if not choices: with wx.MessageDialog(self, "Cannot find any Skill IDs to convert", "Error") as dlg: dlg.ShowModal() return # Show Dialog with ConvertDialog(self, list(choices)) as dlg: if dlg.ShowModal() != wx.ID_OK: return skill_id = dlg.GetValue() # Do conversion item, _ = get_first_item(self.entry_list) changed = 0 while item.IsOk(): data = self.entry_list.GetItemData(item) if 'skill_id' in data.__fields__ and data.skill_id == skill_id: data.skill_id = 0xBACA changed += 1 item = get_next_item(self.entry_list, item) self.on_select(None) pub.sendMessage('set_status_bar', text=f'Changed {changed} skill ids to 0xBACA')
def find_next_available_index(self, item_type, entry, dependency, depend_value): max_value = 0 item = get_first_item(self.entry_list)[0] while item.IsOk(): data = self.entry_list.GetItemData(item) if isinstance(data, item_type) and \ (not dependency or data[dependency] == depend_value) and data[entry] != 0xFFFF: max_value = max(data[entry], max_value) item = get_next_item(self.entry_list, item) return max_value + 1
def on_find(self, _): entry_type = self.choices[self.entry.GetSelection()] value = None try: value = self.get_value(self.find_ctrl) except ValueError: self.status_bar.SetStatusText("Invalid Value") selected = self.entry_list.GetSelections() if len(selected) == 1 and selected[0] != self.entry_list.GetRootItem(): selected = selected[0] else: selected = get_first_item(self.entry_list)[0] self.find(selected, entry_type, value)
def reindex(self, selected=None): for i, entry in enumerate(self.bac.entries): entry.index = i # entry.flags = entry.flags & 0xF if len(entry.sub_entries) > 0 else (entry.flags & 0x0F) | 0x80000000 entry.sub_entries.sort(key=lambda n: n.type) for j, sub_entry in enumerate(entry.sub_entries): sub_entry.index = j sub_entry.items.sort(key=lambda n: n.start_time) for k, item in enumerate(sub_entry.items): item.index = k item, _ = get_first_item(self.entry_list) hidden = self.parent.hidden.GetValue() # Fix tree names while item.IsOk(): to_delete = None data = self.entry_list.GetItemData(item) if data.get_name() == 'Entry': if selected != item and hidden and not self.entry_list.GetFirstChild( item)[0].IsOk(): to_delete = item else: self.entry_list.SetItemText( item, f'{data.index}: Entry (0x{data.flags:X})') elif data.get_name() == 'SubEntry': if selected != item and hidden and not self.entry_list.GetFirstChild( item)[0].IsOk(): to_delete = item else: self.entry_list.SetItemText( item, f'{data.type}: {data.get_type_name()}') sub_entry = self.entry_list.GetItemData(item) for entry in sub_entry.items: item = get_next_item(self.entry_list, item) self.entry_list.SetItemData(item, entry) # UNLEASHED: do the same as the build_sub_tree function if entry.description and entry.description_type: self.entry_list.SetItemText( item, str(entry.start_time) + " - " + entry.description.get( entry.__getattr__(entry.description_type), 'Unknown')) else: self.entry_list.SetItemText( item, str(entry.start_time)) item = get_next_item(self.entry_list, item) if to_delete: self.entry_list.Delete(to_delete)
def on_replace_all(self, _): if not color_db.bcs: self.status_bar.SetStatusText("BCS Not Loaded") return item_type, fields = FIND_ITEM_TYPES[self.items.GetSelection()] entry_type = fields[self.entry.GetSelection()] find = self.find_ctrl.GetValue() replace = self.replace_ctrl.GetValue() if "name" not in entry_type: try: find = int(self.find_ctrl.GetValue(), 0) replace = int(self.replace_ctrl.GetValue(), 0) except ValueError: self.status_bar.SetStatusText("Invalid Value") return count = 0 skipped = 0 skipped_entries = set() item, _ = get_first_item(self.part_sets_list) while item.IsOk(): data = self.part_sets_list.GetItemData(item) res = self.replace_item(data, item_type, entry_type, find, replace, skipped_entries) if res == Replace.REPLACED: count += 1 elif res == Replace.SKIPPED: skipped += 1 item = get_next_item(self.part_sets_list, item) self.main_panel.pages["Part Sets"].on_select(None) pub.sendMessage('reindex_part_sets') msg = f'Replaced {count} entry(s) (skipped {skipped}). ' if skipped: msg += "Check your part colors" self.status_bar.SetStatusText(msg) if item_type == ColorSelector and skipped_entries: if entry_type == "part_colors": msg = "\n".join( f" * Color Selector ({cs[0]}, {cs[1]}) -> ({replace}, {cs[1]})" for cs in sorted(skipped_entries)) else: msg = "\n".join( f" * Color Selector ({cs[0]}, {cs[1]}) -> ({cs[0]}, {replace})" for cs in sorted(skipped_entries)) with MultiMessageDialog( self, f"The following Color Selectors were skipped.\n" f"Please check your part colors.", "Warning", msg, wx.OK) as dlg: dlg.ShowModal()
def find(self, selected, entry_type, find): if not selected.IsOk(): self.status_bar.SetStatusText('No matches found') return item = get_next_item(self.entry_list, selected) while item != selected: data = self.entry_list.GetItemData(item) if find is None or data[entry_type] == find or ( isinstance(data[entry_type], float) and abs(data[entry_type] - find) < 0.000001): self.select_found(item, entry_type) break item = get_next_item(self.entry_list, item) if not item.IsOk(): item = get_first_item(self.entry_list)[0] else: self.status_bar.SetStatusText('No matches found')
def on_replace_all(self, _): entry_type = self.choices[self.entry.GetSelection()] try: find = self.get_value(self.find_ctrl) replace = self.get_value(self.replace_ctrl) except ValueError: self.status_bar.SetStatusText("Invalid Value") return None count = 0 item = get_first_item(self.entry_list)[0] while item.IsOk(): data = self.entry_list.GetItemData(item) if data[entry_type] == find or ( isinstance(data[entry_type], float) and abs(data[entry_type] - find) < 0.000001): data[entry_type] = replace count += 1 item = get_next_item(self.entry_list, item) pub.sendMessage('on_select', _=None) self.status_bar.SetStatusText(f'Replaced {count} entry(s)')
def on_replace(self, _): if not color_db.bcs: self.status_bar.SetStatusText("BCS Not Loaded") return item_type, fields = FIND_ITEM_TYPES[self.items.GetSelection()] entry_type = fields[self.entry.GetSelection()] find = self.find_ctrl.GetValue() replace = self.replace_ctrl.GetValue() if "name" not in entry_type: try: find = int(find, 0) replace = int(replace, 0) except ValueError: self.status_bar.SetStatusText("Invalid Value") return selected = self.part_sets_list.GetSelections() # Only do this if we have don't have one selected item if len(selected) != 1: item, _ = get_first_item(self.part_sets_list) self.find(item, item_type, entry_type, find) return selected = selected[0] data = self.part_sets_list.GetItemData(selected) # Check to see if current entry is not one we're looking for res = self.replace_item(data, item_type, entry_type, find, replace) # Reload if replaced if res == Replace.REPLACED: self.main_panel.pages["Part Sets"].on_select(None) # Find next item to replace self.find(selected, item_type, entry_type, find) if res == Replace.REPLACED: self.status_bar.SetStatusText(f"Replaced 1 entry") elif res == Replace.SKIPPED: self.status_bar.SetStatusText( f"Skipped 1 entry. Check your part colors")
def on_replace_all(self, _): item_type = ITEM_TYPES[self.items.GetSelection()] entry_type = item_type.bac_record.__fields__[self.entry.GetSelection()] try: find = self.get_value(self.find_ctrl) replace = self.get_value(self.replace_ctrl) except ValueError as e: print(e) self.status_bar.SetStatusText("Invalid Value") return None count = 0 item = get_first_item(self.entry_list)[0] while item.IsOk(): data = self.entry_list.GetItemData(item) if type(data) == item_type and ( data[entry_type] == find or (isinstance(data[entry_type], float) and abs(data[entry_type] - find) < 0.000001)): data[entry_type] = replace count += 1 item = get_next_item(self.entry_list, item) pub.sendMessage('on_select', _=None) pub.sendMessage('reindex') self.status_bar.SetStatusText(f'Replaced {count} entry(s)')
def on_replace(self, _): item_type = ITEM_TYPES[self.items.GetSelection()] entry_type = item_type.bac_record.__fields__[self.entry.GetSelection()] try: find = self.get_value(self.find_ctrl) replace = self.get_value(self.replace_ctrl) except ValueError: self.status_bar.SetStatusText("Invalid Value") return None selected = self.entry_list.GetSelections() # Only do this if we have one selected item if len(selected) != 1: self.find(get_first_item(self.entry_list)[0], item_type, entry_type, find) return selected = selected[0] data = self.entry_list.GetItemData(selected) # Check to see if current entry is not one we're looking for if type(data) == item_type and data[entry_type] == find: data[entry_type] = replace self.select_found(selected, entry_type) pub.sendMessage('reindex') self.find(selected, item_type, entry_type, find)