| 179 | |
| 180 | |
| 181 | QWidget* DSCTriageView::initImageTable() |
| 182 | { |
| 183 | m_imageTable = new FilterableTableView(this); |
| 184 | |
| 185 | m_imageModel = new QStandardItemModel(0, 3, m_imageTable); |
| 186 | m_imageModel->setHorizontalHeaderLabels({"Address", "Loaded", "Name"}); |
| 187 | |
| 188 | // Apply custom column styling |
| 189 | m_imageTable->setItemDelegateForColumn(0, new AddressColorDelegate(m_imageTable)); |
| 190 | m_imageTable->setItemDelegateForColumn(1, new LoadedDelegate(m_imageTable)); |
| 191 | |
| 192 | // Context menu |
| 193 | m_imageTable->setContextMenuPolicy(Qt::CustomContextMenu); |
| 194 | connect(m_imageTable, &QWidget::customContextMenuRequested, [this](const QPoint &pos) { |
| 195 | QMenu contextMenu(tr("Load Image Actions"), m_imageTable); |
| 196 | |
| 197 | // Get number of selected images |
| 198 | auto selected = m_imageTable->selectionModel()->selectedRows(); |
| 199 | int selectedCount = 0; |
| 200 | std::vector<uint64_t> addresses; |
| 201 | for (const auto& idx : selected) |
| 202 | { |
| 203 | // Skip rows hidden by the filter |
| 204 | if (m_imageTable->isRowHidden(idx.row())) |
| 205 | continue; |
| 206 | addresses.push_back(idx.data().toString().toULongLong(nullptr, 16)); |
| 207 | selectedCount++; |
| 208 | } |
| 209 | |
| 210 | QAction noSelectionAction("No Images Selected", m_imageTable); |
| 211 | QAction loadImagesAction("", m_imageTable); |
| 212 | QAction loadImagesWithDepsAction("", m_imageTable); |
| 213 | if (selectedCount == 0) |
| 214 | { |
| 215 | noSelectionAction.setEnabled(false); |
| 216 | contextMenu.addAction(&noSelectionAction); |
| 217 | } |
| 218 | else |
| 219 | { |
| 220 | // Format action text for loading selected images |
| 221 | QString loadActionText = (selectedCount == 1) ? "Load Selected Image" : QString("Load %1 Selected Images").arg(selectedCount); |
| 222 | loadImagesAction.setText(loadActionText); |
| 223 | connect(&loadImagesAction, &QAction::triggered, [this, addresses]() { |
| 224 | loadImagesWithAddr(addresses, false); |
| 225 | }); |
| 226 | contextMenu.addAction(&loadImagesAction); |
| 227 | |
| 228 | // Format action text for loading selected images with dependencies |
| 229 | QString loadWithDepsActionText = (selectedCount == 1) ? "Load Selected Image and Dependencies" : QString("Load %1 Selected Images and Dependencies").arg(selectedCount); |
| 230 | loadImagesWithDepsAction.setText(loadWithDepsActionText); |
| 231 | connect(&loadImagesWithDepsAction, &QAction::triggered, [this, addresses]() { |
| 232 | this->loadImagesWithAddr(addresses, true); |
| 233 | }); |
| 234 | contextMenu.addAction(&loadImagesWithDepsAction); |
| 235 | } |
| 236 | |
| 237 | contextMenu.exec(m_imageTable->viewport()->mapToGlobal(pos)); |
| 238 | }); |