def __init__(self, obj_map): self.obj_map = obj_map super().__init__() self.setWindowTitle("Object File Browser") self.childen_windows = [] layout = QVBoxLayout() monospaced_font = get_monospaced_font() layout.addWidget(QLabel("Browse object files by dgo...")) # Set up the tree view self.tree = QTreeView() self.tree_model = QStandardItemModel() self.tree_root = self.tree_model.invisibleRootItem() for dgo_name, dgo in obj_map.dgo_files.items(): dgo_entry = QStandardItem(dgo_name) dgo_entry.setFont(monospaced_font) dgo_entry.setEditable(False) for obj_name, obj in dgo.obj_files.items(): obj_entry = QStandardItem(obj_name) obj_entry.setFont(monospaced_font) obj_entry.setEditable(False) dgo_entry.appendRow(obj_entry) self.tree_root.appendRow(dgo_entry) self.tree.setModel(self.tree_model) self.tree.clicked.connect(self.handle_tree_click) self.tree.doubleClicked.connect(self.handle_tree_double_click) layout.addWidget(self.tree) # Set up the Search Box layout.addWidget(QLabel("Or search for object (regex):")) self.search_box = QLineEdit() self.search_box.textChanged.connect(self.handle_search_change) layout.addWidget(self.search_box) # Set up Search Results self.search_result = QListView() layout.addWidget(self.search_result) self.search_result.clicked.connect(self.handle_search_result_click) self.search_result.doubleClicked.connect( self.handle_search_result_double_click) self.search_result.setMaximumHeight(200) # Set up the info box at the bottom self.text_box = QPlainTextEdit() self.text_box.setReadOnly(True) self.text_box.setFont(monospaced_font) layout.addWidget(self.text_box) self.text_box.setMaximumHeight(100) self.text_box.setPlainText( "Select an object file to see details. Double click to open.") # add it to the window! widget = QWidget() widget.setLayout(layout) self.setCentralWidget(widget)
def handle_search_change(self, text): objs = self.obj_map.get_objs_matching_regex(text) model = QStandardItemModel() root = model.invisibleRootItem() monospaced_font = get_monospaced_font() for x in objs: entry = QStandardItem(x) entry.setFont(monospaced_font) entry.setEditable(False) root.appendRow(entry) self.search_result.setModel(model)
def display_function(self, item): name = item.data() monospaced_font = get_monospaced_font() func = self.functions_by_name[name] basic_op_model = QStandardItemModel() basic_op_root = basic_op_model.invisibleRootItem() asm_model = QStandardItemModel() asm_root = asm_model.invisibleRootItem() self.basic_id_to_asm = [] self.current_function = name op_idx = 0 basic_idx = 0 for op in func["asm"]: if "label" in op: asm_item = QStandardItem(op["label"] + "\n " + op["asm_op"]) else: asm_item = QStandardItem(" " + op["asm_op"]) asm_item.setFont(monospaced_font) asm_item.setEditable(False) asm_root.appendRow(asm_item) if "basic_op" in op: if "label" in op: basic_item = QStandardItem(op["label"] + "\n " + op["basic_op"]) else: basic_item = QStandardItem(" " + op["basic_op"]) basic_item.setFont(monospaced_font) basic_item.setEditable(False) basic_op_root.appendRow(basic_item) self.basic_id_to_asm.append(op_idx) basic_idx = basic_idx + 1 op_idx = op_idx + 1 self.basic_id_to_asm.append(op_idx) self.basic_op_pane.setModel(basic_op_model) self.asm_pane.setModel(asm_model) self.warnings_label.setText(func["warnings"]) self.asm_display.setPlainText("") self.function_header_label.setText( "{}, type: {}\nfunc: {} obj: {}".format(name, func["type"], func["name"], func["parent_object"]))
def __init__(self, name): super().__init__() self.setWindowTitle(name) with open( os.path.join(get_jak_path(), "decompiler_out", "{}_asm.json".format(name))) as f: self.asm_data = json.loads(f.read()) main_layout = QVBoxLayout() monospaced_font = get_monospaced_font() self.header_label = QLabel() main_layout.addWidget(self.header_label) function_splitter = QSplitter() function_splitter.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self.function_list = QTreeView() self.function_list_model = QStandardItemModel() self.functions_by_name = dict() root = self.function_list_model.invisibleRootItem() seg_roots = [] for i in range(3): seg_entry = QStandardItem(segment_id_to_name(i)) seg_entry.setFont(monospaced_font) seg_entry.setEditable(False) root.appendRow(seg_entry) seg_roots.append(seg_entry) for f in self.asm_data["functions"]: function_entry = QStandardItem(f["name"]) function_entry.setFont(monospaced_font) function_entry.setEditable(False) seg_roots[f["segment"]].appendRow(function_entry) self.functions_by_name[f["name"]] = f self.header_label.setText( "Object File {} Functions ({} total):".format( name, len(self.asm_data["functions"]))) self.function_list.setModel(self.function_list_model) self.function_list.clicked.connect(self.display_function) function_splitter.addWidget(self.function_list) layout = QVBoxLayout() self.function_header_label = QLabel("No function selected") self.function_header_label.setFont(monospaced_font) self.header_label.setSizePolicy( QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)) layout.addWidget(self.function_header_label) self.op_asm_split_view = QSplitter() self.op_asm_split_view.setSizePolicy( QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) self.basic_op_pane = QListView() self.basic_op_pane.clicked.connect(self.basic_op_clicked) #layout.addWidget(self.basic_op_pane) self.op_asm_split_view.addWidget(self.basic_op_pane) self.asm_pane = QListView() self.op_asm_split_view.addWidget(self.asm_pane) layout.addWidget(self.op_asm_split_view) self.asm_display = QPlainTextEdit() self.asm_display.setMaximumHeight(80) layout.addWidget(self.asm_display) self.warnings_label = QLabel() layout.addWidget(self.warnings_label) widget = QWidget() widget.setLayout(layout) function_splitter.addWidget(widget) main_layout.addWidget(function_splitter) # add it to the window! self.setLayout(main_layout)