!27 新增VPN功能代码,重新提交PR
Merge pull request !27 from chenxuechao/openkylin/upstream-dev-fork-new
This commit is contained in:
commit
82d8bfc6e2
10
kylin-nm.pro
10
kylin-nm.pro
|
@ -1,11 +1,13 @@
|
||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
CONFIG += ordered \
|
CONFIG += \
|
||||||
qt
|
ordered \
|
||||||
|
qt
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
plugins/plugin.pro \
|
plugins/plugin.pro \
|
||||||
src \
|
src-vpn/src-vpn.pro \
|
||||||
|
src
|
||||||
|
|
||||||
TRANSLATIONS += \
|
TRANSLATIONS += \
|
||||||
translations/kylin-nm_zh_CN.ts \
|
translations/kylin-nm_zh_CN.ts \
|
||||||
|
|
|
@ -3,4 +3,5 @@ SUBDIRS = \
|
||||||
netconnect \
|
netconnect \
|
||||||
wlanconnect \
|
wlanconnect \
|
||||||
mobilehotspot \
|
mobilehotspot \
|
||||||
proxy
|
proxy \
|
||||||
|
vpn
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "itemframe.h"
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
#define LAYOUT_MARGINS 0,0,0,0
|
||||||
|
#define MAIN_LAYOUT_MARGINS 0,0,0,0
|
||||||
|
ItemFrame::ItemFrame(QWidget *parent)
|
||||||
|
:QFrame(parent)
|
||||||
|
{
|
||||||
|
m_mainVLayout = new QVBoxLayout(this);
|
||||||
|
m_mainVLayout->setContentsMargins(MAIN_LAYOUT_MARGINS);
|
||||||
|
m_vpnFrame = new QFrame(this);
|
||||||
|
m_vpnFrame->setFrameShape(QFrame::Shape::NoFrame);
|
||||||
|
m_vpnFrame->setContentsMargins(LAYOUT_MARGINS);
|
||||||
|
|
||||||
|
m_vpnVLayout = new QVBoxLayout(this);
|
||||||
|
m_vpnVLayout->setContentsMargins(LAYOUT_MARGINS);
|
||||||
|
m_vpnVLayout->setSpacing(1);
|
||||||
|
m_addVpnWidget = new AddNetBtn(false, this);
|
||||||
|
m_addVpnWidget->setTextLabel(tr("Add Vpn"));
|
||||||
|
|
||||||
|
m_mainVLayout->setSpacing(1);
|
||||||
|
setLayout(m_mainVLayout);
|
||||||
|
m_vpnFrame->setLayout(m_vpnVLayout);
|
||||||
|
|
||||||
|
m_mainVLayout->addWidget(m_vpnFrame);
|
||||||
|
m_mainVLayout->addWidget(m_addVpnWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemFrame::filletStyleChange()
|
||||||
|
{
|
||||||
|
if (m_vpnVLayout->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m_vpnVLayout->count(); ++i) {
|
||||||
|
QLayoutItem *it = m_vpnVLayout->itemAt(i);
|
||||||
|
VpnItem *itemFrame = (VpnItem*)(it->widget());
|
||||||
|
if (i != m_vpnVLayout->count()-1) {
|
||||||
|
itemFrame->setHalfFillet(false);
|
||||||
|
} else {
|
||||||
|
itemFrame->setHalfFillet(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef ITEMFRAME_H
|
||||||
|
#define ITEMFRAME_H
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include "../component/AddBtn/addnetbtn.h"
|
||||||
|
#include "vpnitem.h"
|
||||||
|
|
||||||
|
class ItemFrame : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ItemFrame(QWidget *parent = nullptr);
|
||||||
|
//VPN整体layout
|
||||||
|
QVBoxLayout * m_mainVLayout = nullptr;
|
||||||
|
//vpn列表Frame
|
||||||
|
QFrame * m_vpnFrame = nullptr;
|
||||||
|
//单设备列表layout
|
||||||
|
QVBoxLayout * m_vpnVLayout = nullptr;
|
||||||
|
//item列表
|
||||||
|
QMap<QString, VpnItem *> m_itemMap;
|
||||||
|
// //已激活uuid
|
||||||
|
// QString uuid = "";
|
||||||
|
//新建无线连接
|
||||||
|
AddNetBtn * m_addVpnWidget = nullptr;
|
||||||
|
void filletStyleChange();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ITEMFRAME_H
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="zh_CN" sourcelanguage="en">
|
||||||
|
<context>
|
||||||
|
<name>AddNetBtn</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../component/AddBtn/addnetbtn.cpp" line="47"/>
|
||||||
|
<source>Add Others</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../component/AddBtn/addnetbtn.cpp" line="51"/>
|
||||||
|
<source>Add WiredNetork</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ItemFrame</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../itemframe.cpp" line="38"/>
|
||||||
|
<source>Add Vpn</source>
|
||||||
|
<translation>添加VPN</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>Vpn</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpn.ui" line="53"/>
|
||||||
|
<source>VPN</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpn.ui" line="68"/>
|
||||||
|
<source>import</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpn.cpp" line="68"/>
|
||||||
|
<source>Vpn</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpn.cpp" line="151"/>
|
||||||
|
<source>Show on Taskbar</source>
|
||||||
|
<translation>在任务栏显示图标</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpn.cpp" line="347"/>
|
||||||
|
<location filename="../vpn.cpp" line="454"/>
|
||||||
|
<source>connected</source>
|
||||||
|
<translation>已连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpn.cpp" line="349"/>
|
||||||
|
<location filename="../vpn.cpp" line="464"/>
|
||||||
|
<source>not connected</source>
|
||||||
|
<translation>未连接</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnItem</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpnitem.cpp" line="58"/>
|
||||||
|
<source>Delete</source>
|
||||||
|
<translation>删除</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpnitem.cpp" line="111"/>
|
||||||
|
<location filename="../vpnitem.cpp" line="124"/>
|
||||||
|
<source>Disconnect</source>
|
||||||
|
<translation>断开</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../vpnitem.cpp" line="113"/>
|
||||||
|
<location filename="../vpnitem.cpp" line="122"/>
|
||||||
|
<source>Connect</source>
|
||||||
|
<translation>连接</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
|
@ -0,0 +1,502 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "vpn.h"
|
||||||
|
#include "ui_vpn.h"
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QtDBus>
|
||||||
|
#include <QDBusArgument>
|
||||||
|
|
||||||
|
#define ACTIVATING 1
|
||||||
|
#define ACTIVATED 2
|
||||||
|
#define DEACTIVATING 3
|
||||||
|
#define DEACTIVATED 4
|
||||||
|
|
||||||
|
#define LABEL_RECT 17, 0, 105, 23
|
||||||
|
#define CONTENTS_MARGINS 0, 0, 0, 0
|
||||||
|
#define ITEM_MARGINS 16, 0, 16, 0
|
||||||
|
#define FRAME_MIN_SIZE 550, 60
|
||||||
|
#define FRAME_MAX_SIZE 16777215, 16777215
|
||||||
|
#define CONTECT_FRAME_MAX_SIZE 16777215, 60
|
||||||
|
#define HINT_TEXT_MARGINS 8, 0, 0, 0
|
||||||
|
#define FRAME_MIN_SIZE 550, 60
|
||||||
|
#define LABLE_MIN_WIDTH 188
|
||||||
|
#define COMBOBOX_MIN_WIDTH 200
|
||||||
|
#define LINE_MAX_SIZE 16777215, 1
|
||||||
|
#define LINE_MIN_SIZE 0, 1
|
||||||
|
#define ICON_SIZE 24,24
|
||||||
|
#define PASSWORD_FRAME_MIN_HIGHT 60
|
||||||
|
#define PASSWORD_FRAME_FIX_HIGHT 80
|
||||||
|
#define PASSWORD_FRAME_MIN_SIZE 550, 60
|
||||||
|
#define PASSWORD_FRAME_MAX_SIZE 16777215, 86
|
||||||
|
#define PASSWORD_ITEM_MARGINS 16, 12, 16, 14
|
||||||
|
|
||||||
|
#define KVpnSymbolic "ukui-vpn-symbolic"
|
||||||
|
|
||||||
|
#define KYLIN_APP_MANAGER_NAME "com.kylin.AppManager"
|
||||||
|
#define KYLIN_APP_MANAGER_PATH "/com/kylin/AppManager"
|
||||||
|
#define KYLIN_APP_MANAGER_INTERFACE "com.kylin.AppManager"
|
||||||
|
|
||||||
|
const QString VISIBLE = "visible";
|
||||||
|
const QByteArray GSETTINGS_SCHEMA = "org.ukui.kylin-nm.vpnicon";
|
||||||
|
|
||||||
|
Vpn::Vpn() : m_firstLoad(true)
|
||||||
|
{
|
||||||
|
QTranslator* translator = new QTranslator(this);
|
||||||
|
translator->load("/usr/share/kylin-nm/vpn/" + QLocale::system().name());
|
||||||
|
QApplication::installTranslator(translator);
|
||||||
|
|
||||||
|
m_pluginName = tr("Vpn");
|
||||||
|
m_pluginType = NETWORK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vpn::~Vpn()
|
||||||
|
{
|
||||||
|
if (!m_firstLoad) {
|
||||||
|
delete ui;
|
||||||
|
ui = nullptr;
|
||||||
|
delete m_interface;
|
||||||
|
delete m_switchGsettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Vpn::plugini18nName(){
|
||||||
|
return m_pluginName;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Vpn::pluginTypes(){
|
||||||
|
return m_pluginType;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *Vpn::pluginUi(){
|
||||||
|
if (m_firstLoad) {
|
||||||
|
m_firstLoad = false;
|
||||||
|
ui = new Ui::Vpn;
|
||||||
|
m_pluginWidget = new QWidget;
|
||||||
|
m_pluginWidget->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
ui->setupUi(m_pluginWidget);
|
||||||
|
|
||||||
|
qDBusRegisterMetaType<QVector<QStringList>>();
|
||||||
|
m_interface = new QDBusInterface("com.kylin.kylinvpn",
|
||||||
|
"/com/kylin/kylinvpn",
|
||||||
|
"com.kylin.kylinvpn",
|
||||||
|
QDBusConnection::sessionBus());
|
||||||
|
if(!m_interface->isValid()) {
|
||||||
|
qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message());
|
||||||
|
}
|
||||||
|
|
||||||
|
initComponent();
|
||||||
|
initConnect();
|
||||||
|
initNet();
|
||||||
|
}
|
||||||
|
return m_pluginWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString Vpn::name() const {
|
||||||
|
|
||||||
|
return QStringLiteral("Vpn");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vpn::isShowOnHomePage() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon Vpn::icon() const
|
||||||
|
{
|
||||||
|
return QIcon::fromTheme("ukui-vpn-symbolic");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vpn::isEnable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vpn::initComponent(){
|
||||||
|
//在任务栏上显示图标
|
||||||
|
//显示已连接时间
|
||||||
|
m_topFrame = new QFrame(m_pluginWidget);
|
||||||
|
m_topFrame->setMinimumSize(FRAME_MIN_SIZE);
|
||||||
|
m_topFrame->setMaximumSize(FRAME_MAX_SIZE);
|
||||||
|
m_topFrame->setFrameShape(QFrame::Box);
|
||||||
|
|
||||||
|
QVBoxLayout *hotspotLyt = new QVBoxLayout(m_pluginWidget);
|
||||||
|
hotspotLyt->setContentsMargins(0, 0, 0, 0);
|
||||||
|
m_topFrame->setLayout(hotspotLyt);
|
||||||
|
|
||||||
|
m_showFrame = new QFrame(m_topFrame);
|
||||||
|
m_showFrame->setFrameShape(QFrame::Shape::NoFrame);
|
||||||
|
m_showFrame->setMinimumSize(FRAME_MIN_SIZE);
|
||||||
|
m_showFrame->setMaximumSize(CONTECT_FRAME_MAX_SIZE);
|
||||||
|
QHBoxLayout *showLayout = new QHBoxLayout(m_showFrame);
|
||||||
|
m_showLabel = new QLabel(tr("Show on Taskbar"), m_showFrame);
|
||||||
|
m_showLabel->setMinimumWidth(LABLE_MIN_WIDTH);
|
||||||
|
m_showBtn = new KSwitchButton(m_showFrame);
|
||||||
|
showLayout->setContentsMargins(ITEM_MARGINS);
|
||||||
|
showLayout->addWidget(m_showLabel);
|
||||||
|
showLayout->addStretch();
|
||||||
|
showLayout->addWidget(m_showBtn);
|
||||||
|
|
||||||
|
m_showFrame->setLayout(showLayout);
|
||||||
|
|
||||||
|
// m_Line = myLine();
|
||||||
|
|
||||||
|
// m_timeFrame = new QFrame(m_topFrame);
|
||||||
|
// m_timeFrame->setFrameShape(QFrame::Shape::NoFrame);
|
||||||
|
// m_timeFrame->setMinimumSize(FRAME_MIN_SIZE);
|
||||||
|
// m_timeFrame->setMaximumSize(CONTECT_FRAME_MAX_SIZE);
|
||||||
|
// QHBoxLayout *timeLayout = new QHBoxLayout(m_timeFrame);
|
||||||
|
// m_timeLabel = new QLabel(tr("Open"), m_timeFrame);
|
||||||
|
// m_timeLabel->setMinimumWidth(LABLE_MIN_WIDTH);
|
||||||
|
// m_timeBtn = new KSwitchButton(m_timeFrame);
|
||||||
|
// timeLayout->setContentsMargins(ITEM_MARGINS);
|
||||||
|
// timeLayout->addWidget(m_timeLabel);
|
||||||
|
// timeLayout->addStretch();
|
||||||
|
// timeLayout->addWidget(m_timeBtn);
|
||||||
|
|
||||||
|
// m_timeFrame->setLayout(timeLayout);
|
||||||
|
|
||||||
|
hotspotLyt->addWidget(m_showFrame);
|
||||||
|
// hotspotLyt->addWidget(m_Line);
|
||||||
|
// hotspotLyt->addWidget(m_timeFrame);
|
||||||
|
hotspotLyt->setSpacing(0);
|
||||||
|
|
||||||
|
//列表
|
||||||
|
m_listFrame = new ItemFrame(m_pluginWidget);
|
||||||
|
|
||||||
|
ui->verticalLayout_4->addWidget(m_topFrame);
|
||||||
|
ui->verticalLayout_3->addWidget(m_listFrame);
|
||||||
|
|
||||||
|
connect(m_listFrame->m_addVpnWidget, &AddNetBtn::clicked, this, [=]() {
|
||||||
|
runExternalApp();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA)) {
|
||||||
|
m_switchGsettings = new QGSettings(GSETTINGS_SCHEMA);
|
||||||
|
setShowSwitchStatus();
|
||||||
|
|
||||||
|
connect(m_switchGsettings, &QGSettings::changed, this, [=] (const QString &key) {
|
||||||
|
if (key == VISIBLE) {
|
||||||
|
setShowSwitchStatus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
m_showBtn->setChecked(false);
|
||||||
|
m_showBtn->setCheckable(false);
|
||||||
|
qDebug()<<"[Vpn] org.ukui.kylin-nm.visible is not installed!";
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(m_showBtn, &KSwitchButton::stateChanged, this, [=](bool state){
|
||||||
|
if (m_switchGsettings != nullptr) {
|
||||||
|
m_switchGsettings->set(VISIBLE, state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// connect(m_timeBtn, &KSwitchButton::stateChanged, this, [=](bool state){
|
||||||
|
// if (m_switchGsettings != nullptr) {
|
||||||
|
// m_switchGsettings->set(VISIBLE, state);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
ui->pushButton->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vpn::initConnect()
|
||||||
|
{
|
||||||
|
connect(m_interface, SIGNAL(vpnAdd(QStringList)), this, SLOT(onVpnAdd(QStringList)));
|
||||||
|
connect(m_interface, SIGNAL(vpnRemove(QString)), this, SLOT(onVpnRemove(QString)));
|
||||||
|
connect(m_interface, SIGNAL(vpnUpdate(QStringList)), this, SLOT(onVpnUpdate(QStringList)));
|
||||||
|
connect(m_interface, SIGNAL(vpnActiveConnectionStateChanged(QString, int)),
|
||||||
|
this, SLOT(onVpnActiveConnectionStateChanged(QString, int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//初始化列表
|
||||||
|
void Vpn::initNet()
|
||||||
|
{
|
||||||
|
qDebug() << "[Vpn]initNet";
|
||||||
|
if (!m_interface->isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QDBusMessage result = m_interface->call(QStringLiteral("getVirtualList"));
|
||||||
|
if(result.type() == QDBusMessage::ErrorMessage)
|
||||||
|
{
|
||||||
|
qWarning() << "getVirtualList error:" << result.errorMessage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto dbusArg = result.arguments().at(0).value<QDBusArgument>();
|
||||||
|
QVector<QStringList> variantList;
|
||||||
|
dbusArg >> variantList;
|
||||||
|
if (variantList.size() == 0) {
|
||||||
|
qDebug() << "[Vpn]initNet list empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < variantList.size(); ++i) {
|
||||||
|
QStringList vpnInfo = variantList.at(i);
|
||||||
|
addOneVirtualItem(vpnInfo);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vpn::setShowSwitchStatus()
|
||||||
|
{
|
||||||
|
if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA)) {
|
||||||
|
bool status = m_switchGsettings->get(VISIBLE).toBool();
|
||||||
|
m_showBtn->setChecked(status);
|
||||||
|
} else {
|
||||||
|
qDebug()<<"[Vpn] org.ukui.kylin-nm.switch is not installed!";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vpn::runExternalApp(){
|
||||||
|
// QString cmd = "nm-connection-editor";
|
||||||
|
// QProcess process(this);
|
||||||
|
// process.startDetached(cmd);
|
||||||
|
|
||||||
|
if (m_interface->isValid()) {
|
||||||
|
m_interface->call(QStringLiteral("showVpnAddWidget"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QFrame* Vpn::myLine()
|
||||||
|
{
|
||||||
|
QFrame *line = new QFrame(m_pluginWidget);
|
||||||
|
line->setMinimumSize(QSize(LINE_MIN_SIZE));
|
||||||
|
line->setMaximumSize(QSize(LINE_MAX_SIZE));
|
||||||
|
line->setLineWidth(0);
|
||||||
|
line->setFrameShape(QFrame::HLine);
|
||||||
|
line->setFrameShadow(QFrame::Sunken);
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
//刪除
|
||||||
|
void Vpn::deleteVpn(QString uuid)
|
||||||
|
{
|
||||||
|
m_interface->call(QStringLiteral("deleteVpn"), uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
//激活
|
||||||
|
void Vpn::activeConnect(QString uuid) {
|
||||||
|
m_interface->call(QStringLiteral("activateVpn"), uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
//详情页
|
||||||
|
void Vpn::showDetailPage(QString uuid) {
|
||||||
|
m_interface->call(QStringLiteral("showDetailPage"), uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
//断开
|
||||||
|
void Vpn::deActiveConnect(QString uuid) {
|
||||||
|
m_interface->call(QStringLiteral("deactivateVpn"), uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//增加一项
|
||||||
|
void Vpn::addOneVirtualItem(QStringList infoList)
|
||||||
|
{
|
||||||
|
if (infoList.size() < 4) {
|
||||||
|
qDebug() << "[Vpn]QStringList size less";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_listFrame->m_itemMap.contains(infoList.at(1))) {
|
||||||
|
qDebug() << "[Vpn]Already exist a virtual " << infoList.at(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "[Vpn]addOneVitualItem" << infoList.at(0) << infoList.at(3) ;
|
||||||
|
QString connName = infoList.at(0);
|
||||||
|
QString connUuid = infoList.at(1);
|
||||||
|
QString connDbusPath = infoList.at(2);
|
||||||
|
int status = infoList.at(3).toInt(); //1-连接中 2-已连接 3-断开中 4-已断开
|
||||||
|
VpnItem * item = new VpnItem(m_pluginWidget);
|
||||||
|
|
||||||
|
QIcon searchIcon = QIcon::fromTheme(KVpnSymbolic);
|
||||||
|
item->m_iconLabel->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(ICON_SIZE))));
|
||||||
|
item->m_titileLabel->setText(connName);
|
||||||
|
|
||||||
|
item->m_uuid = connUuid;
|
||||||
|
item->m_dbusPath = connDbusPath;
|
||||||
|
|
||||||
|
if (status == 1 || status == 3) {
|
||||||
|
item->startLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(item->m_infoLabel, &GrayInfoButton::clicked, this, [=]{
|
||||||
|
showDetailPage(item->m_uuid);
|
||||||
|
});
|
||||||
|
|
||||||
|
item->m_isAcitve = (status == 2);
|
||||||
|
item->setConnectActionText(item->m_isAcitve);
|
||||||
|
|
||||||
|
if (item->m_isAcitve) {
|
||||||
|
item->m_statusLabel->setText(tr("connected"));
|
||||||
|
} else {
|
||||||
|
item->m_statusLabel->setText(tr("not connected"));
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(item, &QPushButton::clicked, this, [=] {
|
||||||
|
if (item->m_isAcitve || item->m_loading) {
|
||||||
|
deActiveConnect(item->m_uuid);
|
||||||
|
} else {
|
||||||
|
activeConnect(item->m_uuid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(item, &VpnItem::connectActionTriggered, this, [=] {
|
||||||
|
activeConnect(item->m_uuid);
|
||||||
|
});
|
||||||
|
connect(item, &VpnItem::disconnectActionTriggered, this, [=] {
|
||||||
|
deActiveConnect(item->m_uuid);
|
||||||
|
});
|
||||||
|
connect(item, &VpnItem::deleteActionTriggered, this, [=] {
|
||||||
|
deleteVpn(item->m_uuid);
|
||||||
|
});
|
||||||
|
|
||||||
|
//记录到deviceFrame的m_itemMap中
|
||||||
|
m_listFrame->m_itemMap.insert(connUuid, item);
|
||||||
|
int index = getInsertPos(connName);
|
||||||
|
qDebug()<<"[Vpn]addOneVirtualItem " << connName << " at pos:" << index;
|
||||||
|
m_listFrame->m_vpnVLayout->insertWidget(index, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vpn::removeOneVirtualItem(QString dbusPath)
|
||||||
|
{
|
||||||
|
qDebug()<<"[Vpn]vpn remove dbus path:" << dbusPath;
|
||||||
|
|
||||||
|
QMap<QString, VpnItem *>::iterator itemIter;
|
||||||
|
for (itemIter = m_listFrame->m_itemMap.begin(); itemIter != m_listFrame->m_itemMap.end(); itemIter++) {
|
||||||
|
if (itemIter.value()->m_dbusPath == dbusPath) {
|
||||||
|
qDebug()<<"[Vpn]vpn remove " << dbusPath << " find in " << itemIter.value()->m_titileLabel->text();
|
||||||
|
QString key = itemIter.key();
|
||||||
|
m_listFrame->m_vpnVLayout->removeWidget(itemIter.value());
|
||||||
|
delete itemIter.value();
|
||||||
|
m_listFrame->m_itemMap.remove(key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//增加
|
||||||
|
void Vpn::onVpnAdd(QStringList infoList)
|
||||||
|
{
|
||||||
|
addOneVirtualItem(infoList);
|
||||||
|
}
|
||||||
|
|
||||||
|
//移出
|
||||||
|
void Vpn::onVpnRemove(QString path)
|
||||||
|
{
|
||||||
|
removeOneVirtualItem(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
//名称变化
|
||||||
|
void Vpn::onVpnUpdate(QStringList info)
|
||||||
|
{
|
||||||
|
if (m_listFrame->m_itemMap.contains(info.at(1))) {
|
||||||
|
qDebug() << "[Vpn]" << m_listFrame->m_itemMap[info.at(1)]->m_titileLabel->text() << "change to" << info.at(0);
|
||||||
|
if (m_listFrame->m_itemMap[info.at(1)]->m_titileLabel->text() != info.at(0)) {
|
||||||
|
m_listFrame->m_itemMap[info.at(1)]->m_titileLabel->setText(info.at(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vpn::onVpnActiveConnectionStateChanged(QString uuid, int status)
|
||||||
|
{
|
||||||
|
if (uuid.isEmpty()) {
|
||||||
|
qDebug() << "[Vpn]onActiveConnectionChanged but uuid is empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qDebug() << "[Vpn]onActiveConnectionChanged " << uuid << status;
|
||||||
|
VpnItem * item= nullptr;
|
||||||
|
|
||||||
|
if (m_listFrame->m_itemMap.contains(uuid)) {
|
||||||
|
item = m_listFrame->m_itemMap[uuid];
|
||||||
|
if (status == ACTIVATED) {
|
||||||
|
//为已连接则放到第一个
|
||||||
|
m_listFrame->m_vpnVLayout->removeWidget(item);
|
||||||
|
m_listFrame->m_vpnVLayout->insertWidget(0,item);
|
||||||
|
} else if (status == DEACTIVATED) {
|
||||||
|
//为断开则重新插入
|
||||||
|
int index = getInsertPos(item->m_titileLabel->text());
|
||||||
|
qDebug() << "[Vpn]reinsert" << item->m_titileLabel->text() << "pos" << index << "because status changes to deactive";
|
||||||
|
m_listFrame->m_vpnVLayout->removeWidget(item);
|
||||||
|
m_listFrame->m_vpnVLayout->insertWidget(index,item);
|
||||||
|
}
|
||||||
|
itemActiveConnectionStatusChanged(item, status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vpn::itemActiveConnectionStatusChanged(VpnItem *item, int status)
|
||||||
|
{
|
||||||
|
// QString iconPath = NoNetSymbolic;
|
||||||
|
if (status == ACTIVATING) {
|
||||||
|
item->startLoading();
|
||||||
|
} else if (status == ACTIVATED) {
|
||||||
|
item->stopLoading();
|
||||||
|
// iconPath = KLanSymbolic;
|
||||||
|
item->m_statusLabel->clear();
|
||||||
|
item->m_statusLabel->setMinimumSize(36,36);
|
||||||
|
item->m_statusLabel->setMaximumSize(16777215,16777215);
|
||||||
|
item->m_statusLabel->setText(tr("connected"));
|
||||||
|
item->m_isAcitve = true;
|
||||||
|
} else if (status == DEACTIVATING) {
|
||||||
|
item->startLoading();
|
||||||
|
} else {
|
||||||
|
item->stopLoading();
|
||||||
|
item->m_statusLabel->setMinimumSize(36,36);
|
||||||
|
item->m_statusLabel->setMaximumSize(16777215,16777215);
|
||||||
|
item->m_statusLabel->clear();
|
||||||
|
item->m_isAcitve = false;
|
||||||
|
item->m_statusLabel->setText(tr("not connected"));
|
||||||
|
}
|
||||||
|
item->setConnectActionText(item->m_isAcitve);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Vpn::getInsertPos(QString connName)
|
||||||
|
{
|
||||||
|
qDebug() << "[Vpn]getInsertPos" << connName;
|
||||||
|
int index = 0;
|
||||||
|
if(!m_interface->isValid()) {
|
||||||
|
index = 0;
|
||||||
|
} else {
|
||||||
|
QDBusMessage result = m_interface->call(QStringLiteral("getVirtualList"));
|
||||||
|
if(result.type() == QDBusMessage::ErrorMessage)
|
||||||
|
{
|
||||||
|
qWarning() << "getVirtualList error:" << result.errorMessage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto dbusArg = result.arguments().at(0).value<QDBusArgument>();
|
||||||
|
QVector<QStringList> variantList;
|
||||||
|
dbusArg >> variantList;
|
||||||
|
for (int i = 0; i < variantList.size(); ++i ) {
|
||||||
|
if (variantList.at(i).at(0) == connName) {
|
||||||
|
qDebug() << "pos in kylin-nm is " << i;
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (variantList.at(0).size() == 1) {
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef VPN_H
|
||||||
|
#define VPN_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QtPlugin>
|
||||||
|
#include <QtDBus/QDBusInterface>
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
#include "interface.h"
|
||||||
|
#include "addbtn.h"
|
||||||
|
#include "imageutil.h"
|
||||||
|
#include "kwidget.h"
|
||||||
|
#include "kswitchbutton.h"
|
||||||
|
#include "itemframe.h"
|
||||||
|
|
||||||
|
using namespace kdk;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class Vpn;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Vpn : public QObject, CommonInterface
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID "org.ukcc.CommonInterface")
|
||||||
|
Q_INTERFACES(CommonInterface)
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vpn();
|
||||||
|
~Vpn();
|
||||||
|
|
||||||
|
QString plugini18nName() Q_DECL_OVERRIDE;
|
||||||
|
int pluginTypes() Q_DECL_OVERRIDE;
|
||||||
|
QWidget * pluginUi() Q_DECL_OVERRIDE;
|
||||||
|
const QString name() const Q_DECL_OVERRIDE;
|
||||||
|
bool isShowOnHomePage() const Q_DECL_OVERRIDE;
|
||||||
|
QIcon icon() const Q_DECL_OVERRIDE;
|
||||||
|
bool isEnable() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void initComponent();
|
||||||
|
void initConnect();
|
||||||
|
|
||||||
|
void runExternalApp();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// bool eventFilter(QObject *watched, QEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::Vpn *ui;
|
||||||
|
|
||||||
|
QString m_pluginName;
|
||||||
|
int m_pluginType;
|
||||||
|
QWidget * m_pluginWidget;
|
||||||
|
|
||||||
|
QDBusInterface *m_interface = nullptr;
|
||||||
|
|
||||||
|
QFrame *m_topFrame;
|
||||||
|
QFrame *m_showFrame;
|
||||||
|
QLabel *m_showLabel;
|
||||||
|
KSwitchButton *m_showBtn;
|
||||||
|
QFrame *m_Line;
|
||||||
|
QFrame *m_timeFrame;
|
||||||
|
QLabel *m_timeLabel;
|
||||||
|
KSwitchButton *m_timeBtn;
|
||||||
|
ItemFrame *m_listFrame;
|
||||||
|
|
||||||
|
bool m_firstLoad;
|
||||||
|
QGSettings *m_switchGsettings;
|
||||||
|
|
||||||
|
QFrame* myLine();
|
||||||
|
|
||||||
|
int getInsertPos(QString connName);
|
||||||
|
|
||||||
|
void deleteVpn(QString uuid);
|
||||||
|
void activeConnect(QString uuid);
|
||||||
|
void deActiveConnect(QString uuid);
|
||||||
|
void showDetailPage(QString uuid);
|
||||||
|
|
||||||
|
//获取设备列表
|
||||||
|
void initNet();
|
||||||
|
//增加一项
|
||||||
|
void addOneVirtualItem(QStringList infoList);
|
||||||
|
//减少一项
|
||||||
|
void removeOneVirtualItem(QString uuid);
|
||||||
|
//单个lan连接状态变化
|
||||||
|
void itemActiveConnectionStatusChanged(VpnItem *item, int status);
|
||||||
|
|
||||||
|
|
||||||
|
void setShowSwitchStatus();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onVpnAdd(QStringList);
|
||||||
|
void onVpnRemove(QString);
|
||||||
|
void onVpnUpdate(QStringList);
|
||||||
|
void onVpnActiveConnectionStateChanged(QString, int);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VPN_H
|
|
@ -0,0 +1,50 @@
|
||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2019-06-29T13:53:10
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += widgets dbus
|
||||||
|
|
||||||
|
TEMPLATE = lib
|
||||||
|
CONFIG += plugin \
|
||||||
|
c++11 \
|
||||||
|
link_pkgconfig
|
||||||
|
|
||||||
|
include(../component/addbtn.pri)
|
||||||
|
|
||||||
|
PKGCONFIG += gsettings-qt \
|
||||||
|
kysdk-qtwidgets \
|
||||||
|
|
||||||
|
TARGET = $$qtLibraryTarget(vpn)
|
||||||
|
DESTDIR = ../..
|
||||||
|
target.path = $$[QT_INSTALL_LIBS]/ukui-control-center
|
||||||
|
trans.files = translations/*
|
||||||
|
trans.path = /usr/share/kylin-nm/vpn/
|
||||||
|
|
||||||
|
INCLUDEPATH += \
|
||||||
|
$$PROJECT_COMPONENTSOURCE \
|
||||||
|
$$PROJECT_ROOTDIR \
|
||||||
|
/usr/include/ukcc/interface \
|
||||||
|
/usr/include/ukcc/widgets
|
||||||
|
|
||||||
|
LIBS += -L$$[QT_INSTALL_LIBS] -lukcc
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
vpn.cpp \
|
||||||
|
itemframe.cpp \
|
||||||
|
vpnitem.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
vpn.h \
|
||||||
|
itemframe.h \
|
||||||
|
vpnitem.h
|
||||||
|
|
||||||
|
FORMS += \
|
||||||
|
vpn.ui
|
||||||
|
|
||||||
|
INSTALLS += target \
|
||||||
|
trans
|
||||||
|
|
||||||
|
TRANSLATIONS += \
|
||||||
|
translations/zh_CN.ts
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Vpn</class>
|
||||||
|
<widget class="QWidget" name="Vpn">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>710</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">Vpn</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>8</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="TitleLabel" name="titleLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>VPN</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>import</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>TitleLabel</class>
|
||||||
|
<extends>QLabel</extends>
|
||||||
|
<header location="global">titlelabel.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -0,0 +1,187 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "vpnitem.h"
|
||||||
|
#include <QPainter>
|
||||||
|
#define FRAME_SPEED 150
|
||||||
|
#define LIMIT_TIME 60*1000
|
||||||
|
#define TOTAL_PAGE 8
|
||||||
|
#define RADIUS 6.0
|
||||||
|
|
||||||
|
#define THEME_QT_SCHEMA "org.ukui.style"
|
||||||
|
#define MODE_QT_KEY "style-name"
|
||||||
|
|
||||||
|
VpnItem::VpnItem(bool bAcitve, QWidget *parent)
|
||||||
|
: m_isAcitve(bAcitve), QPushButton(parent)
|
||||||
|
{
|
||||||
|
this->setMinimumSize(550, 58);
|
||||||
|
this->setProperty("useButtonPalette", true);
|
||||||
|
this->setFlat(true);
|
||||||
|
QPalette pal = this->palette();
|
||||||
|
QColor color = pal.color(QPalette::Button);
|
||||||
|
color.setAlphaF(0.5);
|
||||||
|
pal.setColor(QPalette::Button, color);
|
||||||
|
this->setPalette(pal);
|
||||||
|
QHBoxLayout *mLanLyt = new QHBoxLayout(this);
|
||||||
|
mLanLyt->setContentsMargins(16,0,16,0);
|
||||||
|
mLanLyt->setSpacing(16);
|
||||||
|
m_iconLabel = new QLabel(this);
|
||||||
|
m_iconLabel->setProperty("useIconHighlightEffect", 0x2);
|
||||||
|
m_titileLabel = new FixLabel(this);
|
||||||
|
m_statusLabel = new QLabel(this);
|
||||||
|
m_statusLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||||
|
m_infoLabel = new GrayInfoButton(this);
|
||||||
|
|
||||||
|
m_moreButton = new QToolButton(this);
|
||||||
|
m_moreButton->setProperty("useButtonPalette", true);
|
||||||
|
m_moreButton->setPopupMode(QToolButton::InstantPopup);
|
||||||
|
m_moreButton->setAutoRaise(true);
|
||||||
|
m_moreButton->setIcon(QIcon::fromTheme("view-more-horizontal-symbolic"));
|
||||||
|
m_moreMenu = new QMenu(m_moreButton);
|
||||||
|
m_connectAction = new QAction(m_moreMenu);
|
||||||
|
m_deleteAction = new QAction(tr("Delete"), m_moreMenu);
|
||||||
|
setConnectActionText(m_isAcitve);
|
||||||
|
|
||||||
|
m_moreMenu->addAction(m_connectAction);
|
||||||
|
m_moreMenu->addAction(m_deleteAction);
|
||||||
|
m_moreButton->setMenu(m_moreMenu);
|
||||||
|
|
||||||
|
mLanLyt->addWidget(m_iconLabel);
|
||||||
|
mLanLyt->addWidget(m_titileLabel,Qt::AlignLeft);
|
||||||
|
mLanLyt->addStretch();
|
||||||
|
mLanLyt->addWidget(m_statusLabel);
|
||||||
|
mLanLyt->addWidget(m_infoLabel);
|
||||||
|
mLanLyt->addWidget(m_moreButton);
|
||||||
|
|
||||||
|
m_loadIcons.append(QIcon::fromTheme("ukui-loading-1-symbolic"));
|
||||||
|
m_loadIcons.append(QIcon::fromTheme("ukui-loading-2-symbolic"));
|
||||||
|
m_loadIcons.append(QIcon::fromTheme("ukui-loading-3-symbolic"));
|
||||||
|
m_loadIcons.append(QIcon::fromTheme("ukui-loading-4-symbolic"));
|
||||||
|
m_loadIcons.append(QIcon::fromTheme("ukui-loading-5-symbolic"));
|
||||||
|
m_loadIcons.append(QIcon::fromTheme("ukui-loading-6-symbolic"));
|
||||||
|
m_loadIcons.append(QIcon::fromTheme("ukui-loading-7-symbolic"));
|
||||||
|
|
||||||
|
m_waitTimer = new QTimer(this);
|
||||||
|
connect(m_waitTimer, &QTimer::timeout, this, &VpnItem::updateIcon);
|
||||||
|
|
||||||
|
connect(m_connectAction, &QAction::triggered, this, &VpnItem::onConnectTriggered);
|
||||||
|
connect(m_deleteAction, &QAction::triggered, this, &VpnItem::onDeletetTriggered);
|
||||||
|
m_moreMenu->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnItem::updateIcon()
|
||||||
|
{
|
||||||
|
if (m_currentIconIndex > 6) {
|
||||||
|
m_currentIconIndex = 0;
|
||||||
|
}
|
||||||
|
m_statusLabel->setPixmap(m_loadIcons.at(m_currentIconIndex).pixmap(16,16));
|
||||||
|
m_currentIconIndex ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnItem::startLoading()
|
||||||
|
{
|
||||||
|
m_waitTimer->start(FRAME_SPEED);
|
||||||
|
m_loading = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnItem::stopLoading(){
|
||||||
|
m_waitTimer->stop();
|
||||||
|
m_loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnItem::setConnectActionText(bool isAcitve)
|
||||||
|
{
|
||||||
|
if (isAcitve) {
|
||||||
|
m_connectAction->setText(tr("Disconnect"));
|
||||||
|
} else {
|
||||||
|
m_connectAction->setText(tr("Connect"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnItem::onConnectTriggered()
|
||||||
|
{
|
||||||
|
if (!m_connectAction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_connectAction->text() == tr("Connect")) {
|
||||||
|
Q_EMIT connectActionTriggered();
|
||||||
|
} else if (m_connectAction->text() == tr("Disconnect")) {
|
||||||
|
Q_EMIT disconnectActionTriggered();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnItem::onDeletetTriggered()
|
||||||
|
{
|
||||||
|
if (!m_deleteAction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Q_EMIT deleteActionTriggered();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnItem::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
QPalette pal = this->palette();
|
||||||
|
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.setBrush(pal.color(QPalette::Base));
|
||||||
|
|
||||||
|
QRect rect = this->rect();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (!m_useHalfFillet) {
|
||||||
|
painter.drawRect(rect);
|
||||||
|
} else {
|
||||||
|
QPainterPath path;
|
||||||
|
// path.addRoundedRect (rect, RADIUS, RADIUS);
|
||||||
|
// QRect temp_rect(rect.left(), rect.top(), rect.width(), rect.height()/2);
|
||||||
|
// path.addRect(temp_rect);
|
||||||
|
//设置起点
|
||||||
|
path.moveTo(rect.topLeft().x(), rect.topLeft().y());
|
||||||
|
path.lineTo(rect.bottomLeft().x(), rect.bottomLeft().y() - RADIUS);
|
||||||
|
//绘制圆角 圆弧以外切圆的270度位置为起点,逆时针画圆弧运行90度结束
|
||||||
|
path.arcTo(QRect(QPoint(rect.bottomLeft().x(), rect.bottomLeft().y() - (RADIUS * 2)), QSize(RADIUS * 2, RADIUS * 2)), 180, 90);
|
||||||
|
path.lineTo(rect.bottomRight().x() - RADIUS, rect.bottomRight().y());
|
||||||
|
//画圆弧
|
||||||
|
path.arcTo(QRect(QPoint(rect.bottomRight().x() - (RADIUS * 2), rect.bottomRight().y() - (RADIUS * 2)), QSize(RADIUS * 2, RADIUS * 2)), 270, 90);
|
||||||
|
path.lineTo(rect.topRight());
|
||||||
|
path.lineTo(rect.topLeft());
|
||||||
|
painter.drawPath(path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
painter.drawRect(rect);
|
||||||
|
QPushButton::paintEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VpnItem::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
//菜单右边界与按钮右边界对齐
|
||||||
|
if (event->type() == QEvent::Show && watched == m_moreMenu) {
|
||||||
|
int menuXPos = m_moreMenu->pos().x();
|
||||||
|
int menuWidth = m_moreMenu->size().width();
|
||||||
|
int btnWidth = m_moreButton->size().width();
|
||||||
|
|
||||||
|
QPoint pos = QPoint (menuXPos - menuWidth + btnWidth, m_moreMenu->pos().y());
|
||||||
|
m_moreMenu->move(pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef VPNITEM_H
|
||||||
|
#define VPNITEM_H
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVariantMap>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QGSettings>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QEvent>
|
||||||
|
#include "fixlabel.h"
|
||||||
|
#include "../component/AddBtn/grayinfobutton.h"
|
||||||
|
|
||||||
|
class VpnItem : public QPushButton
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
VpnItem(bool bAcitve, QWidget *parent = nullptr);
|
||||||
|
public:
|
||||||
|
QLabel * m_iconLabel = nullptr;
|
||||||
|
GrayInfoButton * m_infoLabel = nullptr;
|
||||||
|
FixLabel * m_titileLabel = nullptr;
|
||||||
|
QLabel * m_statusLabel = nullptr;
|
||||||
|
QToolButton* m_moreButton = nullptr;
|
||||||
|
QMenu* m_moreMenu = nullptr;
|
||||||
|
QAction* m_connectAction = nullptr;
|
||||||
|
QAction* m_deleteAction = nullptr;
|
||||||
|
|
||||||
|
QString m_uuid = "";
|
||||||
|
QString m_dbusPath = "";
|
||||||
|
|
||||||
|
void setHalfFillet(bool flag) {m_useHalfFillet = flag; repaint();}
|
||||||
|
public:
|
||||||
|
void startLoading();
|
||||||
|
void stopLoading();
|
||||||
|
void setConnectActionText(bool isAcitve);
|
||||||
|
|
||||||
|
bool m_isAcitve = false;
|
||||||
|
bool m_loading = false;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event);
|
||||||
|
bool eventFilter(QObject *watched, QEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTimer *m_waitTimer = nullptr;
|
||||||
|
bool m_useHalfFillet = false;
|
||||||
|
QList<QIcon> m_loadIcons;
|
||||||
|
int m_currentIconIndex=0;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void updateIcon();
|
||||||
|
void onConnectTriggered();
|
||||||
|
void onDeletetTriggered();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void connectActionTriggered();
|
||||||
|
void disconnectActionTriggered();
|
||||||
|
void deleteActionTriggered();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VPNITEM_H
|
|
@ -0,0 +1,10 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
include(../../src/backend/dbus-interface/dbus-interface.pri)
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/vpndbusadaptor.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/vpndbusadaptor.cpp
|
||||||
|
|
||||||
|
DISTFILES +=
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* This file was generated by qdbusxml2cpp version 0.8
|
||||||
|
* Command line was: qdbusxml2cpp com.kylin.weather.xml -a VpnDbusAdaptor -c VpnDbusAdaptor -l MainWindow
|
||||||
|
*
|
||||||
|
* qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
*
|
||||||
|
* This is an auto-generated file.
|
||||||
|
* Do not edit! All changes made to it will be lost.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vpndbusadaptor.h"
|
||||||
|
#include <QtCore/QMetaObject>
|
||||||
|
#include <QtCore/QByteArray>
|
||||||
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of adaptor class VpnDbusAdaptor
|
||||||
|
*/
|
||||||
|
|
||||||
|
VpnDbusAdaptor::VpnDbusAdaptor(vpnObject *parent)
|
||||||
|
: QDBusAbstractAdaptor(parent)
|
||||||
|
{
|
||||||
|
qDBusRegisterMetaType<QMap<QString, bool> >();
|
||||||
|
qDBusRegisterMetaType<QMap<QString, int> >();
|
||||||
|
qDBusRegisterMetaType<QVector<QStringList> >();
|
||||||
|
setAutoRelaySignals(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//虚拟连接列表
|
||||||
|
QVector<QStringList> VpnDbusAdaptor::getVirtualList()
|
||||||
|
{
|
||||||
|
QVector<QStringList> vector;
|
||||||
|
parent()->getVirtualList(vector);
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除
|
||||||
|
void VpnDbusAdaptor::deleteVpn(QString uuid)
|
||||||
|
{
|
||||||
|
qDebug() << "delete vpn" << uuid;
|
||||||
|
parent()->deleteVpn(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
//连接 根据网卡类型 参数1 0:lan 1:wlan 参数3 为ssid/uuid
|
||||||
|
void VpnDbusAdaptor::activateVpn(const QString& connUuid)
|
||||||
|
{
|
||||||
|
qDebug() << "activate vpn" << connUuid;
|
||||||
|
parent()->activateVpn(connUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
//断开连接 根据网卡类型 参数1 0:lan 1:wlan 参数3 为ssid/uuid
|
||||||
|
void VpnDbusAdaptor::deactivateVpn(const QString& connUuid)
|
||||||
|
{
|
||||||
|
qDebug() << "deactivate vpn" << connUuid;
|
||||||
|
parent()->deactivateVpn(connUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnDbusAdaptor::showKylinVpn()
|
||||||
|
{
|
||||||
|
parent()->onShowMainWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnDbusAdaptor::showVpnAddWidget()
|
||||||
|
{
|
||||||
|
qDebug() << "showVpnAddWidget";
|
||||||
|
parent()->showVpnAddWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnDbusAdaptor::showDetailPage(const QString& connUuid)
|
||||||
|
{
|
||||||
|
qDebug() << "showDetailPage vpn" << connUuid;
|
||||||
|
parent()->showDetailPage(connUuid);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* This file was generated by qdbusxml2cpp version 0.8
|
||||||
|
* Command line was: qdbusxml2cpp com.kylin.weather.xml -a dbusadaptor -c DbusAdaptor -l MainWindow
|
||||||
|
*
|
||||||
|
* qdbusxml2cpp is Copyright (C) 2015 The Qt Company Ltd.
|
||||||
|
*
|
||||||
|
* This is an auto-generated file.
|
||||||
|
* This file may have been hand-edited. Look for HAND-EDIT comments
|
||||||
|
* before re-generating it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VPNDBUSADAPTOR_H
|
||||||
|
#define VPNDBUSADAPTOR_H
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtDBus/QtDBus>
|
||||||
|
#include <QtDBus/QDBusMetaType>
|
||||||
|
|
||||||
|
#include "singlepage.h"
|
||||||
|
#include "kylinnetworkdeviceresource.h"
|
||||||
|
#include "kyvpnconnectoperation.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QByteArray;
|
||||||
|
template<class Key, class Value> class QMap;
|
||||||
|
class QString;
|
||||||
|
class QStringList;
|
||||||
|
class QVariant;
|
||||||
|
template<class T> class QVector;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#include "vpnobject.h"
|
||||||
|
|
||||||
|
class VpnDbusAdaptor: public QDBusAbstractAdaptor
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_CLASSINFO("D-Bus Interface", "com.kylin.kylinvpn")
|
||||||
|
public:
|
||||||
|
VpnDbusAdaptor(vpnObject *parent);
|
||||||
|
|
||||||
|
inline vpnObject *parent() const
|
||||||
|
{ return static_cast<vpnObject *>(QObject::parent()); }
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
QVector<QStringList> getVirtualList();
|
||||||
|
Q_NOREPLY void deleteVpn(QString uuid);
|
||||||
|
Q_NOREPLY void activateVpn(const QString& connUuid);
|
||||||
|
Q_NOREPLY void deactivateVpn(const QString& connUuid);
|
||||||
|
Q_NOREPLY void showVpnAddWidget();
|
||||||
|
Q_NOREPLY void showDetailPage(const QString& connUuid);
|
||||||
|
|
||||||
|
void showKylinVpn();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void vpnAdd(QStringList info);
|
||||||
|
void vpnRemove(QString dbusPath);
|
||||||
|
void vpnUpdate(QStringList info);
|
||||||
|
void vpnActiveConnectionStateChanged(QString uuid, int status);
|
||||||
|
|
||||||
|
void activateFailed(QString errorMessage);
|
||||||
|
void deactivateFailed(QString errorMessage);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
include(../../src/frontend/tools/tools.pri)
|
||||||
|
include(list-items/list-items.pri)
|
||||||
|
include(vpndetails/vpndetails.pri)
|
||||||
|
include(single-pages/single-pages.pri)
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/vpnobject.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/vpnobject.cpp
|
|
@ -0,0 +1,10 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/listitem.h \
|
||||||
|
$$PWD/vpnlistitem.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/listitem.cpp \
|
||||||
|
$$PWD/vpnlistitem.cpp
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "listitem.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#define MAIN_LAYOUT_MARGINS 0,0,0,0
|
||||||
|
#define MAIN_LAYOUT_SPACING 0
|
||||||
|
#define ITEM_FRAME_MARGINS 12,6,16,6
|
||||||
|
|
||||||
|
#define ITEM_FRAME_SPACING 8
|
||||||
|
#define FRAME_WIDTH 404
|
||||||
|
#define INFO_ICON_WIDTH 16
|
||||||
|
#define INFO_ICON_HEIGHT 16
|
||||||
|
#define LIGHT_HOVER_COLOR QColor(240,240,240,255)
|
||||||
|
#define DARK_HOVER_COLOR QColor(15,15,15,255)
|
||||||
|
|
||||||
|
ListItem::ListItem(QWidget *parent) : QFrame(parent)
|
||||||
|
{
|
||||||
|
m_connectState = UnknownState;
|
||||||
|
|
||||||
|
initUI();
|
||||||
|
initConnection();
|
||||||
|
connect(qApp, &QApplication::paletteChanged, this, &ListItem::onPaletteChanged);
|
||||||
|
// m_itemFrame->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListItem::~ListItem()
|
||||||
|
{
|
||||||
|
if (nullptr != m_netButton) {
|
||||||
|
delete m_netButton;
|
||||||
|
m_netButton = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nullptr != m_infoButton) {
|
||||||
|
delete m_infoButton;
|
||||||
|
m_infoButton = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItem::setName(const QString &name)
|
||||||
|
{
|
||||||
|
m_nameLabel->setText(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//仅无线调用,有线自己获取
|
||||||
|
void ListItem::setActive(const bool &isActive)
|
||||||
|
{
|
||||||
|
m_netButton->setActive(isActive);
|
||||||
|
m_isActive = isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItem::setConnectState(ConnectState state)
|
||||||
|
{
|
||||||
|
m_connectState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItem::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
qDebug()<<"[ListItem]"<<"mousePressEvent";
|
||||||
|
if (event->button() == Qt::LeftButton) {
|
||||||
|
onNetButtonClicked();
|
||||||
|
} else if (event->button() == Qt::RightButton) {
|
||||||
|
onRightButtonClicked();
|
||||||
|
}
|
||||||
|
return QFrame::mousePressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItem::enterEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItem::leaveEvent(QEvent *event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItem::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItem::initUI()
|
||||||
|
{
|
||||||
|
m_menu = new QMenu(this);//右键菜单
|
||||||
|
// m_menu->setStyleSheet("QMenu::item{border:3px; border-radius:3px}");
|
||||||
|
// m_menu->setStyleSheet("QMenu{border-radius:6px; margin:6px 6px 6px 6px}");
|
||||||
|
connect(m_menu, &QMenu::triggered, this, &ListItem::onMenuTriggered);
|
||||||
|
|
||||||
|
m_mainLayout = new QVBoxLayout(this);
|
||||||
|
m_mainLayout->setContentsMargins(MAIN_LAYOUT_MARGINS);
|
||||||
|
m_mainLayout->setSpacing(MAIN_LAYOUT_SPACING);
|
||||||
|
this->setLayout(m_mainLayout);
|
||||||
|
|
||||||
|
m_itemFrame = new QFrame(this);
|
||||||
|
m_itemFrame->setFixedWidth(FRAME_WIDTH);
|
||||||
|
|
||||||
|
m_hItemLayout = new QHBoxLayout(m_itemFrame);
|
||||||
|
m_hItemLayout->setContentsMargins(ITEM_FRAME_MARGINS);
|
||||||
|
m_hItemLayout->setSpacing(ITEM_FRAME_SPACING);
|
||||||
|
m_hItemLayout->setAlignment(Qt::AlignHCenter);
|
||||||
|
|
||||||
|
m_netButton = new RadioItemButton(m_itemFrame);
|
||||||
|
m_nameLabel = new QLabel(m_itemFrame);
|
||||||
|
m_nameLabel->setMinimumWidth(262);
|
||||||
|
m_infoButton = new InfoButton(m_itemFrame);
|
||||||
|
m_infoButton->setIconSize(QSize(INFO_ICON_WIDTH,INFO_ICON_HEIGHT));
|
||||||
|
|
||||||
|
m_hItemLayout->addWidget(m_netButton);
|
||||||
|
m_hItemLayout->addWidget(m_nameLabel);
|
||||||
|
m_hItemLayout->addStretch();
|
||||||
|
m_hItemLayout->addWidget(m_infoButton);
|
||||||
|
|
||||||
|
m_mainLayout->addWidget(m_itemFrame);
|
||||||
|
|
||||||
|
// this->setAutoFillBackground(true);
|
||||||
|
// this->setBackgroundRole(QPalette::Base);
|
||||||
|
// QPalette pal = qApp->palette();
|
||||||
|
// pal.setColor(QPalette::Window, qApp->palette().base().color());
|
||||||
|
// this->setPalette(pal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ListItem::initConnection()
|
||||||
|
{
|
||||||
|
connect(this->m_netButton, &RadioItemButton::clicked, this, &ListItem::onNetButtonClicked);
|
||||||
|
// connect(this->m_infoButton, &InfoButton::clicked, this, &ListItem::onInfoButtonClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItem::onPaletteChanged()
|
||||||
|
{
|
||||||
|
// QPalette pal = qApp->palette();
|
||||||
|
// pal.setColor(QPalette::Window, qApp->palette().base().color());
|
||||||
|
// this->setPalette(pal);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LISTITEM_H
|
||||||
|
#define LISTITEM_H
|
||||||
|
#include <QFrame>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QApplication>
|
||||||
|
#include "radioitembutton.h"
|
||||||
|
#include "infobutton.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum{
|
||||||
|
UnknownState = 0, /**< The active connection is in an unknown state */
|
||||||
|
Activating, /**< The connection is activating */
|
||||||
|
Activated, /**< The connection is activated */
|
||||||
|
Deactivating, /**< The connection is being torn down and cleaned up */
|
||||||
|
Deactivated /**< The connection is no longer active */
|
||||||
|
}ConnectState;
|
||||||
|
|
||||||
|
class ListItem : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ListItem(QWidget *parent = nullptr);
|
||||||
|
~ListItem();
|
||||||
|
void setName(const QString &name);
|
||||||
|
void setActive(const bool &isActive);
|
||||||
|
void setConnectState(ConnectState state);
|
||||||
|
static void showDesktopNotify(const QString &message, QString soundName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *event);
|
||||||
|
void enterEvent(QEvent *event);
|
||||||
|
void leaveEvent(QEvent *event);
|
||||||
|
void paintEvent(QPaintEvent *event);
|
||||||
|
virtual void onRightButtonClicked() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QFrame * m_itemFrame = nullptr;
|
||||||
|
|
||||||
|
QLabel * m_nameLabel = nullptr;
|
||||||
|
RadioItemButton * m_netButton = nullptr;
|
||||||
|
InfoButton * m_infoButton = nullptr;
|
||||||
|
|
||||||
|
bool m_isActive = false;
|
||||||
|
ConnectState m_connectState;
|
||||||
|
|
||||||
|
QMenu *m_menu = nullptr;
|
||||||
|
public:
|
||||||
|
QVBoxLayout * m_mainLayout = nullptr;
|
||||||
|
QHBoxLayout * m_hItemLayout = nullptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initUI();
|
||||||
|
void initConnection();
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
virtual void onNetButtonClicked() = 0;
|
||||||
|
void onPaletteChanged();
|
||||||
|
virtual void onMenuTriggered(QAction *action)=0;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void detailShow(bool isShow);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LISTITEM_H
|
|
@ -0,0 +1,248 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "vpnlistitem.h"
|
||||||
|
#include "kylinconnectitem.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#define LOG_FLAG "[VpnListItem]"
|
||||||
|
|
||||||
|
VpnListItem::VpnListItem(const KyConnectItem *vpnConnectItem, QWidget *parent):ListItem(parent)
|
||||||
|
{
|
||||||
|
m_connectOperation = new KyVpnConnectOperation(this);
|
||||||
|
m_deviceResource = new KyNetworkDeviceResourse(this);
|
||||||
|
|
||||||
|
connectItemCopy(vpnConnectItem);
|
||||||
|
|
||||||
|
m_nameLabel->setText(m_vpnConnectItem.m_connectName);
|
||||||
|
m_netButton->setButtonIcon(QIcon::fromTheme("ukui-vpn-symbolic"));
|
||||||
|
|
||||||
|
qDebug() << "VpnListItem init:" << m_vpnConnectItem.m_connectName << m_vpnConnectItem.m_connectState << m_vpnConnectItem.m_ifaceName;
|
||||||
|
|
||||||
|
if (Deactivated == m_vpnConnectItem.m_connectState || Activated == m_vpnConnectItem.m_connectState) {
|
||||||
|
m_netButton->stopLoading();
|
||||||
|
if (m_vpnConnectItem.m_connectState == Activated) {
|
||||||
|
setIcon(true);
|
||||||
|
} else {
|
||||||
|
setIcon(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_netButton->startLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_itemFrame->installEventFilter(this);
|
||||||
|
connect(this->m_infoButton, &InfoButton::clicked, this, &VpnListItem::onInfoButtonClicked);
|
||||||
|
connect(m_menu, &QMenu::triggered, this, &VpnListItem::onMenuTriggered);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VpnListItem::VpnListItem(QWidget *parent) : ListItem(parent)
|
||||||
|
{
|
||||||
|
m_isActive = false;
|
||||||
|
m_netButton->setButtonIcon(QIcon::fromTheme("ukui-vpn-symbolic"));
|
||||||
|
setIcon(false);
|
||||||
|
const QString str=tr("Not connected");
|
||||||
|
m_nameLabel->setText(str);
|
||||||
|
this->m_infoButton->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
VpnListItem::~VpnListItem()
|
||||||
|
{
|
||||||
|
qDebug()<<"[LanPage] lan list item is deleted." << m_vpnConnectItem.m_connectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::setIcon(bool isOn)
|
||||||
|
{
|
||||||
|
if (isOn) {
|
||||||
|
m_netButton->setActive(true); //设置图标显示不同颜色
|
||||||
|
} else {
|
||||||
|
m_netButton->setActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::connectItemCopy(const KyConnectItem *vpnConnectItem)
|
||||||
|
{
|
||||||
|
if (vpnConnectItem) {
|
||||||
|
m_vpnConnectItem.m_connectName = vpnConnectItem->m_connectName;
|
||||||
|
m_vpnConnectItem.m_connectPath = vpnConnectItem->m_connectPath;
|
||||||
|
m_vpnConnectItem.m_connectState = vpnConnectItem->m_connectState;
|
||||||
|
m_vpnConnectItem.m_connectUuid = vpnConnectItem->m_connectUuid;
|
||||||
|
m_vpnConnectItem.m_ifaceName = vpnConnectItem->m_ifaceName;
|
||||||
|
m_vpnConnectItem.m_itemType = vpnConnectItem->m_itemType;
|
||||||
|
} else {
|
||||||
|
qDebug() << LOG_FLAG <<"the connect item is nullptr";
|
||||||
|
m_vpnConnectItem.m_connectName = "";
|
||||||
|
m_vpnConnectItem.m_connectPath = "";
|
||||||
|
m_vpnConnectItem.m_connectState = NetworkManager::ActiveConnection::State::Unknown;
|
||||||
|
m_vpnConnectItem.m_connectUuid = "";
|
||||||
|
m_vpnConnectItem.m_ifaceName = "";
|
||||||
|
m_vpnConnectItem.m_itemType = NetworkManager::ConnectionSettings::ConnectionType::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::activeConnection()
|
||||||
|
{
|
||||||
|
if (m_vpnConnectItem.m_connectUuid.isEmpty()) {
|
||||||
|
qDebug() << LOG_FLAG << "connect is empty, so can not connect or disconnect.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Deactivated == m_vpnConnectItem.m_connectState) {
|
||||||
|
//断开的连接,点击激活连接
|
||||||
|
m_connectOperation->activateVpnConnection(m_vpnConnectItem.m_connectUuid);
|
||||||
|
qDebug() << LOG_FLAG << "it will activate connection" << m_vpnConnectItem.m_connectName;
|
||||||
|
m_netButton->startLoading();
|
||||||
|
} else {
|
||||||
|
qDebug() << LOG_FLAG <<"the connection" << m_vpnConnectItem.m_connectName
|
||||||
|
<< "is not deactived, so it can not be operation.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::onNetButtonClicked()
|
||||||
|
{
|
||||||
|
if (m_vpnConnectItem.m_connectUuid.isEmpty()) {
|
||||||
|
qDebug() << LOG_FLAG << "connect is empty, so can not connect or disconnect.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Deactivated == m_vpnConnectItem.m_connectState) {
|
||||||
|
//断开的连接,点击激活连接
|
||||||
|
m_connectOperation->activateVpnConnection(m_vpnConnectItem.m_connectUuid);
|
||||||
|
qDebug() << LOG_FLAG << "it will activate connection" << m_vpnConnectItem.m_connectName;
|
||||||
|
m_netButton->startLoading();
|
||||||
|
} else {
|
||||||
|
qDebug() << LOG_FLAG <<"the connection" << m_vpnConnectItem.m_connectName
|
||||||
|
<< "is not deactived, so it can not be operation.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::onRightButtonClicked()
|
||||||
|
{
|
||||||
|
//右键点击事件
|
||||||
|
qDebug()<< LOG_FLAG <<"onRightButtonClicked";
|
||||||
|
if (!m_menu) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_menu->clear();
|
||||||
|
if (Activated == m_vpnConnectItem.m_connectState || Activating == m_vpnConnectItem.m_connectState) {
|
||||||
|
m_menu->addAction(new QAction(tr("Disconnect"), this));
|
||||||
|
} else if (Deactivated == m_vpnConnectItem.m_connectState) {
|
||||||
|
m_menu->addAction(new QAction(tr("Connect"), this));
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_menu->move(cursor().pos());
|
||||||
|
m_menu->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::onMenuTriggered(QAction *action)
|
||||||
|
{
|
||||||
|
if (action->text() == tr("Connect")) {
|
||||||
|
this->onNetButtonClicked();
|
||||||
|
} else if (action->text() == tr("Disconnect")) {
|
||||||
|
m_connectOperation->deactivateVpnConnection(m_vpnConnectItem.m_connectName, m_vpnConnectItem.m_connectUuid);
|
||||||
|
qDebug() << LOG_FLAG << "it will disconnect connection" << m_vpnConnectItem.m_connectName;
|
||||||
|
m_netButton->startLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VpnListItem::launchApp(QString desktopFile)
|
||||||
|
{
|
||||||
|
QDBusInterface appManagerDbusInterface(KYLIN_APP_MANAGER_NAME,
|
||||||
|
KYLIN_APP_MANAGER_PATH,
|
||||||
|
KYLIN_APP_MANAGER_INTERFACE,
|
||||||
|
QDBusConnection::sessionBus());
|
||||||
|
|
||||||
|
if (!appManagerDbusInterface.isValid()) {
|
||||||
|
qWarning()<<"appManagerDbusInterface init error";
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
QDBusReply<bool> reply = appManagerDbusInterface.call("LaunchApp", desktopFile);
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::runExternalApp() {
|
||||||
|
if (!launchApp("nm-connection-editor.desktop")){
|
||||||
|
QString cmd = "nm-connection-editor";
|
||||||
|
QProcess process(this);
|
||||||
|
process.startDetached(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::onInfoButtonClicked()
|
||||||
|
{
|
||||||
|
if (m_vpnConnectItem.m_itemType != NetworkManager::ConnectionSettings::ConnectionType::Vpn) {
|
||||||
|
runExternalApp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_vpnDetail != nullptr){
|
||||||
|
m_vpnDetail->activateWindow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_vpnDetail = new vpnDetail(m_vpnConnectItem.m_connectUuid, getConnectionName());
|
||||||
|
connect(m_vpnDetail, &vpnDetail::destroyed, [&](){
|
||||||
|
if (m_vpnDetail != nullptr) {
|
||||||
|
m_vpnDetail = nullptr;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_vpnDetail->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::updateConnectionState(ConnectState state)
|
||||||
|
{
|
||||||
|
m_vpnConnectItem.m_connectState = (NetworkManager::ActiveConnection::State)state;
|
||||||
|
|
||||||
|
if (Deactivated == state || Activated == state) {
|
||||||
|
m_netButton->stopLoading();
|
||||||
|
if (state == Activated) {
|
||||||
|
setIcon(true);
|
||||||
|
} else {
|
||||||
|
setIcon(false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_netButton->startLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VpnListItem::getConnectionName()
|
||||||
|
{
|
||||||
|
return m_vpnConnectItem.m_connectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::updateConnectionName(QString connectionName)
|
||||||
|
{
|
||||||
|
m_vpnConnectItem.m_connectName = connectionName;
|
||||||
|
m_nameLabel->setText(m_vpnConnectItem.m_connectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VpnListItem::getConnectionPath()
|
||||||
|
{
|
||||||
|
return m_vpnConnectItem.m_connectPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnListItem::updateConnectionPath(QString connectionPath)
|
||||||
|
{
|
||||||
|
m_vpnConnectItem.m_connectPath = connectionPath;
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef VPNLISTITEM_H
|
||||||
|
#define VPNLISTITEM_H
|
||||||
|
#include "listitem.h"
|
||||||
|
#include "kylinactiveconnectresource.h"
|
||||||
|
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
#include "vpndetails/vpndetail.h"
|
||||||
|
#include "kylinconnectresource.h"
|
||||||
|
//#include "kylinwiredconnectoperation.h"
|
||||||
|
#include "kyvpnconnectoperation.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define KYLIN_APP_MANAGER_NAME "com.kylin.AppManager"
|
||||||
|
#define KYLIN_APP_MANAGER_PATH "/com/kylin/AppManager"
|
||||||
|
#define KYLIN_APP_MANAGER_INTERFACE "com.kylin.AppManager"
|
||||||
|
|
||||||
|
class VpnListItem : public ListItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
VpnListItem(const KyConnectItem *vpnConnectItem, QWidget *parent = nullptr);
|
||||||
|
VpnListItem(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
~VpnListItem();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void updateConnectionState(ConnectState state);
|
||||||
|
|
||||||
|
QString getConnectionName();
|
||||||
|
void updateConnectionName(QString connectionName);
|
||||||
|
|
||||||
|
QString getConnectionPath();
|
||||||
|
void updateConnectionPath(QString connectionPath);
|
||||||
|
|
||||||
|
void activeConnection();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setIcon(bool isOn);
|
||||||
|
void onRightButtonClicked();
|
||||||
|
bool launchApp(QString desktopFile);
|
||||||
|
void runExternalApp();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void connectItemCopy(const KyConnectItem *vpnConnectItem);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void onInfoButtonClicked();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onNetButtonClicked();
|
||||||
|
void onMenuTriggered(QAction *action);
|
||||||
|
|
||||||
|
private:
|
||||||
|
KyConnectItem m_vpnConnectItem;
|
||||||
|
|
||||||
|
KyVpnConnectOperation *m_connectOperation = nullptr;
|
||||||
|
KyNetworkDeviceResourse *m_deviceResource = nullptr;
|
||||||
|
|
||||||
|
QString m_deviceName = "";
|
||||||
|
|
||||||
|
vpnDetail *m_vpnDetail = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VPNLISTITEM_H
|
|
@ -0,0 +1,10 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/vpnpage.h \
|
||||||
|
$$PWD/singlepage.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/vpnpage.cpp \
|
||||||
|
$$PWD/singlepage.cpp
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "singlepage.h"
|
||||||
|
#include <qsettings.h>
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDBusReply>
|
||||||
|
|
||||||
|
#include <KWindowEffects>
|
||||||
|
|
||||||
|
SinglePage::SinglePage(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
initUI();
|
||||||
|
initWindowProperties();
|
||||||
|
initTransparency();
|
||||||
|
}
|
||||||
|
|
||||||
|
SinglePage::~SinglePage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePage::initUI()
|
||||||
|
{
|
||||||
|
m_mainLayout = new QVBoxLayout(this);
|
||||||
|
m_mainLayout->setContentsMargins(MAIN_LAYOUT_MARGINS);
|
||||||
|
m_mainLayout->setSpacing(MAIN_LAYOUT_SPACING);
|
||||||
|
this->setLayout(m_mainLayout);
|
||||||
|
|
||||||
|
m_titleFrame = new QFrame(this);
|
||||||
|
m_titleFrame->setFixedHeight(TITLE_FRAME_HEIGHT);
|
||||||
|
m_titleLayout = new QHBoxLayout(m_titleFrame);
|
||||||
|
m_titleLayout->setContentsMargins(TITLE_LAYOUT_MARGINS);
|
||||||
|
m_titleFrame->setLayout(m_titleLayout);
|
||||||
|
m_titleLabel = new QLabel(m_titleFrame);
|
||||||
|
m_titleLayout->addWidget(m_titleLabel);
|
||||||
|
m_titleLayout->addStretch();
|
||||||
|
|
||||||
|
m_netDivider = new Divider(this);
|
||||||
|
|
||||||
|
m_listFrame = new QFrame(this);
|
||||||
|
m_listLayout = new QVBoxLayout(m_listFrame);
|
||||||
|
m_listLayout->setContentsMargins(NET_LAYOUT_MARGINS);
|
||||||
|
m_listFrame->setLayout(m_listLayout);
|
||||||
|
m_listWidget = new QListWidget(m_listFrame);
|
||||||
|
m_listLayout->addWidget(m_listWidget);
|
||||||
|
|
||||||
|
m_setDivider = new Divider(this);
|
||||||
|
|
||||||
|
m_settingsFrame = new QFrame(this);
|
||||||
|
m_settingsFrame->setFixedHeight(TITLE_FRAME_HEIGHT);
|
||||||
|
m_settingsLayout = new QHBoxLayout(m_settingsFrame);
|
||||||
|
m_settingsLayout->setContentsMargins(SETTINGS_LAYOUT_MARGINS);
|
||||||
|
m_settingsLabel = new KyLable(m_settingsFrame);
|
||||||
|
m_settingsLabel->setCursor(Qt::PointingHandCursor);
|
||||||
|
m_settingsLabel->setText(tr("Settings"));
|
||||||
|
m_settingsLabel->setScaledContents(true);
|
||||||
|
m_settingsLayout->addWidget(m_settingsLabel);
|
||||||
|
m_settingsLayout->addStretch();
|
||||||
|
m_settingsFrame->setLayout(m_settingsLayout);
|
||||||
|
|
||||||
|
m_mainLayout->addWidget(m_titleFrame);
|
||||||
|
m_mainLayout->addWidget(m_netDivider);
|
||||||
|
m_mainLayout->addWidget(m_listFrame);
|
||||||
|
m_mainLayout->addWidget(m_setDivider);
|
||||||
|
m_mainLayout->addWidget(m_settingsFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePage::initWindowProperties()
|
||||||
|
{
|
||||||
|
QPalette pal = m_listFrame->palette();
|
||||||
|
pal.setBrush(QPalette::Base, QColor(0,0,0,0)); //背景透明
|
||||||
|
m_listFrame->setPalette(pal);
|
||||||
|
|
||||||
|
this->setFixedWidth(MAX_WIDTH);
|
||||||
|
this->setAttribute(Qt::WA_TranslucentBackground);
|
||||||
|
this->setProperty("useStyleWindowManager", false); //禁用拖动
|
||||||
|
//绘制毛玻璃特效
|
||||||
|
QString platform = QGuiApplication::platformName();
|
||||||
|
if(!platform.startsWith(QLatin1String("wayland"),Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
QPainterPath path;
|
||||||
|
auto rect = this->rect();
|
||||||
|
path.addRoundedRect(rect, 12, 12);
|
||||||
|
path.addRect(rect);
|
||||||
|
KWindowEffects::enableBlurBehind(this->winId(), true, QRegion(path.toFillPolygon().toPolygon())); //背景模糊
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePage::showDesktopNotify(const QString &message, QString soundName)
|
||||||
|
{
|
||||||
|
QDBusInterface iface("org.freedesktop.Notifications",
|
||||||
|
"/org/freedesktop/Notifications",
|
||||||
|
"org.freedesktop.Notifications",
|
||||||
|
QDBusConnection::sessionBus());
|
||||||
|
QStringList actions; //跳转动作
|
||||||
|
actions.append("kylin-vpn");
|
||||||
|
actions.append("default"); //默认动作:点击消息体时打开麒麟录音
|
||||||
|
QMap<QString, QVariant> hints;
|
||||||
|
if (!soundName.isEmpty()) {
|
||||||
|
hints.insert("sound-name",soundName); //添加声音
|
||||||
|
}
|
||||||
|
QList<QVariant> args;
|
||||||
|
args<<(tr("Kylin VPN"))
|
||||||
|
<<((unsigned int) 0)
|
||||||
|
<<QString("gnome-dev-ethernet")
|
||||||
|
<<tr("kylin vpn applet desktop message") //显示的是什么类型的信息
|
||||||
|
<<message //显示的具体信息
|
||||||
|
<<actions
|
||||||
|
<<hints
|
||||||
|
<<(int)-1;
|
||||||
|
iface.callWithArgumentList(QDBus::AutoDetect,"Notify",args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePage::paintEvent(QPaintEvent *event) {
|
||||||
|
Q_UNUSED(event);
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.setPen(Qt::transparent);
|
||||||
|
QColor col = qApp->palette().window().color();
|
||||||
|
|
||||||
|
QPainterPath rectPath;
|
||||||
|
|
||||||
|
col.setAlphaF(m_transparency);
|
||||||
|
rectPath.addRoundedRect(this->rect(),12,12);
|
||||||
|
|
||||||
|
painter.setBrush(col);
|
||||||
|
painter.drawPath(rectPath);
|
||||||
|
KWindowEffects::enableBlurBehind(this->winId(), true, QRegion(rectPath.toFillPolygon().toPolygon())); //背景模糊
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePage::initTransparency()
|
||||||
|
{
|
||||||
|
if(QGSettings::isSchemaInstalled(QByteArray(TRANSPARENCY_GSETTINGS))) {
|
||||||
|
m_transGsettings = new QGSettings(QByteArray(TRANSPARENCY_GSETTINGS));
|
||||||
|
if(m_transGsettings->keys().contains(TRANSPARENCY)) {
|
||||||
|
m_transparency = m_transGsettings->get(TRANSPARENCY).toDouble() + 0.15;
|
||||||
|
m_transparency = (m_transparency > 1) ? 1 : m_transparency;
|
||||||
|
connect(m_transGsettings, &QGSettings::changed, this, &SinglePage::onTransChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePage::onTransChanged()
|
||||||
|
{
|
||||||
|
m_transparency = m_transGsettings->get("transparency").toDouble() + 0.15;
|
||||||
|
m_transparency = (m_transparency > 1) ? 1 : m_transparency;
|
||||||
|
paintWithTrans();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePage::paintWithTrans()
|
||||||
|
{
|
||||||
|
QPalette pal = this->palette();
|
||||||
|
QColor color = qApp->palette().base().color();
|
||||||
|
color.setAlphaF(m_transparency);
|
||||||
|
pal.setColor(QPalette::Window, color);
|
||||||
|
this->setPalette(pal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SinglePage::keyPressEvent(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if (event->key() == Qt::Key_Escape) {
|
||||||
|
this->hide();
|
||||||
|
}
|
||||||
|
return QWidget::keyPressEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef SINGLEPAGE_H
|
||||||
|
#define SINGLEPAGE_H
|
||||||
|
|
||||||
|
#include "divider.h"
|
||||||
|
#include "kylable.h"
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QEvent>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QDebug>
|
||||||
|
#include "kylinnetworkdeviceresource.h"
|
||||||
|
#include "kwidget.h"
|
||||||
|
#include "kswitchbutton.h"
|
||||||
|
|
||||||
|
using namespace kdk;
|
||||||
|
|
||||||
|
#define MAIN_LAYOUT_MARGINS 0,0,0,0
|
||||||
|
#define MAIN_LAYOUT_SPACING 0
|
||||||
|
#define TITLE_FRAME_HEIGHT 60 //TabWidget的tab和widget有间隙,和设计稿看起来一致就不能设为设计稿里的高度
|
||||||
|
#define TITLE_LAYOUT_MARGINS 24,0,24,0
|
||||||
|
#define NET_LAYOUT_MARGINS 8,8,8,8
|
||||||
|
#define TEXT_HEIGHT 20
|
||||||
|
#define SETTINGS_LAYOUT_MARGINS 23,0,24,0
|
||||||
|
|
||||||
|
#define MAX_ITEMS 4
|
||||||
|
#define MAX_WIDTH 412
|
||||||
|
#define MIN_WIDTH 404
|
||||||
|
|
||||||
|
#define SCROLL_STEP 4
|
||||||
|
|
||||||
|
#define TRANSPARENCY "transparency"
|
||||||
|
#define TRANSPARENCY_GSETTINGS "org.ukui.control-center.personalise"
|
||||||
|
|
||||||
|
class SinglePage : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SinglePage(QWidget *parent = nullptr);
|
||||||
|
~SinglePage();
|
||||||
|
|
||||||
|
static void showDesktopNotify(const QString &message, QString soundName);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void activateFailed(QString errorMessage);
|
||||||
|
void deactivateFailed(QString errorMessage);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onTransChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event);
|
||||||
|
void keyPressEvent(QKeyEvent *event);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initUI();
|
||||||
|
void initTransparency();
|
||||||
|
void paintWithTrans();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initWindowProperties();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVBoxLayout * m_mainLayout = nullptr;
|
||||||
|
|
||||||
|
QLabel * m_titleLabel = nullptr;
|
||||||
|
QFrame * m_titleFrame = nullptr;
|
||||||
|
QHBoxLayout * m_titleLayout = nullptr;
|
||||||
|
|
||||||
|
QFrame * m_listFrame = nullptr;
|
||||||
|
QListWidget * m_listWidget = nullptr;
|
||||||
|
QVBoxLayout * m_listLayout = nullptr;
|
||||||
|
|
||||||
|
QFrame * m_settingsFrame = nullptr;
|
||||||
|
QHBoxLayout * m_settingsLayout = nullptr;
|
||||||
|
KyLable * m_settingsLabel = nullptr;
|
||||||
|
|
||||||
|
Divider * m_netDivider = nullptr;
|
||||||
|
Divider * m_setDivider = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
QGSettings * m_transGsettings = nullptr;
|
||||||
|
double m_transparency = 1.0; //透明度
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TABPAGE_H
|
|
@ -0,0 +1,702 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "vpnpage.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include "windowmanager/windowmanager.h"
|
||||||
|
|
||||||
|
|
||||||
|
VpnPage::VpnPage(QWidget *parent) : SinglePage(parent)
|
||||||
|
{
|
||||||
|
m_activeResourse = new KyActiveConnectResourse(this);
|
||||||
|
m_connectResourse = new KyConnectResourse(this);
|
||||||
|
m_vpnConnectOperation = new KyVpnConnectOperation(this);
|
||||||
|
|
||||||
|
initUI();
|
||||||
|
initVpnArea();
|
||||||
|
installEventFilter(this);
|
||||||
|
|
||||||
|
connect(m_activeResourse, &KyActiveConnectResourse::stateChangeReason, this, &VpnPage::onConnectionStateChange);
|
||||||
|
connect(m_activeResourse, &KyActiveConnectResourse::activeConnectRemove, this, [=] (QString activeConnectUuid) {
|
||||||
|
sendVpnStateChangeSignal(activeConnectUuid,Deactivated);
|
||||||
|
} );
|
||||||
|
|
||||||
|
connect(m_connectResourse, &KyConnectResourse::connectionAdd, this, &VpnPage::onAddConnection);
|
||||||
|
connect(m_connectResourse, &KyConnectResourse::connectionRemove, this, &VpnPage::onRemoveConnection);
|
||||||
|
connect(m_connectResourse, &KyConnectResourse::connectionUpdate, this, &VpnPage::onUpdateConnection);
|
||||||
|
|
||||||
|
connect(m_vpnConnectOperation, &KyVpnConnectOperation::activateConnectionError, this, &VpnPage::activateFailed);
|
||||||
|
connect(m_vpnConnectOperation, &KyVpnConnectOperation::deactivateConnectionError, this, &VpnPage::deactivateFailed);
|
||||||
|
|
||||||
|
connect(KWindowSystem::self(), &KWindowSystem::activeWindowChanged, this, [&](WId activeWindowId){
|
||||||
|
if (activeWindowId != this->winId() && activeWindowId != 0) {
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
VpnPage::~VpnPage()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::deleteConnectionMapItem(QMap<QString, QListWidgetItem *> &connectMap,
|
||||||
|
QListWidget *vpnListWidget, QString uuid)
|
||||||
|
{
|
||||||
|
QListWidgetItem *p_listWidgetItem = connectMap.value(uuid);
|
||||||
|
if (p_listWidgetItem) {
|
||||||
|
connectMap.remove(uuid);
|
||||||
|
VpnListItem *p_vpnItem = (VpnListItem *)vpnListWidget->itemWidget(p_listWidgetItem);
|
||||||
|
vpnListWidget->removeItemWidget(p_listWidgetItem);
|
||||||
|
|
||||||
|
delete p_vpnItem;
|
||||||
|
p_vpnItem = nullptr;
|
||||||
|
|
||||||
|
delete p_listWidgetItem;
|
||||||
|
p_listWidgetItem = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::clearConnectionMap(QMap<QString, QListWidgetItem *> &connectMap,
|
||||||
|
QListWidget *vpnListWidget)
|
||||||
|
{
|
||||||
|
QMap<QString, QListWidgetItem *>::iterator iter;
|
||||||
|
|
||||||
|
iter = connectMap.begin();
|
||||||
|
while (iter != connectMap.end()) {
|
||||||
|
qDebug()<<"[VpnPage] clear connection map item"<< iter.key();
|
||||||
|
|
||||||
|
QListWidgetItem *p_widgetItem = iter.value();
|
||||||
|
VpnListItem *p_vpnItem = (VpnListItem *)vpnListWidget->itemWidget(p_widgetItem);
|
||||||
|
vpnListWidget->removeItemWidget(p_widgetItem);
|
||||||
|
|
||||||
|
delete p_vpnItem;
|
||||||
|
p_vpnItem = nullptr;
|
||||||
|
|
||||||
|
delete p_widgetItem;
|
||||||
|
p_widgetItem = nullptr;
|
||||||
|
|
||||||
|
iter = connectMap.erase(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::constructItemArea()
|
||||||
|
{
|
||||||
|
QList<KyConnectItem *> activedList;
|
||||||
|
QList<KyConnectItem *> netList;
|
||||||
|
|
||||||
|
activedList.clear();
|
||||||
|
netList.clear();
|
||||||
|
clearConnectionMap(m_activeItemMap, m_listWidget);
|
||||||
|
clearConnectionMap(m_vpnItemMap, m_listWidget);
|
||||||
|
|
||||||
|
m_connectResourse->getVpnAndVirtualConnections(netList);
|
||||||
|
KyConnectItem *p_newItem = nullptr;
|
||||||
|
if (!netList.isEmpty()) {
|
||||||
|
for (int index = 0; index < netList.size(); index++) {
|
||||||
|
KyConnectItem *p_netConnectionItem = netList.at(index);
|
||||||
|
p_newItem = m_activeResourse->getActiveConnectionByUuid(p_netConnectionItem->m_connectUuid);
|
||||||
|
if (p_newItem == nullptr) {
|
||||||
|
if (m_vpnItemMap.contains(p_netConnectionItem->m_connectUuid)) {
|
||||||
|
qDebug()<<LOG_FLAG << "has contain uuid" << p_netConnectionItem->m_connectUuid;
|
||||||
|
}
|
||||||
|
QListWidgetItem *p_listWidgetItem = addNewItem(p_netConnectionItem, m_listWidget);
|
||||||
|
m_vpnItemMap.insert(p_netConnectionItem->m_connectUuid, p_listWidgetItem);
|
||||||
|
} else {
|
||||||
|
if (m_activeItemMap.contains(p_netConnectionItem->m_connectUuid)) {
|
||||||
|
qDebug()<<LOG_FLAG << "has contain uuid" << p_netConnectionItem->m_connectUuid;
|
||||||
|
}
|
||||||
|
QListWidgetItem *p_listWidgetItem = addNewItem(p_newItem, m_listWidget);
|
||||||
|
m_activeItemMap.insert(p_netConnectionItem->m_connectUuid, p_listWidgetItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete p_netConnectionItem;
|
||||||
|
p_netConnectionItem = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QGSettings::isSchemaInstalled(GSETTINGS_VPNICON_VISIBLE)) {
|
||||||
|
QGSettings vpnGsettings(GSETTINGS_VPNICON_VISIBLE);
|
||||||
|
if (vpnGsettings.keys().contains(QString(VISIBLE))) {
|
||||||
|
if (!netList.isEmpty()) {
|
||||||
|
vpnGsettings.set(VISIBLE, true);
|
||||||
|
} else {
|
||||||
|
vpnGsettings.set(VISIBLE, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_listWidget->count() <= MAX_ITEMS) {
|
||||||
|
m_listFrame->setFixedWidth(MIN_WIDTH);
|
||||||
|
} else {
|
||||||
|
m_listFrame->setFixedWidth(MAX_WIDTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::initVpnArea()
|
||||||
|
{
|
||||||
|
constructItemArea();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::resetPageHeight()
|
||||||
|
{
|
||||||
|
int height = 0;
|
||||||
|
int count = m_listWidget->count();
|
||||||
|
m_listFrame->setFixedHeight((count >= 4) ? (MAX_ITEMS * ITEM_HEIGHT + ITEM_SPACE) : (count * ITEM_HEIGHT + ITEM_SPACE));
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
m_listWidget->setHidden(true);
|
||||||
|
m_listFrame->setHidden(true);
|
||||||
|
m_netDivider->setHidden(true);
|
||||||
|
} else {
|
||||||
|
m_listWidget->show();
|
||||||
|
m_listFrame->show();
|
||||||
|
m_netDivider->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < m_mainLayout->count(); i ++) {
|
||||||
|
QWidget *w = m_mainLayout->itemAt(i)->widget();
|
||||||
|
if (w != nullptr && w->isHidden() != true) {
|
||||||
|
height += w->height();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->setFixedHeight(height + PAGE_SPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VpnPage::removeConnectionItem(QMap<QString, QListWidgetItem *> &connectMap,
|
||||||
|
QListWidget *vpnListWidget, QString path)
|
||||||
|
{
|
||||||
|
QMap<QString, QListWidgetItem *>::iterator iter;
|
||||||
|
for (iter = connectMap.begin(); iter != connectMap.end(); ++iter) {
|
||||||
|
QListWidgetItem *p_listWidgetItem = iter.value();
|
||||||
|
VpnListItem *p_vpnItem = (VpnListItem*)vpnListWidget->itemWidget(p_listWidgetItem);
|
||||||
|
if (p_vpnItem->getConnectionPath() == path) {
|
||||||
|
qDebug()<<"[VpnPage] Remove a connection from list";
|
||||||
|
|
||||||
|
vpnListWidget->removeItemWidget(p_listWidgetItem);
|
||||||
|
|
||||||
|
delete p_vpnItem;
|
||||||
|
p_vpnItem = nullptr;
|
||||||
|
|
||||||
|
delete p_listWidgetItem;
|
||||||
|
p_listWidgetItem = nullptr;
|
||||||
|
|
||||||
|
iter = connectMap.erase(iter);
|
||||||
|
if (m_listWidget->count() <= MAX_ITEMS) {
|
||||||
|
m_listFrame->setFixedWidth(MIN_WIDTH);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::onRemoveConnection(QString path) //删除时后端会自动断开激活,将其从未激活列表中删除
|
||||||
|
{
|
||||||
|
//for dbus
|
||||||
|
qDebug() << "[VpnPage] emit lanRemove because onRemoveConnection " << path;
|
||||||
|
Q_EMIT vpnRemove(path);
|
||||||
|
|
||||||
|
removeConnectionItem(m_vpnItemMap, m_listWidget, path);
|
||||||
|
removeConnectionItem(m_activeItemMap, m_listWidget, path);
|
||||||
|
resetPageHeight();
|
||||||
|
resetWindowPosition();
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::onAddConnection(QString uuid) //新增一个有线连接,将其加入到激活列表
|
||||||
|
{
|
||||||
|
if (!m_connectResourse->isVirtualConncection(uuid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
KyConnectItem *p_newItem = nullptr;
|
||||||
|
p_newItem = m_connectResourse->getConnectionItemByUuid(uuid);
|
||||||
|
if (nullptr == p_newItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendVpnAddSignal(p_newItem);
|
||||||
|
|
||||||
|
qDebug()<<"[VpnPage] Add a new connection, name:"<<p_newItem->m_connectName;
|
||||||
|
QListWidgetItem *p_listWidgetItem = insertNewItem(p_newItem, m_listWidget);
|
||||||
|
if (m_vpnItemMap.contains(p_newItem->m_connectUuid)) {
|
||||||
|
qDebug()<<LOG_FLAG << "the connection is exist" << p_newItem->m_connectUuid;
|
||||||
|
}
|
||||||
|
m_vpnItemMap.insert(p_newItem->m_connectUuid, p_listWidgetItem);
|
||||||
|
|
||||||
|
delete p_newItem;
|
||||||
|
p_newItem = nullptr;
|
||||||
|
if (m_listWidget->count() >= MAX_ITEMS) {
|
||||||
|
m_listFrame->setFixedWidth(MAX_WIDTH);
|
||||||
|
}
|
||||||
|
resetPageHeight();
|
||||||
|
resetWindowPosition();
|
||||||
|
this->update();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::onShowControlCenter()
|
||||||
|
{
|
||||||
|
QProcess process;
|
||||||
|
process.startDetached("ukui-control-center -m vpn");
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::initUI()
|
||||||
|
{
|
||||||
|
m_titleLabel->setText(tr("VPN"));
|
||||||
|
|
||||||
|
// m_listFrame->setMaximumHeight(MAX_ITEMS * ITEM_HEIGHT + ITEM_SPACE);
|
||||||
|
|
||||||
|
m_listWidget->setFrameShape(QFrame::Shape::NoFrame);
|
||||||
|
m_listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
m_listWidget->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
|
||||||
|
m_listWidget->verticalScrollBar()->setProperty("drawScrollBarGroove",false); //去除滚动条的外侧黑框
|
||||||
|
m_listWidget->verticalScrollBar()->setSingleStep(SCROLL_STEP);
|
||||||
|
m_listWidget->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu);
|
||||||
|
|
||||||
|
m_settingsLabel->setText(tr("VPN Settings"));
|
||||||
|
m_settingsLabel->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QListWidgetItem *VpnPage::insertNewItem(KyConnectItem *itemData, QListWidget *listWidget)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for(index = 0; index < m_listWidget->count(); index++) {
|
||||||
|
QListWidgetItem *p_listWidgetItem = m_listWidget->item(index);
|
||||||
|
VpnListItem *p_vpnItem = (VpnListItem *)m_listWidget->itemWidget(p_listWidgetItem);
|
||||||
|
QString name1 = p_vpnItem->getConnectionName();
|
||||||
|
QString name2 = itemData->m_connectName;
|
||||||
|
if (QString::compare(name1, name2, Qt::CaseInsensitive) > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QListWidgetItem *p_sortListWidgetItem = new QListWidgetItem();
|
||||||
|
p_sortListWidgetItem->setFlags(p_sortListWidgetItem->flags() & (~Qt::ItemIsSelectable)); //设置不可被选中
|
||||||
|
p_sortListWidgetItem->setSizeHint(QSize(listWidget->width(),ITEM_HEIGHT));
|
||||||
|
|
||||||
|
listWidget->insertItem(index, p_sortListWidgetItem);
|
||||||
|
|
||||||
|
VpnListItem *p_sortLanItem = nullptr;
|
||||||
|
p_sortLanItem = new VpnListItem(itemData);
|
||||||
|
listWidget->setItemWidget(p_sortListWidgetItem, p_sortLanItem);
|
||||||
|
|
||||||
|
return p_sortListWidgetItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
QListWidgetItem *VpnPage::addNewItem(KyConnectItem *itemData, QListWidget *listWidget)
|
||||||
|
{
|
||||||
|
QListWidgetItem *p_listWidgetItem = new QListWidgetItem();
|
||||||
|
p_listWidgetItem->setFlags(p_listWidgetItem->flags() & (~Qt::ItemIsSelectable));
|
||||||
|
p_listWidgetItem->setSizeHint(QSize(listWidget->width() - 16, ITEM_HEIGHT));
|
||||||
|
listWidget->addItem(p_listWidgetItem);
|
||||||
|
VpnListItem *p_vpnItem = nullptr;
|
||||||
|
if (itemData != nullptr) {
|
||||||
|
p_vpnItem = new VpnListItem(itemData);
|
||||||
|
qDebug() << "[VpnPage] addNewItem, connection: " << itemData->m_connectName;
|
||||||
|
} else {
|
||||||
|
p_vpnItem = new VpnListItem();
|
||||||
|
qDebug() << "[VpnPage] Add nullItem!";
|
||||||
|
}
|
||||||
|
|
||||||
|
listWidget->setItemWidget(p_listWidgetItem, p_vpnItem);
|
||||||
|
return p_listWidgetItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::updateActivatedConnectionArea(KyConnectItem *p_newItem)
|
||||||
|
{
|
||||||
|
if (m_activeItemMap.contains(p_newItem->m_connectUuid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteConnectionMapItem(m_vpnItemMap, m_listWidget, p_newItem->m_connectUuid);
|
||||||
|
qDebug()<<"[VpnPage]update active connection item"<<p_newItem->m_connectName;
|
||||||
|
deleteConnectionMapItem(m_activeItemMap, m_listWidget, p_newItem->m_connectUuid);
|
||||||
|
QListWidgetItem *p_listWidgetItem = addNewItem(p_newItem, m_listWidget);
|
||||||
|
m_activeItemMap.insert(p_newItem->m_connectUuid, p_listWidgetItem);
|
||||||
|
if (m_listWidget->count() <= MAX_ITEMS) {
|
||||||
|
m_listFrame->setFixedWidth(MIN_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::updateConnectionArea(KyConnectItem *p_newItem)
|
||||||
|
{
|
||||||
|
if (m_vpnItemMap.contains(p_newItem->m_connectUuid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteConnectionMapItem(m_activeItemMap, m_listWidget, p_newItem->m_connectUuid);
|
||||||
|
qDebug()<<"[VpnPage] update connection item"<<p_newItem->m_connectName;
|
||||||
|
QListWidgetItem *p_listWidgetItem = insertNewItem(p_newItem, m_listWidget);
|
||||||
|
m_vpnItemMap.insert(p_newItem->m_connectUuid, p_listWidgetItem);
|
||||||
|
|
||||||
|
if (m_listWidget->count() <= MAX_ITEMS) {
|
||||||
|
m_listFrame->setFixedWidth(MIN_WIDTH);
|
||||||
|
} else {
|
||||||
|
m_listFrame->setFixedWidth(MAX_WIDTH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::updateConnectionState(QMap<QString, QListWidgetItem *> &connectMap,
|
||||||
|
QListWidget *vpnListWidget, QString uuid, ConnectState state)
|
||||||
|
{
|
||||||
|
qDebug() << LOG_FLAG << "update connection state";
|
||||||
|
|
||||||
|
QListWidgetItem *p_listWidgetItem = connectMap.value(uuid);
|
||||||
|
if (p_listWidgetItem) {
|
||||||
|
VpnListItem *p_vpnItem = (VpnListItem *)vpnListWidget->itemWidget(p_listWidgetItem);
|
||||||
|
p_vpnItem->updateConnectionState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::onConnectionStateChange(QString uuid,
|
||||||
|
NetworkManager::ActiveConnection::State state,
|
||||||
|
NetworkManager::ActiveConnection::Reason reason)
|
||||||
|
{
|
||||||
|
//VpnPage函数内持续监听连接状态的变化并记录供其他函数调用获取状态
|
||||||
|
if (!m_connectResourse->isVirtualConncection(uuid)) {
|
||||||
|
qDebug() << "[VpnPage] connection state change signal but not vpn";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendVpnStateChangeSignal(uuid, (ConnectState)state);
|
||||||
|
|
||||||
|
if (m_activeItemMap.keys().contains(uuid) && state == NetworkManager::ActiveConnection::State::Activated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug()<<"[VpnPage] connection uuid"<< uuid
|
||||||
|
<< "state change slot:"<< state;
|
||||||
|
|
||||||
|
KyConnectItem *p_newItem = nullptr;
|
||||||
|
QString deviceName = "";
|
||||||
|
QString ssid = "";
|
||||||
|
|
||||||
|
if (state == NetworkManager::ActiveConnection::State::Activated) {
|
||||||
|
p_newItem = m_activeResourse->getActiveConnectionByUuid(uuid);
|
||||||
|
if (nullptr == p_newItem) {
|
||||||
|
qWarning()<<"[VpnPage] get active connection failed, connection uuid" << uuid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid = p_newItem->m_connectName;
|
||||||
|
updateActivatedConnectionArea(p_newItem);
|
||||||
|
updateConnectionState(m_activeItemMap, m_listWidget, uuid, (ConnectState)state);
|
||||||
|
} else if (state == NetworkManager::ActiveConnection::State::Deactivated) {
|
||||||
|
p_newItem = m_connectResourse->getConnectionItemByUuid(uuid);
|
||||||
|
qDebug() << "[VpnPage] deactivated reason" << reason;
|
||||||
|
if (nullptr == p_newItem) {
|
||||||
|
qWarning()<<"[VpnPage] get active connection failed, connection uuid" << uuid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssid = p_newItem->m_connectName;
|
||||||
|
updateConnectionArea(p_newItem);
|
||||||
|
updateConnectionState(m_vpnItemMap, m_listWidget, uuid, (ConnectState)state);
|
||||||
|
} else if (state == NetworkManager::ActiveConnection::State::Activating) {
|
||||||
|
updateConnectionState(m_vpnItemMap, m_listWidget, uuid, (ConnectState)state);
|
||||||
|
} else if (state == NetworkManager::ActiveConnection::State::Deactivating) {
|
||||||
|
updateConnectionState(m_activeItemMap, m_listWidget, uuid, (ConnectState)state);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT vpnActiveConnectionStateChanged(uuid, state);
|
||||||
|
|
||||||
|
if (p_newItem) {
|
||||||
|
delete p_newItem;
|
||||||
|
p_newItem = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::getVirtualList(QVector<QStringList> &vector)
|
||||||
|
{
|
||||||
|
QList<KyConnectItem *> netConnectList;
|
||||||
|
vector.clear();
|
||||||
|
m_connectResourse->getVpnAndVirtualConnections(netConnectList); //未激活列表的显示
|
||||||
|
if (!netConnectList.isEmpty()) {
|
||||||
|
for (int i = 0; i < netConnectList.size(); i++) {
|
||||||
|
KyConnectItem *p_newItem = nullptr;
|
||||||
|
KyConnectItem *p_netConnectionItem = netConnectList.at(i);
|
||||||
|
p_newItem = m_activeResourse->getActiveConnectionByUuid(p_netConnectionItem->m_connectUuid);
|
||||||
|
NetworkManager::ActiveConnection::State state = p_netConnectionItem->m_connectState;
|
||||||
|
if (p_newItem != nullptr) {
|
||||||
|
state = NetworkManager::ActiveConnection::Activated;
|
||||||
|
}
|
||||||
|
vector.append(QStringList() << netConnectList.at(i)->m_connectName
|
||||||
|
<< netConnectList.at(i)->m_connectUuid
|
||||||
|
<< netConnectList.at(i)->m_connectPath
|
||||||
|
<< QString::number(state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::sendVpnUpdateSignal(KyConnectItem *p_connectItem)
|
||||||
|
{
|
||||||
|
QStringList info;
|
||||||
|
info << p_connectItem->m_connectName << p_connectItem->m_connectUuid << p_connectItem->m_connectPath;
|
||||||
|
Q_EMIT vpnUpdate(info);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::sendVpnAddSignal(KyConnectItem *p_connectItem)
|
||||||
|
{
|
||||||
|
QStringList info;
|
||||||
|
KyConnectItem *p_newItem = nullptr;
|
||||||
|
p_newItem = m_activeResourse->getActiveConnectionByUuid(p_connectItem->m_connectUuid);
|
||||||
|
NetworkManager::ActiveConnection::State state = p_connectItem->m_connectState;
|
||||||
|
if (p_newItem != nullptr) {
|
||||||
|
state = NetworkManager::ActiveConnection::Activated;
|
||||||
|
}
|
||||||
|
info << p_connectItem->m_connectName
|
||||||
|
<< p_connectItem->m_connectUuid
|
||||||
|
<< p_connectItem->m_connectPath
|
||||||
|
<< QString::number(state);
|
||||||
|
qDebug() << "[VpnPage] emit vpnAdd because addConnection ";
|
||||||
|
Q_EMIT vpnAdd(info);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::sendVpnStateChangeSignal(QString uuid, ConnectState state)
|
||||||
|
{
|
||||||
|
if (state == Activating || state == Deactivating) {
|
||||||
|
if (m_activeResourse->connectionIsVirtual(uuid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT this->vpnConnectChanged(state);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::updateConnectionProperty(KyConnectItem *p_connectItem)
|
||||||
|
{
|
||||||
|
QString newUuid = p_connectItem->m_connectUuid;
|
||||||
|
|
||||||
|
if (m_vpnItemMap.contains(newUuid)) {
|
||||||
|
QListWidgetItem *p_listWidgetItem = m_vpnItemMap.value(newUuid);
|
||||||
|
VpnListItem *p_vpnItem = (VpnListItem*)m_listWidget->itemWidget(p_listWidgetItem);
|
||||||
|
if (p_connectItem->m_connectName != p_vpnItem->getConnectionName()){
|
||||||
|
//只要名字改变就要删除,重新插入,主要是为了排序
|
||||||
|
deleteConnectionMapItem(m_vpnItemMap, m_listWidget, newUuid);
|
||||||
|
QListWidgetItem *p_sortListWidgetItem = insertNewItem(p_connectItem, m_listWidget);
|
||||||
|
if (m_vpnItemMap.contains(newUuid)) {
|
||||||
|
qDebug()<<LOG_FLAG << "has contained connection" << newUuid;
|
||||||
|
}
|
||||||
|
m_vpnItemMap.insert(newUuid, p_sortListWidgetItem);
|
||||||
|
} else if (p_connectItem->m_connectPath != p_vpnItem->getConnectionPath()) {
|
||||||
|
p_vpnItem->updateConnectionPath(p_connectItem->m_connectPath);
|
||||||
|
}
|
||||||
|
} else if (!m_activeItemMap.contains(newUuid)){
|
||||||
|
if (p_connectItem->m_ifaceName.isEmpty()) {
|
||||||
|
QListWidgetItem *p_listWidgetItem = insertNewItem(p_connectItem, m_listWidget);
|
||||||
|
if (m_vpnItemMap.contains(newUuid)) {
|
||||||
|
qDebug()<<LOG_FLAG << "has contained connection uuid" << newUuid;
|
||||||
|
}
|
||||||
|
m_vpnItemMap.insert(newUuid, p_listWidgetItem);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qWarning() << LOG_FLAG << newUuid <<" is in activemap, so not process.";
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::updateActiveConnectionProperty(KyConnectItem *p_connectItem)
|
||||||
|
{
|
||||||
|
QString newUuid = p_connectItem->m_connectUuid;
|
||||||
|
|
||||||
|
if (m_activeItemMap.contains(newUuid)) {
|
||||||
|
QListWidgetItem *p_listWidgetItem = m_activeItemMap.value(newUuid);
|
||||||
|
VpnListItem *p_vpnItem = (VpnListItem *)m_listWidget->itemWidget(p_listWidgetItem);
|
||||||
|
if (p_vpnItem->getConnectionName() != p_connectItem->m_connectName) {
|
||||||
|
p_vpnItem->updateConnectionName(p_connectItem->m_connectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_vpnItem->getConnectionName() != p_connectItem->m_connectPath) {
|
||||||
|
p_vpnItem->updateConnectionPath(p_connectItem->m_connectPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::onUpdateConnection(QString uuid)
|
||||||
|
{
|
||||||
|
if (!m_connectResourse->isVirtualConncection(uuid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "[VpnPage]:Connection property Changed." << Q_FUNC_INFO << __LINE__;
|
||||||
|
|
||||||
|
KyConnectItem *p_newItem = nullptr;
|
||||||
|
if (m_connectResourse->isActivatedConnection(uuid)) {
|
||||||
|
p_newItem = m_activeResourse->getActiveConnectionByUuid(uuid);
|
||||||
|
if (nullptr == p_newItem) {
|
||||||
|
qWarning()<<"[VpnPage] get item failed, when update activate connection."
|
||||||
|
<<"connection uuid" << uuid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateActiveConnectionProperty(p_newItem);
|
||||||
|
} else {
|
||||||
|
p_newItem = m_connectResourse->getConnectionItemByUuid(uuid);
|
||||||
|
if (nullptr == p_newItem) {
|
||||||
|
qWarning()<<"[VpnPage] get item failed, when update connection."
|
||||||
|
<<"connection uuid"<<uuid;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateConnectionProperty(p_newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendVpnUpdateSignal(p_newItem);
|
||||||
|
|
||||||
|
delete p_newItem;
|
||||||
|
p_newItem = nullptr;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VpnPage::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
if (watched == m_settingsLabel) {
|
||||||
|
if (event->type() == QEvent::MouseButtonRelease) {
|
||||||
|
onShowControlCenter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QWidget::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::deleteVpn(const QString &connUuid)
|
||||||
|
{
|
||||||
|
qDebug() << "[VpnPage] deleteVpn" << connUuid;
|
||||||
|
if (connUuid == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_vpnConnectOperation->deleteVpnConnect(connUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::activateVpn(const QString& connUuid)
|
||||||
|
{
|
||||||
|
if (m_vpnItemMap.contains(connUuid)) {
|
||||||
|
qDebug() << "[VpnPage] activateVpn" << connUuid;
|
||||||
|
m_vpnConnectOperation->activateVpnConnection(connUuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::deactivateVpn(const QString& connUuid)
|
||||||
|
{
|
||||||
|
qDebug() << "[VpnPage] deactivateVpn" << connUuid;
|
||||||
|
QString name("");
|
||||||
|
m_vpnConnectOperation->deactivateVpnConnection(name, connUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::showDetailPage(QString uuid)
|
||||||
|
{
|
||||||
|
QListWidgetItem * vpnlistItem = m_vpnItemMap.value(uuid);
|
||||||
|
VpnListItem *vpnItem = (VpnListItem *)m_listWidget->itemWidget(vpnlistItem);
|
||||||
|
vpnItem->onInfoButtonClicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::showUI()
|
||||||
|
{
|
||||||
|
//2209中窗管在hide界面时会刷新属性,需要重新设置无图标属性
|
||||||
|
const KWindowInfo info(this->winId(), NET::WMState);
|
||||||
|
if (!info.hasState(NET::SkipTaskbar) || !info.hasState(NET::SkipPager)) {
|
||||||
|
KWindowSystem::setState(this->winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||||
|
}
|
||||||
|
|
||||||
|
resetPageHeight();
|
||||||
|
|
||||||
|
showNormal();
|
||||||
|
raise();
|
||||||
|
activateWindow();
|
||||||
|
resetWindowPosition();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VpnPage::resetWindowPosition()
|
||||||
|
{
|
||||||
|
|
||||||
|
#define MARGIN 4
|
||||||
|
#define PANEL_TOP 1
|
||||||
|
#define PANEL_LEFT 2
|
||||||
|
#define PANEL_RIGHT 3
|
||||||
|
//#define PANEL_BOTTOM 4
|
||||||
|
if (!m_positionInterface) {
|
||||||
|
m_positionInterface = new QDBusInterface("org.ukui.panel",
|
||||||
|
"/panel/position",
|
||||||
|
"org.ukui.panel",
|
||||||
|
QDBusConnection::sessionBus());
|
||||||
|
}
|
||||||
|
QRect rect;
|
||||||
|
QDBusReply<QVariantList> reply = m_positionInterface->call("GetPrimaryScreenGeometry");
|
||||||
|
//reply获取的参数共5个,分别是 主屏可用区域的起点x坐标,主屏可用区域的起点y坐标,主屏可用区域的宽度,主屏可用区域高度,任务栏位置
|
||||||
|
if (!m_positionInterface->isValid() || !reply.isValid() || reply.value().size() < 5) {
|
||||||
|
qCritical() << QDBusConnection::sessionBus().lastError().message();
|
||||||
|
kdk::WindowManager::setGeometry(this->windowHandle(), QRect(0, 0, this->width(), this->height()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QVariantList position_list = reply.value();
|
||||||
|
int position = position_list.at(4).toInt();
|
||||||
|
switch(position){
|
||||||
|
case PANEL_TOP:
|
||||||
|
//任务栏位于上方
|
||||||
|
rect = QRect(position_list.at(0).toInt() + position_list.at(2).toInt() - this->width() - MARGIN,
|
||||||
|
position_list.at(1).toInt() + MARGIN,
|
||||||
|
this->width(), this->height());
|
||||||
|
break;
|
||||||
|
//任务栏位于左边
|
||||||
|
case PANEL_LEFT:
|
||||||
|
rect = QRect(position_list.at(0).toInt() + MARGIN,
|
||||||
|
position_list.at(1).toInt() + reply.value().at(3).toInt() - this->height() - MARGIN,
|
||||||
|
this->width(), this->height());
|
||||||
|
break;
|
||||||
|
//任务栏位于右边
|
||||||
|
case PANEL_RIGHT:
|
||||||
|
rect = QRect(position_list.at(0).toInt() + position_list.at(2).toInt() - this->width() - MARGIN,
|
||||||
|
position_list.at(1).toInt() + reply.value().at(3).toInt() - this->height() - MARGIN,
|
||||||
|
this->width(), this->height());
|
||||||
|
break;
|
||||||
|
//任务栏位于下方
|
||||||
|
default:
|
||||||
|
rect = QRect(position_list.at(0).toInt() + position_list.at(2).toInt() - this->width() - MARGIN,
|
||||||
|
position_list.at(1).toInt() + reply.value().at(3).toInt() - this->height() - MARGIN,
|
||||||
|
this->width(), this->height());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
kdk::WindowManager::setGeometry(this->windowHandle(), rect);
|
||||||
|
qDebug() << " Position of ukui-panel is " << position << "; Position of mainwindow is " << this->geometry() << "." << Q_FUNC_INFO << __LINE__;
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef VPNPAGE_H
|
||||||
|
#define VPNPAGE_H
|
||||||
|
|
||||||
|
#include "divider.h"
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QGSettings>
|
||||||
|
|
||||||
|
#include <KWindowSystem>
|
||||||
|
|
||||||
|
#include "list-items/listitem.h"
|
||||||
|
#include "list-items/vpnlistitem.h"
|
||||||
|
#include "single-pages/singlepage.h"
|
||||||
|
|
||||||
|
#define VPNPAGE_LAYOUT_MARGINS 0,0,0,0
|
||||||
|
#define VPN_LIST_SPACING 0
|
||||||
|
#define ITEM_HEIGHT 50
|
||||||
|
#define ITEM_SPACE 16
|
||||||
|
#define PAGE_SPACE 22
|
||||||
|
|
||||||
|
#define LOG_FLAG "[VpnPage]"
|
||||||
|
|
||||||
|
#define VISIBLE "visible"
|
||||||
|
const QByteArray GSETTINGS_VPNICON_VISIBLE = "org.ukui.kylin-nm.vpnicon";
|
||||||
|
|
||||||
|
class VpnListItem;
|
||||||
|
|
||||||
|
class VpnPage : public SinglePage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit VpnPage(QWidget *parent = nullptr);
|
||||||
|
~VpnPage();
|
||||||
|
|
||||||
|
//for dbus
|
||||||
|
void getVirtualList(QVector<QStringList> &vector);
|
||||||
|
void deleteVpn(const QString &connUuid);
|
||||||
|
void activateVpn(const QString& connUuid);
|
||||||
|
void deactivateVpn(const QString& connUuid);
|
||||||
|
void showDetailPage(QString uuid);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *watched, QEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initUI();
|
||||||
|
void initVpnArea();
|
||||||
|
void resetPageHeight();
|
||||||
|
|
||||||
|
inline void initDeviceCombox() { return; }
|
||||||
|
|
||||||
|
QListWidgetItem *insertNewItem(KyConnectItem *itemData, QListWidget *listWidget);
|
||||||
|
QListWidgetItem *addNewItem(KyConnectItem *itemData, QListWidget *listWidget);
|
||||||
|
bool removeConnectionItem(QMap<QString, QListWidgetItem *> &connectMap,
|
||||||
|
QListWidget *vpnListWidget, QString path);
|
||||||
|
|
||||||
|
void constructItemArea();
|
||||||
|
|
||||||
|
void updateConnectionArea(KyConnectItem *p_newItem);
|
||||||
|
void updateActivatedConnectionArea(KyConnectItem *p_newItem);
|
||||||
|
void updateConnectionState(QMap<QString, QListWidgetItem *> &connectMap,
|
||||||
|
QListWidget *vpnListWidget, QString uuid, ConnectState state);
|
||||||
|
|
||||||
|
void updateActiveConnectionProperty(KyConnectItem *p_connectItem);
|
||||||
|
void updateConnectionProperty(KyConnectItem *p_connectItem);
|
||||||
|
|
||||||
|
void sendVpnUpdateSignal(KyConnectItem *p_connectItem);
|
||||||
|
void sendVpnAddSignal(KyConnectItem *p_connectItem);
|
||||||
|
void sendVpnStateChangeSignal(QString uuid, ConnectState state);
|
||||||
|
|
||||||
|
void clearConnectionMap(QMap<QString, QListWidgetItem *> &connectMap,
|
||||||
|
QListWidget *vpnListWidget);
|
||||||
|
void deleteConnectionMapItem(QMap<QString, QListWidgetItem *> &connectMap,
|
||||||
|
QListWidget *vpnListWidget, QString uuid);
|
||||||
|
|
||||||
|
void resetWindowPosition();
|
||||||
|
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void vpnAdd(QStringList info);
|
||||||
|
void vpnRemove(QString dbusPath);
|
||||||
|
void vpnUpdate(QStringList info);
|
||||||
|
|
||||||
|
void vpnActiveConnectionStateChanged(QString uuid, int status);
|
||||||
|
void vpnConnectChanged(int state);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onConnectionStateChange(QString uuid,
|
||||||
|
NetworkManager::ActiveConnection::State state,
|
||||||
|
NetworkManager::ActiveConnection::Reason reason);
|
||||||
|
|
||||||
|
void onAddConnection(QString uuid);
|
||||||
|
void onRemoveConnection(QString path);
|
||||||
|
void onUpdateConnection(QString uuid);
|
||||||
|
|
||||||
|
void onShowControlCenter();
|
||||||
|
|
||||||
|
private:
|
||||||
|
KyVpnConnectOperation *m_vpnConnectOperation = nullptr;
|
||||||
|
KyActiveConnectResourse *m_activeResourse = nullptr; //激活的连接
|
||||||
|
KyConnectResourse *m_connectResourse = nullptr; //未激活的连接
|
||||||
|
|
||||||
|
QMap<QString, QListWidgetItem *> m_vpnItemMap;
|
||||||
|
QMap<QString, QListWidgetItem *> m_activeItemMap;
|
||||||
|
|
||||||
|
QDBusInterface * m_positionInterface = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void showUI();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LANPAGE_H
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include "vpnobject.h"
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
#include "ukuistylehelper/ukuistylehelper.h"
|
||||||
|
|
||||||
|
vpnObject::vpnObject(QMainWindow *parent) : QMainWindow(parent)
|
||||||
|
{
|
||||||
|
initUI();
|
||||||
|
initTrayIcon();
|
||||||
|
initDbusConnnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
vpnObject::~vpnObject()
|
||||||
|
{
|
||||||
|
if (m_vpnGsettings != nullptr) {
|
||||||
|
delete m_vpnGsettings;
|
||||||
|
m_vpnGsettings = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpnObject::initUI()
|
||||||
|
{
|
||||||
|
m_vpnPage = new VpnPage(nullptr);
|
||||||
|
m_vpnPage->update();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpnObject::initTrayIcon()
|
||||||
|
{
|
||||||
|
m_vpnTrayIcon = new QSystemTrayIcon(this);
|
||||||
|
m_vpnTrayIcon->setToolTip(QString(tr("vpn tool")));
|
||||||
|
m_vpnTrayIcon->setIcon(QIcon::fromTheme("ukui-vpn-symbolic"));
|
||||||
|
m_vpnTrayIcon->setVisible(true);
|
||||||
|
initVpnIconVisible();
|
||||||
|
connect(m_vpnTrayIcon, &QSystemTrayIcon::activated, this, &vpnObject::onTrayIconActivated);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpnObject::initVpnIconVisible()
|
||||||
|
{
|
||||||
|
if (QGSettings::isSchemaInstalled(QByteArray(GSETTINGS_VPNICON_VISIBLE))) {
|
||||||
|
m_vpnGsettings = new QGSettings(QByteArray(GSETTINGS_VPNICON_VISIBLE));
|
||||||
|
if (m_vpnGsettings->keys().contains(QString(VISIBLE))) {
|
||||||
|
m_vpnTrayIcon->setVisible(m_vpnGsettings->get(VISIBLE).toBool());
|
||||||
|
connect(m_vpnGsettings, &QGSettings::changed, this, [=]() {
|
||||||
|
m_vpnTrayIcon->setVisible(m_vpnGsettings->get(VISIBLE).toBool());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief vpnObject::onTrayIconActivated 点击托盘图标的槽函数
|
||||||
|
*/
|
||||||
|
void vpnObject::onTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
|
||||||
|
{
|
||||||
|
switch(reason) {
|
||||||
|
case QSystemTrayIcon::Trigger:
|
||||||
|
if(m_vpnPage->isActiveWindow()) {
|
||||||
|
m_vpnPage->hide();
|
||||||
|
} else {
|
||||||
|
onShowMainWindow();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpnObject::getVirtualList(QVector<QStringList> &vector)
|
||||||
|
{
|
||||||
|
vector.clear();
|
||||||
|
if (nullptr != m_vpnPage) {
|
||||||
|
m_vpnPage->getVirtualList(vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Vpn连接删除
|
||||||
|
void vpnObject::deleteVpn(const QString &connUuid)
|
||||||
|
{
|
||||||
|
m_vpnPage->deleteVpn(connUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Vpn连接断开
|
||||||
|
void vpnObject::activateVpn(const QString& connUuid)
|
||||||
|
{
|
||||||
|
m_vpnPage->activateVpn(connUuid);
|
||||||
|
}
|
||||||
|
void vpnObject::deactivateVpn(const QString& connUuid)
|
||||||
|
{
|
||||||
|
m_vpnPage->deactivateVpn(connUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpnObject::showDetailPage(const QString& connUuid)
|
||||||
|
{
|
||||||
|
m_vpnPage->showDetailPage(connUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void vpnObject::onShowMainWindow()
|
||||||
|
{
|
||||||
|
kdk::UkuiStyleHelper::self()->removeHeader(m_vpnPage);
|
||||||
|
m_vpnPage->showUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpnObject::initDbusConnnect()
|
||||||
|
{
|
||||||
|
connect(m_vpnPage, &VpnPage::activateFailed, this, &vpnObject::activateFailed);
|
||||||
|
connect(m_vpnPage, &VpnPage::deactivateFailed, this, &vpnObject::deactivateFailed);
|
||||||
|
|
||||||
|
connect(m_vpnPage, &VpnPage::vpnAdd, this, &vpnObject::vpnAdd);
|
||||||
|
connect(m_vpnPage, &VpnPage::vpnRemove, this, &vpnObject::vpnRemove);
|
||||||
|
connect(m_vpnPage, &VpnPage::vpnUpdate, this, &vpnObject::vpnUpdate);
|
||||||
|
connect(m_vpnPage, &VpnPage::vpnActiveConnectionStateChanged, this, &vpnObject::vpnActiveConnectionStateChanged);
|
||||||
|
//模式切换
|
||||||
|
QDBusConnection::sessionBus().connect(QString("com.kylin.statusmanager.interface"),
|
||||||
|
QString("/"),
|
||||||
|
QString("com.kylin.statusmanager.interface"),
|
||||||
|
QString("mode_change_signal"), this, SLOT(onTabletModeChanged(bool)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpnObject::onTabletModeChanged(bool mode)
|
||||||
|
{
|
||||||
|
qDebug() << "TabletMode change" << mode;
|
||||||
|
Q_UNUSED(mode)
|
||||||
|
//模式切换时,隐藏主界面
|
||||||
|
m_vpnPage->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vpnObject::showVpnAddWidget()
|
||||||
|
{
|
||||||
|
if (m_vpnAddPage == nullptr) {
|
||||||
|
m_vpnAddPage = new vpnAddPage();
|
||||||
|
connect(m_vpnAddPage, &vpnAddPage::closed, [&] () {m_vpnAddPage = nullptr;});
|
||||||
|
m_vpnAddPage->show();
|
||||||
|
}
|
||||||
|
m_vpnAddPage->raise();
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
#ifndef VPNOBJECT_H
|
||||||
|
#define VPNOBJECT_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QSystemTrayIcon>
|
||||||
|
#include <QMainWindow>
|
||||||
|
|
||||||
|
#include "vpnpage.h"
|
||||||
|
#include "vpnaddpage.h"
|
||||||
|
class VpnPage;
|
||||||
|
|
||||||
|
#define VISIBLE "visible"
|
||||||
|
#define GSETTINGS_VPNICON_VISIBLE "org.ukui.kylin-nm.vpnicon"
|
||||||
|
//const QByteArray GSETTINGS_VPNICON_VISIBLE = "org.ukui.kylin-nm.vpnicon";
|
||||||
|
|
||||||
|
|
||||||
|
class vpnObject : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit vpnObject(QMainWindow *parent = nullptr);
|
||||||
|
~vpnObject();
|
||||||
|
|
||||||
|
void getVirtualList(QVector<QStringList> &vector);
|
||||||
|
//Vpn连接删除
|
||||||
|
void deleteVpn(const QString &connUuid);
|
||||||
|
//有线连接断开
|
||||||
|
void activateVpn(const QString& connUuid);
|
||||||
|
void deactivateVpn(const QString& connUuid);
|
||||||
|
|
||||||
|
void showDetailPage(const QString& connUuid);
|
||||||
|
|
||||||
|
void showVpnAddWidget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initUI();
|
||||||
|
void initTrayIcon();
|
||||||
|
void initVpnIconVisible();
|
||||||
|
void initDbusConnnect();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
VpnPage *m_vpnPage = nullptr;
|
||||||
|
QSystemTrayIcon * m_vpnTrayIcon = nullptr;
|
||||||
|
QGSettings * m_vpnGsettings; //VPN配置文件
|
||||||
|
double tran =1;
|
||||||
|
QGSettings *StyleSettings = nullptr;
|
||||||
|
QWidget * vpnWidget = nullptr;
|
||||||
|
|
||||||
|
QDBusInterface * m_positionInterface = nullptr;
|
||||||
|
bool m_isShowInCenter = false;
|
||||||
|
|
||||||
|
vpnAddPage *m_vpnAddPage = nullptr;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void onShowMainWindow();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onTrayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||||
|
void onTabletModeChanged(bool mode);
|
||||||
|
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void vpnAdd(QStringList info);
|
||||||
|
void vpnRemove(QString dbusPath);
|
||||||
|
void vpnUpdate(QStringList info);
|
||||||
|
void vpnActiveConnectionStateChanged(QString uuid, int status);
|
||||||
|
void activateFailed(QString errorMessage);
|
||||||
|
void deactivateFailed(QString errorMessage);
|
||||||
|
void mainWindowVisibleChanged(const bool &visible);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VPNOBJECT_H
|
|
@ -0,0 +1,18 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Encoding=UTF-8
|
||||||
|
Name=Kylin VPN
|
||||||
|
Name[zh_CN]=麒麟VPN设置工具
|
||||||
|
Name[zh_HK]=麒麟VPN設置工具
|
||||||
|
Name[zh_TW]=麒麟VPN設置工具
|
||||||
|
Icon=gnome-dev-ethernet
|
||||||
|
Comment=Beautiful Network Config Applet
|
||||||
|
Comment[zh_CN]=麒麟VPN设置工具,提供查看和简单设置功能,拥有美观的界面和舒适的操作.
|
||||||
|
Keywords=applet;vpn;network;network-manager;
|
||||||
|
Exec=/usr/bin/kylin-vpn
|
||||||
|
StartupNotify=false
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
OnlyShowIn=UKUI
|
||||||
|
X-UKUI-AutoRestart=true
|
||||||
|
NoDisplay=true
|
||||||
|
X-UKUI-Autostart-Phase=Application
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Tianjin KYLIN Information Technology 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, 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#include "mainwindow.h"
|
||||||
|
//#include "dbusadaptor.h"
|
||||||
|
#include "vpndbusadaptor.h"
|
||||||
|
#include <QTranslator>
|
||||||
|
#include <QLocale>
|
||||||
|
#include "qt-single-application.h"
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QFile>
|
||||||
|
#include <ukui-log4qt.h>
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||||
|
#include "xatom-helper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "vpnobject.h"
|
||||||
|
|
||||||
|
#define LOG_IDENT "kylin_vpn"
|
||||||
|
|
||||||
|
const QString QT_TRANSLATE_FILE = "/usr/share/qt5/translations/qt_zh_CN.qm";
|
||||||
|
|
||||||
|
void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||||
|
{
|
||||||
|
QByteArray localMsg = msg.toLocal8Bit();
|
||||||
|
QByteArray currentDateTime = QDateTime::currentDateTime().toString().toLocal8Bit();
|
||||||
|
|
||||||
|
bool showDebug = true;
|
||||||
|
QString logFilePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/ukui/kylin-nm.log";
|
||||||
|
FILE *log_file = nullptr;
|
||||||
|
|
||||||
|
if (showDebug) {
|
||||||
|
log_file = fopen(logFilePath.toLocal8Bit().constData(), "a+");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *file = context.file ? context.file : "";
|
||||||
|
const char *function = context.function ? context.function : "";
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg:
|
||||||
|
if (!log_file) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(log_file, "Debug: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function);
|
||||||
|
break;
|
||||||
|
case QtInfoMsg:
|
||||||
|
fprintf(log_file? log_file: stdout, "Info: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function);
|
||||||
|
break;
|
||||||
|
case QtWarningMsg:
|
||||||
|
fprintf(log_file? log_file: stderr, "Warning: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function);
|
||||||
|
break;
|
||||||
|
case QtCriticalMsg:
|
||||||
|
fprintf(log_file? log_file: stderr, "Critical: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function);
|
||||||
|
break;
|
||||||
|
case QtFatalMsg:
|
||||||
|
fprintf(log_file? log_file: stderr, "Fatal: %s: %s (%s:%u, %s)\n", currentDateTime.constData(), localMsg.constData(), file, context.line, function);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log_file)
|
||||||
|
fclose(log_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
initUkuiLog4qt("kylin-vpn");
|
||||||
|
|
||||||
|
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||||
|
|
||||||
|
QString id = QString("kylin-vpn"+ QLatin1String(getenv("DISPLAY")));
|
||||||
|
QtSingleApplication a(id, argc, argv);
|
||||||
|
|
||||||
|
QApplication::setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
|
QThread thread;
|
||||||
|
KyNetworkResourceManager *p_networkResource = KyNetworkResourceManager::getInstance();
|
||||||
|
p_networkResource->moveToThread(&thread);
|
||||||
|
QObject::connect(&thread, SIGNAL(started()), p_networkResource, SLOT(onInitNetwork()));
|
||||||
|
thread.start();
|
||||||
|
|
||||||
|
// Internationalization
|
||||||
|
QString locale = QLocale::system().name();
|
||||||
|
QTranslator trans_global;
|
||||||
|
qDebug() << "QLocale " << QLocale();
|
||||||
|
if (trans_global.load(QLocale(), "kylin-vpn", "_", ":/translations/"))
|
||||||
|
{
|
||||||
|
a.installTranslator(&trans_global);
|
||||||
|
qDebug()<<"Translations load success";
|
||||||
|
} else {
|
||||||
|
qWarning() << "Translations load fail";
|
||||||
|
}
|
||||||
|
|
||||||
|
QTranslator qtBaseTranslator;
|
||||||
|
if (qtBaseTranslator.load(QLocale(), "qt", "_", "/usr/share/qt5/translations/"))
|
||||||
|
{
|
||||||
|
a.installTranslator(&qtBaseTranslator);
|
||||||
|
qDebug()<<"QtBase Translations load success";
|
||||||
|
} else {
|
||||||
|
qWarning() << "QtBase Translations load fail";
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!p_networkResource->NetworkManagerIsInited()) {
|
||||||
|
::usleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
vpnObject vpnobject;
|
||||||
|
a.setActivationWindow(&vpnobject);
|
||||||
|
vpnobject.setProperty("useStyleWindowManager", false); //禁用拖动
|
||||||
|
a.setWindowIcon(QIcon::fromTheme("ukui-vpn-symbolic"));
|
||||||
|
|
||||||
|
VpnDbusAdaptor vpnAdaptor(&vpnobject);
|
||||||
|
Q_UNUSED(vpnAdaptor);
|
||||||
|
|
||||||
|
auto connection = QDBusConnection::sessionBus();
|
||||||
|
if (!connection.registerService("com.kylin.kylinvpn")
|
||||||
|
|| !connection.registerObject("/com/kylin/kylinvpn", &vpnobject)) {
|
||||||
|
qCritical() << "QDbus register service failed reason:" << connection.lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.exec();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<schemalist gettext-domain="kylin-vpn">
|
||||||
|
<schema id="org.ukui.kylin-nm.vpnicon" path="/org/ukui/kylin-nm/vpnicon/">
|
||||||
|
<key type="b" name="visible">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>vpnicon visible</summary>
|
||||||
|
<description>vpnicon visible.true is visible,false is invisible.</description>
|
||||||
|
</key>
|
||||||
|
</schema>
|
||||||
|
</schemalist>
|
|
@ -0,0 +1,205 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||||
|
** 2020 KylinSoft Co., Ltd.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Solutions component.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qt-local-peer.h"
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QTime>
|
||||||
|
|
||||||
|
#if defined(Q_OS_UNIX)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace QtLP_Private {
|
||||||
|
#include "qt-locked-file.cpp"
|
||||||
|
#include "qt-locked-file-unix.cpp"
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* QtLocalPeer::ack = "ack";
|
||||||
|
|
||||||
|
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
||||||
|
: QObject(parent), id(appId) {
|
||||||
|
QString prefix = id;
|
||||||
|
if(id.isEmpty()) {
|
||||||
|
id = QCoreApplication::applicationFilePath();
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
id = id.toLower();
|
||||||
|
#endif
|
||||||
|
prefix = id.section(QLatin1Char('/'), -1); //完整路径按‘/’分隔后取最后一个字段
|
||||||
|
}
|
||||||
|
prefix.remove(QRegExp("[^a-zA-Z]")); //去掉名称中的非字母
|
||||||
|
prefix.truncate(6); //取前六位
|
||||||
|
|
||||||
|
QByteArray idc = id.toUtf8();
|
||||||
|
quint16 idNum = qChecksum(idc.constData(), idc.size());
|
||||||
|
socketName = QLatin1String("qtsingleapp-") + prefix
|
||||||
|
+ QLatin1Char('-') + QString::number(idNum, 16);
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
if(!pProcessIdToSessionId) {
|
||||||
|
QLibrary lib("kernel32");
|
||||||
|
pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
|
||||||
|
}
|
||||||
|
if(pProcessIdToSessionId) {
|
||||||
|
DWORD sessionId = 0;
|
||||||
|
pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
|
||||||
|
socketName += QLatin1Char('-') + QString::number(sessionId, 16);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
server = new QLocalServer(this);
|
||||||
|
QString lockName = QDir(QDir::tempPath()).absolutePath()
|
||||||
|
+ QLatin1Char('/') + socketName
|
||||||
|
+ QLatin1String("-lockfile"); //tmp目录下的锁文件
|
||||||
|
lockFile.setFileName(lockName);
|
||||||
|
lockFile.open(QIODevice::ReadWrite);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool QtLocalPeer::isClient() {
|
||||||
|
if(lockFile.isLocked())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
//由于文件锁的存在,仅当本进程第一次启动时能执行到此并使server进行监听和关联槽函数
|
||||||
|
bool res = server->listen(socketName);
|
||||||
|
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
|
||||||
|
// ### Workaround
|
||||||
|
if(!res && server->serverError() == QAbstractSocket::AddressInUseError) {
|
||||||
|
QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName);
|
||||||
|
res = server->listen(socketName);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(!res)
|
||||||
|
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
||||||
|
QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QtLocalPeer::sendMessage(const QString &message, int timeout) {
|
||||||
|
if(!isClient())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QLocalSocket socket;
|
||||||
|
bool connOk = false;
|
||||||
|
for(int i = 0; i < 2; i++) {
|
||||||
|
// Try twice, in case the other instance is just starting up
|
||||||
|
socket.connectToServer(socketName);
|
||||||
|
connOk = socket.waitForConnected(timeout / 2);
|
||||||
|
if(connOk || i)
|
||||||
|
break;
|
||||||
|
int ms = 250;
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
Sleep(DWORD(ms));
|
||||||
|
#else
|
||||||
|
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if(!connOk)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QByteArray uMsg(message.toUtf8());
|
||||||
|
QDataStream ds(&socket);
|
||||||
|
ds.writeBytes(uMsg.constData(), uMsg.size());
|
||||||
|
bool res = socket.waitForBytesWritten(timeout);
|
||||||
|
if(res) {
|
||||||
|
res &= socket.waitForReadyRead(timeout); // wait for ack
|
||||||
|
if(res)
|
||||||
|
res &= (socket.read(qstrlen(ack)) == ack);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QtLocalPeer::receiveConnection 当新进程启动时,会尝试连接此进程server,server接收到newConnection信号并触发此槽函数
|
||||||
|
*/
|
||||||
|
void QtLocalPeer::receiveConnection() {
|
||||||
|
QLocalSocket* socket = server->nextPendingConnection(); //获取新进程的socket
|
||||||
|
if(!socket)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
if(socket->state() == QLocalSocket::UnconnectedState) {
|
||||||
|
qWarning("QtLocalPeer: Peer disconnected");
|
||||||
|
delete socket;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(socket->bytesAvailable() >= qint64(sizeof(quint32)))
|
||||||
|
break;
|
||||||
|
socket->waitForReadyRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDataStream ds(socket);
|
||||||
|
QByteArray uMsg;
|
||||||
|
quint32 remaining;
|
||||||
|
ds >> remaining;
|
||||||
|
uMsg.resize(remaining);
|
||||||
|
int got = 0;
|
||||||
|
char* uMsgBuf = uMsg.data();
|
||||||
|
do {
|
||||||
|
got = ds.readRawData(uMsgBuf, remaining);
|
||||||
|
remaining -= got;
|
||||||
|
uMsgBuf += got;
|
||||||
|
} while(remaining && got >= 0 && socket->waitForReadyRead(2000));
|
||||||
|
if(got < 0) {
|
||||||
|
qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
|
||||||
|
delete socket;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString message(QString::fromUtf8(uMsg));
|
||||||
|
socket->write(ack, qstrlen(ack));
|
||||||
|
socket->waitForBytesWritten(1000);
|
||||||
|
socket->waitForDisconnected(1000); // make sure client reads ack
|
||||||
|
delete socket;
|
||||||
|
Q_EMIT messageReceived(message); //获取新进程的启动信息并作为信号发送给前端
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||||
|
** 2020 KylinSoft Co., Ltd.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Solutions component.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QTLOCALPEER_H
|
||||||
|
#define QTLOCALPEER_H
|
||||||
|
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "qt-locked-file.h"
|
||||||
|
|
||||||
|
class QtLocalPeer : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
|
||||||
|
bool isClient();
|
||||||
|
bool sendMessage(const QString &message, int timeout);
|
||||||
|
QString applicationId() const {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void messageReceived(const QString &message);
|
||||||
|
|
||||||
|
protected Q_SLOTS:
|
||||||
|
void receiveConnection();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QString id;
|
||||||
|
QString socketName;
|
||||||
|
QLocalServer* server;
|
||||||
|
QtLP_Private::QtLockedFile lockFile;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char* ack;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QTLOCALPEER_H
|
|
@ -0,0 +1,113 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||||
|
** 2020 KylinSoft Co., Ltd.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Solutions component.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "qt-locked-file.h"
|
||||||
|
|
||||||
|
bool QtLockedFile::lock(LockMode mode, bool block) {
|
||||||
|
if(!isOpen()) {
|
||||||
|
qWarning("QtLockedFile::lock(): file is not opened");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mode == NoLock)
|
||||||
|
return unlock();
|
||||||
|
|
||||||
|
if(mode == m_lock_mode)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(m_lock_mode != NoLock)
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
struct flock fl;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
fl.l_start = 0;
|
||||||
|
fl.l_len = 0;
|
||||||
|
fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
|
||||||
|
int cmd = block ? F_SETLKW : F_SETLK;
|
||||||
|
int ret = fcntl(handle(), cmd, &fl);
|
||||||
|
|
||||||
|
if(ret == -1) {
|
||||||
|
if(errno != EINTR && errno != EAGAIN)
|
||||||
|
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
m_lock_mode = mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QtLockedFile::unlock() {
|
||||||
|
if(!isOpen()) {
|
||||||
|
qWarning("QtLockedFile::unlock(): file is not opened");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isLocked())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
struct flock fl;
|
||||||
|
fl.l_whence = SEEK_SET;
|
||||||
|
fl.l_start = 0;
|
||||||
|
fl.l_len = 0;
|
||||||
|
fl.l_type = F_UNLCK;
|
||||||
|
int ret = fcntl(handle(), F_SETLKW, &fl);
|
||||||
|
|
||||||
|
if(ret == -1) {
|
||||||
|
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lock_mode = NoLock;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtLockedFile::~QtLockedFile() {
|
||||||
|
if(isOpen())
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||||
|
** 2020 KylinSoft Co., Ltd.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Solutions component.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qt-locked-file.h"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QtLockedFile
|
||||||
|
|
||||||
|
\brief The QtLockedFile class extends QFile with advisory locking
|
||||||
|
functions.
|
||||||
|
|
||||||
|
A file may be locked in read or write mode. Multiple instances of
|
||||||
|
\e QtLockedFile, created in multiple processes running on the same
|
||||||
|
machine, may have a file locked in read mode. Exactly one instance
|
||||||
|
may have it locked in write mode. A read and a write lock cannot
|
||||||
|
exist simultaneously on the same file.
|
||||||
|
|
||||||
|
The file locks are advisory. This means that nothing prevents
|
||||||
|
another process from manipulating a locked file using QFile or
|
||||||
|
file system functions offered by the OS. Serialization is only
|
||||||
|
guaranteed if all processes that access the file use
|
||||||
|
QLockedFile. Also, while holding a lock on a file, a process
|
||||||
|
must not open the same file again (through any API), or locks
|
||||||
|
can be unexpectedly lost.
|
||||||
|
|
||||||
|
The lock provided by an instance of \e QtLockedFile is released
|
||||||
|
whenever the program terminates. This is true even when the
|
||||||
|
program crashes and no destructors are called.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! \enum QtLockedFile::LockMode
|
||||||
|
|
||||||
|
This enum describes the available lock modes.
|
||||||
|
|
||||||
|
\value ReadLock A read lock.
|
||||||
|
\value WriteLock A write lock.
|
||||||
|
\value NoLock Neither a read lock nor a write lock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs an unlocked \e QtLockedFile object. This constructor
|
||||||
|
behaves in the same way as \e QFile::QFile().
|
||||||
|
|
||||||
|
\sa QFile::QFile()
|
||||||
|
*/
|
||||||
|
QtLockedFile::QtLockedFile()
|
||||||
|
: QFile() {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
wmutex = 0;
|
||||||
|
rmutex = 0;
|
||||||
|
#endif
|
||||||
|
m_lock_mode = NoLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs an unlocked QtLockedFile object with file \a name. This
|
||||||
|
constructor behaves in the same way as \e QFile::QFile(const
|
||||||
|
QString&).
|
||||||
|
|
||||||
|
\sa QFile::QFile()
|
||||||
|
*/
|
||||||
|
QtLockedFile::QtLockedFile(const QString &name)
|
||||||
|
: QFile(name) {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
wmutex = 0;
|
||||||
|
rmutex = 0;
|
||||||
|
#endif
|
||||||
|
m_lock_mode = NoLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Opens the file in OpenMode \a mode.
|
||||||
|
|
||||||
|
This is identical to QFile::open(), with the one exception that the
|
||||||
|
Truncate mode flag is disallowed. Truncation would conflict with the
|
||||||
|
advisory file locking, since the file would be modified before the
|
||||||
|
write lock is obtained. If truncation is required, use resize(0)
|
||||||
|
after obtaining the write lock.
|
||||||
|
|
||||||
|
Returns true if successful; otherwise false.
|
||||||
|
|
||||||
|
\sa QFile::open(), QFile::resize()
|
||||||
|
*/
|
||||||
|
bool QtLockedFile::open(OpenMode mode) {
|
||||||
|
if(mode & QIODevice::Truncate) {
|
||||||
|
qWarning("QtLockedFile::open(): Truncate mode not allowed.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return QFile::open(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns \e true if this object has a in read or write lock;
|
||||||
|
otherwise returns \e false.
|
||||||
|
|
||||||
|
\sa lockMode()
|
||||||
|
*/
|
||||||
|
bool QtLockedFile::isLocked() const {
|
||||||
|
return m_lock_mode != NoLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the type of lock currently held by this object, or \e
|
||||||
|
QtLockedFile::NoLock.
|
||||||
|
|
||||||
|
\sa isLocked()
|
||||||
|
*/
|
||||||
|
QtLockedFile::LockMode QtLockedFile::lockMode() const {
|
||||||
|
return m_lock_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool QtLockedFile::lock(LockMode mode, bool block = true)
|
||||||
|
|
||||||
|
Obtains a lock of type \a mode. The file must be opened before it
|
||||||
|
can be locked.
|
||||||
|
|
||||||
|
If \a block is true, this function will block until the lock is
|
||||||
|
aquired. If \a block is false, this function returns \e false
|
||||||
|
immediately if the lock cannot be aquired.
|
||||||
|
|
||||||
|
If this object already has a lock of type \a mode, this function
|
||||||
|
returns \e true immediately. If this object has a lock of a
|
||||||
|
different type than \a mode, the lock is first released and then a
|
||||||
|
new lock is obtained.
|
||||||
|
|
||||||
|
This function returns \e true if, after it executes, the file is
|
||||||
|
locked by this object, and \e false otherwise.
|
||||||
|
|
||||||
|
\sa unlock(), isLocked(), lockMode()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool QtLockedFile::unlock()
|
||||||
|
|
||||||
|
Releases a lock.
|
||||||
|
|
||||||
|
If the object has no lock, this function returns immediately.
|
||||||
|
|
||||||
|
This function returns \e true if, after it executes, the file is
|
||||||
|
not locked by this object, and \e false otherwise.
|
||||||
|
|
||||||
|
\sa lock(), isLocked(), lockMode()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn QtLockedFile::~QtLockedFile()
|
||||||
|
|
||||||
|
Destroys the \e QtLockedFile object. If any locks were held, they
|
||||||
|
are released.
|
||||||
|
*/
|
|
@ -0,0 +1,97 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||||
|
** 2020 KylinSoft Co., Ltd.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Solutions component.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QTLOCKEDFILE_H
|
||||||
|
#define QTLOCKEDFILE_H
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <QVector>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
|
||||||
|
# define QT_QTLOCKEDFILE_EXPORT
|
||||||
|
# elif defined(QT_QTLOCKEDFILE_IMPORT)
|
||||||
|
# if defined(QT_QTLOCKEDFILE_EXPORT)
|
||||||
|
# undef QT_QTLOCKEDFILE_EXPORT
|
||||||
|
# endif
|
||||||
|
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
|
||||||
|
# elif defined(QT_QTLOCKEDFILE_EXPORT)
|
||||||
|
# undef QT_QTLOCKEDFILE_EXPORT
|
||||||
|
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define QT_QTLOCKEDFILE_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace QtLP_Private {
|
||||||
|
|
||||||
|
class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile {
|
||||||
|
public:
|
||||||
|
enum LockMode { NoLock = 0, ReadLock, WriteLock };
|
||||||
|
|
||||||
|
QtLockedFile();
|
||||||
|
QtLockedFile(const QString &name);
|
||||||
|
~QtLockedFile();
|
||||||
|
|
||||||
|
bool open(OpenMode mode);
|
||||||
|
|
||||||
|
bool lock(LockMode mode, bool block = true);
|
||||||
|
bool unlock();
|
||||||
|
bool isLocked() const;
|
||||||
|
LockMode lockMode() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
Qt::HANDLE wmutex;
|
||||||
|
Qt::HANDLE rmutex;
|
||||||
|
QVector<Qt::HANDLE> rmutexes;
|
||||||
|
QString mutexname;
|
||||||
|
|
||||||
|
Qt::HANDLE getMutexHandle(int idx, bool doCreate);
|
||||||
|
bool waitMutex(Qt::HANDLE mutex, bool doBlock);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
LockMode m_lock_mode;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,351 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||||
|
** 2020 KylinSoft Co., Ltd.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Solutions component.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "qt-single-application.h"
|
||||||
|
#include "qt-local-peer.h"
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QDBusConnection>
|
||||||
|
#include <QDBusInterface>
|
||||||
|
#include <QDBusReply>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include "../vpnobject.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QtSingleApplication qtsingleapplication.h
|
||||||
|
\brief The QtSingleApplication class provides an API to detect and
|
||||||
|
communicate with running instances of an application.
|
||||||
|
|
||||||
|
This class allows you to create applications where only one
|
||||||
|
instance should be running at a time. I.e., if the user tries to
|
||||||
|
launch another instance, the already running instance will be
|
||||||
|
activated instead. Another usecase is a client-server system,
|
||||||
|
where the first started instance will assume the role of server,
|
||||||
|
and the later instances will act as clients of that server.
|
||||||
|
|
||||||
|
By default, the full path of the executable file is used to
|
||||||
|
determine whether two processes are instances of the same
|
||||||
|
application. You can also provide an explicit identifier string
|
||||||
|
that will be compared instead.
|
||||||
|
|
||||||
|
The application should create the QtSingleApplication object early
|
||||||
|
in the startup phase, and call isRunning() to find out if another
|
||||||
|
instance of this application is already running. If isRunning()
|
||||||
|
returns false, it means that no other instance is running, and
|
||||||
|
this instance has assumed the role as the running instance. In
|
||||||
|
this case, the application should continue with the initialization
|
||||||
|
of the application user interface before entering the event loop
|
||||||
|
with exec(), as normal.
|
||||||
|
|
||||||
|
The messageReceived() signal will be emitted when the running
|
||||||
|
application receives messages from another instance of the same
|
||||||
|
application. When a message is received it might be helpful to the
|
||||||
|
user to raise the application so that it becomes visible. To
|
||||||
|
facilitate this, QtSingleApplication provides the
|
||||||
|
setActivationWindow() function and the activateWindow() slot.
|
||||||
|
|
||||||
|
If isRunning() returns true, another instance is already
|
||||||
|
running. It may be alerted to the fact that another instance has
|
||||||
|
started by using the sendMessage() function. Also data such as
|
||||||
|
startup parameters (e.g. the name of the file the user wanted this
|
||||||
|
new instance to open) can be passed to the running instance with
|
||||||
|
this function. Then, the application should terminate (or enter
|
||||||
|
client mode).
|
||||||
|
|
||||||
|
If isRunning() returns true, but sendMessage() fails, that is an
|
||||||
|
indication that the running instance is frozen.
|
||||||
|
|
||||||
|
Here's an example that shows how to convert an existing
|
||||||
|
application to use QtSingleApplication. It is very simple and does
|
||||||
|
not make use of all QtSingleApplication's functionality (see the
|
||||||
|
examples for that).
|
||||||
|
|
||||||
|
\code
|
||||||
|
// Original
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
MyMainWidget mmw;
|
||||||
|
mmw.show();
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single instance
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
QtSingleApplication app(argc, argv);
|
||||||
|
|
||||||
|
if (app.isRunning())
|
||||||
|
return !app.sendMessage(someDataString);
|
||||||
|
|
||||||
|
MyMainWidget mmw;
|
||||||
|
app.setActivationWindow(&mmw);
|
||||||
|
mmw.show();
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Once this QtSingleApplication instance is destroyed (normally when
|
||||||
|
the process exits or crashes), when the user next attempts to run the
|
||||||
|
application this instance will not, of course, be encountered. The
|
||||||
|
next instance to call isRunning() or sendMessage() will assume the
|
||||||
|
role as the new running instance.
|
||||||
|
|
||||||
|
For console (non-GUI) applications, QtSingleCoreApplication may be
|
||||||
|
used instead of this class, to avoid the dependency on the QtGui
|
||||||
|
library.
|
||||||
|
|
||||||
|
\sa QtSingleCoreApplication
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void QtSingleApplication::sysInit(const QString &appId) {
|
||||||
|
m_activateWindow = 0;
|
||||||
|
m_peer = new QtLocalPeer(this, appId);
|
||||||
|
connect(m_peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::messageReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a QtSingleApplication object. The application identifier
|
||||||
|
will be QCoreApplication::applicationFilePath(). \a argc, \a
|
||||||
|
argv, and \a GUIenabled are passed on to the QAppliation constructor.
|
||||||
|
|
||||||
|
If you are creating a console application (i.e. setting \a
|
||||||
|
GUIenabled to false), you may consider using
|
||||||
|
QtSingleCoreApplication instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
|
||||||
|
: QApplication(argc, argv, GUIenabled) {
|
||||||
|
sysInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a QtSingleApplication object with the application
|
||||||
|
identifier \a appId. \a argc and \a argv are passed on to the
|
||||||
|
QAppliation constructor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
|
||||||
|
: QApplication(argc, argv) {
|
||||||
|
sysInit(appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a QtSingleApplication object. The application identifier
|
||||||
|
will be QCoreApplication::applicationFilePath(). \a argc, \a
|
||||||
|
argv, and \a type are passed on to the QAppliation constructor.
|
||||||
|
*/
|
||||||
|
QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type)
|
||||||
|
: QApplication(argc, argv, type) {
|
||||||
|
sysInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# if defined(Q_WS_X11)
|
||||||
|
/*!
|
||||||
|
Special constructor for X11, ref. the documentation of
|
||||||
|
QApplication's corresponding constructor. The application identifier
|
||||||
|
will be QCoreApplication::applicationFilePath(). \a dpy, \a visual,
|
||||||
|
and \a cmap are passed on to the QApplication constructor.
|
||||||
|
*/
|
||||||
|
QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||||
|
: QApplication(dpy, visual, cmap) {
|
||||||
|
sysInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Special constructor for X11, ref. the documentation of
|
||||||
|
QApplication's corresponding constructor. The application identifier
|
||||||
|
will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a
|
||||||
|
argv, \a visual, and \a cmap are passed on to the QApplication
|
||||||
|
constructor.
|
||||||
|
*/
|
||||||
|
QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||||
|
: QApplication(dpy, argc, argv, visual, cmap) {
|
||||||
|
sysInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Special constructor for X11, ref. the documentation of
|
||||||
|
QApplication's corresponding constructor. The application identifier
|
||||||
|
will be \a appId. \a dpy, \a argc, \a
|
||||||
|
argv, \a visual, and \a cmap are passed on to the QApplication
|
||||||
|
constructor.
|
||||||
|
*/
|
||||||
|
QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||||
|
: QApplication(dpy, argc, argv, visual, cmap) {
|
||||||
|
sysInit(appId);
|
||||||
|
}
|
||||||
|
# endif // Q_WS_X11
|
||||||
|
#endif // QT_VERSION < 0x050000
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns true if another instance of this application is running;
|
||||||
|
otherwise false.
|
||||||
|
|
||||||
|
This function does not find instances of this application that are
|
||||||
|
being run by a different user (on Windows: that are running in
|
||||||
|
another session).
|
||||||
|
|
||||||
|
\sa sendMessage()
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool QtSingleApplication::isRunning() {
|
||||||
|
return m_peer->isClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Tries to send the text \a message to the currently running
|
||||||
|
instance. The QtSingleApplication object in the running instance
|
||||||
|
will emit the messageReceived() signal when it receives the
|
||||||
|
message.
|
||||||
|
|
||||||
|
This function returns true if the message has been sent to, and
|
||||||
|
processed by, the current instance. If there is no instance
|
||||||
|
currently running, or if the running instance fails to process the
|
||||||
|
message within \a timeout milliseconds, this function return false.
|
||||||
|
|
||||||
|
\sa isRunning(), messageReceived()
|
||||||
|
*/
|
||||||
|
bool QtSingleApplication::sendMessage(const QString &message, int timeout) {
|
||||||
|
return m_peer->sendMessage(message, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the application identifier. Two processes with the same
|
||||||
|
identifier will be regarded as instances of the same application.
|
||||||
|
*/
|
||||||
|
QString QtSingleApplication::id() const {
|
||||||
|
return m_peer->applicationId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Sets the activation window of this application to \a aw. The
|
||||||
|
activation window is the widget that will be activated by
|
||||||
|
activateWindow(). This is typically the application's main window.
|
||||||
|
|
||||||
|
If \a activateOnMessage is true (the default), the window will be
|
||||||
|
activated automatically every time a message is received, just prior
|
||||||
|
to the messageReceived() signal being emitted.
|
||||||
|
|
||||||
|
\sa activateWindow(), messageReceived()
|
||||||
|
*/
|
||||||
|
|
||||||
|
void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) {
|
||||||
|
m_activateWindow = aw;
|
||||||
|
if (activateOnMessage)
|
||||||
|
connect(m_peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow);
|
||||||
|
else
|
||||||
|
disconnect(m_peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the applications activation window if one has been set by
|
||||||
|
calling setActivationWindow(), otherwise returns 0.
|
||||||
|
|
||||||
|
\sa setActivationWindow()
|
||||||
|
*/
|
||||||
|
QWidget* QtSingleApplication::activationWindow() const {
|
||||||
|
return m_activateWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
De-minimizes, raises, and activates this application's activation window.
|
||||||
|
This function does nothing if no activation window has been set.
|
||||||
|
|
||||||
|
This is a convenience function to show the user that this
|
||||||
|
application instance has been activated when he has tried to start
|
||||||
|
another instance.
|
||||||
|
|
||||||
|
This function should typically be called in response to the
|
||||||
|
messageReceived() signal. By default, that will happen
|
||||||
|
automatically, if an activation window has been set.
|
||||||
|
|
||||||
|
\sa setActivationWindow(), messageReceived(), initialize()
|
||||||
|
*/
|
||||||
|
void QtSingleApplication::activateWindow() {
|
||||||
|
if (m_activateWindow) {
|
||||||
|
if(this->applicationState() & Qt::ApplicationInactive)
|
||||||
|
{
|
||||||
|
m_activateWindow->setWindowState(m_activateWindow->windowState() & ~Qt::WindowMinimized);
|
||||||
|
m_activateWindow->raise();
|
||||||
|
m_activateWindow->showNormal();
|
||||||
|
m_activateWindow->activateWindow();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_activateWindow->setWindowState(m_activateWindow->windowState() & Qt::WindowMinimized);
|
||||||
|
m_activateWindow->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void QtSingleApplication::messageReceived(const QString& message)
|
||||||
|
|
||||||
|
This signal is emitted when the current instance receives a \a
|
||||||
|
message from another instance of this application.
|
||||||
|
|
||||||
|
\sa sendMessage(), setActivationWindow(), activateWindow()
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn void QtSingleApplication::initialize(bool dummy = true)
|
||||||
|
|
||||||
|
\obsolete
|
||||||
|
*/
|
|
@ -0,0 +1,109 @@
|
||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||||
|
** 2020 KylinSoft Co., Ltd.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Solutions component.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QTSINGLEAPPLICATION_H
|
||||||
|
#define QTSINGLEAPPLICATION_H
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
class QtLocalPeer;
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT)
|
||||||
|
# define QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
# elif defined(QT_QTSINGLEAPPLICATION_IMPORT)
|
||||||
|
# if defined(QT_QTSINGLEAPPLICATION_EXPORT)
|
||||||
|
# undef QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
# endif
|
||||||
|
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport)
|
||||||
|
# elif defined(QT_QTSINGLEAPPLICATION_EXPORT)
|
||||||
|
# undef QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
|
||||||
|
QtSingleApplication(const QString &id, int &argc, char **argv);
|
||||||
|
#if QT_VERSION < 0x050000
|
||||||
|
QtSingleApplication(int &argc, char **argv, Type type);
|
||||||
|
# if defined(Q_WS_X11)
|
||||||
|
QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
|
||||||
|
QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0);
|
||||||
|
QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
|
||||||
|
# endif // Q_WS_X11
|
||||||
|
#endif // QT_VERSION < 0x050000
|
||||||
|
|
||||||
|
bool isRunning();
|
||||||
|
QString id() const;
|
||||||
|
|
||||||
|
void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
|
||||||
|
QWidget* activationWindow() const;
|
||||||
|
|
||||||
|
// Obsolete:
|
||||||
|
void initialize(bool dummy = true) {
|
||||||
|
isRunning();
|
||||||
|
Q_UNUSED(dummy)
|
||||||
|
}
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
bool sendMessage(const QString &message, int timeout = 5000);
|
||||||
|
void activateWindow();
|
||||||
|
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void messageReceived(const QString &message);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void sysInit(const QString &appId = QString());
|
||||||
|
QtLocalPeer *m_peer;
|
||||||
|
QWidget *m_activateWindow;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QTSINGLEAPPLICATION_H
|
|
@ -0,0 +1,27 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
DEPENDPATH += $$PWD
|
||||||
|
QT *= network
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets
|
||||||
|
|
||||||
|
qtsingleapplication-uselib:!qtsingleapplication-buildlib {
|
||||||
|
LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME
|
||||||
|
} else {
|
||||||
|
SOURCES +=
|
||||||
|
HEADERS +=
|
||||||
|
}
|
||||||
|
|
||||||
|
win32 {
|
||||||
|
contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT
|
||||||
|
else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT
|
||||||
|
}
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/qt-local-peer.h \
|
||||||
|
$$PWD/qt-locked-file.h \
|
||||||
|
$$PWD/qt-single-application.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/qt-local-peer.cpp \
|
||||||
|
$$PWD/qt-locked-file-unix.cpp \
|
||||||
|
$$PWD/qt-single-application.cpp \
|
||||||
|
$$PWD/qt-locked-file.cpp
|
|
@ -0,0 +1,73 @@
|
||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2018-10-19T15:29:47
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += core gui x11extras dbus KWindowSystem svg concurrent network
|
||||||
|
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
|
||||||
|
TARGET = kylin-vpn
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
CONFIG += c++14 qt warn_on link_pkgconfig no_keywords
|
||||||
|
#CONFIG += release
|
||||||
|
|
||||||
|
PKGCONFIG +=gio-2.0 glib-2.0 gio-unix-2.0 libnm libnma libsecret-1 gtk+-3.0 gsettings-qt libcap kysdk-qtwidgets kysdk-waylandhelper
|
||||||
|
PKGCONFIG +=kysdk-sysinfo
|
||||||
|
|
||||||
|
INCLUDEPATH += /usr/include/KF5/NetworkManagerQt
|
||||||
|
|
||||||
|
LIBS += -L/usr/lib/ -lgsettings-qt -lX11 -lKF5NetworkManagerQt -lukui-log4qt -lkysec
|
||||||
|
|
||||||
|
target.path = /usr/bin
|
||||||
|
target.source += $$TARGET
|
||||||
|
desktop.path = /etc/xdg/autostart/
|
||||||
|
desktop.files = kylin-vpn.desktop
|
||||||
|
gschema.files = org.ukui.kylin-vpn.switch.gschema.xml
|
||||||
|
gschema.path = /usr/share/glib-2.0/schemas/
|
||||||
|
|
||||||
|
INSTALLS += target \
|
||||||
|
desktop \
|
||||||
|
gschema \
|
||||||
|
|
||||||
|
# The following define makes your compiler emit warnings if you use
|
||||||
|
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||||
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
# deprecated API in order to know how to port your code away from it.
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS
|
||||||
|
|
||||||
|
# You can also make your code fail to compile if you use deprecated APIs.
|
||||||
|
# In order to do so, uncomment the following line.
|
||||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
|
# QMAKE_CXXFLAGS += -Wno-unused-parameter
|
||||||
|
QMAKE_CPPFLAGS *= $(shell dpkg-buildflags --get CPPFLAGS)
|
||||||
|
QMAKE_CFLAGS *= $(shell dpkg-buildflags --get CFLAGS)
|
||||||
|
QMAKE_CXXFLAGS *= $(shell dpkg-buildflags --get CXXFLAGS)
|
||||||
|
QMAKE_LFLAGS *= $(shell dpkg-buildflags --get LDFLAGS)
|
||||||
|
|
||||||
|
include(singleapplication/qt-single-application.pri)
|
||||||
|
include(backend/backend.pri)
|
||||||
|
include(frontend/frontend.pri)
|
||||||
|
|
||||||
|
RESOURCES += \
|
||||||
|
vpnqrc.qrc
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
main.cpp
|
||||||
|
|
||||||
|
unix {
|
||||||
|
UI_DIR = .ui
|
||||||
|
MOC_DIR = .moc
|
||||||
|
OBJECTS_DIR = .obj
|
||||||
|
}
|
||||||
|
|
||||||
|
DISTFILES += \
|
||||||
|
org.ukui.kylin-vpn.switch.gschema.xml
|
||||||
|
|
||||||
|
TRANSLATIONS += \
|
||||||
|
translations/kylin-vpn_zh_CN.ts \
|
||||||
|
translations/kylin-vpn_bo_CN.ts
|
|
@ -0,0 +1,147 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="bo_CN">
|
||||||
|
<context>
|
||||||
|
<name>SinglePage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/singlepage.cpp" line="73"/>
|
||||||
|
<source>Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/singlepage.cpp" line="121"/>
|
||||||
|
<source>Kylin VPN</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/singlepage.cpp" line="124"/>
|
||||||
|
<source>kylin vpn applet desktop message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnListItem</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="61"/>
|
||||||
|
<source>Not connected</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="160"/>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="176"/>
|
||||||
|
<source>Disconnect</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="162"/>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="174"/>
|
||||||
|
<source>Connect</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/vpnpage.cpp" line="259"/>
|
||||||
|
<source>VPN</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/vpnpage.cpp" line="270"/>
|
||||||
|
<source>VPN Settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnAddPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="15"/>
|
||||||
|
<source>create VPN</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="47"/>
|
||||||
|
<source>VPN Type</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="75"/>
|
||||||
|
<source>VPN Name</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="81"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="103"/>
|
||||||
|
<source>Required</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="98"/>
|
||||||
|
<source>VPN Server</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnConfigPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="35"/>
|
||||||
|
<source>VPN Type</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnDetail</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="15"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="27"/>
|
||||||
|
<source>VPN</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="28"/>
|
||||||
|
<source>IPv4</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="30"/>
|
||||||
|
<source>IPv6</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="32"/>
|
||||||
|
<source>Advanced</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnDetailPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetailpage.cpp" line="12"/>
|
||||||
|
<source>VPN</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetailpage.cpp" line="41"/>
|
||||||
|
<source>Auto Connection</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetailpage.cpp" line="53"/>
|
||||||
|
<source>Confirm</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetailpage.cpp" line="56"/>
|
||||||
|
<source>Cancel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnObject</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpnobject.cpp" line="31"/>
|
||||||
|
<source>vpn tool</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
|
@ -0,0 +1,838 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="zh_CN">
|
||||||
|
<context>
|
||||||
|
<name>SinglePage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/singlepage.cpp" line="73"/>
|
||||||
|
<source>Settings</source>
|
||||||
|
<translation>设置</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/singlepage.cpp" line="121"/>
|
||||||
|
<source>Kylin VPN</source>
|
||||||
|
<translation>VPN工具</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/singlepage.cpp" line="124"/>
|
||||||
|
<source>kylin vpn applet desktop message</source>
|
||||||
|
<translation>vpn配置桌面提示</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnAdvancedPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="791"/>
|
||||||
|
<source>MPPE encryption algorithm:</source>
|
||||||
|
<translation>MPPE加密算法:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="792"/>
|
||||||
|
<source>Use Stateful encryption</source>
|
||||||
|
<translation>使用有状态加密</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="793"/>
|
||||||
|
<source>Send PPP echo packets</source>
|
||||||
|
<translation>发送PPP回显包</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="794"/>
|
||||||
|
<source>Authentication Mode:</source>
|
||||||
|
<translation>认证方式:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="795"/>
|
||||||
|
<source>PAP authentication</source>
|
||||||
|
<translation>PAP认证</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="796"/>
|
||||||
|
<source>CHAP authentication</source>
|
||||||
|
<translation>CHAP认证</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="797"/>
|
||||||
|
<source>MSCHAP authentication</source>
|
||||||
|
<translation>MSCHAP认证</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="798"/>
|
||||||
|
<source>MSCHAP2 authentication</source>
|
||||||
|
<translation>MSCHAP2认证</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="799"/>
|
||||||
|
<source>EAP authentication</source>
|
||||||
|
<translation>EAP认证</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="800"/>
|
||||||
|
<source>Compression Mode:</source>
|
||||||
|
<translation>压缩方式:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="801"/>
|
||||||
|
<source>Allow BSD data compression</source>
|
||||||
|
<translation>允许BSD压缩</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="802"/>
|
||||||
|
<source>Allow Default data compression</source>
|
||||||
|
<translation>允许Default压缩</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="803"/>
|
||||||
|
<source>Allow TCP header compression</source>
|
||||||
|
<translation>允许TCP头压缩</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="804"/>
|
||||||
|
<source>Use protocol field compression negotiation</source>
|
||||||
|
<translation>使用协议域压缩协商</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="805"/>
|
||||||
|
<source>Use Address/Control compression</source>
|
||||||
|
<translation>使用地址/控制压缩</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="811"/>
|
||||||
|
<source>All Available</source>
|
||||||
|
<translation>任意</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="812"/>
|
||||||
|
<source>128-bit</source>
|
||||||
|
<translation>128位</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="813"/>
|
||||||
|
<source>40-bit</source>
|
||||||
|
<translation>40位</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1010"/>
|
||||||
|
<source>Use custom gateway port</source>
|
||||||
|
<translation>使用自定义网关端口</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1011"/>
|
||||||
|
<source>Use compression</source>
|
||||||
|
<translation>使用压缩</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1012"/>
|
||||||
|
<source>Use a TCP connection</source>
|
||||||
|
<translation>使用TCP连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1013"/>
|
||||||
|
<source>Set virtual device type</source>
|
||||||
|
<translation>设置虚拟设备类型</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1014"/>
|
||||||
|
<source>Set virtual device name</source>
|
||||||
|
<translation>设置虚拟设备名称</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1015"/>
|
||||||
|
<source>Limit TCP Maximum Segment Size(MSS)</source>
|
||||||
|
<translation>限制TCP最大段尺寸(MSS)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1016"/>
|
||||||
|
<source>Randomize remote hosts</source>
|
||||||
|
<translation>随机化远程主机</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1017"/>
|
||||||
|
<source>IPv6 tun link</source>
|
||||||
|
<translation>IPv6 tun连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1018"/>
|
||||||
|
<source>Specify ping interval</source>
|
||||||
|
<translation>指定Ping周期</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1019"/>
|
||||||
|
<source>Specify exit or restart ping</source>
|
||||||
|
<translation>指定退出或重启的Ping</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1020"/>
|
||||||
|
<source>Specify max routes</source>
|
||||||
|
<translation>指定路由上限</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1021"/>
|
||||||
|
<source>Infinite retry on error</source>
|
||||||
|
<translation>出错时无限重试</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1022"/>
|
||||||
|
<source>Use custom key size</source>
|
||||||
|
<translation>使用自定义密钥大小</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1023"/>
|
||||||
|
<source>Choose</source>
|
||||||
|
<translation>选择</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1026"/>
|
||||||
|
<source>Use custom renegotiation interval</source>
|
||||||
|
<translation>使用自定义重协商间隔</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1028"/>
|
||||||
|
<source>Use custom tunnel Maximum Transmission Umit(MTU)</source>
|
||||||
|
<translation>使用自定义隧道最大单元传输(MTU)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1030"/>
|
||||||
|
<source>Use custom UDP fragment size</source>
|
||||||
|
<translation>使用自定义UDP分片大小</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1032"/>
|
||||||
|
<source>Accept authenticated packets from any address (Float)</source>
|
||||||
|
<translation>接受来自任何地址(Float)已通过身份验证的数据包</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1034"/>
|
||||||
|
<source>Subject Match</source>
|
||||||
|
<translation>主题匹配</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1035"/>
|
||||||
|
<source>Key File</source>
|
||||||
|
<translation>密钥文件</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1036"/>
|
||||||
|
<source>Key Direction</source>
|
||||||
|
<translation>密钥方向</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1038"/>
|
||||||
|
<source>Server Address</source>
|
||||||
|
<translation>服务器地址</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1039"/>
|
||||||
|
<source>Port</source>
|
||||||
|
<translation>端口</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1040"/>
|
||||||
|
<source>Proxy USername</source>
|
||||||
|
<translation>代理用户名</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1041"/>
|
||||||
|
<source>Proxy Password</source>
|
||||||
|
<translation>代理密码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1043"/>
|
||||||
|
<source>General</source>
|
||||||
|
<translation>常规</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1044"/>
|
||||||
|
<source>TLS settings</source>
|
||||||
|
<translation>TLS设置</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1045"/>
|
||||||
|
<source>Server Certificate Check</source>
|
||||||
|
<translation>服务器证书检验</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1047"/>
|
||||||
|
<source>Use the previous authentication end (server) certificate</source>
|
||||||
|
<translation>使用前面验证端(服务器)证书</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1049"/>
|
||||||
|
<source>Verify peer (server) certificate nsCertType specification</source>
|
||||||
|
<translation>验证对等点(服务器)证书nsCertType指定</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1050"/>
|
||||||
|
<source>Mode</source>
|
||||||
|
<translation>模式</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1051"/>
|
||||||
|
<source>Proxies</source>
|
||||||
|
<translation>代理</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1052"/>
|
||||||
|
<source>Proxy Type</source>
|
||||||
|
<translation>代理类型</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1053"/>
|
||||||
|
<source>Security</source>
|
||||||
|
<translation>安全</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1054"/>
|
||||||
|
<source>HMAC Authentication</source>
|
||||||
|
<translation>HMAC认证</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1064"/>
|
||||||
|
<source>Input content</source>
|
||||||
|
<translation>输入内容</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1066"/>
|
||||||
|
<source>No</source>
|
||||||
|
<translation>否</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1070"/>
|
||||||
|
<source>Self-adaption</source>
|
||||||
|
<translation>自适应</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1071"/>
|
||||||
|
<source>Automatic</source>
|
||||||
|
<translation>自动</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1076"/>
|
||||||
|
<source>Exit</source>
|
||||||
|
<translation>退出</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1077"/>
|
||||||
|
<source>Restart</source>
|
||||||
|
<translation>重启</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1079"/>
|
||||||
|
<source>Don't verify certificate identification</source>
|
||||||
|
<translation>不验证证书标识</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1080"/>
|
||||||
|
<source>Verify the entire subject exactly</source>
|
||||||
|
<translation>确切地验证整个主题</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1081"/>
|
||||||
|
<source>Verify name exactly</source>
|
||||||
|
<translation>精确验证名称</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1082"/>
|
||||||
|
<source>Verify name by prefix</source>
|
||||||
|
<translation>按前缀验证名称</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1084"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1087"/>
|
||||||
|
<source>Server</source>
|
||||||
|
<translation>服务器</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1085"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1088"/>
|
||||||
|
<source>Client</source>
|
||||||
|
<translation>客户端</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1090"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1094"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1103"/>
|
||||||
|
<source>None</source>
|
||||||
|
<translation>无</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1091"/>
|
||||||
|
<source>TLS-Certification</source>
|
||||||
|
<translation>TLS-认证</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1092"/>
|
||||||
|
<source>TLS-Encryption</source>
|
||||||
|
<translation>TLS-加密</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1098"/>
|
||||||
|
<source>Not Required</source>
|
||||||
|
<translation>不需要</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1102"/>
|
||||||
|
<source>Default</source>
|
||||||
|
<translation>默认</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1176"/>
|
||||||
|
<source>Options:</source>
|
||||||
|
<translation>选项:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1179"/>
|
||||||
|
<source>Request an inner IP address</source>
|
||||||
|
<translation>请求内部IP地址</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1180"/>
|
||||||
|
<source>Enforce UDP encapsulation</source>
|
||||||
|
<translation>强制UDP封装</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1181"/>
|
||||||
|
<source>Use IP compression</source>
|
||||||
|
<translation>使用IP压缩</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnadvancedpage.cpp" line="1182"/>
|
||||||
|
<source>Enable custom password suggestions</source>
|
||||||
|
<translation>启用自定义密码建议</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnConfigPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="312"/>
|
||||||
|
<source>Type</source>
|
||||||
|
<translation>类型</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="313"/>
|
||||||
|
<source>Name</source>
|
||||||
|
<translation>名称</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="314"/>
|
||||||
|
<source>Static Key</source>
|
||||||
|
<translation>静态密钥</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="315"/>
|
||||||
|
<source>Local IP</source>
|
||||||
|
<translation>本地IP地址</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="316"/>
|
||||||
|
<source>Remote IP</source>
|
||||||
|
<translation>远程IP地址</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="317"/>
|
||||||
|
<source>PIN Code</source>
|
||||||
|
<translation>PIN码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="318"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="790"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="797"/>
|
||||||
|
<source>Password</source>
|
||||||
|
<translation>密码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="319"/>
|
||||||
|
<source>NT Domain</source>
|
||||||
|
<translation>NT域</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="321"/>
|
||||||
|
<source>Server Address</source>
|
||||||
|
<translation>服务器地址</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="322"/>
|
||||||
|
<source>Authentication Mode</source>
|
||||||
|
<translation>认证方式</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="323"/>
|
||||||
|
<source>CA Certificate</source>
|
||||||
|
<translation>CA证书</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="324"/>
|
||||||
|
<source>User Certificate</source>
|
||||||
|
<translation>用户证书</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="325"/>
|
||||||
|
<source>Key Direction</source>
|
||||||
|
<translation>密钥方向</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="326"/>
|
||||||
|
<source>Private Key</source>
|
||||||
|
<translation>私钥</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="327"/>
|
||||||
|
<source>Private Key Password</source>
|
||||||
|
<translation>私有密钥密码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="328"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="330"/>
|
||||||
|
<source>Password Options</source>
|
||||||
|
<translation>密码选项</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="329"/>
|
||||||
|
<source>Username</source>
|
||||||
|
<translation>用户名</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="333"/>
|
||||||
|
<source>Notice:
|
||||||
|
If key direction is used, it must be opposite to the VPN side used. If '1' is used, the connection must use '0'. If you are not sure which value to use, please contact your system administrator.</source>
|
||||||
|
<translation>注意:
|
||||||
|
如果使用了密钥方向,它必须和使用的VPN端相反。如果使用了“1”,连接必须要使用“0”。如果不确定使用哪个值,请联系您的系统管理员。</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="340"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="341"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="342"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="343"/>
|
||||||
|
<source>Choose</source>
|
||||||
|
<translation>选择</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="350"/>
|
||||||
|
<source>None</source>
|
||||||
|
<translation>无</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="354"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="360"/>
|
||||||
|
<source>Save password only for this user</source>
|
||||||
|
<translation>仅对当前用户保存密码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="355"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="361"/>
|
||||||
|
<source>Save password for all users</source>
|
||||||
|
<translation>为所有用户保存密码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="356"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="362"/>
|
||||||
|
<source>Ask password every time</source>
|
||||||
|
<translation>每次都询问</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="357"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="363"/>
|
||||||
|
<source>Don't require a password</source>
|
||||||
|
<translation>不需要密码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="366"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="367"/>
|
||||||
|
<source>Required</source>
|
||||||
|
<translation>必填</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="795"/>
|
||||||
|
<source>Certificate(TLS)</source>
|
||||||
|
<translation>证书(TLS)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="796"/>
|
||||||
|
<source>Static key</source>
|
||||||
|
<translation>静态密钥</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="798"/>
|
||||||
|
<source>Password and certificate(TLS)</source>
|
||||||
|
<translation>密码和证书(TLS)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="807"/>
|
||||||
|
<source>Certificate/Private key</source>
|
||||||
|
<translation>证书/私钥</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="808"/>
|
||||||
|
<source>Certificate/ssh-agent</source>
|
||||||
|
<translation>证书/ssh-agent</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="809"/>
|
||||||
|
<source>Smart card</source>
|
||||||
|
<translation>智能卡</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="864"/>
|
||||||
|
<source>Choose a private key</source>
|
||||||
|
<translation>选择私钥</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="866"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="905"/>
|
||||||
|
<source>Key Files (*.key *.pem *.der *.p12 *.pfx)</source>
|
||||||
|
<translation>私钥文件(*.key *.pem *.der *.p12 *.pfx)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="877"/>
|
||||||
|
<source>Choose a CA certificate</source>
|
||||||
|
<translation>选择CA证书</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="879"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="892"/>
|
||||||
|
<source>CA Files (*.pem *.der *.p12 *.crt *.cer *.pfx)</source>
|
||||||
|
<translation>CA文件 (*.pem *.der *.p12 *.crt *.cer *.pfx)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="890"/>
|
||||||
|
<source>Choose a User certificate</source>
|
||||||
|
<translation>选择用户证书</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnconfigpage.cpp" line="903"/>
|
||||||
|
<source>Choose a Static key</source>
|
||||||
|
<translation>选择静态密钥</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnIpv4Page</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="152"/>
|
||||||
|
<source>IPv4 Config</source>
|
||||||
|
<translation>IPv4配置</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="153"/>
|
||||||
|
<source>Address</source>
|
||||||
|
<translation>地址</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="154"/>
|
||||||
|
<source>Netmask</source>
|
||||||
|
<translation>子网掩码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="155"/>
|
||||||
|
<source>Default Gateway</source>
|
||||||
|
<translation>默认网关</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="156"/>
|
||||||
|
<source>DNS Server</source>
|
||||||
|
<translation>DNS服务器</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="157"/>
|
||||||
|
<source>Search Domain</source>
|
||||||
|
<translation>搜索域</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="158"/>
|
||||||
|
<source>DHCP Client ID</source>
|
||||||
|
<translation>DHCP客户端ID</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="160"/>
|
||||||
|
<source>Auto(DHCP)</source>
|
||||||
|
<translation>自动(DHCP)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv4page.cpp" line="161"/>
|
||||||
|
<source>Manual</source>
|
||||||
|
<translation>手动</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnIpv6Page</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv6page.cpp" line="141"/>
|
||||||
|
<source>IPv6 Config</source>
|
||||||
|
<translation>IPv6配置</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv6page.cpp" line="142"/>
|
||||||
|
<source>Address</source>
|
||||||
|
<translation>地址</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv6page.cpp" line="143"/>
|
||||||
|
<source>Netmask</source>
|
||||||
|
<translation>子网掩码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv6page.cpp" line="144"/>
|
||||||
|
<source>Default Gateway</source>
|
||||||
|
<translation>默认网关</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv6page.cpp" line="145"/>
|
||||||
|
<source>DNS Server</source>
|
||||||
|
<translation>DNS服务器</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv6page.cpp" line="146"/>
|
||||||
|
<source>Search Domain</source>
|
||||||
|
<translation>搜索域</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv6page.cpp" line="148"/>
|
||||||
|
<source>Auto(DHCP)</source>
|
||||||
|
<translation>自动(DHCP)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnipv6page.cpp" line="149"/>
|
||||||
|
<source>Manual</source>
|
||||||
|
<translation>手动</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnListItem</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="61"/>
|
||||||
|
<source>Not connected</source>
|
||||||
|
<translation>未连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="160"/>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="176"/>
|
||||||
|
<source>Disconnect</source>
|
||||||
|
<translation>断开</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="162"/>
|
||||||
|
<location filename="../frontend/list-items/vpnlistitem.cpp" line="174"/>
|
||||||
|
<source>Connect</source>
|
||||||
|
<translation>连接</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VpnPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/vpnpage.cpp" line="259"/>
|
||||||
|
<source>VPN</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/single-pages/vpnpage.cpp" line="270"/>
|
||||||
|
<source>VPN Settings</source>
|
||||||
|
<translation>VPN设置</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnAddPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="15"/>
|
||||||
|
<source>create VPN</source>
|
||||||
|
<translation>创建VPN</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="47"/>
|
||||||
|
<source>VPN Type</source>
|
||||||
|
<translation>VPN类型</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="75"/>
|
||||||
|
<source>VPN Name</source>
|
||||||
|
<translation>VPN名称</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="81"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="103"/>
|
||||||
|
<source>Required</source>
|
||||||
|
<translation>必填</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpnaddpage.cpp" line="98"/>
|
||||||
|
<source>VPN Server</source>
|
||||||
|
<translation>服务器地址</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnConfigPage</name>
|
||||||
|
<message>
|
||||||
|
<source>VPN Type</source>
|
||||||
|
<translation type="vanished">VPN类型</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnDetail</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="61"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="145"/>
|
||||||
|
<source>VPN</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="146"/>
|
||||||
|
<source>IPv4</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="148"/>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="225"/>
|
||||||
|
<source>IPv6</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="153"/>
|
||||||
|
<source>Advanced</source>
|
||||||
|
<translation>高级</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="158"/>
|
||||||
|
<source>Auto Connection</source>
|
||||||
|
<translation>自动连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="159"/>
|
||||||
|
<source>Cancel</source>
|
||||||
|
<translation>取消</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetail.cpp" line="160"/>
|
||||||
|
<source>Confirm</source>
|
||||||
|
<translation>确定</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnDetailPage</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetailpage.cpp" line="12"/>
|
||||||
|
<source>VPN</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetailpage.cpp" line="41"/>
|
||||||
|
<source>Auto Connection</source>
|
||||||
|
<translation>自动连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetailpage.cpp" line="53"/>
|
||||||
|
<source>Confirm</source>
|
||||||
|
<translation>确定</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpndetails/vpndetailpage.cpp" line="56"/>
|
||||||
|
<source>Cancel</source>
|
||||||
|
<translation>取消</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>vpnObject</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../frontend/vpnobject.cpp" line="31"/>
|
||||||
|
<source>vpn tool</source>
|
||||||
|
<translation>VPN工具</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>translations/kylin-vpn_zh_CN.qm</file>
|
||||||
|
<file>translations/kylin-vpn_bo_CN.qm</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
|
@ -21,6 +21,7 @@ HEADERS += \
|
||||||
$$PWD/kywirelessconnectoperation.h \
|
$$PWD/kywirelessconnectoperation.h \
|
||||||
$$PWD/kywirelessnetitem.h \
|
$$PWD/kywirelessnetitem.h \
|
||||||
$$PWD/kywirelessnetresource.h \
|
$$PWD/kywirelessnetresource.h \
|
||||||
|
$$PWD/kyvpnconnectoperation.h \
|
||||||
$$PWD/nm-macros-internal.h
|
$$PWD/nm-macros-internal.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -42,5 +43,6 @@ SOURCES += \
|
||||||
$$PWD/kylinwiredconnectoperation.cpp \
|
$$PWD/kylinwiredconnectoperation.cpp \
|
||||||
$$PWD/kywirelessconnectoperation.cpp \
|
$$PWD/kywirelessconnectoperation.cpp \
|
||||||
$$PWD/kywirelessnetitem.cpp \
|
$$PWD/kywirelessnetitem.cpp \
|
||||||
|
$$PWD/kyvpnconnectoperation.cpp \
|
||||||
$$PWD/kywirelessnetresource.cpp
|
$$PWD/kywirelessnetresource.cpp
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,36 @@ static bool subLanListSort(const KyConnectItem* info1, const KyConnectItem* info
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool subVpnListSort(const KyConnectItem* info1, const KyConnectItem* info2)
|
||||||
|
{
|
||||||
|
if (info1->m_connectState != info2->m_connectState) {
|
||||||
|
if (info1->m_connectState == 2) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info2->m_connectState == 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString name1 = info1->m_connectName;
|
||||||
|
QString name2 = info2->m_connectName;
|
||||||
|
bool result = true;
|
||||||
|
if (QString::compare(name1, name2, Qt::CaseInsensitive) > 0) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void lanListSort(QList<KyConnectItem *> &list)
|
static void lanListSort(QList<KyConnectItem *> &list)
|
||||||
{
|
{
|
||||||
qSort(list.begin(), list.end(), subLanListSort);
|
qSort(list.begin(), list.end(), subLanListSort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vpnListSort(QList<KyConnectItem *> &list)
|
||||||
|
{
|
||||||
|
qSort(list.begin(), list.end(), subVpnListSort);
|
||||||
|
}
|
||||||
|
|
||||||
KyConnectResourse::KyConnectResourse(QObject *parent) : QObject(parent)
|
KyConnectResourse::KyConnectResourse(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
m_networkResourceInstance = KyNetworkResourceManager::getInstance();
|
m_networkResourceInstance = KyNetworkResourceManager::getInstance();
|
||||||
|
@ -200,6 +225,61 @@ KyConnectItem * KyConnectResourse::getConnectionItemByUuid(QString connectUuid,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KyConnectResourse::getVpnAndVirtualConnections(QList<KyConnectItem *> &connectItemList)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
NetworkManager::Connection::List connectList;
|
||||||
|
|
||||||
|
qDebug()<<"[KyConnectResourse]"<<"get vpn && virtual connections";
|
||||||
|
|
||||||
|
connectList.clear();
|
||||||
|
connectList = m_networkResourceInstance->getConnectList();
|
||||||
|
|
||||||
|
if (connectList.empty()) {
|
||||||
|
qWarning()<<"[KyConnectResourse]"<<"get vpn connections failed, the connect list is empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkManager::Connection::Ptr connectPtr = nullptr;
|
||||||
|
for (index = 0; index < connectList.size(); index++) {
|
||||||
|
connectPtr = connectList.at(index);
|
||||||
|
if (connectPtr.isNull()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (NetworkManager::ConnectionSettings::ConnectionType::Vpn != connectPtr->settings()->connectionType()
|
||||||
|
&& NetworkManager::ConnectionSettings::ConnectionType::Bond != connectPtr->settings()->connectionType()
|
||||||
|
&& NetworkManager::ConnectionSettings::ConnectionType::Bridge != connectPtr->settings()->connectionType()
|
||||||
|
&& NetworkManager::ConnectionSettings::ConnectionType::Vlan != connectPtr->settings()->connectionType()
|
||||||
|
&& NetworkManager::ConnectionSettings::ConnectionType::Team != connectPtr->settings()->connectionType()
|
||||||
|
&& NetworkManager::ConnectionSettings::ConnectionType::IpTunnel != connectPtr->settings()->connectionType()
|
||||||
|
&& NetworkManager::ConnectionSettings::ConnectionType::Wired != connectPtr->settings()->connectionType()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
NetworkManager::Device::Ptr devicePtr = nullptr;
|
||||||
|
devicePtr = m_networkResourceInstance->findDeviceInterface(connectPtr->settings()->interfaceName());
|
||||||
|
if (NetworkManager::ConnectionSettings::ConnectionType::Wired == connectPtr->settings()->connectionType()) {
|
||||||
|
if (devicePtr == nullptr || !devicePtr->udi().startsWith("/sys/devices/virtual/net")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString devName = "";
|
||||||
|
if (!devicePtr.isNull()) {
|
||||||
|
devName = devicePtr->interfaceName();
|
||||||
|
}
|
||||||
|
|
||||||
|
KyConnectItem *connectItem = getConnectionItem(connectPtr, devName);
|
||||||
|
if (nullptr != connectItem) {
|
||||||
|
connectItemList << connectItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectPtr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connectItemList.size() > 1) {
|
||||||
|
vpnListSort(connectItemList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KyConnectResourse::getConnectionList(QString deviceName,
|
void KyConnectResourse::getConnectionList(QString deviceName,
|
||||||
NetworkManager::ConnectionSettings::ConnectionType connectionType,
|
NetworkManager::ConnectionSettings::ConnectionType connectionType,
|
||||||
QList<KyConnectItem *> &connectItemList)
|
QList<KyConnectItem *> &connectItemList)
|
||||||
|
@ -748,6 +828,35 @@ void KyConnectResourse::getApConnections(QList<KyApConnectItem *> &apConnectItem
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KyConnectResourse::isVirtualConncection(QString uuid)
|
||||||
|
{
|
||||||
|
NetworkManager::Connection::Ptr connectPtr = nullptr;
|
||||||
|
|
||||||
|
connectPtr = m_networkResourceInstance->getConnect(uuid);
|
||||||
|
if (nullptr == connectPtr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NetworkManager::ConnectionSettings::ConnectionType::Vpn == connectPtr->settings()->connectionType()
|
||||||
|
||NetworkManager::ConnectionSettings::ConnectionType::Bond == connectPtr->settings()->connectionType()
|
||||||
|
||NetworkManager::ConnectionSettings::ConnectionType::Bridge == connectPtr->settings()->connectionType()
|
||||||
|
||NetworkManager::ConnectionSettings::ConnectionType::Vlan == connectPtr->settings()->connectionType()
|
||||||
|
||NetworkManager::ConnectionSettings::ConnectionType::Team == connectPtr->settings()->connectionType()
|
||||||
|
||NetworkManager::ConnectionSettings::ConnectionType::IpTunnel == connectPtr->settings()->connectionType()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkManager::Device::Ptr devicePtr = nullptr;
|
||||||
|
devicePtr = m_networkResourceInstance->findDeviceInterface(connectPtr->settings()->interfaceName());
|
||||||
|
if (devicePtr.isNull()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (devicePtr->udi().startsWith("/sys/devices/virtual/net")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool KyConnectResourse::isWiredConnection(QString uuid)
|
bool KyConnectResourse::isWiredConnection(QString uuid)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
KyConnectItem *getConnectionItemByUuid(QString connectUuid);
|
KyConnectItem *getConnectionItemByUuid(QString connectUuid);
|
||||||
KyConnectItem *getConnectionItemByUuidWithoutActivateChecking(QString connectUuid);
|
KyConnectItem *getConnectionItemByUuidWithoutActivateChecking(QString connectUuid);
|
||||||
KyConnectItem *getConnectionItemByUuid(QString connectUuid, QString deviceName);
|
KyConnectItem *getConnectionItemByUuid(QString connectUuid, QString deviceName);
|
||||||
|
void getVpnAndVirtualConnections(QList<KyConnectItem *> &connectItemList);
|
||||||
void getConnectionList(QString deviceName,
|
void getConnectionList(QString deviceName,
|
||||||
NetworkManager::ConnectionSettings::ConnectionType connectionType,
|
NetworkManager::ConnectionSettings::ConnectionType connectionType,
|
||||||
QList<KyConnectItem *> &connectItemList);
|
QList<KyConnectItem *> &connectItemList);
|
||||||
|
@ -55,6 +56,7 @@ public:
|
||||||
bool getInterfaceByUuid(QString &deviceName, const QString connUuid);
|
bool getInterfaceByUuid(QString &deviceName, const QString connUuid);
|
||||||
void getConnectivity(NetworkManager::Connectivity &connectivity);
|
void getConnectivity(NetworkManager::Connectivity &connectivity);
|
||||||
|
|
||||||
|
bool isVirtualConncection(QString uuid);
|
||||||
bool isWiredConnection(QString uuid);
|
bool isWiredConnection(QString uuid);
|
||||||
bool isWirelessConnection(QString uuid);
|
bool isWirelessConnection(QString uuid);
|
||||||
bool isActivatedConnection(QString uuid);
|
bool isActivatedConnection(QString uuid);
|
||||||
|
|
|
@ -165,61 +165,6 @@ void KyWiredConnectOperation::deactivateWiredConnection(const QString activeConn
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyWiredConnectOperation::activateVpnConnection(const QString connectUuid)
|
|
||||||
{
|
|
||||||
QString connectPath = "";
|
|
||||||
QString deviceIdentifier = "";
|
|
||||||
QString connectName = "";
|
|
||||||
//QString deviceName = "";
|
|
||||||
QString specificObject = "";
|
|
||||||
NetworkManager::Connection::Ptr connectPtr = nullptr;
|
|
||||||
|
|
||||||
qDebug()<<"it will activate vpn connect"<<connectUuid;
|
|
||||||
connectPtr = NetworkManager::findConnectionByUuid(connectUuid);
|
|
||||||
if (nullptr == connectPtr) {
|
|
||||||
QString errorMessage = "the connect uuid " + connectUuid + "is not exsit";
|
|
||||||
qWarning()<<errorMessage;
|
|
||||||
Q_EMIT activateConnectionError(errorMessage);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NetworkManager::ConnectionSettings::Vpn != connectPtr->settings()->connectionType()) {
|
|
||||||
QString errorMessage = tr("the connect type is")
|
|
||||||
+ connectPtr->settings()->connectionType()
|
|
||||||
+ tr(", but it is not vpn");
|
|
||||||
qWarning()<<errorMessage;
|
|
||||||
Q_EMIT activateConnectionError(errorMessage);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connectPath = connectPtr->path();
|
|
||||||
connectName = connectPtr->name();
|
|
||||||
//deviceName = connectPtr->settings()->interfaceName();
|
|
||||||
specificObject = deviceIdentifier = QStringLiteral("/");
|
|
||||||
|
|
||||||
qDebug() <<"active wired connect: path "<< connectPath
|
|
||||||
<< "device identify " << deviceIdentifier
|
|
||||||
<< "connect name " << connectName
|
|
||||||
// << "device name" << deviceName
|
|
||||||
<< "specific parameter"<< specificObject;
|
|
||||||
|
|
||||||
QDBusPendingCallWatcher * watcher;
|
|
||||||
watcher = new QDBusPendingCallWatcher{NetworkManager::activateConnection(connectPath, deviceIdentifier, specificObject), this};
|
|
||||||
connect(watcher, &QDBusPendingCallWatcher::finished, [this, connectName] (QDBusPendingCallWatcher * watcher) {
|
|
||||||
if (watcher->isError() || !watcher->isValid()) {
|
|
||||||
QString errorMessage = tr("activate vpn connection failed: ") + watcher->error().message();
|
|
||||||
qWarning()<<errorMessage;
|
|
||||||
Q_EMIT this->activateConnectionError(errorMessage);
|
|
||||||
} else {
|
|
||||||
qWarning()<<"active vpn connect complete.";
|
|
||||||
}
|
|
||||||
|
|
||||||
watcher->deleteLater();
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KyWiredConnectOperation::saveActiveConnection(QString &deviceName, QString &connectUuid)
|
void KyWiredConnectOperation::saveActiveConnection(QString &deviceName, QString &connectUuid)
|
||||||
{
|
{
|
||||||
QSettings *p_settings = new QSettings(WIRED_NETWORK_STATE_CONF_FILE, QSettings::IniFormat);
|
QSettings *p_settings = new QSettings(WIRED_NETWORK_STATE_CONF_FILE, QSettings::IniFormat);
|
||||||
|
|
|
@ -45,7 +45,6 @@ public:
|
||||||
void updateWiredConnect(const QString &connectUuid, const KyConnectSetting &connectSettingsInfo);
|
void updateWiredConnect(const QString &connectUuid, const KyConnectSetting &connectSettingsInfo);
|
||||||
void deleteWiredConnect(const QString &connectUuid);
|
void deleteWiredConnect(const QString &connectUuid);
|
||||||
void activateWiredConnection(const QString connectUuid, const QString devName);
|
void activateWiredConnection(const QString connectUuid, const QString devName);
|
||||||
void activateVpnConnection(const QString connectUuid);
|
|
||||||
void deactivateWiredConnection(const QString activeConnectName, const QString &activeConnectUuid);
|
void deactivateWiredConnection(const QString activeConnectName, const QString &activeConnectUuid);
|
||||||
|
|
||||||
int closeWiredNetworkWithDevice(QString deviceName);
|
int closeWiredNetworkWithDevice(QString deviceName);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,515 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Tianjin KYLIN Information Technology 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef KYVPNCONNECTOPERATION_H
|
||||||
|
#define KYVPNCONNECTOPERATION_H
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "kylinnetworkresourcemanager.h"
|
||||||
|
#include "kylinconnectsetting.h"
|
||||||
|
#include "kylinconnectoperation.h"
|
||||||
|
#include "kylinconnectresource.h"
|
||||||
|
#include "kyenterpricesettinginfo.h"
|
||||||
|
#include <NetworkManagerQt/VpnSetting>
|
||||||
|
|
||||||
|
|
||||||
|
#define VPN_SERVERTYPE_L2TP "org.freedesktop.NetworkManager.l2tp"
|
||||||
|
#define VPN_SERVERTYPE_PPTP "org.freedesktop.NetworkManager.pptp"
|
||||||
|
#define VPN_SERVERTYPE_OPENVPN "org.freedesktop.NetworkManager.openvpn"
|
||||||
|
#define VPN_SERVERTYPE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan"
|
||||||
|
|
||||||
|
#define KYVPN_VPN_KEY "vpn"
|
||||||
|
|
||||||
|
#define KYVPN_GATEWAY_KEY "gateway"
|
||||||
|
#define KYVPN_REMOTE_KEY "remote"
|
||||||
|
#define KYVPN_ADDRESS_KEY "address"
|
||||||
|
|
||||||
|
#define KYVPN_USER_KEY "user"
|
||||||
|
#define KYVPN_PASSWD_KEY "password"
|
||||||
|
#define KYVPN_SECRETS_KEY "secrets"
|
||||||
|
#define KYVPN_PASSWDFLAGS_KEY "password-flags"
|
||||||
|
|
||||||
|
#define KYVPN_REFUSEPAP_KEY "refuse-pap"
|
||||||
|
#define KYVPN_REFUSECHAP_KEY "refuse-chap"
|
||||||
|
#define KYVPN_REFUSEEAP_KEY "refuse-eap"
|
||||||
|
#define KYVPN_REFUSEMSCHAP_KEY "refuse-mschap"
|
||||||
|
#define KYVPN_REFUSEMSCHAPV2_KEY "refuse-mschapv2"
|
||||||
|
|
||||||
|
#define KYVPN_NOVJCOMP_KEY "no-vj-comp"
|
||||||
|
#define KYVPN_NOACCOMP_KEY "noaccomp"
|
||||||
|
#define KYVPN_NOBSDCOMP_KEY "nobsdcomp"
|
||||||
|
#define KYVPN_NODEFLATE_KEY "nodeflate"
|
||||||
|
#define KYVPN_NOPCOMP_KEY "nopcomp"
|
||||||
|
|
||||||
|
#define KYVPN_DOMAIN_KEY "domain"
|
||||||
|
#define KYVPN_REQUIREMPPE_KEY "require-mppe"
|
||||||
|
#define KYVPN_MPPESTATEFUL_KEY "mppe-stateful"
|
||||||
|
#define KYVPN_LCPECHOFAILURE_KEY "lcp-echo-failure"
|
||||||
|
#define KYVPN_LCPECHOINTERVAL_KEY "lcp-echo-interval"
|
||||||
|
#define KYVPN_MRU_KEY "mru"
|
||||||
|
#define KYVPN_MTU_KEY "mtu"
|
||||||
|
|
||||||
|
#define KYVPN_REQUIREMPPE128_KEY "require-mppe-128"
|
||||||
|
#define KYVPN_REQUIREMPPE40_KEY "require-mppe-40"
|
||||||
|
|
||||||
|
#define KYVPN_USERCERT_KEY "usercert"
|
||||||
|
#define KYVPN_USERKEY_KEY "userkey"
|
||||||
|
#define KYVPN_CERTPASSWD_KEY "cert-pass"
|
||||||
|
#define KYVPN_CERTPASSWDFLAGS_KEY "cert-pass-flags"
|
||||||
|
#define KYVPN_PIN_KEY "pin"
|
||||||
|
#define KYVPN_VIRTUAL_KEY "virtual"
|
||||||
|
#define KYVPN_ENCAP_KEY "encap"
|
||||||
|
#define KYVPN_IPCOMP_KEY "ipcomp"
|
||||||
|
#define KYVPN_PROPOSAL_KEY "proposal"
|
||||||
|
#define KYVPN_IKE_KEY "ike"
|
||||||
|
#define KYVPN_ESP_KEY "esp"
|
||||||
|
|
||||||
|
//openvpn
|
||||||
|
#define KYVPN_CONNECTIONTYPE_KEY "connection-type"
|
||||||
|
|
||||||
|
#define KYVPN_CA_KEY "ca"
|
||||||
|
#define KYVPN_CERT_KEY "cert"
|
||||||
|
#define KYVPN_KEY_KEY "key"
|
||||||
|
|
||||||
|
#define KYVPN_USERNAME_KEY "username"
|
||||||
|
#define KYVPN_STATICKEY_KEY "static-key"
|
||||||
|
#define KYVPN_STATICKEYDIR_KEY "static-key-direction"
|
||||||
|
#define KYVPN_LOCALIP_KEY "local-ip"
|
||||||
|
#define KYVPN_REMOTEIP_KEY "remote-ip"
|
||||||
|
|
||||||
|
#define KYVPN_PORT_KEY "port"
|
||||||
|
#define KYVPN_RENEGSEC_KEY "reneg-seconds"
|
||||||
|
#define KYVPN_COMPLZO_KEY "comp-lzo"
|
||||||
|
#define KYVPN_COMPRESS_KEY "compress"
|
||||||
|
#define COMPLZO_LZODISABLE "no-by-default"
|
||||||
|
#define COMPLZO_ADAPTIVE "adaptive"
|
||||||
|
#define COMPRESS_LZO "lzo"
|
||||||
|
#define COMPRESS_LZ4 "lz4"
|
||||||
|
#define COMPRESS_LZ4V2 "lz4-v2"
|
||||||
|
|
||||||
|
#define KYVPN_PROTOTCP_KEY "proto-tcp"
|
||||||
|
#define KYVPN_DEVTYPE_KEY "dev-type"
|
||||||
|
#define DEVTYPE_TUN "tun"
|
||||||
|
#define DEVTYPE_TAP "tap"
|
||||||
|
#define KYVPN_DEV_KEY "dev"
|
||||||
|
#define KYVPN_TUNNELMTU_KEY "tunnel-mtu"
|
||||||
|
#define KYVPN_FRAGMENTSIZE_KEY "fragment-size"
|
||||||
|
#define KYVPN_MSSFIX_KEY "mssfix"
|
||||||
|
#define KYVPN_REMOTERANDOM_KEY "remote-random"
|
||||||
|
#define KYVPN_TUNIPV6_KEY "tun-ipv6"
|
||||||
|
#define KYVPN_PING_KEY "ping"
|
||||||
|
#define KYVPN_PINGEXIT_KEY "ping-exit"
|
||||||
|
#define KYVPN_PINGRESTART_KEY "ping-restart"
|
||||||
|
#define KYVPN_FLOAT_KEY "float"
|
||||||
|
#define KYVPN_MAXROUTES_KEY "max-routes"
|
||||||
|
#define KYVPN_VERIFYX509NAME_KEY "verify-x509-name"
|
||||||
|
#define X509NAME_SUBJECT "subject"
|
||||||
|
#define X509NAME_NAME "name"
|
||||||
|
#define X509NAME_NAMEPREFIX "name-prefix"
|
||||||
|
|
||||||
|
#define KYVPN_REMOTECERTTLS_KEY "remote-cert-tls"
|
||||||
|
#define KYVPN_NSCERTTYPE_KEY "ns-cert-type"
|
||||||
|
#define KYVPN_SERVER "server"
|
||||||
|
#define KYVPN_CLIENT "client"
|
||||||
|
|
||||||
|
#define KYVPN_TA_KEY "ta"
|
||||||
|
#define KYVPN_TLSCRYPT_KEY "tls-crypt"
|
||||||
|
#define KYVPN_TADIR_KEY "ta-dir"
|
||||||
|
|
||||||
|
#define KYVPN_PROXYTYPE_KEY "proxy-type"
|
||||||
|
#define PROXYTYPE_HTTP "http"
|
||||||
|
#define PROXYTYPE_SOCKS "socks"
|
||||||
|
#define KYVPN_PROXYSERVER_KEY "proxy-server"
|
||||||
|
#define KYVPN_PROXYPORT_KEY "proxy-port"
|
||||||
|
#define KYVPN_PROXYRETRY_KEY "proxy-retry"
|
||||||
|
#define KYVPN_HTTPPROXYUSERNAME_KEY "http-proxy-username"
|
||||||
|
#define KYVPN_HTTPPROXYPASSWD_KEY "http-proxy-password"
|
||||||
|
#define KYVPN_HTTPPROXYPASSWDFLAGS_KEY "http-proxy-password-flags"
|
||||||
|
|
||||||
|
#define KYVPN_KEYSIZE_KEY "keysize"
|
||||||
|
#define KYVPN_AUTH_KEY "auth"
|
||||||
|
|
||||||
|
#define KYVPN_METHOD_KEY "method"
|
||||||
|
|
||||||
|
#define KYVPN_YES "yes"
|
||||||
|
#define KYVPN_NO "no"
|
||||||
|
|
||||||
|
//VPN类型
|
||||||
|
enum KyVpnType{
|
||||||
|
KYVPNTYPE_UNKNOWN = -1,
|
||||||
|
KYVPNTYPE_L2TP = 0,
|
||||||
|
KYVPNTYPE_OPENVPN,
|
||||||
|
KYVPNTYPE_PPTP,
|
||||||
|
KYVPNTYPE_STRONGSWAN
|
||||||
|
};
|
||||||
|
|
||||||
|
//密码策略
|
||||||
|
enum KyPasswdPolicy{
|
||||||
|
KYPASSWD_FORTHISUSER = 0,
|
||||||
|
KYPASSWD_FORALLUSER,
|
||||||
|
KYPASSWD_ASKEVERYTIME,
|
||||||
|
KYPASSWD_ISNOTREQUIRED = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
//认证方式
|
||||||
|
enum KyAuthMethod2 {
|
||||||
|
KYAUTH2_PAP = 1u << 0, //PAP认证
|
||||||
|
KYAUTH2_CHAP = 1u << 1, //CHAP认证
|
||||||
|
KYAUTH2_MSCHAP = 1u << 2, //MSCHAP认证
|
||||||
|
KYAUTH2_MSCHAPV2 = 1u << 3, //MSCHAPV2认证
|
||||||
|
KYAUTH2_EAP = 1u << 4, //EAP认证
|
||||||
|
KYAUTH2_ALL = KYAUTH2_PAP | KYAUTH2_CHAP | KYAUTH2_MSCHAP | KYAUTH2_MSCHAPV2 | KYAUTH2_EAP
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(KyAuthMethods, KyAuthMethod2)
|
||||||
|
|
||||||
|
//压缩方式
|
||||||
|
enum KyCompressMethod {
|
||||||
|
KYCOMP_BSD = 1u << 0, //允许BSD压缩
|
||||||
|
KYCOMP_DEFLATE = 1u << 1, //允许Deflate压缩
|
||||||
|
KYCOMP_TCP = 1u << 2, //允许TCP头压缩
|
||||||
|
KYCOMP_PROTO = 1u << 3, //使用协议域压缩协商
|
||||||
|
KYCOMP_ADDR = 1u << 4, //使用地址/控制压缩
|
||||||
|
KYCOMP_ALL = KYCOMP_BSD | KYCOMP_DEFLATE | KYCOMP_TCP | KYCOMP_PROTO | KYCOMP_ADDR
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(KyCompressMethods, KyCompressMethod)
|
||||||
|
|
||||||
|
//高级设置
|
||||||
|
enum KyMPPEMethod {
|
||||||
|
KYMPPE_DEFAULT = 0, //默认MPPE加密
|
||||||
|
KYMPPE_REQUIRE128, //128位加密
|
||||||
|
KYMPPE_REQUIRE40 //40位加密
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyAuthMethod{
|
||||||
|
KYAUTH_ERROR = -1,
|
||||||
|
KYAUTH_PASSWD = 0,
|
||||||
|
KYAUTH_KEY,
|
||||||
|
KYAUTH_AGENT,
|
||||||
|
KYAUTH_SMARTCARD,
|
||||||
|
KYAUTH_EAP,
|
||||||
|
KYAUTH_CERTIFICATE,
|
||||||
|
KYAUTH_CERTIFICATEANDPASSWD,
|
||||||
|
KYAUTH_STATICPASSWD
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyCompressMethod2{
|
||||||
|
KYCOMP2_LZODISABLE = 0,
|
||||||
|
KYCOMP2_LZO,
|
||||||
|
KYCOMP2_LZ4,
|
||||||
|
KYCOMP2_LZ4V2,
|
||||||
|
KYCOMP2_LZOADAPTIVE,
|
||||||
|
KYCOMP2_AUTO
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyVirtualDeviceType{
|
||||||
|
KYVIRDEVTYPE_TUN = 0,
|
||||||
|
KYVIRDEVTYPE_TAP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyVpnPingMethod{
|
||||||
|
KYVPNPING_EXIT = 0,
|
||||||
|
KYVPNPING_RESTART
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyVpnCheckServerMethod{
|
||||||
|
KYCHECKSERVER_NONE = 0,
|
||||||
|
KYCHECKSERVER_ENTIRETHEME,
|
||||||
|
KYCHECKSERVER_ENTIRENAME,
|
||||||
|
KYCHECKSERVER_PRENAME
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyVpnCertType{
|
||||||
|
KYVPNCERT_SERVER = 0,
|
||||||
|
KYVPNCERT_CLIENT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyVpnTlsMode{
|
||||||
|
KYVPNTLS_NONE = 0,
|
||||||
|
KYVPNTLS_AUTHENTICATION,
|
||||||
|
KYVPNTLS_CRYPT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyVpnProxyType{
|
||||||
|
KYVPNPROXY_NONE = 0,
|
||||||
|
KYVPNPROXY_HTTP,
|
||||||
|
KYVPNPROXY_SOCKS
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KyHMACAuthMethod{
|
||||||
|
KYHMACAUTH_DEFAULT = 0,
|
||||||
|
KYHMACAUTH_NONE,
|
||||||
|
KYHMACAUTH_MD4,
|
||||||
|
KYHMACAUTH_MD5,
|
||||||
|
KYHMACAUTH_SHA1,
|
||||||
|
KYHMACAUTH_SHA224,
|
||||||
|
KYHMACAUTH_SHA256,
|
||||||
|
KYHMACAUTH_SHA384,
|
||||||
|
KYHMACAUTH_SHA512,
|
||||||
|
KYHMACAUTH_RIPEMD160
|
||||||
|
};
|
||||||
|
|
||||||
|
class KyVpnConfig : public KyConnectSetting
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KyVpnType m_vpnType;
|
||||||
|
QString m_vpnName;
|
||||||
|
QString m_gateway;
|
||||||
|
|
||||||
|
//认证方式
|
||||||
|
KyAuthMethod m_authMethod;
|
||||||
|
//VPN用户密码信息
|
||||||
|
QString m_userName;
|
||||||
|
//用户密码
|
||||||
|
QString m_userPasswd;
|
||||||
|
//密码策略
|
||||||
|
KyPasswdPolicy m_passwdPolicy = KYPASSWD_ASKEVERYTIME;
|
||||||
|
//NT域
|
||||||
|
QString m_ntDomain;
|
||||||
|
|
||||||
|
//CA证书
|
||||||
|
QString m_caCertificate;
|
||||||
|
//用户证书
|
||||||
|
QString m_userCertificate;
|
||||||
|
//用户私钥
|
||||||
|
QString m_userKey;
|
||||||
|
//静态密钥
|
||||||
|
QString m_staticKey;
|
||||||
|
//用户私有密钥密码
|
||||||
|
QString m_privatePasswd;
|
||||||
|
//用户私有密码策略
|
||||||
|
KyPasswdPolicy m_privatePasswdPolicy = KYPASSWD_ASKEVERYTIME;
|
||||||
|
//密钥方向
|
||||||
|
QString m_vpnKeyDir;
|
||||||
|
//本地IP地址
|
||||||
|
QString m_localAddress;
|
||||||
|
//远程IP地址
|
||||||
|
QString m_remoteAddress;
|
||||||
|
//PIN码
|
||||||
|
QString m_pinId;
|
||||||
|
|
||||||
|
//MPPE加密开关
|
||||||
|
bool m_mppeEnable = false;
|
||||||
|
//MPPE加密算法
|
||||||
|
KyMPPEMethod m_mppeEncryptMethod = KYMPPE_DEFAULT;
|
||||||
|
//使用有状态加密
|
||||||
|
bool m_isAllowStatefulEncryption = false;
|
||||||
|
//发送PPP回显包
|
||||||
|
bool m_sendPppPackage = false;
|
||||||
|
//认证方式
|
||||||
|
KyAuthMethods m_authMethods = KYAUTH2_ALL;
|
||||||
|
//压缩方式
|
||||||
|
KyCompressMethods m_compressMethods = KYCOMP_ALL;
|
||||||
|
//MRU 最大接收单元
|
||||||
|
QString m_mru;
|
||||||
|
//MTU 最大传输单元
|
||||||
|
QString m_mtu;
|
||||||
|
//请求使用内部IP
|
||||||
|
bool m_virtual;
|
||||||
|
//强制UDP封装
|
||||||
|
bool m_encap;
|
||||||
|
//使用IP压缩
|
||||||
|
bool m_ipcomp;
|
||||||
|
//启用自定义密码建议
|
||||||
|
bool m_proposal;
|
||||||
|
//IKE
|
||||||
|
QString m_ike;
|
||||||
|
//ESP
|
||||||
|
QString m_esp;
|
||||||
|
|
||||||
|
//使用自定义网关端口
|
||||||
|
bool m_useAssignPort;
|
||||||
|
QString m_assignPort;
|
||||||
|
|
||||||
|
//使用自定义重协商间隔
|
||||||
|
bool m_useRenegSeconds;
|
||||||
|
QString m_renegSeconds;
|
||||||
|
|
||||||
|
//使用压缩
|
||||||
|
bool m_useCompress;
|
||||||
|
KyCompressMethod2 m_openvpnCompress;
|
||||||
|
|
||||||
|
//使用TCP连接
|
||||||
|
bool m_useTcpLink;
|
||||||
|
|
||||||
|
//设置虚拟设备类型
|
||||||
|
bool m_setDevType;
|
||||||
|
KyVirtualDeviceType m_devType;
|
||||||
|
|
||||||
|
//设置虚拟设备名称
|
||||||
|
bool m_setDevName;
|
||||||
|
QString m_devName;
|
||||||
|
|
||||||
|
//使用自定义隧道最大单元传输
|
||||||
|
bool m_useTunnelMtu;
|
||||||
|
QString m_tunnelMtu;
|
||||||
|
|
||||||
|
//使用自定义UDP分片大小
|
||||||
|
bool m_useFragmentSize;
|
||||||
|
QString m_fragmentSize;
|
||||||
|
|
||||||
|
//限制TCP最大段尺寸
|
||||||
|
bool m_mssfix;
|
||||||
|
|
||||||
|
//随机化远程主机
|
||||||
|
bool m_remoteRandom;
|
||||||
|
|
||||||
|
//IPv6 tun link
|
||||||
|
bool m_ipv6TunLink;
|
||||||
|
|
||||||
|
//指定Ping周期
|
||||||
|
bool m_setPingCycle;
|
||||||
|
QString m_pingCycle;
|
||||||
|
|
||||||
|
//指定退出或重启Ping
|
||||||
|
bool m_usePingMethod;
|
||||||
|
KyVpnPingMethod m_pingMethod;
|
||||||
|
QString m_pingMethodTime;
|
||||||
|
|
||||||
|
//接受来自任何地址(Float)已通过身份验证的数据包
|
||||||
|
bool m_float;
|
||||||
|
|
||||||
|
//指定路由上限
|
||||||
|
bool m_setMaxRoute;
|
||||||
|
QString m_maxRoute;
|
||||||
|
|
||||||
|
//服务器证书检验
|
||||||
|
KyVpnCheckServerMethod m_checkServerCa;
|
||||||
|
|
||||||
|
//主题匹配
|
||||||
|
QString m_verifyName;
|
||||||
|
|
||||||
|
//验证对等(服务器)证书用法签名
|
||||||
|
bool m_useRemoteCertTls;
|
||||||
|
KyVpnCertType m_remoteCertType;
|
||||||
|
|
||||||
|
//验证对等(服务器)证书nsCertType签名
|
||||||
|
bool m_useNsCertTls;
|
||||||
|
KyVpnCertType m_nsCertType;
|
||||||
|
|
||||||
|
//其他TLS身份验证
|
||||||
|
//模式
|
||||||
|
KyVpnTlsMode m_vpnTlsMode;
|
||||||
|
//密钥文件
|
||||||
|
QString m_vpnKeyFile;
|
||||||
|
//密钥方向
|
||||||
|
QString m_vpnTlsTaDir;
|
||||||
|
|
||||||
|
//代理
|
||||||
|
//代理类型
|
||||||
|
KyVpnProxyType m_vpnProxyType;
|
||||||
|
//服务器地址
|
||||||
|
QString m_vpnProxyServer;
|
||||||
|
//端口
|
||||||
|
QString m_vpnProxyPort;
|
||||||
|
//出错时无限重试
|
||||||
|
bool m_vpnProxyRetry;
|
||||||
|
//代理用户名
|
||||||
|
QString m_vpnProxyName;
|
||||||
|
//代理用户名
|
||||||
|
QString m_vpnProxyPasswd;
|
||||||
|
//代理密码策略
|
||||||
|
KyPasswdPolicy m_vpnProxyPasswdPolicy = KYPASSWD_ASKEVERYTIME;
|
||||||
|
|
||||||
|
//安全
|
||||||
|
//使用自定义密钥大小
|
||||||
|
bool m_useKeysize;
|
||||||
|
QString m_keySize;
|
||||||
|
//HMAC认证
|
||||||
|
KyHMACAuthMethod m_hmacAuthMethod;
|
||||||
|
|
||||||
|
//IPv4Setting
|
||||||
|
QStringList m_ipv4DnsSearch;
|
||||||
|
QString m_ipv4DhcpClientId;
|
||||||
|
|
||||||
|
//IPv6Setting
|
||||||
|
QStringList m_ipv6DnsSearch;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class KyVpnConnectOperation : public KyConnectOperation
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit KyVpnConnectOperation(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void createVpnConnect(KyVpnConfig &vpnSettings);
|
||||||
|
void setVpnConfig(QString connectUuid, KyVpnConfig &vpnConfig);
|
||||||
|
KyVpnConfig getVpnConfig(QString connectUuid);
|
||||||
|
|
||||||
|
void activateVpnConnection(const QString connectUuid);
|
||||||
|
void deactivateVpnConnection(const QString activeConnectName, const QString &activeConnectUuid);
|
||||||
|
void deleteVpnConnect(const QString &connectUuid);
|
||||||
|
|
||||||
|
private:
|
||||||
|
KyHMACAuthMethod getHmacAuthMethod(const QString method);
|
||||||
|
KyAuthMethod getAuthMethod(const QString method);
|
||||||
|
|
||||||
|
void getConnectionSetting(QString connectUuid, KyVpnConfig &vpnConfig);
|
||||||
|
void setConnectionSetting(NetworkManager::ConnectionSettings::Ptr connectionSettings, KyVpnConfig &vpnConfig);
|
||||||
|
|
||||||
|
void getL2tpConfig(KyVpnConfig &vpnConfig);
|
||||||
|
void setL2tpConfig(KyVpnConfig &vpnConfig);
|
||||||
|
void getPptpConfig(KyVpnConfig &vpnConfig);
|
||||||
|
void setPptpConfig(KyVpnConfig &vpnConfig);
|
||||||
|
void getStrongswanConfig(KyVpnConfig &vpnConfig);
|
||||||
|
void setStrongswanConfig(KyVpnConfig &vpnConfig);
|
||||||
|
void getOpenvpnConfig(KyVpnConfig &vpnConfig);
|
||||||
|
void setOpenvpnConfig(KyVpnConfig &vpnConfig);
|
||||||
|
|
||||||
|
void getUsrPasswdAndPolicy(KyVpnConfig &vpnConfig);
|
||||||
|
void setUsrPasswdAndPolicy(KyVpnConfig &vpnConfig);
|
||||||
|
|
||||||
|
void getCertPasswdAndPolicy(KyVpnConfig &vpnConfig);
|
||||||
|
void setCertPasswdAndPolicy(KyVpnConfig &vpnConfig);
|
||||||
|
|
||||||
|
NMVariantMapMap setIpConfig(NetworkManager::ConnectionSettings::Ptr connectionSettings, KyVpnConfig &vpnConfig);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMap<QString, KyAuthMethod> m_authMethodMap = {
|
||||||
|
{"password" , KYAUTH_PASSWD },
|
||||||
|
{"key" , KYAUTH_KEY },
|
||||||
|
{"agent" , KYAUTH_AGENT },
|
||||||
|
{"smartcard" , KYAUTH_SMARTCARD },
|
||||||
|
{"eap" , KYAUTH_EAP },
|
||||||
|
{"tls" , KYAUTH_CERTIFICATE },
|
||||||
|
{"password-tls" , KYAUTH_CERTIFICATEANDPASSWD },
|
||||||
|
{"static-password" , KYAUTH_STATICPASSWD }
|
||||||
|
};
|
||||||
|
|
||||||
|
QMap<QString, KyHMACAuthMethod> m_hmacMap = {
|
||||||
|
{"none" , KYHMACAUTH_NONE },
|
||||||
|
{"RSA-MD4" , KYHMACAUTH_MD4 },
|
||||||
|
{"MD5" , KYHMACAUTH_MD5 },
|
||||||
|
{"SHA1" , KYHMACAUTH_SHA1 },
|
||||||
|
{"SHA224" , KYHMACAUTH_SHA224 },
|
||||||
|
{"SHA256" , KYHMACAUTH_SHA256 },
|
||||||
|
{"SHA384" , KYHMACAUTH_SHA384 },
|
||||||
|
{"SHA512" , KYHMACAUTH_SHA512 },
|
||||||
|
{"RIPEMD160" , KYHMACAUTH_RIPEMD160 }
|
||||||
|
};
|
||||||
|
|
||||||
|
NMStringMap m_vpnData;
|
||||||
|
NMStringMap m_vpnSecrets;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KYVPNCONNECTOPERATION_H
|
Loading…
Reference in New Issue