diff --git a/ui/adaptersettings.cpp b/ui/adaptersettings.cpp index 95f41260..3959b9bc 100644 --- a/ui/adaptersettings.cpp +++ b/ui/adaptersettings.cpp @@ -28,6 +28,9 @@ using namespace std; AdapterSettingsDialog::AdapterSettingsDialog(QWidget* parent, DbgRef controller, const std::string& highlightGroup) : QDialog(), m_controller(controller), m_highlightGroup(highlightGroup) { + setProperty("bn.uiTestId", "debugger.adapterSettingsDialog"); + setProperty("bn.uiTestScope", "debugger.adapterSettingsDialog"); + setAccessibleName("Debug Adapter Settings"); setWindowTitle("Debug Adapter Settings"); setAttribute(Qt::WA_DeleteOnClose); @@ -37,6 +40,8 @@ AdapterSettingsDialog::AdapterSettingsDialog(QWidget* parent, DbgRefsetSpacing(0); m_adapterEntry = new QComboBox(this); + m_adapterEntry->setProperty("bn.uiTestId", "debugger.adapterSettingsDialog.adapter"); + m_adapterEntry->setAccessibleName("Debug adapter"); for (const std::string& adapter : DebugAdapterType::GetAvailableAdapters(m_controller->GetData())) { m_adapterEntry->addItem(QString::fromStdString(adapter)); @@ -63,6 +68,8 @@ AdapterSettingsDialog::AdapterSettingsDialog(QWidget* parent, DbgRefsetAlignment(Qt::AlignCenter); m_stack = new QStackedWidget(this); + m_stack->setProperty("bn.uiTestId", "debugger.adapterSettingsDialog.settings"); + m_stack->setAccessibleName("Debug adapter settings"); m_stack->addWidget(m_noSettingsLabel); auto widget = getWidgetForAdapter(m_adapterEntry->currentText()); @@ -71,6 +78,7 @@ AdapterSettingsDialog::AdapterSettingsDialog(QWidget* parent, DbgRefsetProperty("bn.uiTestId", "debugger.adapterSettingsDialog.reuseSettings"); m_useSameSettingsCheckbox->setChecked(!m_controller->ShowAdapterSettingsNextTime()); if (!highlightGroup.empty()) @@ -85,8 +93,10 @@ AdapterSettingsDialog::AdapterSettingsDialog(QWidget* parent, DbgRefsetContentsMargins(0, 0, 0, 0); QPushButton* cancelButton = new QPushButton("Cancel"); + cancelButton->setProperty("bn.uiTestId", "debugger.adapterSettingsDialog.cancel"); connect(cancelButton, &QPushButton::clicked, [&]() { reject(); }); QPushButton* acceptButton = new QPushButton("Accept"); + acceptButton->setProperty("bn.uiTestId", "debugger.adapterSettingsDialog.accept"); connect(acceptButton, &QPushButton::clicked, [&]() { apply(); }); acceptButton->setDefault(true); diff --git a/ui/attachprocess.cpp b/ui/attachprocess.cpp index da6e7365..2f289d3a 100644 --- a/ui/attachprocess.cpp +++ b/ui/attachprocess.cpp @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include "../../../ui/shared/internalaction.h" #include "attachprocess.h" @@ -288,6 +289,9 @@ void ProcessListWidget::contextMenuEvent(QContextMenuEvent* event) ProcessListWidget::ProcessListWidget(QWidget* parent, DbgRef controller) : QTableView(parent), m_controller(controller) { + setProperty("bn.uiTestId", "debugger.processList"); + setProperty("bn.uiTestScope", "debugger.processList"); + setAccessibleName("Debug processes"); m_model = new ProcessListModel(this); m_delegate = new ProcessItemDelegate(this); m_filter = new ProcessListFilterProxyModel(this); @@ -321,7 +325,7 @@ ProcessListWidget::ProcessListWidget(QWidget* parent, DbgRef m_contextMenuManager = new ContextMenuManager(this); QString actionName = QString::fromStdString("Refresh"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { updateContent(); })); @@ -392,13 +396,21 @@ void ProcessListWidget::activateSelection() {} AttachProcessDialog::AttachProcessDialog(QWidget* parent, DbgRef controller) : QDialog(parent) { + setProperty("bn.uiTestId", "debugger.attachProcessDialog"); + setProperty("bn.uiTestScope", "debugger.attachProcessDialog"); + setAccessibleName("Attach to process"); setWindowTitle("Attach to process"); setMinimumSize(UIContext::getScaledWindowSize(800, 600)); setSizeGripEnabled(true); setModal(true); m_processListWidget = new ProcessListWidget(this, controller); + m_processListWidget->setProperty("bn.uiTestId", "debugger.attachProcessDialog.processes"); + m_processListWidget->setProperty("bn.uiTestScope", "debugger.attachProcessDialog.processes"); + m_processListWidget->setAccessibleName("Processes available to attach"); m_separateEdit = new FilterEdit(m_processListWidget); + m_separateEdit->setProperty("bn.uiTestId", "debugger.attachProcessDialog.filter"); + m_separateEdit->setAccessibleName("Search processes"); m_separateEdit->showRegexToggle(true); m_filter = new FilteredView(this, m_processListWidget, m_processListWidget, m_separateEdit); m_filter->setFilterPlaceholderText("Search process"); @@ -418,9 +430,11 @@ AttachProcessDialog::AttachProcessDialog(QWidget* parent, DbgRefsetContentsMargins(0, 0, 0, 0); QPushButton* cancelButton = new QPushButton("Cancel"); + cancelButton->setProperty("bn.uiTestId", "debugger.attachProcessDialog.cancel"); connect(cancelButton, &QPushButton::clicked, [&]() { reject(); }); QPushButton* acceptButton = new QPushButton("Attach"); + acceptButton->setProperty("bn.uiTestId", "debugger.attachProcessDialog.attach"); connect(acceptButton, &QPushButton::clicked, [&]() { apply(); }); acceptButton->setDefault(true); diff --git a/ui/breakpointswidget.cpp b/ui/breakpointswidget.cpp index a3dc39ce..f1a512f8 100644 --- a/ui/breakpointswidget.cpp +++ b/ui/breakpointswidget.cpp @@ -1,3 +1,4 @@ +#include "../../../ui/shared/internalaction.h" /* Copyright 2020-2026 Vector 35 Inc. @@ -383,13 +384,13 @@ DebugBreakpointsWidget::DebugBreakpointsWidget(ViewFrame* view, BinaryViewRef da m_menu = menu; QString removeBreakpointActionName = QString::fromStdString("Remove Breakpoint"); - UIAction::registerAction(removeBreakpointActionName, QKeySequence::Delete); + UIIdentity::registerBuiltInAction(removeBreakpointActionName, QKeySequence::Delete); m_menu->addAction(removeBreakpointActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( removeBreakpointActionName, UIAction([&]() { remove(); }, [&]() { return selectionNotEmpty(); })); QString jumpToBreakpointActionName = QString::fromStdString("Jump To Breakpoint"); - UIAction::registerAction(jumpToBreakpointActionName); + UIIdentity::registerBuiltInAction(jumpToBreakpointActionName); m_menu->addAction(jumpToBreakpointActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( jumpToBreakpointActionName, UIAction([&]() { jump(); }, [&]() { return selectionNotEmpty(); })); @@ -399,24 +400,25 @@ DebugBreakpointsWidget::DebugBreakpointsWidget(ViewFrame* view, BinaryViewRef da "Copy", UIAction([&]() { copySelection(); }, [&]() { return selectionNotEmpty(); }), HighActionPriority); QString addBreakpointActionName = QString::fromStdString("Add Breakpoint..."); - UIAction::registerAction(addBreakpointActionName); + UIIdentity::registerBuiltInAction(addBreakpointActionName); m_menu->addAction(addBreakpointActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( addBreakpointActionName, UIAction([&]() { addSoftwareBreakpoint(); })); QString addHardwareBreakpointActionName = QString::fromStdString("Add Hardware Breakpoint..."); + UIIdentity::registerBuiltInAction(addHardwareBreakpointActionName); m_menu->addAction(addHardwareBreakpointActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( addHardwareBreakpointActionName, UIAction([&]() { addHardwareBreakpoint(); })); QString toggleEnabledActionName = QString::fromStdString("Toggle Enabled"); - UIAction::registerAction(toggleEnabledActionName, QKeySequence("Ctrl+Shift+B")); + UIIdentity::registerBuiltInAction(toggleEnabledActionName, QKeySequence("Ctrl+Shift+B")); m_menu->addAction(toggleEnabledActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( toggleEnabledActionName, UIAction([&]() { toggleSelected(); }, [&]() { return selectionNotEmpty(); })); QString editConditionActionName = QString::fromStdString("Edit Condition..."); - UIAction::registerAction(editConditionActionName); + UIIdentity::registerBuiltInAction(editConditionActionName); m_menu->addAction(editConditionActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( editConditionActionName, UIAction([&]() { editCondition(); }, [&]() { @@ -425,19 +427,19 @@ DebugBreakpointsWidget::DebugBreakpointsWidget(ViewFrame* view, BinaryViewRef da })); QString enableAllActionName = QString::fromStdString("Enable All Breakpoints"); - UIAction::registerAction(enableAllActionName); + UIIdentity::registerBuiltInAction(enableAllActionName); m_menu->addAction(enableAllActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( enableAllActionName, UIAction([&]() { enableAll(); })); QString disableAllActionName = QString::fromStdString("Disable All Breakpoints"); - UIAction::registerAction(disableAllActionName); + UIIdentity::registerBuiltInAction(disableAllActionName); m_menu->addAction(disableAllActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( disableAllActionName, UIAction([&]() { disableAll(); })); QString soloBreakpointActionName = QString::fromStdString("Solo Breakpoint"); - UIAction::registerAction(soloBreakpointActionName); + UIIdentity::registerBuiltInAction(soloBreakpointActionName); m_menu->addAction(soloBreakpointActionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( soloBreakpointActionName, UIAction([&]() { soloSelected(); }, [&]() { return selectionNotEmpty(); })); @@ -596,8 +598,13 @@ void DebugBreakpointsWidget::add() // Show options for software or hardware breakpoint QMenu menu(this); + menu.setProperty("bn.uiTestId", "debugger.breakpoints.addMenu"); + menu.setProperty("bn.uiTestScope", "debugger.breakpoints.addMenu"); + menu.setAccessibleName("Add debugger breakpoint"); QAction* softwareAction = menu.addAction("Software Breakpoint"); + softwareAction->setProperty("bn.uiTestId", "debugger.breakpoints.addSoftware"); QAction* hardwareAction = menu.addAction("Hardware Breakpoint..."); + hardwareAction->setProperty("bn.uiTestId", "debugger.breakpoints.addHardware"); QAction* chosen = menu.exec(QCursor::pos()); if (!chosen) diff --git a/ui/controlswidget.cpp b/ui/controlswidget.cpp index 913cd1a1..df15b2ad 100644 --- a/ui/controlswidget.cpp +++ b/ui/controlswidget.cpp @@ -39,6 +39,9 @@ using namespace BinaryNinja; DebugControlsWidget::DebugControlsWidget(QWidget* parent, const std::string name, BinaryViewRef data) : QToolBar(parent), m_name(name) { + setProperty("bn.uiTestId", "debugger.controls"); + setProperty("bn.uiTestScope", "debugger.controls"); + setAccessibleName("Debugger controls"); m_controller = DebuggerController::GetController(data); if (!m_controller) return; @@ -51,16 +54,19 @@ DebugControlsWidget::DebugControlsWidget(QWidget* parent, const std::string name m_actionRun = addAction(getColoredIcon(":/debugger/start", red), "Launch", [this]() { performLaunch(); }); + m_actionRun->setProperty("bn.uiTestId", "debugger.controls.launch"); m_actionRun->setToolTip(getToolTip("Launch")); m_actionPause = addAction(getColoredIcon(":/debugger/pause", white), "Pause", [this]() { performPause(); }); + m_actionPause->setProperty("bn.uiTestId", "debugger.controls.pause"); m_actionPause->setToolTip(getToolTip("Pause")); m_actionResume = addAction(getColoredIcon(":/debugger/resume", green), "Resume", [this]() { performResume(); }); + m_actionResume->setProperty("bn.uiTestId", "debugger.controls.resume"); m_actionResume->setToolTip(getToolTip("Resume")); // m_actionRun->setVisible(true); @@ -70,50 +76,59 @@ DebugControlsWidget::DebugControlsWidget(QWidget* parent, const std::string name m_actionAttachPid = addAction(getColoredIcon(":/debugger/connect", white), "Attach To Process...", [this]() { performAttachPID(); }); + m_actionAttachPid->setProperty("bn.uiTestId", "debugger.controls.attachProcess"); m_actionAttachPid->setToolTip(getToolTip("Attach To Process...")); m_actionDetach = addAction(getColoredIcon(":/debugger/disconnect", red), "Detach", [this]() { performDetach(); }); + m_actionDetach->setProperty("bn.uiTestId", "debugger.controls.detach"); m_actionDetach->setVisible(false); m_actionDetach->setToolTip(getToolTip("Detach")); m_actionRestart = addAction(getColoredIcon(":/debugger/restart", red), "Restart", [this]() { performRestart(); }); + m_actionRestart->setProperty("bn.uiTestId", "debugger.controls.restart"); m_actionRestart->setToolTip(getToolTip("Restart")); m_actionQuit = addAction(getColoredIcon(":/debugger/cancel", red), "Kill", [this]() { performQuit(); }); + m_actionQuit->setProperty("bn.uiTestId", "debugger.controls.kill"); m_actionQuit->setToolTip(getToolTip("Kill")); addSeparator(); m_actionStepInto = addAction(getColoredIcon(":/debugger/step-into", cyan), "Step Into", [this]() { performStepInto(); }); + m_actionStepInto->setProperty("bn.uiTestId", "debugger.controls.stepInto"); m_actionStepInto->setToolTip(getToolTip("Step Into")); m_actionStepOver = addAction(getColoredIcon(":/debugger/step-over", cyan), "Step Over", [this]() { performStepOver(); }); + m_actionStepOver->setProperty("bn.uiTestId", "debugger.controls.stepOver"); m_actionStepOver->setToolTip(getToolTip("Step Over")); m_actionStepReturn = addAction(getColoredIcon(":/debugger/step-out", cyan), "Step Return", [this]() { performStepReturn(); }); + m_actionStepReturn->setProperty("bn.uiTestId", "debugger.controls.stepReturn"); m_actionStepReturn->setToolTip(getToolTip("Step Return")); addSeparator(); m_actionSettings = addAction(getColoredIcon(":/debugger/settings", cyan), "Settings", [this]() { performSettings(); }); + m_actionSettings->setProperty("bn.uiTestId", "debugger.controls.settings"); m_actionSettings->setToolTip(getToolTip("Debug Adapter Settings")); addSeparator(); m_actionToggleBreakpoint = addAction(getColoredIcon(":/debugger/breakpoint", red), "Breakpoint", [this]() { toggleBreakpoint(); }); + m_actionToggleBreakpoint->setProperty("bn.uiTestId", "debugger.controls.toggleBreakpoint"); m_actionToggleBreakpoint->setToolTip(getToolTip("Toggle Breakpoint")); if(m_controller->IsTTD()) @@ -122,36 +137,43 @@ DebugControlsWidget::DebugControlsWidget(QWidget* parent, const std::string name m_actionGoBack = addAction(getColoredIcon(":/debugger/resume-reverse", red), "Go Backwards", [this]() { performGoReverse(); }); + m_actionGoBack->setProperty("bn.uiTestId", "debugger.controls.goBackward"); m_actionGoBack->setToolTip(getToolTip("Go Backwards")); m_actionStepIntoBack = addAction(getColoredIcon(":/debugger/step-into-reverse", red), "Step Into Backwards", [this]() { performStepIntoReverse(); }); + m_actionStepIntoBack->setProperty("bn.uiTestId", "debugger.controls.stepIntoBackward"); m_actionStepIntoBack->setToolTip(getToolTip("Step Into Backwards")); m_actionStepOverBack = addAction(getColoredIcon(":/debugger/step-back", red), "Step Over Backwards", [this]() { performStepOverReverse(); }); + m_actionStepOverBack->setProperty("bn.uiTestId", "debugger.controls.stepOverBackward"); m_actionStepOverBack->setToolTip(getToolTip("Step Over Backwards")); m_actionStepReturnBack = addAction(getColoredIcon(":/debugger/step-out-reverse", red), "Step Return Backwards", [this]() { performStepReturnReverse(); }); + m_actionStepReturnBack->setProperty("bn.uiTestId", "debugger.controls.stepReturnBackward"); m_actionStepReturnBack->setToolTip(getToolTip("Step Return Backwards")); m_actionTimestampNavigation = addAction(getColoredIcon(":/debugger/ttd-timestamp", cyan), "Navigate to Timestamp", [this]() { performTimestampNavigation(); }); + m_actionTimestampNavigation->setProperty("bn.uiTestId", "debugger.controls.navigateTimestamp"); m_actionTimestampNavigation->setToolTip(getToolTip("Navigate to TTD Timestamp...")); m_actionTTDNavigateBack = addAction(getColoredIcon(":/debugger/ttd-back", cyan), "TTD Navigate Back", [this]() { performTTDNavigateBack(); }); + m_actionTTDNavigateBack->setProperty("bn.uiTestId", "debugger.controls.ttdBack"); m_actionTTDNavigateBack->setToolTip(getToolTip("TTD Navigate Back")); m_actionTTDNavigateForward = addAction(getColoredIcon(":/debugger/ttd-forward", cyan), "TTD Navigate Forward", [this]() { performTTDNavigateForward(); }); + m_actionTTDNavigateForward->setProperty("bn.uiTestId", "debugger.controls.ttdForward"); m_actionTTDNavigateForward->setToolTip(getToolTip("TTD Navigate Forward")); updateButtons(); diff --git a/ui/debuggerinfowidget.cpp b/ui/debuggerinfowidget.cpp index c2ab9d82..069b47a9 100644 --- a/ui/debuggerinfowidget.cpp +++ b/ui/debuggerinfowidget.cpp @@ -32,6 +32,9 @@ using namespace std; DebugInfoSidebarWidget::DebugInfoSidebarWidget(BinaryViewRef data): SidebarWidget("Debugger Info"), m_data(data) { + setProperty("bn.uiTestId", "sidebar.debuggerInfo"); + setProperty("bn.uiTestScope", "sidebar.debuggerInfo"); + setAccessibleName("Debugger Info"); m_debugger = DebuggerController::GetController(data); auto* layout = new QVBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); @@ -891,6 +894,8 @@ DebuggerInfoEntry DebuggerInfoEntryItemModel::getRow(int row) const DebuggerInfoTable::DebuggerInfoTable(BinaryViewRef data): m_data(data) { + setProperty("bn.uiTestId", "sidebar.debuggerInfo.entries"); + setAccessibleName("Debugger information"); m_debugger = DebuggerController::GetController(data); m_model = new DebuggerInfoEntryItemModel(this, data); diff --git a/ui/debuggerwidget.cpp b/ui/debuggerwidget.cpp index a25472bd..edb84dbd 100644 --- a/ui/debuggerwidget.cpp +++ b/ui/debuggerwidget.cpp @@ -31,6 +31,9 @@ using namespace std; DebuggerWidget::DebuggerWidget(const QString& name, ViewFrame* view, BinaryViewRef data) : SidebarWidget(name), m_view(view) { + setProperty("bn.uiTestId", "sidebar.debugger"); + setProperty("bn.uiTestScope", "sidebar.debugger"); + setAccessibleName("Debugger"); m_controller = DebuggerController::GetController(data); QVBoxLayout* layout = new QVBoxLayout(this); @@ -39,6 +42,8 @@ DebuggerWidget::DebuggerWidget(const QString& name, ViewFrame* view, BinaryViewR layout->setAlignment(Qt::AlignTop); m_adapterSelector = new QComboBox(); + m_adapterSelector->setProperty("bn.uiTestId", "debugger.sidebar.adapter"); + m_adapterSelector->setAccessibleName("Debug adapter"); // Populate adapter selector for (const std::string& adapter : DebugAdapterType::GetAvailableAdapters(m_controller->GetData())) { @@ -68,14 +73,19 @@ DebuggerWidget::DebuggerWidget(const QString& name, ViewFrame* view, BinaryViewR layout->addWidget(m_adapterSelector); m_splitter = new QSplitter(Qt::Vertical, this); + m_splitter->setProperty("bn.uiTestId", "debugger.sidebar.splitter"); m_splitter->setChildrenCollapsible(true); m_controlsWidget = new DebugControlsWidget(this, "Controls", data); m_tabs = new QTabWidget(this); + m_tabs->setProperty("bn.uiTestId", "debugger.sidebar.tabs"); + m_tabs->setAccessibleName("Debugger sidebar tabs"); m_registersWidget = new DebugRegistersContainer(m_view, data, m_menu); m_breakpointsWidget = new DebugBreakpointsWidget(m_view, data, m_menu); + m_breakpointsWidget->setProperty("bn.uiTestId", "debugger.sidebar.breakpoints"); + m_breakpointsWidget->setAccessibleName(tr("Debugger Breakpoints")); m_tabs->addTab(m_registersWidget, "Registers"); m_tabs->addTab(m_breakpointsWidget, "Breakpoints"); diff --git a/ui/hardwarebreakpointdialog.cpp b/ui/hardwarebreakpointdialog.cpp index 51ce9c85..e16d3d10 100644 --- a/ui/hardwarebreakpointdialog.cpp +++ b/ui/hardwarebreakpointdialog.cpp @@ -21,6 +21,9 @@ limitations under the License. HardwareBreakpointDialog::HardwareBreakpointDialog(QWidget* parent, DbgRef controller, uint64_t suggestedAddress) : QDialog(parent), m_controller(controller), m_suggestedAddress(suggestedAddress) { + setProperty("bn.uiTestId", "debugger.hardwareBreakpointDialog"); + setProperty("bn.uiTestScope", "debugger.hardwareBreakpointDialog"); + setAccessibleName("Add Hardware Breakpoint"); setWindowTitle("Add Hardware Breakpoint"); setModal(true); resize(350, 150); @@ -30,12 +33,16 @@ HardwareBreakpointDialog::HardwareBreakpointDialog(QWidget* parent, DbgRefsetProperty("bn.uiTestId", "debugger.hardwareBreakpointDialog.address"); + m_addressEdit->setAccessibleName("Hardware breakpoint address"); if (suggestedAddress != 0) m_addressEdit->setText(QString("0x%1").arg(suggestedAddress, 0, 16)); formLayout->addRow("Address:", m_addressEdit); // Type selection m_typeCombo = new QComboBox(); + m_typeCombo->setProperty("bn.uiTestId", "debugger.hardwareBreakpointDialog.type"); + m_typeCombo->setAccessibleName("Hardware breakpoint type"); m_typeCombo->addItem("Hardware Execute", static_cast(HardwareExecuteBreakpoint)); m_typeCombo->addItem("Hardware Read", static_cast(HardwareReadBreakpoint)); m_typeCombo->addItem("Hardware Write", static_cast(HardwareWriteBreakpoint)); @@ -61,6 +68,8 @@ HardwareBreakpointDialog::HardwareBreakpointDialog(QWidget* parent, DbgRefsetProperty("bn.uiTestId", "debugger.hardwareBreakpointDialog.size"); + m_sizeCombo->setAccessibleName("Hardware breakpoint size"); m_sizeCombo->setEditable(true); m_sizeCombo->addItem("1", 1); m_sizeCombo->addItem("2", 2); @@ -71,6 +80,9 @@ HardwareBreakpointDialog::HardwareBreakpointDialog(QWidget* parent, DbgRefsetProperty("bn.uiTestId", "debugger.hardwareBreakpointDialog.buttons"); + m_buttonBox->button(QDialogButtonBox::Ok)->setProperty("bn.uiTestId", "debugger.hardwareBreakpointDialog.add"); + m_buttonBox->button(QDialogButtonBox::Cancel)->setProperty("bn.uiTestId", "debugger.hardwareBreakpointDialog.cancel"); // Main layout QVBoxLayout* mainLayout = new QVBoxLayout(); @@ -185,4 +197,4 @@ void HardwareBreakpointDialog::typeChanged() // Execution breakpoints are always 1 byte if (type == HardwareExecuteBreakpoint) m_sizeCombo->setCurrentIndex(0); -} \ No newline at end of file +} diff --git a/ui/memorymapwidget.cpp b/ui/memorymapwidget.cpp index 9678bf84..0c065e72 100644 --- a/ui/memorymapwidget.cpp +++ b/ui/memorymapwidget.cpp @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include "../../../ui/shared/internalaction.h" #include #include #include @@ -274,6 +275,9 @@ QSize DebugMemoryMapItemDelegate::sizeHint(const QStyleOptionViewItem& option, c DebugMemoryMapWidget::DebugMemoryMapWidget(ViewFrame* view, BinaryViewRef data) : QTableView(view), m_view(view) { + setProperty("bn.uiTestId", "debugger.memoryMap.table"); + setProperty("bn.uiTestScope", "debugger.memoryMap.table"); + setAccessibleName("Debugger memory regions"); m_controller = DebuggerController::GetController(data); if (!m_controller) return; @@ -305,12 +309,12 @@ DebugMemoryMapWidget::DebugMemoryMapWidget(ViewFrame* view, BinaryViewRef data) m_contextMenuManager = new ContextMenuManager(this); QString actionName = QString::fromStdString("Jump To Start"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { jumpToStart(); })); actionName = QString::fromStdString("Jump To End"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { jumpToEnd(); })); @@ -343,13 +347,13 @@ DebugMemoryMapWidget::DebugMemoryMapWidget(ViewFrame* view, BinaryViewRef data) m_actionHandler.bindAction("Copy All", UIAction([&]() { copyAll(); }, [&]() { return canCopyAll(); })); actionName = QString::fromStdString("Select In Binary View"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( actionName, UIAction([this]() { selectInView(); }, [this]() { return canSelectRegion(); })); actionName = QString::fromStdString("Save Region To Disk..."); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_LAST); m_actionHandler.bindAction( actionName, UIAction([this]() { saveToDisk(); }, [this]() { return canSaveRegion(); })); @@ -750,8 +754,13 @@ void DebugMemoryMapWidget::activateSelection() {} DebugMemoryMapWithFilter::DebugMemoryMapWithFilter(ViewFrame* view, BinaryViewRef data) : m_view(view) { + setProperty("bn.uiTestId", "debugger.memoryMap"); + setProperty("bn.uiTestScope", "debugger.memoryMap"); + setAccessibleName("Debugger Memory Map"); m_memoryMap = new DebugMemoryMapWidget(view, data); m_separateEdit = new FilterEdit(m_memoryMap); + m_separateEdit->setProperty("bn.uiTestId", "debugger.memoryMap.filter"); + m_separateEdit->setAccessibleName("Search debugger memory regions"); m_separateEdit->showRegexToggle(true); m_filter = new FilteredView(this, m_memoryMap, m_memoryMap, m_separateEdit); m_filter->setFilterPlaceholderText("Search memory regions"); @@ -766,6 +775,8 @@ DebugMemoryMapWithFilter::DebugMemoryMapWithFilter(ViewFrame* view, BinaryViewRe headerLayout->setAlignment(Qt::AlignBaseline); auto* icon = new ClickableIcon(QImage(":/debugger/menu"), QSize(16, 16)); + icon->setProperty("bn.uiTestId", "debugger.memoryMap.menu"); + icon->setAccessibleName("Debugger memory map menu"); connect(icon, &ClickableIcon::clicked, m_memoryMap, &DebugMemoryMapWidget::showContextMenu); headerLayout->addWidget(icon); @@ -785,6 +796,9 @@ void DebugMemoryMapWithFilter::updateFonts() DebugMemoryMapContainer::DebugMemoryMapContainer(ViewFrame* frame, BinaryViewRef data) : SidebarWidget("Debugger Memory Map") { + setProperty("bn.uiTestId", "sidebar.debuggerMemoryMap"); + setProperty("bn.uiTestScope", "sidebar.debuggerMemoryMap"); + setAccessibleName("Debugger Memory Map"); m_widget = new DebugMemoryMapWithFilter(frame, data); auto* layout = new QVBoxLayout(this); diff --git a/ui/moduleswidget.cpp b/ui/moduleswidget.cpp index 035a6543..c1945c7d 100644 --- a/ui/moduleswidget.cpp +++ b/ui/moduleswidget.cpp @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include "../../../ui/shared/internalaction.h" #include #include #include @@ -295,6 +296,9 @@ QSize DebugModulesItemDelegate::sizeHint(const QStyleOptionViewItem& option, con DebugModulesWidget::DebugModulesWidget(ViewFrame* view, BinaryViewRef data) : QTableView(view), m_view(view) { + setProperty("bn.uiTestId", "debugger.modules.table"); + setProperty("bn.uiTestScope", "debugger.modules.table"); + setAccessibleName("Debugger modules"); m_controller = DebuggerController::GetController(data); if (!m_controller) return; @@ -326,12 +330,12 @@ DebugModulesWidget::DebugModulesWidget(ViewFrame* view, BinaryViewRef data) : QT m_contextMenuManager = new ContextMenuManager(this); QString actionName = QString::fromStdString("Jump To Start"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { jumpToStart(); })); actionName = QString::fromStdString("Jump To End"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { jumpToEnd(); })); @@ -742,8 +746,13 @@ void DebugModulesWidget::activateSelection() {} DebugModulesWithFilter::DebugModulesWithFilter(ViewFrame* view, BinaryViewRef data) : m_view(view) { + setProperty("bn.uiTestId", "debugger.modules"); + setProperty("bn.uiTestScope", "debugger.modules"); + setAccessibleName("Debugger Modules"); m_modules = new DebugModulesWidget(view, data); m_separateEdit = new FilterEdit(m_modules); + m_separateEdit->setProperty("bn.uiTestId", "debugger.modules.filter"); + m_separateEdit->setAccessibleName("Search debugger modules"); m_separateEdit->showRegexToggle(true); m_filter = new FilteredView(this, m_modules, m_modules, m_separateEdit); m_filter->setFilterPlaceholderText("Search modules"); @@ -758,6 +767,8 @@ DebugModulesWithFilter::DebugModulesWithFilter(ViewFrame* view, BinaryViewRef da headerLayout->setAlignment(Qt::AlignBaseline); auto* icon = new ClickableIcon(QImage(":/debugger/menu"), QSize(16, 16)); + icon->setProperty("bn.uiTestId", "debugger.modules.menu"); + icon->setAccessibleName("Debugger modules menu"); connect(icon, &ClickableIcon::clicked, m_modules, &DebugModulesWidget::showContextMenu); headerLayout->addWidget(icon); @@ -776,6 +787,9 @@ void DebugModulesWithFilter::updateFonts() DebugModulesContainer::DebugModulesContainer(ViewFrame* frame, BinaryViewRef data) : SidebarWidget("Debugger Modules") { + setProperty("bn.uiTestId", "sidebar.debuggerModules"); + setProperty("bn.uiTestScope", "sidebar.debuggerModules"); + setAccessibleName("Debugger Modules"); m_widget = new DebugModulesWithFilter(frame, data); auto* layout = new QVBoxLayout(this); diff --git a/ui/registerswidget.cpp b/ui/registerswidget.cpp index 10fb6c44..fb312253 100644 --- a/ui/registerswidget.cpp +++ b/ui/registerswidget.cpp @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include "../../../ui/shared/internalaction.h" #include #include #include @@ -421,6 +422,9 @@ void DebugRegistersWidget::updateColumnWidths() DebugRegistersWidget::DebugRegistersWidget(ViewFrame* view, BinaryViewRef data, Menu* menu) : QTableView(view), m_view(view) { + setProperty("bn.uiTestId", "debugger.registers.table"); + setProperty("bn.uiTestScope", "debugger.registers.table"); + setAccessibleName("Debugger registers"); m_controller = DebuggerController::GetController(data); if (!m_controller) return; @@ -455,46 +459,46 @@ DebugRegistersWidget::DebugRegistersWidget(ViewFrame* view, BinaryViewRef data, m_menu = menu; QString actionName = QString::fromStdString("Set to Zero"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu->addAction(actionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction(actionName, UIAction([this]() { setToZero(); }, [this]() { return selectionNotEmpty(); })); actionName = QString::fromStdString("Edit Value"); - UIAction::registerAction(actionName, QKeySequence(Qt::Key_E)); + UIIdentity::registerBuiltInAction(actionName, QKeySequence(Qt::Key_E)); m_menu->addAction(actionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction(actionName, UIAction([this]() { editValue(); }, [this]() { return selectionModel()->selectedRows().size() == 1; })); actionName = QString::fromStdString("Go to Previous Write"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu->addAction(actionName, "TTD", MENU_ORDER_FIRST); m_menu->setGroupOrdering("TTD", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { goToPrevRegisterWrite(); }, [this]() { return ttdSingleRegisterSelected(); })); actionName = QString::fromStdString("Go to Next Write"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu->addAction(actionName, "TTD", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { goToNextRegisterWrite(); }, [this]() { return ttdSingleRegisterSelected(); })); actionName = QString::fromStdString("Jump to Address"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu->addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { jump(); }, [this]() { return selectionModel()->selectedRows().size() == 1; })); actionName = QString::fromStdString("Jump to Address in New Pane"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu->addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { jumpInNewPane(); }, [this]() { return selectionModel()->selectedRows().size() == 1; })); actionName = QString::fromStdString("Open Each in New Pane"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu->addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction(actionName, UIAction([this]() { jumpEachInNewPane(); }, [this]() { return selectionModel()->selectedRows().size() > 1; @@ -526,7 +530,8 @@ DebugRegistersWidget::DebugRegistersWidget(ViewFrame* view, BinaryViewRef data, }); actionName = QString::fromStdString("Copy Row"); - UIAction::registerAction(actionName, QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_C)); + UIIdentity::registerBuiltInAction( + actionName, QKeySequence(Qt::ControlModifier | Qt::ShiftModifier | Qt::Key_C)); m_menu->addAction(actionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction(actionName, UIAction([this]() { copyRows(); }, [this]() { return selectionNotEmpty(); })); m_actionHandler.setActionDisplayName(actionName, [this]() { @@ -538,12 +543,12 @@ DebugRegistersWidget::DebugRegistersWidget(ViewFrame* view, BinaryViewRef data, m_actionHandler.bindAction("Paste", UIAction([this]() { paste(); }, [this]() { return canPaste(); })); actionName = QString::fromStdString("Select All"); - UIAction::registerAction(actionName, QKeySequence(Qt::ControlModifier | Qt::Key_A)); + UIIdentity::registerBuiltInAction(actionName, QKeySequence(Qt::ControlModifier | Qt::Key_A)); m_menu->addAction(actionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction(actionName, UIAction([this]() { selectAll(); })); actionName = QString::fromStdString("Hide Unused Registers"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu->addAction(actionName, "Display", MENU_ORDER_NORMAL); m_menu->setGroupOrdering("Display", MENU_ORDER_LAST); @@ -1033,8 +1038,13 @@ void DebugRegistersWidget::activateSelection() {} DebugRegistersContainer::DebugRegistersContainer(ViewFrame* view, BinaryViewRef data, Menu* menu) : m_view(view) { + setProperty("bn.uiTestId", "debugger.registers"); + setProperty("bn.uiTestScope", "debugger.registers"); + setAccessibleName("Debugger Registers"); m_register = new DebugRegistersWidget(view, data, menu); m_separateEdit = new FilterEdit(m_register); + m_separateEdit->setProperty("bn.uiTestId", "debugger.registers.filter"); + m_separateEdit->setAccessibleName("Search debugger registers"); m_separateEdit->showRegexToggle(true); m_filter = new FilteredView(this, m_register, m_register, m_separateEdit); m_filter->setFilterPlaceholderText("Search registers"); @@ -1049,6 +1059,8 @@ DebugRegistersContainer::DebugRegistersContainer(ViewFrame* view, BinaryViewRef headerLayout->setAlignment(Qt::AlignBaseline); ClickableIcon* icon = new ClickableIcon(QImage(":/debugger/menu"), QSize(16, 16)); + icon->setProperty("bn.uiTestId", "debugger.registers.menu"); + icon->setAccessibleName("Debugger registers menu"); connect(icon, &ClickableIcon::clicked, m_register, &DebugRegistersWidget::showContextMenu); headerLayout->addWidget(icon); diff --git a/ui/threadframes.cpp b/ui/threadframes.cpp index 536c7e56..8ec4b600 100644 --- a/ui/threadframes.cpp +++ b/ui/threadframes.cpp @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include "../../../ui/shared/internalaction.h" #include "threadframes.h" #include @@ -654,6 +655,8 @@ void ThreadFramesWidget::copyAllFrames() ThreadFramesWidget::ThreadFramesWidget(QWidget* parent, ViewFrame* frame, BinaryViewRef data) : QTreeView(parent), m_view(frame) { + setProperty("bn.uiTestId", "sidebar.stackTrace.frames"); + setAccessibleName("Stack trace frames"); m_debugger = DebuggerController::GetController(data); if (!m_debugger) return; @@ -677,19 +680,19 @@ ThreadFramesWidget::ThreadFramesWidget(QWidget* parent, ViewFrame* frame, Binary m_contextMenuManager = new ContextMenuManager(this); QString actionName = QString::fromStdString("Suspend Thread"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction( actionName, UIAction([this]() { suspendThread(); }, [this]() { return canSuspendOrResume(); })); actionName = QString::fromStdString("Resume Thread"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction( actionName, UIAction([this]() { resumeThread(); }, [this]() { return canSuspendOrResume(); })); actionName = QString::fromStdString("Make It Solo Thread"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_FIRST); m_actionHandler.bindAction( actionName, UIAction([this]() { makeItSoloThread(); }, [this]() { return canSuspendOrResume(); })); @@ -725,13 +728,13 @@ ThreadFramesWidget::ThreadFramesWidget(QWidget* parent, ViewFrame* frame, Binary }); actionName = QString::fromStdString("Copy Current Stack Trace"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction( actionName, UIAction([this]() { copyCurrentFrame(); }, [this]() { return selectionNotEmpty(); })); actionName = QString::fromStdString("Copy All Stack Traces"); - UIAction::registerAction(actionName); + UIIdentity::registerBuiltInAction(actionName); m_menu.addAction(actionName, "Options", MENU_ORDER_NORMAL); m_actionHandler.bindAction(actionName, UIAction([this]() { copyAllFrames(); })); @@ -878,6 +881,9 @@ void ThreadFramesWidget::onDoubleClicked() ThreadFramesContainer::ThreadFramesContainer(ViewFrame* frame, BinaryViewRef data) : SidebarWidget("Stack Trace") { + setProperty("bn.uiTestId", "sidebar.stackTrace"); + setProperty("bn.uiTestScope", "sidebar.stackTrace"); + setAccessibleName("Stack Trace"); m_widget = new ThreadFramesWidget(this, frame, data); auto* layout = new QVBoxLayout(this); diff --git a/ui/timestampnavigationdialog.cpp b/ui/timestampnavigationdialog.cpp index 562665b6..82a76972 100644 --- a/ui/timestampnavigationdialog.cpp +++ b/ui/timestampnavigationdialog.cpp @@ -23,6 +23,9 @@ limitations under the License. TimestampNavigationDialog::TimestampNavigationDialog(QWidget* parent, DbgRef controller) : QDialog(parent), m_controller(controller) { + setProperty("bn.uiTestId", "ttd.timestampNavigationDialog"); + setProperty("bn.uiTestScope", "ttd.timestampNavigationDialog"); + setAccessibleName("Navigate to TTD Timestamp"); setWindowTitle("Navigate to TTD Timestamp"); setModal(true); @@ -34,6 +37,8 @@ TimestampNavigationDialog::TimestampNavigationDialog(QWidget* parent, DbgRefsetProperty("bn.uiTestId", "ttd.timestampNavigationDialog.timestamp"); + m_timestampEdit->setAccessibleName("TTD timestamp"); m_timestampEdit->setPlaceholderText("e.g., 1A0:12F"); m_timestampEdit->setFont(QFont("monospace")); @@ -52,6 +57,9 @@ TimestampNavigationDialog::TimestampNavigationDialog(QWidget* parent, DbgRefsetProperty("bn.uiTestId", "ttd.timestampNavigationDialog.buttons"); + m_buttonBox->button(QDialogButtonBox::Ok)->setProperty("bn.uiTestId", "ttd.timestampNavigationDialog.navigate"); + m_buttonBox->button(QDialogButtonBox::Cancel)->setProperty("bn.uiTestId", "ttd.timestampNavigationDialog.cancel"); m_buttonBox->button(QDialogButtonBox::Ok)->setText("Navigate"); m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); @@ -161,4 +169,4 @@ void TimestampNavigationDialog::navigate() { QMessageBox::warning(this, "Error", "Failed to navigate to the specified timestamp.\nThe position might be invalid or out of range."); } -} \ No newline at end of file +} diff --git a/ui/ttdanalysisdialog.cpp b/ui/ttdanalysisdialog.cpp index a8e9d5cf..485da68d 100644 --- a/ui/ttdanalysisdialog.cpp +++ b/ui/ttdanalysisdialog.cpp @@ -96,6 +96,9 @@ void TTDAnalysisWorker::run() TTDAnalysisDialog::TTDAnalysisDialog(UIContext* context, BinaryViewRef data, QWidget* parent) : QDialog(parent), m_context(context), m_data(data), m_currentWorker(nullptr) { + setProperty("bn.uiTestId", "ttd.analysisDialog"); + setProperty("bn.uiTestScope", "ttd.analysisDialog"); + setAccessibleName("TTD analysis"); m_controller = DebuggerController::GetController(data); setWindowTitle("TTD Analysis"); @@ -134,6 +137,8 @@ void TTDAnalysisDialog::setupUI() QVBoxLayout* selectionLayout = new QVBoxLayout(selectionGroup); m_analysisTypeCombo = new QComboBox(); + m_analysisTypeCombo->setProperty("bn.uiTestId", "ttd.analysisDialog.analysisType"); + m_analysisTypeCombo->setAccessibleName("TTD analysis type"); m_analysisTypeCombo->addItem("Code Coverage", static_cast(TTDAnalysisType::CodeCoverage)); // Future analysis types can be added here selectionLayout->addWidget(m_analysisTypeCombo); @@ -151,6 +156,8 @@ void TTDAnalysisDialog::setupUI() QVBoxLayout* listLayout = new QVBoxLayout(listGroup); m_analysisListWidget = new QListWidget(); + m_analysisListWidget->setProperty("bn.uiTestId", "ttd.analysisDialog.analyses"); + m_analysisListWidget->setAccessibleName("Available TTD analyses"); listLayout->addWidget(m_analysisListWidget); contentSplitter->addWidget(listGroup); @@ -160,6 +167,8 @@ void TTDAnalysisDialog::setupUI() QVBoxLayout* detailsLayout = new QVBoxLayout(detailsGroup); m_analysisDetailsText = new QTextEdit(); + m_analysisDetailsText->setProperty("bn.uiTestId", "ttd.analysisDialog.details"); + m_analysisDetailsText->setAccessibleName("TTD analysis details"); m_analysisDetailsText->setReadOnly(true); detailsLayout->addWidget(m_analysisDetailsText); @@ -173,9 +182,12 @@ void TTDAnalysisDialog::setupUI() QVBoxLayout* statusLayout = new QVBoxLayout(statusGroup); m_statusLabel = new QLabel("Ready"); + m_statusLabel->setProperty("bn.uiTestId", "ttd.analysisDialog.status"); statusLayout->addWidget(m_statusLabel); m_progressBar = new QProgressBar(); + m_progressBar->setProperty("bn.uiTestId", "ttd.analysisDialog.progress"); + m_progressBar->setAccessibleName("TTD analysis progress"); m_progressBar->setVisible(false); statusLayout->addWidget(m_progressBar); @@ -186,18 +198,23 @@ void TTDAnalysisDialog::setupUI() QVBoxLayout* rangeLayout = new QVBoxLayout(rangeGroup); m_useRangeCheckBox = new QCheckBox("Specify address range for analysis"); + m_useRangeCheckBox->setProperty("bn.uiTestId", "ttd.analysisDialog.useRange"); m_useRangeCheckBox->setChecked(true); rangeLayout->addWidget(m_useRangeCheckBox); QHBoxLayout* rangeControlsLayout = new QHBoxLayout(); rangeControlsLayout->addWidget(new QLabel("Start Address:")); m_startAddressEdit = new QLineEdit(); + m_startAddressEdit->setProperty("bn.uiTestId", "ttd.analysisDialog.startAddress"); + m_startAddressEdit->setAccessibleName("TTD analysis start address"); m_startAddressEdit->setText(QString("0x") + QString::number(m_data->GetImageBase(), 16)); m_startAddressEdit->setEnabled(true); rangeControlsLayout->addWidget(m_startAddressEdit); rangeControlsLayout->addWidget(new QLabel("End Address:")); m_endAddressEdit = new QLineEdit(); + m_endAddressEdit->setProperty("bn.uiTestId", "ttd.analysisDialog.endAddress"); + m_endAddressEdit->setAccessibleName("TTD analysis end address"); // TODO: hack for demo, should read the modules info from the debugger m_endAddressEdit->setText(QString("0x") + QString::number(m_data->GetImageBase() + 0x7000, 16)); m_endAddressEdit->setEnabled(true); @@ -211,12 +228,16 @@ void TTDAnalysisDialog::setupUI() QHBoxLayout* timeControlsLayout = new QHBoxLayout(); timeControlsLayout->addWidget(new QLabel("Start Time:")); m_startTimeEdit = new QLineEdit(); + m_startTimeEdit->setProperty("bn.uiTestId", "ttd.analysisDialog.startTime"); + m_startTimeEdit->setAccessibleName("TTD analysis start time"); //set text to starting position m_startTimeEdit->setEnabled(true); timeControlsLayout->addWidget(m_startTimeEdit); timeControlsLayout->addWidget(new QLabel("End Time:")); m_endTimeEdit = new QLineEdit(); + m_endTimeEdit->setProperty("bn.uiTestId", "ttd.analysisDialog.endTime"); + m_endTimeEdit->setAccessibleName("TTD analysis end time"); //set text to ending position m_endTimeEdit->setEnabled(true); timeControlsLayout->addWidget(m_endTimeEdit); @@ -236,16 +257,20 @@ void TTDAnalysisDialog::setupUI() QVBoxLayout* cacheLayout = new QVBoxLayout(cacheGroup); m_autoCacheCheckBox = new QCheckBox("Automatically cache results"); + m_autoCacheCheckBox->setProperty("bn.uiTestId", "ttd.analysisDialog.automaticCache"); m_autoCacheCheckBox->setChecked(true); cacheLayout->addWidget(m_autoCacheCheckBox); QHBoxLayout* cachePathLayout = new QHBoxLayout(); cachePathLayout->addWidget(new QLabel("Cache Directory:")); m_cachePathEdit = new QLineEdit(); + m_cachePathEdit->setProperty("bn.uiTestId", "ttd.analysisDialog.cachePath"); + m_cachePathEdit->setAccessibleName("TTD analysis cache directory"); m_cachePathEdit->setText(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/ttd_analysis"); cachePathLayout->addWidget(m_cachePathEdit); m_browseCacheButton = new QPushButton("Browse..."); + m_browseCacheButton->setProperty("bn.uiTestId", "ttd.analysisDialog.browseCache"); connect(m_browseCacheButton, &QPushButton::clicked, [this]() { QString dir = QFileDialog::getExistingDirectory(this, "Select Cache Directory", m_cachePathEdit->text()); if (!dir.isEmpty()) @@ -261,22 +286,27 @@ void TTDAnalysisDialog::setupUI() buttonLayout->addStretch(); m_runButton = new QPushButton("Run Analysis"); + m_runButton->setProperty("bn.uiTestId", "ttd.analysisDialog.run"); connect(m_runButton, &QPushButton::clicked, this, &TTDAnalysisDialog::onRunAnalysis); buttonLayout->addWidget(m_runButton); m_saveButton = new QPushButton("Save Results"); + m_saveButton->setProperty("bn.uiTestId", "ttd.analysisDialog.save"); connect(m_saveButton, &QPushButton::clicked, this, &TTDAnalysisDialog::onSaveResults); buttonLayout->addWidget(m_saveButton); m_loadButton = new QPushButton("Load Results"); + m_loadButton->setProperty("bn.uiTestId", "ttd.analysisDialog.load"); connect(m_loadButton, &QPushButton::clicked, this, &TTDAnalysisDialog::onLoadResults); buttonLayout->addWidget(m_loadButton); m_clearCacheButton = new QPushButton("Clear Cache"); + m_clearCacheButton->setProperty("bn.uiTestId", "ttd.analysisDialog.clearCache"); connect(m_clearCacheButton, &QPushButton::clicked, this, &TTDAnalysisDialog::onClearCache); buttonLayout->addWidget(m_clearCacheButton); QPushButton* closeButton = new QPushButton("Close"); + closeButton->setProperty("bn.uiTestId", "ttd.analysisDialog.close"); connect(closeButton, &QPushButton::clicked, this, &QDialog::accept); buttonLayout->addWidget(closeButton); diff --git a/ui/ttdbookmarkwidget.cpp b/ui/ttdbookmarkwidget.cpp index 28f28ff6..f6261d4f 100644 --- a/ui/ttdbookmarkwidget.cpp +++ b/ui/ttdbookmarkwidget.cpp @@ -33,6 +33,9 @@ TTDBookmarkEditDialog::TTDBookmarkEditDialog(QWidget* parent, const QString& pos const QString& viewAddress) : QDialog(parent) { + setProperty("bn.uiTestId", "ttd.bookmarkEditDialog"); + setProperty("bn.uiTestScope", "ttd.bookmarkEditDialog"); + setAccessibleName(position.isEmpty() ? "Add TTD Bookmark" : "Edit TTD Bookmark"); setWindowTitle(position.isEmpty() ? "Add TTD Bookmark" : "Edit TTD Bookmark"); setModal(true); setMinimumWidth(500); @@ -42,19 +45,28 @@ TTDBookmarkEditDialog::TTDBookmarkEditDialog(QWidget* parent, const QString& pos layout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); m_positionEdit = new QLineEdit(position); + m_positionEdit->setProperty("bn.uiTestId", "ttd.bookmarkEditDialog.position"); + m_positionEdit->setAccessibleName("TTD bookmark position"); m_positionEdit->setPlaceholderText("sequence:step (hex), e.g. 1a0:12f"); layout->addRow("Position:", m_positionEdit); m_viewAddressEdit = new QLineEdit(viewAddress); + m_viewAddressEdit->setProperty("bn.uiTestId", "ttd.bookmarkEditDialog.viewAddress"); + m_viewAddressEdit->setAccessibleName("TTD bookmark view address"); m_viewAddressEdit->setPlaceholderText("View address (hex, optional)"); layout->addRow("View Address:", m_viewAddressEdit); m_noteEdit = new QLineEdit(note); + m_noteEdit->setProperty("bn.uiTestId", "ttd.bookmarkEditDialog.note"); + m_noteEdit->setAccessibleName("TTD bookmark note"); m_noteEdit->setPlaceholderText("Optional note for this bookmark"); m_noteEdit->setMinimumWidth(400); layout->addRow("Note:", m_noteEdit); auto buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + buttons->setProperty("bn.uiTestId", "ttd.bookmarkEditDialog.buttons"); + buttons->button(QDialogButtonBox::Ok)->setProperty("bn.uiTestId", "ttd.bookmarkEditDialog.save"); + buttons->button(QDialogButtonBox::Cancel)->setProperty("bn.uiTestId", "ttd.bookmarkEditDialog.cancel"); connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); layout->addRow(buttons); @@ -75,6 +87,9 @@ TTDBookmarkWidget::TTDBookmarkWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent), m_data(data), m_resultsTable(nullptr), m_statusLabel(nullptr), m_addButton(nullptr), m_contextMenuManager(nullptr) { + setProperty("bn.uiTestId", "ttd.bookmarks"); + setProperty("bn.uiTestScope", "ttd.bookmarks"); + setAccessibleName("TTD Bookmarks"); m_controller = DebuggerController::GetController(data); setupUI(); @@ -99,10 +114,12 @@ void TTDBookmarkWidget::setupUI() // Button bar auto buttonLayout = new QHBoxLayout(); m_addButton = new QPushButton("Add TTD Bookmark"); + m_addButton->setProperty("bn.uiTestId", "ttd.bookmarks.add"); connect(m_addButton, &QPushButton::clicked, this, &TTDBookmarkWidget::addBookmarkFromDialog); buttonLayout->addWidget(m_addButton); auto addCurrentButton = new QPushButton("Bookmark Current Position"); + addCurrentButton->setProperty("bn.uiTestId", "ttd.bookmarks.addCurrent"); connect(addCurrentButton, &QPushButton::clicked, this, &TTDBookmarkWidget::addBookmarkFromCurrentPosition); buttonLayout->addWidget(addCurrentButton); @@ -111,10 +128,13 @@ void TTDBookmarkWidget::setupUI() // Results table m_resultsTable = new QTableWidget(); + m_resultsTable->setProperty("bn.uiTestId", "ttd.bookmarks.table"); + m_resultsTable->setAccessibleName("TTD bookmarks"); mainLayout->addWidget(m_resultsTable, 1); // Status label m_statusLabel = new QLabel("No bookmarks."); + m_statusLabel->setProperty("bn.uiTestId", "ttd.bookmarks.status"); m_statusLabel->setContentsMargins(5, 5, 5, 5); mainLayout->addWidget(m_statusLabel); @@ -543,6 +563,9 @@ void TTDBookmarkWidget::copyEntireTable() TTDBookmarkSidebarWidget::TTDBookmarkSidebarWidget(BinaryViewRef data) : SidebarWidget("TTD Bookmarks"), m_data(data) { + setProperty("bn.uiTestId", "sidebar.ttdBookmarks"); + setProperty("bn.uiTestScope", "sidebar.ttdBookmarks"); + setAccessibleName("TTD Bookmarks"); m_controller = DebuggerController::GetController(data); auto layout = new QVBoxLayout(this); diff --git a/ui/ttdcallswidget.cpp b/ui/ttdcallswidget.cpp index 2ad30a1f..76361305 100644 --- a/ui/ttdcallswidget.cpp +++ b/ui/ttdcallswidget.cpp @@ -36,6 +36,8 @@ limitations under the License. TTDCallsQueryWidget::TTDCallsQueryWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent), m_data(data) { + setProperty("bn.uiTestId", "ttd.calls.query"); + setAccessibleName("TTD calls query"); m_controller = DebuggerController::GetController(data); // Initialize column names and default visibility @@ -80,6 +82,8 @@ void TTDCallsQueryWidget::setupUI() // Symbols input (single line for comma-separated symbols) m_symbolsEdit = new QLineEdit(); + m_symbolsEdit->setProperty("bn.uiTestId", "ttd.calls.query.symbols"); + m_symbolsEdit->setAccessibleName("TTD call symbols"); m_symbolsEdit->setPlaceholderText( "Enter symbols separated by commas, e.g.: kernel32!*, ntdll!NtCreateFile, module!symbol"); inputLayout->addRow("Symbols:", m_symbolsEdit); @@ -87,9 +91,13 @@ void TTDCallsQueryWidget::setupUI() // Address range filter (optional) - temporarily disabled due to crashes auto addressLayout = new QHBoxLayout(); m_startAddressEdit = new QLineEdit(); + m_startAddressEdit->setProperty("bn.uiTestId", "ttd.calls.query.startAddress"); + m_startAddressEdit->setAccessibleName("TTD call return address range start"); m_startAddressEdit->setPlaceholderText("Start address (hex, optional)"); m_startAddressEdit->setEnabled(true); m_endAddressEdit = new QLineEdit(); + m_endAddressEdit->setProperty("bn.uiTestId", "ttd.calls.query.endAddress"); + m_endAddressEdit->setAccessibleName("TTD call return address range end"); m_endAddressEdit->setPlaceholderText("End address (hex, optional)"); m_endAddressEdit->setEnabled(true); addressLayout->addWidget(new QLabel("Return Address Range:")); @@ -102,8 +110,10 @@ void TTDCallsQueryWidget::setupUI() // Button layout auto buttonLayout = new QHBoxLayout(); m_queryButton = new QPushButton("Query TTD Calls"); + m_queryButton->setProperty("bn.uiTestId", "ttd.calls.query.run"); m_queryButton->setToolTip("Execute TTD calls query with the specified symbols and address range"); m_clearButton = new QPushButton("Clear Results"); + m_clearButton->setProperty("bn.uiTestId", "ttd.calls.query.clear"); buttonLayout->addWidget(m_queryButton); buttonLayout->addWidget(m_clearButton); buttonLayout->addStretch(); @@ -115,6 +125,8 @@ void TTDCallsQueryWidget::setupUI() // Results table m_resultsTable = new QTableWidget(0, static_cast(m_columnNames.size())); + m_resultsTable->setProperty("bn.uiTestId", "ttd.calls.query.results"); + m_resultsTable->setAccessibleName("TTD call results"); m_resultsTable->setHorizontalHeaderLabels(m_columnNames); m_resultsTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_resultsTable->setAlternatingRowColors(true); @@ -126,6 +138,7 @@ void TTDCallsQueryWidget::setupUI() // Status label m_statusLabel = new QLabel("Ready"); + m_statusLabel->setProperty("bn.uiTestId", "ttd.calls.query.status"); m_statusLabel->setContentsMargins(5, 5, 5, 5); layout->addWidget(m_statusLabel); @@ -677,6 +690,9 @@ bool TTDCallsQueryWidget::isUnused() const TTDCallsWidget::TTDCallsWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent), m_data(data) { + setProperty("bn.uiTestId", "ttd.calls"); + setProperty("bn.uiTestScope", "ttd.calls"); + setAccessibleName("TTD Calls"); m_controller = DebuggerController::GetController(data); setupUI(); } @@ -690,10 +706,15 @@ void TTDCallsWidget::setupUI() // Tab widget setup m_tabWidget = new QTabWidget(); + m_tabWidget->setProperty("bn.uiTestId", "ttd.calls.tabs"); + m_tabWidget->setProperty("bn.uiTestScope", "ttd.calls.tabs"); + m_tabWidget->setAccessibleName("TTD calls query tabs"); m_tabWidget->setTabsClosable(true); // Create "+" button as corner widget (matches TTD Memory widget) m_newTabButton = new QToolButton(); + m_newTabButton->setProperty("bn.uiTestId", "ttd.calls.newTab"); + m_newTabButton->setAccessibleName("New TTD calls query tab"); m_newTabButton->setText("+"); m_newTabButton->setAutoRaise(true); m_newTabButton->setToolTip("New TTD Calls Query Tab"); @@ -726,6 +747,9 @@ void TTDCallsWidget::createNewTab() // Create new tab auto queryWidget = new TTDCallsQueryWidget(this, m_data); + const qulonglong queryKey = m_tabWidget->property("bn.nextUiTestQueryKey").toULongLong() + 1; + m_tabWidget->setProperty("bn.nextUiTestQueryKey", queryKey); + queryWidget->setProperty("bn.uiTestKey", QStringLiteral("queryInstance.%1").arg(queryKey)); int index = m_tabWidget->addTab(queryWidget, QString("Query %1").arg(m_tabWidget->count() + 1)); m_tabWidget->setCurrentIndex(index); @@ -790,6 +814,9 @@ void TTDCallsWidget::setParametersAndQueryInNewTab(const std::string& symbols, u TTDCallsSidebarWidget::TTDCallsSidebarWidget(BinaryViewRef data) : SidebarWidget("TTD Calls"), m_data(data) { + setProperty("bn.uiTestId", "sidebar.ttdCalls"); + setProperty("bn.uiTestScope", "sidebar.ttdCalls"); + setAccessibleName("TTD Calls"); m_controller = DebuggerController::GetController(data); auto layout = new QVBoxLayout(this); @@ -850,4 +877,4 @@ void TTDCallsWidgetType::SetPendingQuery( query.startAddr = startAddr; query.endAddr = endAddr; s_pendingQueries[key] = query; -} \ No newline at end of file +} diff --git a/ui/ttdeventswidget.cpp b/ui/ttdeventswidget.cpp index f62bd907..c164c529 100644 --- a/ui/ttdeventswidget.cpp +++ b/ui/ttdeventswidget.cpp @@ -40,6 +40,9 @@ static uint64_t PositionSortValue(const TTDPosition& position) TTDEventsColumnVisibilityDialog::TTDEventsColumnVisibilityDialog(QWidget* parent, const QStringList& columnNames, const QList& visibility) : QDialog(parent) { + setProperty("bn.uiTestId", "ttd.events.columnVisibilityDialog"); + setProperty("bn.uiTestScope", "ttd.events.columnVisibilityDialog"); + setAccessibleName("TTD event column visibility"); setWindowTitle("Column Visibility"); setModal(true); resize(300, 400); @@ -50,6 +53,8 @@ TTDEventsColumnVisibilityDialog::TTDEventsColumnVisibilityDialog(QWidget* parent layout->addWidget(label); m_columnList = new QListWidget(); + m_columnList->setProperty("bn.uiTestId", "ttd.events.columnVisibilityDialog.columns"); + m_columnList->setAccessibleName("TTD event columns"); for (int i = 0; i < columnNames.size(); ++i) { @@ -62,6 +67,11 @@ TTDEventsColumnVisibilityDialog::TTDEventsColumnVisibilityDialog(QWidget* parent layout->addWidget(m_columnList); QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults); + buttons->setProperty("bn.uiTestId", "ttd.events.columnVisibilityDialog.buttons"); + buttons->button(QDialogButtonBox::Ok)->setProperty("bn.uiTestId", "ttd.events.columnVisibilityDialog.apply"); + buttons->button(QDialogButtonBox::Cancel)->setProperty("bn.uiTestId", "ttd.events.columnVisibilityDialog.cancel"); + buttons->button(QDialogButtonBox::RestoreDefaults)->setProperty( + "bn.uiTestId", "ttd.events.columnVisibilityDialog.restoreDefaults"); connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); @@ -110,6 +120,9 @@ TTDEventsQueryWidget::TTDEventsQueryWidget(QWidget* parent, BinaryViewRef data, m_exceptionCheck(nullptr), m_queryButton(nullptr), m_clearButton(nullptr), m_resultsTable(nullptr), m_statusLabel(nullptr), m_contextMenuManager(nullptr) { + setProperty("bn.uiTestId", "ttd.events.query"); + setProperty("bn.uiTestKey", QStringLiteral("eventType.%1").arg(static_cast(type))); + setAccessibleName("TTD events query"); m_controller = DebuggerController::GetController(data); if (!m_controller) { @@ -149,26 +162,31 @@ void TTDEventsQueryWidget::setupUI() // Event type checkboxes m_threadCreatedCheck = new QCheckBox("Thread Created"); + m_threadCreatedCheck->setProperty("bn.uiTestId", "ttd.events.query.threadCreated"); m_threadCreatedCheck->setChecked(true); connect(m_threadCreatedCheck, &QCheckBox::toggled, this, &TTDEventsQueryWidget::onFilterChanged); inputLayout->addWidget(m_threadCreatedCheck); m_threadTerminatedCheck = new QCheckBox("Thread Terminated"); + m_threadTerminatedCheck->setProperty("bn.uiTestId", "ttd.events.query.threadTerminated"); m_threadTerminatedCheck->setChecked(true); connect(m_threadTerminatedCheck, &QCheckBox::toggled, this, &TTDEventsQueryWidget::onFilterChanged); inputLayout->addWidget(m_threadTerminatedCheck); m_moduleLoadedCheck = new QCheckBox("Module Loaded"); + m_moduleLoadedCheck->setProperty("bn.uiTestId", "ttd.events.query.moduleLoaded"); m_moduleLoadedCheck->setChecked(true); connect(m_moduleLoadedCheck, &QCheckBox::toggled, this, &TTDEventsQueryWidget::onFilterChanged); inputLayout->addWidget(m_moduleLoadedCheck); m_moduleUnloadedCheck = new QCheckBox("Module Unloaded"); + m_moduleUnloadedCheck->setProperty("bn.uiTestId", "ttd.events.query.moduleUnloaded"); m_moduleUnloadedCheck->setChecked(true); connect(m_moduleUnloadedCheck, &QCheckBox::toggled, this, &TTDEventsQueryWidget::onFilterChanged); inputLayout->addWidget(m_moduleUnloadedCheck); m_exceptionCheck = new QCheckBox("Exception"); + m_exceptionCheck->setProperty("bn.uiTestId", "ttd.events.query.exception"); m_exceptionCheck->setChecked(true); connect(m_exceptionCheck, &QCheckBox::toggled, this, &TTDEventsQueryWidget::onFilterChanged); inputLayout->addWidget(m_exceptionCheck); @@ -177,11 +195,13 @@ void TTDEventsQueryWidget::setupUI() QHBoxLayout* buttonLayout = new QHBoxLayout(); m_queryButton = new QPushButton("Query All TTD Events"); + m_queryButton->setProperty("bn.uiTestId", "ttd.events.query.run"); m_queryButton->setDefault(true); connect(m_queryButton, &QPushButton::clicked, this, &TTDEventsQueryWidget::performQuery); buttonLayout->addWidget(m_queryButton); m_clearButton = new QPushButton("Clear Results"); + m_clearButton->setProperty("bn.uiTestId", "ttd.events.query.clear"); connect(m_clearButton, &QPushButton::clicked, this, &TTDEventsQueryWidget::clearResults); buttonLayout->addWidget(m_clearButton); @@ -204,10 +224,13 @@ void TTDEventsQueryWidget::setupUI() // Results table m_resultsTable = new QTableWidget(); + m_resultsTable->setProperty("bn.uiTestId", "ttd.events.query.results"); + m_resultsTable->setAccessibleName("TTD event results"); mainLayout->addWidget(m_resultsTable, 1); // Give table most of the space // Status label m_statusLabel = new QLabel("Ready to query TTD events."); + m_statusLabel->setProperty("bn.uiTestId", "ttd.events.query.status"); m_statusLabel->setContentsMargins(5, 5, 5, 5); // Add padding around status text mainLayout->addWidget(m_statusLabel); @@ -1005,6 +1028,9 @@ bool TTDEventsQueryWidget::isUnused() const TTDEventsWidget::TTDEventsWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent), m_data(data), m_isPopulated(false) { + setProperty("bn.uiTestId", "ttd.events"); + setProperty("bn.uiTestScope", "ttd.events"); + setAccessibleName("TTD Events"); m_controller = DebuggerController::GetController(data); setupUI(); @@ -1027,12 +1053,17 @@ void TTDEventsWidget::setupUI() // Create tab widget m_tabWidget = new QTabWidget(); + m_tabWidget->setProperty("bn.uiTestId", "ttd.events.tabs"); + m_tabWidget->setProperty("bn.uiTestScope", "ttd.events.tabs"); + m_tabWidget->setAccessibleName("TTD event tabs"); m_tabWidget->setTabsClosable(true); connect(m_tabWidget, &QTabWidget::tabCloseRequested, this, &TTDEventsWidget::closeTab); layout->addWidget(m_tabWidget); // Create "+" button as corner widget m_newTabButton = new QToolButton(m_tabWidget); + m_newTabButton->setProperty("bn.uiTestId", "ttd.events.newTab"); + m_newTabButton->setAccessibleName("New TTD events query tab"); m_newTabButton->setText("+"); m_newTabButton->setAutoRaise(true); m_newTabButton->setToolTip("New tab"); @@ -1108,6 +1139,9 @@ void TTDEventsWidget::createNewTab() { // Create new tab with AllEvents type (has filtering controls) TTDEventsQueryWidget* queryWidget = new TTDEventsQueryWidget(this, m_data, TTDEventsQueryWidget::AllEvents); + const qulonglong queryKey = m_tabWidget->property("bn.nextUiTestQueryKey").toULongLong() + 1; + m_tabWidget->setProperty("bn.nextUiTestQueryKey", queryKey); + queryWidget->setProperty("bn.uiTestKey", QStringLiteral("queryInstance.%1").arg(queryKey)); int tabIndex = m_tabWidget->addTab(queryWidget, QString("Query %1").arg(m_tabWidget->count() - 2)); // -2 because we have 3 fixed tabs m_tabWidget->setCurrentIndex(tabIndex); @@ -1133,6 +1167,9 @@ void TTDEventsWidget::closeTab(int index) TTDEventsSidebarWidget::TTDEventsSidebarWidget(BinaryViewRef data) : SidebarWidget("TTD Events"), m_data(data) { + setProperty("bn.uiTestId", "sidebar.ttdEvents"); + setProperty("bn.uiTestScope", "sidebar.ttdEvents"); + setAccessibleName("TTD Events"); m_controller = DebuggerController::GetController(data); QVBoxLayout* layout = new QVBoxLayout(); diff --git a/ui/ttdmemorywidget.cpp b/ui/ttdmemorywidget.cpp index ecbe8b25..e35d493d 100644 --- a/ui/ttdmemorywidget.cpp +++ b/ui/ttdmemorywidget.cpp @@ -36,6 +36,9 @@ limitations under the License. ColumnVisibilityDialog::ColumnVisibilityDialog(QWidget* parent, const QStringList& columnNames, const QList& visibility) : QDialog(parent) { + setProperty("bn.uiTestId", "ttd.memory.columnVisibilityDialog"); + setProperty("bn.uiTestScope", "ttd.memory.columnVisibilityDialog"); + setAccessibleName("TTD memory column visibility"); setWindowTitle("Column Visibility"); setModal(true); resize(300, 400); @@ -46,6 +49,8 @@ ColumnVisibilityDialog::ColumnVisibilityDialog(QWidget* parent, const QStringLis layout->addWidget(label); m_columnList = new QListWidget(); + m_columnList->setProperty("bn.uiTestId", "ttd.memory.columnVisibilityDialog.columns"); + m_columnList->setAccessibleName("TTD memory columns"); for (int i = 0; i < columnNames.size(); ++i) { @@ -58,6 +63,11 @@ ColumnVisibilityDialog::ColumnVisibilityDialog(QWidget* parent, const QStringLis layout->addWidget(m_columnList); QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults); + buttons->setProperty("bn.uiTestId", "ttd.memory.columnVisibilityDialog.buttons"); + buttons->button(QDialogButtonBox::Ok)->setProperty("bn.uiTestId", "ttd.memory.columnVisibilityDialog.apply"); + buttons->button(QDialogButtonBox::Cancel)->setProperty("bn.uiTestId", "ttd.memory.columnVisibilityDialog.cancel"); + buttons->button(QDialogButtonBox::RestoreDefaults)->setProperty( + "bn.uiTestId", "ttd.memory.columnVisibilityDialog.restoreDefaults"); connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); @@ -100,6 +110,8 @@ QList ColumnVisibilityDialog::getColumnVisibility() const TTDMemoryQueryWidget::TTDMemoryQueryWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent), m_data(data) { + setProperty("bn.uiTestId", "ttd.memory.query"); + setAccessibleName("TTD memory query"); m_controller = DebuggerController::GetController(m_data); // Initialize column names and visibility @@ -139,9 +151,13 @@ void TTDMemoryQueryWidget::setupUI() // Address range inputs m_startAddressEdit = new QLineEdit(); + m_startAddressEdit->setProperty("bn.uiTestId", "ttd.memory.query.startAddress"); + m_startAddressEdit->setAccessibleName("TTD memory range start address"); m_startAddressEdit->setToolTip("Start address in hexadecimal format"); m_endAddressEdit = new QLineEdit(); + m_endAddressEdit->setProperty("bn.uiTestId", "ttd.memory.query.endAddress"); + m_endAddressEdit->setAccessibleName("TTD memory range end address"); m_endAddressEdit->setToolTip("End address in hexadecimal format"); // Set default values based on binary view address range @@ -168,10 +184,14 @@ void TTDMemoryQueryWidget::setupUI() inputLayout->addRow("Address Range:", addressLayout); m_startTimeEdit = new QLineEdit(); + m_startTimeEdit->setProperty("bn.uiTestId", "ttd.memory.query.startTime"); + m_startTimeEdit->setAccessibleName("TTD memory range start time"); m_startTimeEdit->setToolTip("Start time in format 'sequence:step' (hexadecimal), leave blank for start of recording"); m_startTimeEdit->setPlaceholderText("e.g. 0:0"); m_endTimeEdit = new QLineEdit(); + m_endTimeEdit->setProperty("bn.uiTestId", "ttd.memory.query.endTime"); + m_endTimeEdit->setAccessibleName("TTD memory range end time"); m_endTimeEdit->setToolTip("End time in format 'sequence:step' (hexadecimal), leave blank for end of recording"); m_endTimeEdit->setPlaceholderText("e.g. 23f:a7"); @@ -186,14 +206,17 @@ void TTDMemoryQueryWidget::setupUI() // Memory access type checkboxes QHBoxLayout* accessLayout = new QHBoxLayout(); m_readAccessCheck = new QCheckBox("Read"); + m_readAccessCheck->setProperty("bn.uiTestId", "ttd.memory.query.read"); m_readAccessCheck->setChecked(true); m_readAccessCheck->setToolTip("Include memory read operations"); m_writeAccessCheck = new QCheckBox("Write"); + m_writeAccessCheck->setProperty("bn.uiTestId", "ttd.memory.query.write"); m_writeAccessCheck->setChecked(true); m_writeAccessCheck->setToolTip("Include memory write operations"); m_executeAccessCheck = new QCheckBox("Execute"); + m_executeAccessCheck->setProperty("bn.uiTestId", "ttd.memory.query.execute"); m_executeAccessCheck->setChecked(false); m_executeAccessCheck->setToolTip("Include memory execute operations"); @@ -207,19 +230,23 @@ void TTDMemoryQueryWidget::setupUI() // Control buttons QHBoxLayout* buttonLayout = new QHBoxLayout(); m_queryButton = new QPushButton("Query Memory Events"); + m_queryButton->setProperty("bn.uiTestId", "ttd.memory.query.run"); m_queryButton->setToolTip("Execute TTD memory analysis query"); connect(m_queryButton, &QPushButton::clicked, this, &TTDMemoryQueryWidget::performQuery); m_clearButton = new QPushButton("Clear Results"); + m_clearButton->setProperty("bn.uiTestId", "ttd.memory.query.clear"); m_clearButton->setToolTip("Clear the results table"); connect(m_clearButton, &QPushButton::clicked, this, &TTDMemoryQueryWidget::clearResults); m_prevAccessButton = new QPushButton("Prev"); + m_prevAccessButton->setProperty("bn.uiTestId", "ttd.memory.query.previousAccess"); m_prevAccessButton->setToolTip("Find the previous memory access to the start address from the current TTD position and time travel to it"); m_prevAccessButton->setEnabled(false); connect(m_prevAccessButton, &QPushButton::clicked, this, &TTDMemoryQueryWidget::findPrevMemoryAccess); m_nextAccessButton = new QPushButton("Next"); + m_nextAccessButton->setProperty("bn.uiTestId", "ttd.memory.query.nextAccess"); m_nextAccessButton->setToolTip("Find the next memory access to the start address from the current TTD position and time travel to it"); m_nextAccessButton->setEnabled(false); connect(m_nextAccessButton, &QPushButton::clicked, this, &TTDMemoryQueryWidget::findNextMemoryAccess); @@ -247,6 +274,7 @@ void TTDMemoryQueryWidget::setupUI() // Status label m_statusLabel = new QLabel("Ready"); + m_statusLabel->setProperty("bn.uiTestId", "ttd.memory.query.status"); m_statusLabel->setContentsMargins(5, 5, 5, 5); mainLayout->addWidget(m_statusLabel); @@ -261,6 +289,8 @@ void TTDMemoryQueryWidget::setupUI() void TTDMemoryQueryWidget::setupTable() { m_resultsTable = new QTableWidget(); + m_resultsTable->setProperty("bn.uiTestId", "ttd.memory.query.results"); + m_resultsTable->setAccessibleName("TTD memory query results"); m_resultsTable->setColumnCount(m_columnNames.size()); m_resultsTable->setHorizontalHeaderLabels(m_columnNames); @@ -977,6 +1007,9 @@ bool TTDMemoryQueryWidget::isUnused() const TTDMemoryWidget::TTDMemoryWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent), m_data(data) { + setProperty("bn.uiTestId", "ttd.memory"); + setProperty("bn.uiTestScope", "ttd.memory"); + setAccessibleName("TTD memory analysis"); m_controller = DebuggerController::GetController(m_data); setupUI(); } @@ -996,11 +1029,16 @@ void TTDMemoryWidget::setupUI() // Tab widget setup m_tabWidget = new QTabWidget(this); + m_tabWidget->setProperty("bn.uiTestId", "ttd.memory.tabs"); + m_tabWidget->setProperty("bn.uiTestScope", "ttd.memory.tabs"); + m_tabWidget->setAccessibleName("TTD memory query tabs"); m_tabWidget->setTabsClosable(true); connect(m_tabWidget, &QTabWidget::tabCloseRequested, this, &TTDMemoryWidget::closeTab); // Create "+" button as corner widget m_newTabButton = new QToolButton(m_tabWidget); + m_newTabButton->setProperty("bn.uiTestId", "ttd.memory.newQuery"); + m_newTabButton->setAccessibleName("New TTD memory query"); m_newTabButton->setText("+"); m_newTabButton->setAutoRaise(true); m_newTabButton->setToolTip("New tab"); @@ -1031,6 +1069,9 @@ void TTDMemoryWidget::createNewTab() // Create new tab TTDMemoryQueryWidget* queryWidget = new TTDMemoryQueryWidget(this, m_data); + const qulonglong queryKey = m_tabWidget->property("bn.nextUiTestQueryKey").toULongLong() + 1; + m_tabWidget->setProperty("bn.nextUiTestQueryKey", queryKey); + queryWidget->setProperty("bn.uiTestKey", QStringLiteral("queryInstance.%1").arg(queryKey)); int tabIndex = m_tabWidget->addTab(queryWidget, QString("Query %1").arg(m_tabWidget->count() + 1)); m_tabWidget->setCurrentIndex(tabIndex); @@ -1099,6 +1140,9 @@ void TTDMemoryWidget::setParametersAndQueryInNewTab(uint64_t startAddr, uint64_t TTDMemorySidebarWidget::TTDMemorySidebarWidget(BinaryViewRef data) : SidebarWidget("TTD Memory"), m_data(data) { + setProperty("bn.uiTestId", "sidebar.ttdMemory"); + setProperty("bn.uiTestScope", "sidebar.ttdMemory"); + setAccessibleName("TTD memory sidebar"); m_controller = DebuggerController::GetController(data); auto* layout = new QVBoxLayout(); @@ -1141,6 +1185,9 @@ constexpr auto TTDMemoryAccessTypesKey = "ui/debugger/ttd/memoryAccessTypes"; TTDMemoryAccessNextPrevDialog::TTDMemoryAccessNextPrevDialog(QWidget* parent, BinaryViewRef data, uint64_t startAddr, uint64_t endAddr) : QDialog(parent), m_data(data) { + setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog"); + setProperty("bn.uiTestScope", "ttd.memory.accessNavigationDialog"); + setAccessibleName("TTD memory access navigation"); m_controller = DebuggerController::GetController(m_data); setWindowTitle("TTD Memory Access (Next/Prev)"); @@ -1153,9 +1200,13 @@ TTDMemoryAccessNextPrevDialog::TTDMemoryAccessNextPrevDialog(QWidget* parent, Bi QHBoxLayout* addressLayout = new QHBoxLayout(); m_startAddressEdit = new QLineEdit(); + m_startAddressEdit->setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog.startAddress"); + m_startAddressEdit->setAccessibleName("TTD memory access range start address"); m_startAddressEdit->setText(QString("0x%1").arg(startAddr, 0, 16)); m_startAddressEdit->setToolTip("Start address in hexadecimal format"); m_endAddressEdit = new QLineEdit(); + m_endAddressEdit->setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog.endAddress"); + m_endAddressEdit->setAccessibleName("TTD memory access range end address"); m_endAddressEdit->setText(QString("0x%1").arg(endAddr, 0, 16)); m_endAddressEdit->setToolTip("End address in hexadecimal format"); addressLayout->addWidget(new QLabel("Start:")); @@ -1178,10 +1229,13 @@ TTDMemoryAccessNextPrevDialog::TTDMemoryAccessNextPrevDialog(QWidget* parent, Bi QHBoxLayout* accessLayout = new QHBoxLayout(); m_readAccessCheck = new QCheckBox("Read"); + m_readAccessCheck->setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog.read"); m_readAccessCheck->setChecked(defaultAccessType & TTDMemoryRead); m_writeAccessCheck = new QCheckBox("Write"); + m_writeAccessCheck->setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog.write"); m_writeAccessCheck->setChecked(defaultAccessType & TTDMemoryWrite); m_executeAccessCheck = new QCheckBox("Execute"); + m_executeAccessCheck->setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog.execute"); m_executeAccessCheck->setChecked(defaultAccessType & TTDMemoryExecute); // Remember the selection as soon as it changes, so it survives closing the dialog @@ -1204,14 +1258,17 @@ TTDMemoryAccessNextPrevDialog::TTDMemoryAccessNextPrevDialog(QWidget* parent, Bi // Buttons: Prev, Next, Close QHBoxLayout* buttonLayout = new QHBoxLayout(); QPushButton* prevButton = new QPushButton("\xe2\x97\x80 Prev"); + prevButton->setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog.previous"); prevButton->setToolTip("Find the previous memory access and time travel to it"); connect(prevButton, &QPushButton::clicked, this, &TTDMemoryAccessNextPrevDialog::findPrev); QPushButton* nextButton = new QPushButton("Next \xe2\x96\xb6"); + nextButton->setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog.next"); nextButton->setToolTip("Find the next memory access and time travel to it"); connect(nextButton, &QPushButton::clicked, this, &TTDMemoryAccessNextPrevDialog::findNext); QPushButton* closeButton = new QPushButton("Close"); + closeButton->setProperty("bn.uiTestId", "ttd.memory.accessNavigationDialog.close"); connect(closeButton, &QPushButton::clicked, this, &QDialog::close); buttonLayout->addStretch(); diff --git a/ui/ttdrecord.cpp b/ui/ttdrecord.cpp index 7f0643db..19683f57 100644 --- a/ui/ttdrecord.cpp +++ b/ui/ttdrecord.cpp @@ -151,6 +151,9 @@ static std::vector EnumerateProcessesWithCommandLine() TTDRecordDialog::TTDRecordDialog(QWidget* parent, BinaryView* data) : QDialog() { + setProperty("bn.uiTestId", "ttd.recordDialog"); + setProperty("bn.uiTestScope", "ttd.recordDialog"); + setAccessibleName("TTD record"); if (data) m_controller = DebuggerController::GetController(data); @@ -162,14 +165,28 @@ TTDRecordDialog::TTDRecordDialog(QWidget* parent, BinaryView* data) : layout->setSpacing(0); m_pathEntry = new QLineEdit(this); + m_pathEntry->setProperty("bn.uiTestId", "ttd.recordDialog.executablePath"); + m_pathEntry->setAccessibleName("Executable path"); m_pathEntry->setMinimumWidth(800); m_argumentsEntry = new QLineEdit(this); + m_argumentsEntry->setProperty("bn.uiTestId", "ttd.recordDialog.arguments"); + m_argumentsEntry->setAccessibleName("Command line arguments"); m_workingDirectoryEntry = new QLineEdit(this); + m_workingDirectoryEntry->setProperty("bn.uiTestId", "ttd.recordDialog.workingDirectory"); + m_workingDirectoryEntry->setAccessibleName("Working directory"); m_outputDirectory = new QLineEdit(this); + m_outputDirectory->setProperty("bn.uiTestId", "ttd.recordDialog.outputDirectory"); + m_outputDirectory->setAccessibleName("Trace output directory"); m_launchWithoutTracing = new QCheckBox(this); + m_launchWithoutTracing->setProperty("bn.uiTestId", "ttd.recordDialog.launchWithoutTracing"); + m_launchWithoutTracing->setAccessibleName("Start application with recording off"); m_traceChildProcesses = new QCheckBox(this); + m_traceChildProcesses->setProperty("bn.uiTestId", "ttd.recordDialog.traceChildProcesses"); + m_traceChildProcesses->setAccessibleName("Trace child processes"); auto* pathSelector = new QPushButton("...", this); + pathSelector->setProperty("bn.uiTestId", "ttd.recordDialog.selectExecutable"); + pathSelector->setAccessibleName("Select executable"); pathSelector->setMaximumWidth(30); connect(pathSelector, &QPushButton::clicked, [&]() { auto fileName = QFileDialog::getOpenFileName(this, "Select Executable Path", m_pathEntry->text()); @@ -178,6 +195,8 @@ TTDRecordDialog::TTDRecordDialog(QWidget* parent, BinaryView* data) : }); auto* workingDirSelector = new QPushButton("...", this); + workingDirSelector->setProperty("bn.uiTestId", "ttd.recordDialog.selectWorkingDirectory"); + workingDirSelector->setAccessibleName("Select working directory"); workingDirSelector->setMaximumWidth(30); connect(workingDirSelector, &QPushButton::clicked, [&]() { auto pathName = QFileDialog::getExistingDirectory(this, "Specify Working Directory", @@ -187,6 +206,8 @@ TTDRecordDialog::TTDRecordDialog(QWidget* parent, BinaryView* data) : }); auto* outputDirSelector = new QPushButton("...", this); + outputDirSelector->setProperty("bn.uiTestId", "ttd.recordDialog.selectOutputDirectory"); + outputDirSelector->setAccessibleName("Select trace output directory"); outputDirSelector->setMaximumWidth(30); connect(outputDirSelector, &QPushButton::clicked, [&]() { auto pathName = QFileDialog::getExistingDirectory(this, "Specify Trace Output Directory", @@ -234,8 +255,10 @@ TTDRecordDialog::TTDRecordDialog(QWidget* parent, BinaryView* data) : buttonLayout->setContentsMargins(0, 0, 0, 0); QPushButton* cancelButton = new QPushButton("Cancel"); + cancelButton->setProperty("bn.uiTestId", "ttd.recordDialog.cancel"); connect(cancelButton, &QPushButton::clicked, [&]() { reject(); }); QPushButton* acceptButton = new QPushButton("Record"); + acceptButton->setProperty("bn.uiTestId", "ttd.recordDialog.record"); connect(acceptButton, &QPushButton::clicked, [&]() { apply(); }); acceptButton->setDefault(true); @@ -366,6 +389,9 @@ void TTDRecordDialog::DoTTDTrace() TTDAttachDialog::TTDAttachDialog(QWidget* parent, BinaryView* data) : QDialog() { + setProperty("bn.uiTestId", "ttd.attachDialog"); + setProperty("bn.uiTestScope", "ttd.attachDialog"); + setAccessibleName("TTD attach to process"); if (data) m_controller = DebuggerController::GetController(data); @@ -381,8 +407,14 @@ TTDAttachDialog::TTDAttachDialog(QWidget* parent, BinaryView* data) : // Process list section - pass nullptr to avoid using controller's GetProcessList // We always want to use our own EnumerateProcessesWithCommandLine() for TTD m_processListWidget = new ProcessListWidget(this, nullptr); + m_processListWidget->setProperty("bn.uiTestId", "ttd.attachDialog.processes"); + m_processListWidget->setProperty("bn.uiTestScope", "ttd.attachDialog.processes"); + m_processListWidget->setAccessibleName("Processes available for TTD recording"); m_separateEdit = new FilterEdit(m_processListWidget); + m_separateEdit->setProperty("bn.uiTestId", "ttd.attachDialog.processFilter"); + m_separateEdit->setAccessibleName("Filter processes"); m_filter = new FilteredView(this, m_processListWidget, m_processListWidget, m_separateEdit); + m_filter->setProperty("bn.uiTestId", "ttd.attachDialog.filteredProcesses"); m_filter->setFilterPlaceholderText("Search process"); auto headerLayout = new QHBoxLayout(); @@ -395,9 +427,15 @@ TTDAttachDialog::TTDAttachDialog(QWidget* parent, BinaryView* data) : // TTD options section m_outputDirectory = new QLineEdit(this); + m_outputDirectory->setProperty("bn.uiTestId", "ttd.attachDialog.outputDirectory"); + m_outputDirectory->setAccessibleName("Trace output directory"); m_traceChildProcesses = new QCheckBox(this); + m_traceChildProcesses->setProperty("bn.uiTestId", "ttd.attachDialog.traceChildProcesses"); + m_traceChildProcesses->setAccessibleName("Trace child processes"); auto* outputDirSelector = new QPushButton("...", this); + outputDirSelector->setProperty("bn.uiTestId", "ttd.attachDialog.selectOutputDirectory"); + outputDirSelector->setAccessibleName("Select trace output directory"); outputDirSelector->setMaximumWidth(30); connect(outputDirSelector, &QPushButton::clicked, [&]() { auto pathName = QFileDialog::getExistingDirectory(this, "Specify Trace Output Directory", @@ -426,8 +464,10 @@ TTDAttachDialog::TTDAttachDialog(QWidget* parent, BinaryView* data) : buttonLayout->setContentsMargins(0, 0, 0, 0); QPushButton* cancelButton = new QPushButton("Cancel"); + cancelButton->setProperty("bn.uiTestId", "ttd.attachDialog.cancel"); connect(cancelButton, &QPushButton::clicked, [&]() { reject(); }); QPushButton* acceptButton = new QPushButton("Attach and Record"); + acceptButton->setProperty("bn.uiTestId", "ttd.attachDialog.record"); connect(acceptButton, &QPushButton::clicked, [&]() { apply(); }); acceptButton->setDefault(true); diff --git a/ui/ui.cpp b/ui/ui.cpp index 3175a4bd..c8a77c99 100644 --- a/ui/ui.cpp +++ b/ui/ui.cpp @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +#include "../../../ui/shared/internalaction.h" #include "ui.h" #include "binaryninjaapi.h" #include "breakpointswidget.h" @@ -1157,7 +1158,7 @@ void GlobalDebuggerUI::SetupMenu(UIContext* context) debuggerMenu->addAction("Connect to Remote Process", "Launch"); QString showAreaWidgets = "Show Debugger Sidebar Widgets"; - UIAction::registerAction(showAreaWidgets); + UIIdentity::registerBuiltInAction(showAreaWidgets); context->globalActions()->bindAction(showAreaWidgets, UIAction([](const UIActionContext& ctxt) { auto uiContext = ctxt.context; @@ -1674,6 +1675,9 @@ void GlobalDebuggerUI::installTTD(const UIActionContext& ctxt) // Offer to restart Binary Ninja QMessageBox msgBox(mainWindow); + msgBox.setProperty("bn.uiTestId", "debugger.winDbgInstallResultDialog"); + msgBox.setProperty("bn.uiTestScope", "debugger.winDbgInstallResultDialog"); + msgBox.setAccessibleName("WinDbg/TTD installation successful"); msgBox.setWindowTitle("Installation Successful"); msgBox.setText("WinDbg/TTD has been installed successfully!"); msgBox.setInformativeText("The debugger settings have been configured automatically.\n\n" @@ -1681,7 +1685,9 @@ void GlobalDebuggerUI::installTTD(const UIActionContext& ctxt) msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); msgBox.button(QMessageBox::Yes)->setText("Restart Now"); + msgBox.button(QMessageBox::Yes)->setProperty("bn.uiTestId", "debugger.winDbgInstallResultDialog.restart"); msgBox.button(QMessageBox::No)->setText("Restart Later"); + msgBox.button(QMessageBox::No)->setProperty("bn.uiTestId", "debugger.winDbgInstallResultDialog.later"); if (msgBox.exec() == QMessageBox::Yes) { // Restart Binary Ninja by spawning a new instance before quitting diff --git a/ui/uinotification.cpp b/ui/uinotification.cpp index 5645ce36..04e9c65f 100644 --- a/ui/uinotification.cpp +++ b/ui/uinotification.cpp @@ -108,12 +108,17 @@ bool NotificationListener::OnBeforeCloseFile(UIContext* context, FileContext* fi if (controller->IsConnected()) { QMessageBox* msgBox = new QMessageBox(mainWindow); + msgBox->setProperty("bn.uiTestId", "debugger.activeFileCloseDialog"); + msgBox->setProperty("bn.uiTestScope", "debugger.activeFileCloseDialog"); + msgBox->setAccessibleName("Debugger active while closing file"); msgBox->setAttribute(Qt::WA_DeleteOnClose); msgBox->setIcon(QMessageBox::Question); msgBox->setText(QObject::tr("The debugger file ") + file->getShortFileName(mainWindow) + QObject::tr(" is active. Do you want to stop it before closing?")); msgBox->setWindowTitle(QObject::tr("Debugger Active")); msgBox->setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + msgBox->button(QMessageBox::Yes)->setProperty("bn.uiTestId", "debugger.activeFileCloseDialog.stop"); + msgBox->button(QMessageBox::Cancel)->setProperty("bn.uiTestId", "debugger.activeFileCloseDialog.cancel"); msgBox->setDefaultButton(QMessageBox::Yes); msgBox->show(); msgBox->move(mainWindow->frameGeometry().center() - msgBox->rect().center()); diff --git a/ui/windbgupdatedialog.cpp b/ui/windbgupdatedialog.cpp index ebb35036..f384a3d9 100644 --- a/ui/windbgupdatedialog.cpp +++ b/ui/windbgupdatedialog.cpp @@ -29,6 +29,9 @@ using namespace BinaryNinjaDebuggerAPI; WinDbgUpdateDialog::WinDbgUpdateDialog(QWidget* parent, const std::string& installPath, const std::string& installedVersion) : QDialog(parent), m_installPath(installPath), m_installedVersion(installedVersion) { + setProperty("bn.uiTestId", "debugger.winDbgUpdateDialog"); + setProperty("bn.uiTestScope", "debugger.winDbgUpdateDialog"); + setAccessibleName("WinDbg/TTD Version"); setWindowTitle("WinDbg/TTD Version"); setMinimumWidth(450); @@ -107,12 +110,14 @@ WinDbgUpdateDialog::WinDbgUpdateDialog(QWidget* parent, const std::string& insta buttonLayout->addStretch(); m_cancelButton = new QPushButton("Cancel", this); + m_cancelButton->setProperty("bn.uiTestId", "debugger.winDbgUpdateDialog.cancel"); connect(m_cancelButton, &QPushButton::clicked, this, &WinDbgUpdateDialog::onCancelClicked); buttonLayout->addWidget(m_cancelButton); /* Not "Update": when the installed version is newer than the configured one, this * deliberately replaces it with an older build. */ m_updateButton = new QPushButton(versionMatches ? "Reinstall" : "Install", this); + m_updateButton->setProperty("bn.uiTestId", "debugger.winDbgUpdateDialog.install"); m_updateButton->setDefault(true); connect(m_updateButton, &QPushButton::clicked, this, &WinDbgUpdateDialog::onUpdateClicked); buttonLayout->addWidget(m_updateButton);