bool RegisterHandler::setData(const QModelIndex &idx, const QVariant &data, int role) { if (role == BaseTreeView::ItemViewEventRole) { ItemViewEvent ev = data.value<ItemViewEvent>(); if (ev.type() == QEvent::ContextMenu) return contextMenuEvent(ev); } return RegisterModel::setData(idx, data, role); }
bool RegisterHandler::contextMenuEvent(const ItemViewEvent &ev) { const bool actionsEnabled = m_engine->debuggerActionsEnabled(); const DebuggerState state = m_engine->state(); RegisterItem *registerItem = itemForIndexAtLevel<1>(ev.index()); RegisterSubItem *registerSubItem = itemForIndexAtLevel<2>(ev.index()); const quint64 address = registerItem ? registerItem->addressValue() : 0; const QString registerName = registerItem ? registerItem->m_reg.name : QString(); auto menu = new QMenu; addAction(menu, tr("Reload Register Listing"), m_engine->hasCapability(RegisterCapability) && (state == InferiorStopOk || state == InferiorUnrunnable), [this] { m_engine->reloadRegisters(); }); menu->addSeparator(); addAction(menu, tr("Open Memory View at Value of Register %1 0x%2") .arg(registerName).arg(address, 0, 16), tr("Open Memory View at Value of Register"), address, [this, registerName, address] { MemoryViewSetupData data; data.startAddress = address; data.registerName = registerName; data.trackRegisters = true; data.separateView = true; m_engine->openMemoryView(data); }); addAction(menu, tr("Open Memory Editor at 0x%1").arg(address, 0, 16), tr("Open Memory Editor"), address && actionsEnabled && m_engine->hasCapability(ShowMemoryCapability), [this, registerName, address] { MemoryViewSetupData data; data.startAddress = address; data.registerName = registerName; data.markup = registerViewMarkup(address, registerName); data.title = registerViewTitle(registerName); m_engine->openMemoryView(data); }); addAction(menu, tr("Open Disassembler at 0x%1").arg(address, 0, 16), tr("Open Disassembler"), address && m_engine->hasCapability(DisassemblerCapability), [this, address] { m_engine->openDisassemblerView(Location(address)); }); addAction(menu, tr("Open Disassembler..."), m_engine->hasCapability(DisassemblerCapability), [this, address] { AddressDialog dialog; if (address) dialog.setAddress(address); if (dialog.exec() == QDialog::Accepted) m_engine->openDisassemblerView(Location(dialog.address())); }); menu->addSeparator(); const RegisterFormat currentFormat = registerItem ? registerItem->m_format : registerSubItem ? registerSubItem->parent()->m_format : HexadecimalFormat; auto addFormatAction = [menu, currentFormat, registerItem](const QString &display, RegisterFormat format) { addCheckableAction(menu, display, registerItem, currentFormat == format, [registerItem, format] { registerItem->m_format = format; registerItem->update(); }); }; addFormatAction(tr("Hexadecimal"), HexadecimalFormat); addFormatAction(tr("Decimal"), DecimalFormat); addFormatAction(tr("Octal"), OctalFormat); addFormatAction(tr("Binary"), BinaryFormat); menu->addSeparator(); menu->addAction(action(SettingsDialog)); menu->popup(ev.globalPos()); return true; }
bool StackHandler::contextMenuEvent(const ItemViewEvent &ev) { auto menu = new QMenu; const int row = ev.index().row(); StackFrame frame; if (row >= 0 && row < stackSize()) frame = frameAt(row); const quint64 address = frame.address; menu->addAction(action(ExpandStack)); addAction(menu, tr("Copy Contents to Clipboard"), true, [this] { copyContentsToClipboard(); }); addAction(menu, tr("Save as Task File..."), true, [this] { saveTaskFile(); }); if (m_engine->hasCapability(CreateFullBacktraceCapability)) menu->addAction(action(CreateFullBacktrace)); if (m_engine->hasCapability(AdditionalQmlStackCapability)) addAction(menu, tr("Load QML Stack"), true, [this] { m_engine->loadAdditionalQmlStack(); }); if (m_engine->hasCapability(ShowMemoryCapability)) addAction(menu, tr("Open Memory Editor at 0x%1").arg(address, 0, 16), tr("Open Memory Editor"), address, [this, row, frame, address] { MemoryViewSetupData data; data.startAddress = address; data.title = tr("Memory at Frame #%1 (%2) 0x%3") .arg(row).arg(frame.function).arg(address, 0, 16); data.markup.push_back(MemoryMarkup(address, 1, QColor(Qt::blue).lighter(), tr("Frame #%1 (%2)").arg(row).arg(frame.function))); m_engine->openMemoryView(data); }); if (m_engine->hasCapability(DisassemblerCapability)) { addAction(menu, tr("Open Disassembler at 0x%1").arg(address, 0, 16), tr("Open Disassembler"), address, [this, frame] { m_engine->openDisassemblerView(frame); }); addAction(menu, tr("Open Disassembler at Address..."), true, [this, address] { AddressDialog dialog; if (address) dialog.setAddress(address); if (dialog.exec() == QDialog::Accepted) m_engine->openDisassemblerView(Location(dialog.address())); }); addAction(menu, tr("Disassemble Function..."), true, [this] { const StackFrame frame = inputFunctionForDisassembly(); if (!frame.function.isEmpty()) m_engine->openDisassemblerView(Location(frame)); }); } if (m_engine->hasCapability(ShowModuleSymbolsCapability)) { addAction(menu, tr("Try to Load Unknown Symbols"), true, [this] { m_engine->loadSymbolsForStack(); }); } if (m_engine->hasCapability(MemoryAddressCapability)) menu->addAction(action(UseAddressInStackView)); menu->addSeparator(); menu->addAction(action(UseToolTipsInStackView)); menu->addSeparator(); menu->addAction(action(SettingsDialog)); menu->popup(ev.globalPos()); return true; }