| 5184 | // ─── Peripherals tab — manual IP connect for TGXL, PGXL, AG (#914) ─────────── |
| 5185 | |
| 5186 | QWidget* RadioSetupDialog::buildPeripheralsTab() |
| 5187 | { |
| 5188 | auto* page = new QWidget; |
| 5189 | auto* vbox = new QVBoxLayout(page); |
| 5190 | vbox->setSpacing(8); |
| 5191 | |
| 5192 | auto* group = new QGroupBox("External Devices — Manual IP Connection"); |
| 5193 | group->setStyleSheet(kGroupStyle); |
| 5194 | auto* grid = new QGridLayout(group); |
| 5195 | grid->setSpacing(6); |
| 5196 | |
| 5197 | // Column headers |
| 5198 | auto addHeader = [&](int col, const QString& text) { |
| 5199 | auto* lbl = new QLabel(text); |
| 5200 | AetherSDR::ThemeManager::instance().applyStyleSheet(lbl, "QLabel { color: {{color.text.secondary}}; font-size: 11px; font-weight: bold; }"); |
| 5201 | grid->addWidget(lbl, 0, col); |
| 5202 | }; |
| 5203 | addHeader(0, "Device"); |
| 5204 | addHeader(1, "IP Address"); |
| 5205 | addHeader(2, "Port"); |
| 5206 | addHeader(3, ""); |
| 5207 | addHeader(4, "Status"); |
| 5208 | |
| 5209 | auto& settings = AppSettings::instance(); |
| 5210 | |
| 5211 | static const QString kBtnStyle = |
| 5212 | "QPushButton { background: #1a2a3a; border: 1px solid #304050; " |
| 5213 | "border-radius: 3px; color: #c8d8e8; font-size: 11px; font-weight: bold; " |
| 5214 | "padding: 3px 10px; }" |
| 5215 | "QPushButton:hover { background: #203040; }"; |
| 5216 | |
| 5217 | // Helper to build one peripheral row |
| 5218 | auto buildRow = [&](int row, const QString& label, const QString& ipKey, |
| 5219 | const QString& portKey, int defaultPort, |
| 5220 | auto connectFn, auto disconnectFn, auto isConnectedFn, |
| 5221 | auto peerAddressFn, auto peerPortFn) { |
| 5222 | // Device label |
| 5223 | auto* devLbl = new QLabel(label); |
| 5224 | devLbl->setStyleSheet(kLabelStyle); |
| 5225 | grid->addWidget(devLbl, row, 0); |
| 5226 | |
| 5227 | // IP field — pre-fill from settings, or from live connection if discovered |
| 5228 | auto* ipEdit = new QLineEdit; |
| 5229 | ipEdit->setPlaceholderText("e.g. 192.168.1.100"); |
| 5230 | ipEdit->setStyleSheet(kEditStyle); |
| 5231 | ipEdit->setMinimumWidth(140); |
| 5232 | QString savedIp = settings.value(ipKey, "").toString(); |
| 5233 | if (!savedIp.isEmpty()) { |
| 5234 | ipEdit->setText(savedIp); |
| 5235 | } else if (isConnectedFn()) { |
| 5236 | ipEdit->setText(peerAddressFn()); |
| 5237 | } |
| 5238 | grid->addWidget(ipEdit, row, 1); |
| 5239 | |
| 5240 | // Port field — pre-fill from settings, or from live connection |
| 5241 | auto* portSpin = new QSpinBox; |
| 5242 | portSpin->setRange(1, 65535); |
| 5243 | int savedPort = settings.value(portKey, "0").toInt(); |
nothing calls this directly
no test coverage detected