#include "desktop_settings_dialog.h" #include #include #include #include #include #include #include #include #include "desktop_store.h" namespace vdi { DesktopSettingsDialog::DesktopSettingsDialog(std::vector desktops, const QString& selectId, QWidget* parent) : QDialog(parent), desktops_(std::move(desktops)) { setWindowTitle(QStringLiteral("桌面连接设置")); setMinimumWidth(560); // Kiosk 主窗口是全屏窗口,必须置顶否则对话框会被完全遮挡 setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); auto* root = new QVBoxLayout(this); root->setSpacing(14); auto* hint = new QLabel( QStringLiteral("为每张桌面配置连接参数。地址支持 IP、域名或 VPN 隧道地址;" "地址留空表示待分配,卡片将不可连接。"), this); hint->setWordWrap(true); hint->setStyleSheet(QStringLiteral("color: #8a94a6;")); root->addWidget(hint); auto* form = new QFormLayout(); form->setHorizontalSpacing(14); form->setVerticalSpacing(12); comboDesktop_ = new QComboBox(this); for (const DesktopInfo& d : desktops_) { comboDesktop_->addItem(d.name, d.id); } form->addRow(QStringLiteral("桌面"), comboDesktop_); // 协议统一 Moonlight(RDP 渲染实测差,已不提供选项;代码保留作网关备用) editEndpoint_ = new QLineEdit(this); editEndpoint_->setPlaceholderText(QStringLiteral("例如 192.168.1.70 或 VPN 隧道地址")); form->addRow(QStringLiteral("服务器地址"), editEndpoint_); editApp_ = new QLineEdit(this); editApp_->setPlaceholderText(QStringLiteral("Sunshine 应用名,通常为 Desktop")); form->addRow(QStringLiteral("应用名"), editApp_); comboResolution_ = new QComboBox(this); const char* resolutions[] = {"1920x1080", "2560x1440", "1920x1440", "3840x2160", "1280x720"}; for (const char* r : resolutions) { comboResolution_->addItem(QString::fromLatin1(r), QString::fromLatin1(r)); } form->addRow(QStringLiteral("分辨率"), comboResolution_); comboFps_ = new QComboBox(this); comboFps_->addItem(QStringLiteral("60"), 60); comboFps_->addItem(QStringLiteral("30"), 30); form->addRow(QStringLiteral("帧率"), comboFps_); root->addLayout(form); auto* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); buttons->button(QDialogButtonBox::Ok)->setText(QStringLiteral("保存")); buttons->button(QDialogButtonBox::Cancel)->setText(QStringLiteral("取消")); root->addWidget(buttons); connect(comboDesktop_, QOverload::of(&QComboBox::currentIndexChanged), this, &DesktopSettingsDialog::onDesktopChanged); connect(buttons, &QDialogButtonBox::accepted, this, &DesktopSettingsDialog::onAccepted); connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject); // 预选指定桌面 int index = 0; if (!selectId.isEmpty()) { for (int i = 0; i < comboDesktop_->count(); ++i) { if (comboDesktop_->itemData(i).toString() == selectId) { index = i; break; } } } comboDesktop_->setCurrentIndex(index); loadCurrent(); } void DesktopSettingsDialog::onDesktopChanged(int index) { Q_UNUSED(index); loadCurrent(); } void DesktopSettingsDialog::loadCurrent() { const QString id = comboDesktop_->currentData().toString(); for (const DesktopInfo& d : desktops_) { if (d.id != id) { continue; } loading_ = true; editEndpoint_->setText(d.endpoint); editApp_->setText(d.app); int resIndex = comboResolution_->findData( QStringLiteral("%1x%2").arg(d.width).arg(d.height)); comboResolution_->setCurrentIndex(resIndex >= 0 ? resIndex : 0); int fpsIndex = comboFps_->findData(d.fps); comboFps_->setCurrentIndex(fpsIndex >= 0 ? fpsIndex : 0); loading_ = false; break; } } void DesktopSettingsDialog::onAccepted() { const QString id = comboDesktop_->currentData().toString(); for (DesktopInfo& d : desktops_) { if (d.id != id) { continue; } d.protocol = Protocol::kMoonlight; d.endpoint = editEndpoint_->text().trimmed(); d.app = editApp_->text().trimmed(); const QString res = comboResolution_->currentData().toString(); sscanf(res.toLatin1().constData(), "%dx%d", &d.width, &d.height); d.fps = comboFps_->currentData().toInt(); d.state = d.endpoint.isEmpty() ? DesktopState::kUnassigned : DesktopState::kAvailable; DesktopStore::update(d); break; } accept(); } } // namespace vdi