def _init_widgets(self): layout = QGridLayout() row = 0 # validation_failures = set() addr = hex(self._addr) address_label = QLabel(self) address_label.setText(f"Hook at address {addr}:") layout.addWidget(address_label, row, 0) row += 1 options_container = QGroupBox(self) options = QVBoxLayout() for name, template in sorted(self.templates.items()): child = QRadioButton() child.setText(name) child.template = template child.toggled.connect(self.selected) options.addWidget(child) scroll_area = QScrollArea(self) scroll_area.setWidgetResizable(True) widget = QWidget() scroll_area.setWidget(widget) layout_scroll = QVBoxLayout(widget) header_label = QLabel(self) header_label.setText("Presets:") layout_scroll.addWidget(header_label) layout_scroll.addWidget(options_container) options_container.setLayout(options) layout.addWidget(scroll_area, row, 0) row += 1 function_box = CodeEdit(self) function_box.use_spaces_instead_of_tabs = True function_box.tab_length = 4 function_box.modes.append(CaretLineHighlighterMode()) function_box.modes.append( PygmentsSyntaxHighlighter(function_box.document())) function_box.modes.append(AutoIndentMode()) function_box.setWordWrapMode(QTextOption.WordWrap) self._function_box = function_box layout.addWidget(function_box, row, 0) row += 1 self.main_layout.addLayout(layout) buttons = QDialogButtonBox(parent=self) buttons.setStandardButtons(QDialogButtonBox.StandardButton.Cancel | QDialogButtonBox.StandardButton.Ok) buttons.button(QDialogButtonBox.Ok).setText('Append to Console') def do_ok(): code = function_box.toPlainText() self.instance.append_code_to_console(code) self.close() buttons.accepted.connect(do_ok) buttons.rejected.connect(self.close) self.main_layout.addWidget(buttons)
def _init_widgets(self): layout = QGridLayout() row = 0 # validation_failures = set() addr = hex(self._addr) address_label = QLabel(self) address_label.setText(f"Hook at address {addr}:") layout.addWidget(address_label, row, 0) row += 1 options_container = QGroupBox(self) options = QVBoxLayout() for name, template in sorted(self.templates.items()): child = QRadioButton() child.setText(name) child.template = template child.toggled.connect(self.selected) options.addWidget(child) scroll_area = QScrollArea(self) scroll_area.setWidgetResizable(True) widget = QWidget() scroll_area.setWidget(widget) layout_scroll = QVBoxLayout(widget) header_label = QLabel(self) header_label.setText("Presets:") layout_scroll.addWidget(header_label) layout_scroll.addWidget(options_container) options_container.setLayout(options) layout.addWidget(scroll_area, row, 0) row += 1 function_box = QPlainTextEdit(self) if addr in self.hooks.keys(): function_box.insertPlainText(self.hooks[addr]) highlight = PythonHighlighter(function_box.document()) function_box.setWordWrapMode(QTextOption.WordWrap) self._function_box = function_box layout.addWidget(function_box, row, 0) row += 1 # def add_indent(): # txt = function_box.toPlainText() # if txt.endswith('\n'): # embed() # indent = txt.search() # if txt.endswith(':\n'): # function_box.insertPlainText(' ') # function_box.textChanged.connect(add_indent) # TODO: add python autoindent # buttons ok_button = QPushButton(self) ok_button.setText('OK') def do_ok(): hook_code_string = function_box.toPlainText() self.instance.apply_hook(self._addr, hook_code_string) self.hooks[hex(self._addr)] = hook_code_string disasm_view = self.instance.workspace.view_manager.first_view_in_category( "disassembly") # So the hook icon shows up in the disasm view disasm_view.refresh() self.close() ok_button.clicked.connect(do_ok) cancel_button = QPushButton(self) cancel_button.setText('Cancel') def do_cancel(): self.close() cancel_button.clicked.connect(do_cancel) buttons_layout = QHBoxLayout() buttons_layout.addWidget(ok_button) buttons_layout.addWidget(cancel_button) self.main_layout.addLayout(layout) self.main_layout.addLayout(buttons_layout)