diff --git a/terminal/kiosk-shell/src/desktop_settings_dialog.cpp b/terminal/kiosk-shell/src/desktop_settings_dialog.cpp new file mode 100644 index 0000000..6d93244 --- /dev/null +++ b/terminal/kiosk-shell/src/desktop_settings_dialog.cpp @@ -0,0 +1,143 @@ +#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_); + + comboProtocol_ = new QComboBox(this); + comboProtocol_->addItem(QStringLiteral("Moonlight"), QStringLiteral("moonlight")); + comboProtocol_->addItem(QStringLiteral("RDP"), QStringLiteral("rdp")); + form->addRow(QStringLiteral("协议"), comboProtocol_); + + 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("应用名(Moonlight)"), 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; + comboProtocol_->setCurrentIndex(d.protocol == Protocol::kRdp ? 1 : 0); + 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 = comboProtocol_->currentData().toString() == QStringLiteral("rdp") + ? Protocol::kRdp + : 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