459 lines
15 KiB
C++
459 lines
15 KiB
C++
/*
|
||
*
|
||
* Copyright (C) 2023, KylinSoft Co., Ltd.
|
||
*
|
||
* This program is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation, either version 3 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
*
|
||
*
|
||
*/
|
||
#include "vpndetail.h"
|
||
|
||
#define WINDOW_WIDTH 520
|
||
#define WINDOW_HEIGHT 562
|
||
#define NO_LAYOUT_MARGINS 0,0,0,0
|
||
#define HLAYOUT_MARGINS 24,0,24,0
|
||
#define CENTER_LAYOUT_MARGINS 24,0,0,0
|
||
#define NO_SPACE 0
|
||
#define HLAYOUT_SPACING 16
|
||
#define VLAYOUT_SPACING 24
|
||
#define BOTTOM_WIDGET_HEIGHT 85
|
||
#define TAB_HEIGHT 36
|
||
#define TAB_WIDTH 80
|
||
#define MAX_TAB_TEXT_LENGTH 44
|
||
#define VPNTAB_WIDTH 240
|
||
#define PAGE_WIDTH 472
|
||
#define SCRO_WIDTH 496
|
||
#define CONFIG_PAGE_NUM 0
|
||
#define IPV4_PAGE_NUM 1
|
||
#define IPV6_PAGE_NUM 2
|
||
#define ADVANCED_PAGE_NUM 3
|
||
#define NORMAL_PAGE_COUNT 3
|
||
#define LOG_FLAG "[VPN Detail]"
|
||
#define TAB_HEIGHT_TABLET 48
|
||
|
||
VpnDetail::VpnDetail(QString vpnUuid, QString vpnName, QWidget *parent) :
|
||
m_vpnName(vpnName),
|
||
m_uuid(vpnUuid),
|
||
QWidget(parent)
|
||
{
|
||
initWindow();
|
||
centerToScreen();
|
||
getVpnConfig(m_uuid, m_vpnInfo);
|
||
|
||
initUI();
|
||
initConnection();
|
||
pagePadding(m_isOpenVpn);
|
||
|
||
m_isConfigOk = true;
|
||
m_isIpv4Ok = true;
|
||
m_isIpv6Ok = true;
|
||
m_isAdvancedOk = true;
|
||
setConfirmEnable();
|
||
}
|
||
|
||
void VpnDetail::paintEvent(QPaintEvent *event)
|
||
{
|
||
QPalette pal = qApp->palette();
|
||
QPainter painter(this);
|
||
painter.setBrush(pal.color(QPalette::Base));
|
||
painter.drawRect(this->rect());
|
||
painter.fillRect(rect(), QBrush(pal.color(QPalette::Base)));
|
||
|
||
return QWidget::paintEvent(event);
|
||
}
|
||
|
||
|
||
void VpnDetail::initWindow()
|
||
{
|
||
this->setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT);
|
||
this->setWindowTitle(tr("VPN"));
|
||
this->setAttribute(Qt::WA_DeleteOnClose);
|
||
}
|
||
|
||
void VpnDetail::initTabBar()
|
||
{
|
||
//文本长度超出显示区域设置tooltip
|
||
int tabCount = m_vpnTabBar->count();
|
||
for (int i = 0; i< tabCount; ++i) {
|
||
QFontMetrics fontMetrics(m_vpnTabBar->font());
|
||
int fontSize = fontMetrics.width(m_vpnTabBar->tabText(i));
|
||
if (fontSize > MAX_TAB_TEXT_LENGTH) {
|
||
m_vpnTabBar->setTabToolTip(i, m_vpnTabBar->tabText(i));
|
||
} else {
|
||
m_vpnTabBar->setTabToolTip(i, "");
|
||
}
|
||
}
|
||
}
|
||
|
||
void VpnDetail::initUI()
|
||
{
|
||
//控件
|
||
m_topWidget = new QWidget(this);
|
||
m_centerWidget = new QWidget(this);
|
||
m_bottomWidget = new QWidget(this);
|
||
m_divider = new Divider(false, this);
|
||
m_vpnTabBar = new VpnTabBar(this);
|
||
m_autoConnectBox = new QCheckBox(this);
|
||
m_autoConnectLabel = new QLabel(this);
|
||
m_cancelBtn = new QPushButton(this);
|
||
m_confimBtn = new QPushButton(this);
|
||
m_stackWidget = new QStackedWidget(m_centerWidget);
|
||
|
||
m_configPage = new VpnConfigPage(this);
|
||
m_ipv4Page = new VpnIpv4Page(this);
|
||
m_ipv6Page = new VpnIpv6Page(this);
|
||
m_advancedPage = new VpnAdvancedPage(this);
|
||
|
||
m_configScroArea = new QScrollArea(m_centerWidget);
|
||
m_configScroArea->setFrameShape(QFrame::NoFrame);
|
||
m_configScroArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||
m_configScroArea->setWidget(m_configPage);
|
||
m_configScroArea->setWidgetResizable(true);
|
||
|
||
m_ipv4ScroArea = new QScrollArea(m_centerWidget);
|
||
m_ipv4ScroArea->setFrameShape(QFrame::NoFrame);
|
||
m_ipv4ScroArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||
m_ipv4ScroArea->setWidget(m_ipv4Page);
|
||
m_ipv4ScroArea->setWidgetResizable(true);
|
||
|
||
m_ipv6ScroArea = new QScrollArea(m_centerWidget);
|
||
m_ipv6ScroArea->setFrameShape(QFrame::NoFrame);
|
||
m_ipv6ScroArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||
m_ipv6ScroArea->setWidget(m_ipv6Page);
|
||
m_ipv6ScroArea->setWidgetResizable(true);
|
||
|
||
m_advancedScroArea = new QScrollArea(m_centerWidget);
|
||
m_advancedScroArea->setFrameShape(QFrame::NoFrame);
|
||
m_advancedScroArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||
m_advancedScroArea->setWidget(m_advancedPage);
|
||
m_advancedScroArea->setWidgetResizable(true);
|
||
|
||
QPalette pal = m_configScroArea->palette();
|
||
pal.setBrush(QPalette::Window, Qt::transparent);
|
||
m_configScroArea->setPalette(pal);
|
||
m_ipv4ScroArea->setPalette(pal);
|
||
m_ipv6ScroArea->setPalette(pal);
|
||
m_advancedScroArea->setPalette(pal);
|
||
|
||
m_configPage->setFixedWidth(PAGE_WIDTH);
|
||
m_ipv4Page->setFixedWidth(PAGE_WIDTH);
|
||
m_ipv6Page->setFixedWidth(PAGE_WIDTH);
|
||
m_advancedPage->setFixedWidth(PAGE_WIDTH);
|
||
m_configScroArea->setFixedWidth(SCRO_WIDTH);
|
||
m_ipv4ScroArea->setFixedWidth(SCRO_WIDTH);
|
||
m_ipv6ScroArea->setFixedWidth(SCRO_WIDTH);
|
||
m_advancedScroArea->setFixedWidth(SCRO_WIDTH);
|
||
|
||
m_stackWidget->addWidget(m_configScroArea);
|
||
m_stackWidget->addWidget(m_ipv4ScroArea);
|
||
m_stackWidget->addWidget(m_ipv6ScroArea);
|
||
m_stackWidget->addWidget(m_advancedScroArea);
|
||
|
||
//控件显示文本
|
||
m_vpnTabBar->addTab(tr("VPN"));
|
||
m_vpnTabBar->addTab(tr("IPv4"));
|
||
if (m_isOpenVpn) {
|
||
m_vpnTabBar->addTab(tr("IPv6"));
|
||
m_vpnTabBar->setFixedWidth(VPNTAB_WIDTH + TAB_WIDTH);
|
||
} else {
|
||
m_vpnTabBar->setFixedWidth(VPNTAB_WIDTH);
|
||
}
|
||
m_vpnTabBar->addTab(tr("Advanced"));
|
||
m_vpnTabBar->setFixedHeight(TAB_HEIGHT);
|
||
initTabBar();
|
||
|
||
m_autoConnectBox->setChecked(false);
|
||
m_autoConnectLabel->setText(tr("Auto Connection"));
|
||
m_cancelBtn->setText(tr("Cancel"));
|
||
m_confimBtn->setText(tr("Confirm"));
|
||
|
||
//布局
|
||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||
mainLayout->setContentsMargins(NO_LAYOUT_MARGINS);
|
||
mainLayout->setSpacing(NO_SPACE);
|
||
mainLayout->addSpacing(HLAYOUT_SPACING);
|
||
mainLayout->addWidget(m_topWidget);
|
||
mainLayout->addSpacing(VLAYOUT_SPACING);
|
||
mainLayout->addWidget(m_centerWidget);
|
||
mainLayout->addStretch();
|
||
mainLayout->addWidget(m_divider);
|
||
mainLayout->addWidget(m_bottomWidget);
|
||
m_bottomWidget->setFixedHeight(BOTTOM_WIDGET_HEIGHT);
|
||
|
||
QHBoxLayout *topLayout = new QHBoxLayout(m_topWidget);
|
||
topLayout->setContentsMargins(HLAYOUT_MARGINS);
|
||
topLayout->addWidget(m_vpnTabBar, Qt::AlignCenter);
|
||
|
||
QVBoxLayout *centerlayout = new QVBoxLayout(m_centerWidget);
|
||
centerlayout->setContentsMargins(CENTER_LAYOUT_MARGINS); // 右边距为0,为安全页滚动区域留出空间
|
||
centerlayout->addWidget(m_stackWidget);
|
||
|
||
QHBoxLayout *bottomLayout = new QHBoxLayout(m_bottomWidget);
|
||
bottomLayout->setContentsMargins(HLAYOUT_MARGINS);
|
||
bottomLayout->setSpacing(NO_SPACE);
|
||
bottomLayout->addWidget(m_autoConnectBox);
|
||
bottomLayout->addSpacing(8);
|
||
bottomLayout->addWidget(m_autoConnectLabel);
|
||
bottomLayout->addStretch();
|
||
bottomLayout->addWidget(m_cancelBtn);
|
||
bottomLayout->addSpacing(HLAYOUT_SPACING);
|
||
bottomLayout->addWidget(m_confimBtn);
|
||
|
||
m_advancedPage->setVpnAdvancedPage(m_configPage->getVpnType());
|
||
}
|
||
|
||
void VpnDetail::initConnection()
|
||
{
|
||
connect(m_vpnTabBar, &VpnTabBar::currentChanged, this, &VpnDetail::onTabCurrentRowChange);
|
||
connect(m_cancelBtn, &QPushButton::clicked, [&] () {this->close();});
|
||
connect(m_confimBtn, &QPushButton::clicked, this, &VpnDetail::onConfimBtnClicked);
|
||
|
||
connect(m_configPage, &VpnConfigPage::setConfigPageState, this, [=] (bool state) {
|
||
m_isConfigOk = state;
|
||
setConfirmEnable();
|
||
});
|
||
connect(m_ipv4Page, &VpnIpv4Page::setIpv4PageState, this, [=] (bool state) {
|
||
m_isIpv4Ok = state;
|
||
setConfirmEnable();
|
||
});
|
||
connect(m_ipv6Page, &VpnIpv6Page::setIpv6PageState, this, [=] (bool state) {
|
||
m_isIpv6Ok = state;
|
||
setConfirmEnable();
|
||
});
|
||
connect(m_advancedPage, &VpnAdvancedPage::setAdvancedPageState, this, [=] (bool state) {
|
||
m_isAdvancedOk = state;
|
||
setConfirmEnable();
|
||
});
|
||
|
||
connect(m_configPage, &VpnConfigPage::vpnTypeChanged, m_advancedPage, &VpnAdvancedPage::setVpnAdvancedPage);
|
||
|
||
connect(m_configPage, &VpnConfigPage::vpnTypeChanged, this, [=](VpnType type) {
|
||
if (type == OPEN_VPN) {
|
||
if (m_vpnTabBar->count() == NORMAL_PAGE_COUNT) {
|
||
m_vpnTabBar->insertTab(IPV6_PAGE_NUM, tr("IPv6"));
|
||
m_vpnTabBar->setFixedWidth(VPNTAB_WIDTH + TAB_WIDTH);
|
||
}
|
||
} else {
|
||
if (m_vpnTabBar->count() > NORMAL_PAGE_COUNT) {
|
||
m_vpnTabBar->removeTab(IPV6_PAGE_NUM);
|
||
m_vpnTabBar->setFixedWidth(VPNTAB_WIDTH);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
void VpnDetail::centerToScreen()
|
||
{
|
||
QDesktopWidget* m = QApplication::desktop();
|
||
QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos()));
|
||
int desk_x = desk_rect.width();
|
||
int desk_y = desk_rect.height();
|
||
int x = this->width();
|
||
int y = this->height();
|
||
this->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top());
|
||
}
|
||
|
||
void VpnDetail::setConfirmEnable()
|
||
{
|
||
bool isConfirmBtnEnable = false;
|
||
if (m_isConfigOk && m_isIpv4Ok && m_isAdvancedOk) {
|
||
if (m_isOpenVpn && !m_isIpv6Ok) {
|
||
isConfirmBtnEnable = false;
|
||
} else {
|
||
isConfirmBtnEnable = true;
|
||
}
|
||
}
|
||
m_confimBtn->setEnabled(isConfirmBtnEnable);
|
||
}
|
||
|
||
void VpnDetail::getVpnConfig(QString connectUuid, KyVpnConfig &vpnInfo)
|
||
{
|
||
KyVpnConnectOperation vpnConnect(this);
|
||
vpnInfo = vpnConnect.getVpnConfig(connectUuid);
|
||
m_isOpenVpn = m_vpnInfo.m_vpnType == KYVPNTYPE_OPENVPN;
|
||
}
|
||
|
||
void VpnDetail::pagePadding(bool isOpenVpn)
|
||
{
|
||
m_autoConnectBox->setChecked(m_vpnInfo.m_isAutoConnect);
|
||
|
||
//配置页面填充
|
||
m_configPage->setVpnConfigInfo(m_vpnInfo);
|
||
|
||
//IPv4页面填充
|
||
m_ipv4Page->setVpnIpv4Info(m_vpnInfo);
|
||
if (!m_vpnInfo.m_ipv4Dns.isEmpty()) {
|
||
m_ipv4Page->setDns(m_vpnInfo.m_ipv4Dns.at(0).toString());
|
||
}
|
||
if (!m_vpnInfo.m_ipv4DnsSearch.isEmpty()) {
|
||
m_ipv4Page->setSearchDomain(m_vpnInfo.m_ipv4DnsSearch.at(0));
|
||
}
|
||
m_ipv4Page->setDhcpClientId(m_vpnInfo.m_ipv4DhcpClientId);
|
||
//IPv6页面填充
|
||
if (isOpenVpn) {
|
||
m_ipv6Page->setVpnIpv6Info(m_vpnInfo);
|
||
if (!m_vpnInfo.m_ipv6Dns.isEmpty()) {
|
||
m_ipv6Page->setDns(m_vpnInfo.m_ipv6Dns.at(0).toString());
|
||
}
|
||
if (!m_vpnInfo.m_ipv6DnsSearch.isEmpty()) {
|
||
m_ipv6Page->setSearchDomain(m_vpnInfo.m_ipv6DnsSearch.at(0));
|
||
}
|
||
}
|
||
|
||
//高级页面填充
|
||
if (m_vpnInfo.m_vpnType == KYVPNTYPE_L2TP || m_vpnInfo.m_vpnType == KYVPNTYPE_PPTP) {
|
||
m_advancedPage->setL2tpOrPptpAdiaInfo(m_vpnInfo);
|
||
} else if (m_vpnInfo.m_vpnType == KYVPNTYPE_OPENVPN) {
|
||
m_advancedPage->setOpenVpnAdiaInfo(m_vpnInfo);
|
||
} else if (m_vpnInfo.m_vpnType == KYVPNTYPE_STRONGSWAN) {
|
||
m_advancedPage->setStrongSwanAdiaInfo(m_vpnInfo);
|
||
}
|
||
}
|
||
|
||
bool VpnDetail::updateVpnCnofig()
|
||
{
|
||
KyVpnConnectOperation vpnConnect(this);
|
||
KyVpnConfig vpnConfig = m_vpnInfo;
|
||
bool needUpdate = false;
|
||
VpnType vpnType = m_configPage->getVpnType();
|
||
|
||
if (m_vpnInfo.m_isAutoConnect != m_autoConnectBox->isChecked()) {
|
||
vpnConfig.m_isAutoConnect = m_autoConnectBox->isChecked();
|
||
needUpdate = true;
|
||
}
|
||
|
||
if (m_configPage->checkIsChanged(m_vpnInfo)) {
|
||
m_configPage->updateVpnConfigInfo(vpnConfig);
|
||
needUpdate = true;
|
||
}
|
||
|
||
if (m_ipv4Page->checkIsChanged(m_vpnInfo)) {
|
||
m_ipv4Page->updateVpnIpv4Info(vpnConfig);
|
||
needUpdate = true;
|
||
}
|
||
|
||
if (vpnType == OPEN_VPN) {
|
||
if (m_ipv6Page->checkIsChanged(m_vpnInfo)) {
|
||
m_ipv6Page->updateVpnIpv6Info(vpnConfig);
|
||
needUpdate = true;
|
||
}
|
||
}
|
||
|
||
if (m_advancedPage->checkIsChanged(m_vpnInfo, vpnType)) {
|
||
if (vpnType == L2TP || vpnType == PPTP) {
|
||
m_advancedPage->updateL2tpOrPptpAdiaInfo(vpnConfig);
|
||
needUpdate = true;
|
||
} else if (vpnType == OPEN_VPN) {
|
||
m_advancedPage->updateOpenVpnAdiaInfo(vpnConfig);
|
||
needUpdate = true;
|
||
} else if (vpnType == STRONG_SWAN) {
|
||
m_advancedPage->updateStrongSwanAdiaInfo(vpnConfig);
|
||
needUpdate = true;
|
||
}
|
||
}
|
||
|
||
if (needUpdate) {
|
||
vpnConnect.setVpnConfig(m_uuid, vpnConfig);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void VpnDetail::setVpndetailSomeEnable(bool on)
|
||
{
|
||
m_configPage->setEnabled(on);
|
||
m_ipv4Page->setEnabled(on);
|
||
m_ipv6Page->setEnabled(on);
|
||
m_advancedPage->setEnabled(on);
|
||
m_cancelBtn->setEnabled(on);
|
||
m_confimBtn->setEnabled(on);
|
||
}
|
||
|
||
void VpnDetail::onTabCurrentRowChange(int row)
|
||
{
|
||
if (row < 2) {
|
||
m_stackWidget->setCurrentIndex(row);
|
||
} else {
|
||
if (m_configPage->getVpnType() == OPEN_VPN) {
|
||
m_stackWidget->setCurrentIndex(row);
|
||
} else {
|
||
m_stackWidget->setCurrentIndex(ADVANCED_PAGE_NUM);
|
||
}
|
||
}
|
||
}
|
||
|
||
void VpnDetail::onConfimBtnClicked()
|
||
{
|
||
qDebug() << "onConfimBtnClicked";
|
||
setVpndetailSomeEnable(false);
|
||
//更新连接
|
||
qDebug() << "Confirm update connect";
|
||
if (!updateVpnCnofig()) {
|
||
setVpndetailSomeEnable(true);
|
||
return;
|
||
}
|
||
close();
|
||
}
|
||
|
||
|
||
VpnTabBar::VpnTabBar(QWidget *parent)
|
||
:KTabBar(KTabBarStyle::SegmentDark, parent)
|
||
{
|
||
//模式切换
|
||
QDBusConnection::sessionBus().connect(QString("com.kylin.statusmanager.interface"),
|
||
QString("/"),
|
||
QString("com.kylin.statusmanager.interface"),
|
||
QString("mode_change_signal"), this, SLOT(onModeChanged(bool)));
|
||
//模式获取
|
||
QDBusInterface interface(QString("com.kylin.statusmanager.interface"),
|
||
QString("/"),
|
||
QString("com.kylin.statusmanager.interface"),
|
||
QDBusConnection::sessionBus());
|
||
if(!interface.isValid()) {
|
||
this->setFixedHeight(TAB_HEIGHT);
|
||
return;
|
||
}
|
||
QDBusReply<bool> reply = interface.call("get_current_tabletmode");
|
||
if (!reply.isValid()) {
|
||
this->setFixedHeight(TAB_HEIGHT);
|
||
return;
|
||
}
|
||
onModeChanged(reply.value());
|
||
}
|
||
|
||
QSize VpnTabBar::sizeHint() const
|
||
{
|
||
QSize size = KTabBar::sizeHint();
|
||
size.setWidth(TAB_WIDTH);
|
||
return size;
|
||
}
|
||
|
||
QSize VpnTabBar::minimumTabSizeHint(int index) const
|
||
{
|
||
Q_UNUSED(index)
|
||
QSize size = KTabBar::minimumTabSizeHint(index);
|
||
size.setWidth(TAB_WIDTH);
|
||
return size;
|
||
}
|
||
|
||
void VpnTabBar::onModeChanged(bool mode)
|
||
{
|
||
if (mode) {
|
||
this->setFixedHeight(TAB_HEIGHT_TABLET); // 平板模式
|
||
} else {
|
||
this->setFixedHeight(TAB_HEIGHT); // PC模式
|
||
}
|
||
|
||
}
|