commit b80aabb11363e0aa0352717ed5810aa607dd7eca Author: 谢炜 Date: Thu Jun 2 16:31:24 2022 +0800 Import Upstream version 3.1.1.34update1 diff --git a/BiometricAuth/BiometricAuth.pri b/BiometricAuth/BiometricAuth.pri new file mode 100644 index 0000000..cbb2ea1 --- /dev/null +++ b/BiometricAuth/BiometricAuth.pri @@ -0,0 +1,9 @@ +SOURCES += \ + $$PWD/biometricproxy.cpp \ + $$PWD/biometricauthwidget.cpp \ + $$PWD/biometricdeviceswidget.cpp + +HEADERS += \ + $$PWD/biometricproxy.h \ + $$PWD/biometricauthwidget.h \ + $$PWD/biometricdeviceswidget.h diff --git a/BiometricAuth/BiometricAuth.pro b/BiometricAuth/BiometricAuth.pro new file mode 100644 index 0000000..00bc543 --- /dev/null +++ b/BiometricAuth/BiometricAuth.pro @@ -0,0 +1,37 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-12-06T09:17:41 +# +#------------------------------------------------- + +QT += core gui dbus + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = BiometricAuth +TEMPLATE = app + +# 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 + + +SOURCES += \ + main.cpp \ + biometricauthwidget.cpp \ + biometricproxy.cpp \ + biometricdeviceswidget.cpp + +HEADERS += \ + biometricauthwidget.h \ + biometricproxy.h \ + biometricdeviceswidget.h + +FORMS += diff --git a/BiometricAuth/CMakeLists.txt b/BiometricAuth/CMakeLists.txt new file mode 100644 index 0000000..9ba7d2c --- /dev/null +++ b/BiometricAuth/CMakeLists.txt @@ -0,0 +1,28 @@ +qt5_wrap_cpp(BiometricAuth_SRC + biometricdeviceinfo.h + biometricproxy.h + biometricauthwidget.h + biometricdeviceswidget.h + giodbus.h + ) + +set(BiometricAuth_SRC + ${BiometricAuth_SRC} + biometricdeviceinfo.cpp + biometricproxy.cpp + biometricauthwidget.cpp + biometricdeviceswidget.cpp + giodbus.cpp + ) + +include_directories( + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ${Qt5DBus_INCLUDE_DIRS} + ${OpenCV_INCLUDE_DIRS} + ${GLIB2_INCLUDE_DIRS} + ) + + +add_library(BiometricAuth STATIC ${BiometricAuth_SRC}) +target_link_libraries(BiometricAuth Qt5::Core Qt5::DBus Qt5::Widgets ${OpenCV_LIBS} ${GIOUNIX2_LIBRARIES}) diff --git a/BiometricAuth/biometricauthwidget.cpp b/BiometricAuth/biometricauthwidget.cpp new file mode 100644 index 0000000..a7b552d --- /dev/null +++ b/BiometricAuth/biometricauthwidget.cpp @@ -0,0 +1,344 @@ +/** + * Copyright (C) 2018 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, 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 "biometricauthwidget.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "giodbus.h" + +BiometricAuthWidget::BiometricAuthWidget(BiometricProxy *proxy, QWidget *parent) : + QWidget(parent), + proxy(proxy), + isInAuth(false), + movieTimer(nullptr), + failedCount(0), + timeoutCount(0), + beStopped(false), + retrytimer(nullptr), + usebind(false) +{ + usebind = getAuthDouble(); + initUI(); + resize(400, 260); + + if(this->proxy) + { + connect(this->proxy, &BiometricProxy::StatusChanged, + this, &BiometricAuthWidget::onStatusChanged); + + connect(this->proxy, &BiometricProxy::FrameWritten, + this, &BiometricAuthWidget::onFrameWritten); + } + +} + +void BiometricAuthWidget::initUI() +{ + //显示提示信息 + lblNotify = new QLabel(this); + lblNotify->setWordWrap(true); + lblNotify->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); + + //显示当前设备 + lblDevice = new QLabel(this); + lblDevice->setWordWrap(true); + lblDevice->setAlignment(Qt::AlignCenter); + + //显示图片 + lblImage = new QLabel(this); + lblImage->setFixedSize(100, 100); + +} + + +void BiometricAuthWidget::resizeEvent(QResizeEvent */*event*/) +{ + lblNotify->setGeometry(0, 0, width(), 45); + lblDevice->setGeometry(0, lblNotify->geometry().bottom()+5, width(), 30); + lblImage->setGeometry((width() - lblImage->width()) / 2, + lblDevice->geometry().bottom() + 10, + lblImage->width(), lblImage->height()); + //qDebug() +} + +void BiometricAuthWidget::startAuth(DeviceInfoPtr device, int uid) +{ + if(!proxy) + { + qWarning() << "BiometricProxy doesn't exist."; + return; + } + + if(isInAuth) + { + qDebug() << "Identification is currently under way, stop it"; + stopAuth(); + } + + this->device = device; + this->uid = uid; + this->userName = getpwuid(uid)->pw_name; + this->failedCount = 0; + this->timeoutCount = 0; + this->beStopped = false; + proxy->StopOps(device->id); + startAuth_(); + + if(device->deviceType != DeviceType::Type::Face){ + updateImage(1); + } + +} + +void BiometricAuthWidget::startAuth_() +{ + lblDevice->setText(tr("Current device: ") + device->shortName); + + //qDebug().noquote() << QString("Identify:[drvid: %1, uid: %2]").arg(1).arg(2); + + isInAuth = true; + dup_fd = -1; + + QDBusPendingCall call = proxy->Identify(device->id, uid); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + this, &BiometricAuthWidget::onIdentifyComplete); + +} + +void BiometricAuthWidget::stopAuth() +{ + beStopped = true; + if(!isInAuth) + { + return; + } + + proxy->StopOps(device->id); + if(retrytimer&&retrytimer->isActive()){ + retrytimer->stop(); + delete retrytimer; + retrytimer = nullptr; + } + isInAuth = false; + updateImage(0); +} + +void BiometricAuthWidget::onIdentifyComplete(QDBusPendingCallWatcher *watcher) +{ + QDBusPendingReply reply = *watcher; + if(reply.isError()) + { + qWarning() << "Identify error: " << reply.error().message(); + Q_EMIT authComplete(false); + updateImage(0); + return; + } + int result = reply.argumentAt(0).toInt(); + int authUid = reply.argumentAt(1).toInt(); + + // 特征识别成功,而且用户id匹配 + if(result == DBUS_RESULT_SUCCESS && authUid == uid) + { + qDebug() << "Identify success"; + Q_EMIT authComplete(true); + } + // 特征识别不匹配 + else if(result == DBUS_RESULT_NOTMATCH) + { + if(usebind){ + Q_EMIT authComplete(false); + return; + } + qDebug() << "Identify failed"; + failedCount++; + if(failedCount >= GetMaxFailedAutoRetry(userName)) + { + Q_EMIT authComplete(false); + } + else + { + lblNotify->setText(tr("Identify failed, Please retry.")); + if(!beStopped){ + // QTimer::singleShot(1000, this, &BiometricAuthWidget::startAuth_); + if(!retrytimer){ + retrytimer = new QTimer(this); + retrytimer->setSingleShot(true); + connect(retrytimer, &QTimer::timeout, this, &BiometricAuthWidget::startAuth_); + } + retrytimer->start(1000); + } + } + } + //识别发生错误 + else if(result == DBUS_RESULT_ERROR) + { + if(usebind){ + Q_EMIT authComplete(false); + return; + } + StatusReslut ret = proxy->UpdateStatus(device->id); + //识别操作超时 + if(ret.result == 0 && ret.opsStatus == OPS_IDENTIFY_TIMEOUT) + { + timeoutCount++; + if(timeoutCount >= GetMaxTimeoutAutoRetry(userName)) + { + Q_EMIT authComplete(false); + } + else + { + QTimer::singleShot(1000, [&]{ + if(!beStopped) + { + startAuth_(); + } + }); + } + }else{ + Q_EMIT authComplete(false); + } + }else{ + Q_EMIT authComplete(false); + } + updateImage(0); +} + +void BiometricAuthWidget::onFrameWritten(int drvid) +{ + + if(dup_fd == -1){ + dup_fd = get_server_gvariant_stdout(drvid); + } + + if(dup_fd <= 0) + return ; + + cv::Mat img; + lseek(dup_fd, 0, SEEK_SET); + char base64_bufferData[1024*1024]; + int rc = read(dup_fd, base64_bufferData, 1024*1024); + printf("rc = %d\n", rc); + + cv::Mat mat2(1, sizeof(base64_bufferData), CV_8U, base64_bufferData); + img = cv::imdecode(mat2, cv::IMREAD_COLOR); + cv::cvtColor(img,img,cv::COLOR_BGR2RGB); + + QImage srcQImage = QImage((uchar*)(img.data), img.cols, img.rows, QImage::Format_RGB888); + lblImage->setFixedSize(160,160); + lblImage->setGeometry((width() - lblImage->width()) / 2, + lblDevice->geometry().bottom() + 10, + lblImage->width(), lblImage->height()); + lblImage->setPixmap(QPixmap::fromImage(srcQImage).scaled(lblImage->size())); + +} + +void BiometricAuthWidget::onStatusChanged(int drvid, int status) +{ + if(!isInAuth) + { + return; + } + if(drvid != device->id) + { + return; + } + + // 显示来自服务的提示信息 + if(status == STATUS_NOTIFY) + { + QString notifyMsg = proxy->GetNotifyMesg(drvid); + lblNotify->setText(notifyMsg); + } +} + +static int count = 0; +void BiometricAuthWidget::updateImage(int type) +{ + if(device->deviceType == DeviceType::Type::Face) + return ; + + if(type == 0) + { + if(movieTimer && movieTimer->isActive()) + { + movieTimer->stop(); + } + + QString imagePath = QString(UKUI_BIOMETRIC_IMAGES_PATH "%1/01.png") + .arg(DeviceType::getDeviceType(device->deviceType)); + setImage(imagePath); + } + else + { + if(!movieTimer) + { + movieTimer = new QTimer(this); + movieTimer->setInterval(100); + connect(movieTimer, &QTimer::timeout, + this, &BiometricAuthWidget::onMoviePixmapUpdate); + } + count = 0; + movieTimer->start(); + } +} + +void BiometricAuthWidget::onMoviePixmapUpdate() +{ + if(count >= 18) + { + count = 0; + } + count++; + QString fileName = (count < 10 ? "0" : "") + QString::number(count); + QString imagePath = QString(UKUI_BIOMETRIC_IMAGES_PATH "%1/%2.png") + .arg(DeviceType::getDeviceType(device->deviceType)) + .arg(fileName); + setImage(imagePath); +} + +void BiometricAuthWidget::setImage(const QString &path) +{ + QPixmap image(path); + image = image.scaled(lblImage->width(), lblImage->height(), + Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + + lblImage->setPixmap(image); +} + +bool BiometricAuthWidget::getAuthDouble() +{ + QSettings settings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat); + bool distribId = settings.value("DoubleAuth").toBool(); + return distribId; +} + +void BiometricAuthWidget::setMinImage(float val) +{ + resize(400,100+100*val); + lblImage->setFixedSize(100*val, 100*val); +} diff --git a/BiometricAuth/biometricauthwidget.h b/BiometricAuth/biometricauthwidget.h new file mode 100644 index 0000000..e380abf --- /dev/null +++ b/BiometricAuth/biometricauthwidget.h @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2018 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, 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 BIOMETRICAUTHWIDGET_H +#define BIOMETRICAUTHWIDGET_H + +#include +#include "biometricproxy.h" + +class QLabel; +//class QDBusPendingCallWatcher; +//class BiometricProxy; +//class DeviceIdentityPtr; +class BiometricAuthWidget : public QWidget +{ + Q_OBJECT +public: + explicit BiometricAuthWidget(BiometricProxy *proxy, QWidget *parent = 0); + + /** + * @brief 进行生物识别认证 + * @param deviceInfo 使用的设备 + * @param uid 待认证的用户id + */ + void startAuth(DeviceInfoPtr device, int uid); + + /** + * @brief 终止生物识别认证 + */ + void stopAuth(); + + bool isAuthenticating() { return isInAuth; } + + void setMinImage(float val); + +protected: + void resizeEvent(QResizeEvent *event); + +Q_SIGNALS: + /** + * @brief 认证完成 + * @param result 认证结果 + */ + void authComplete(bool result); + +private Q_SLOTS: + void onIdentifyComplete(QDBusPendingCallWatcher *watcher); + void onStatusChanged(int drvid, int status); + void onFrameWritten(int drvid); + void onMoviePixmapUpdate(); + void startAuth_(); + +private: + void initUI(); + void updateImage(int type = 0); + void setImage(const QString &path); + bool getAuthDouble(); + +private: + QLabel *lblNotify; + QLabel *lblDevice; + QLabel *lblImage; + + BiometricProxy *proxy; + int uid; + QString userName; + DeviceInfoPtr device; + bool isInAuth; + QTimer *movieTimer; + int failedCount; + int timeoutCount; + bool beStopped; + QTimer *retrytimer; + bool usebind; + int fd = -1; + int dup_fd = -1; +}; + +#endif // BIOMETRICAUTHWIDGET_H diff --git a/BiometricAuth/biometricdeviceinfo.cpp b/BiometricAuth/biometricdeviceinfo.cpp new file mode 100644 index 0000000..368b1d0 --- /dev/null +++ b/BiometricAuth/biometricdeviceinfo.cpp @@ -0,0 +1,248 @@ +/** + * Copyright (C) 2018 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, 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 "biometricdeviceinfo.h" + +#include +#include +#include +//#include + +QString DeviceType::getDeviceType(int deviceType) +{ + if(deviceType >= __MAX_NR_TYPES) + { + return ""; + } + QMetaEnum meta = QMetaEnum::fromType(); + const char *typeString = meta.valueToKey(deviceType); + return QString(typeString); +} + +QString DeviceType::getDeviceType_tr(int deviceType) +{ + switch(deviceType) + { + case FingerPrint: + return tr("FingerPrint"); + case FingerVein: + return tr("FingerVein"); + case Iris: + return tr("Iris"); + case Face: + return tr("Face"); + case VoicePrint: + return tr("VoicePrint"); + case REMOTE_QRCODE_TYPE: + return tr("QRCode"); + default: + return ""; + } +} + +QDebug operator <<(QDebug stream, const DeviceInfo &deviceInfo) +{ + stream << "[" + << deviceInfo.id + << deviceInfo.shortName + << deviceInfo.fullName + << deviceInfo.deviceType + << deviceInfo.driverEnable + << deviceInfo.deviceNum + << "]"; + return stream; +} + +QDBusArgument &operator <<(QDBusArgument &arg, const DeviceInfo &deviceInfo) +{ + arg.beginStructure(); + arg << deviceInfo.id + << deviceInfo.shortName + << deviceInfo.fullName + << deviceInfo.driverEnable + << deviceInfo.deviceNum + << deviceInfo.deviceType + << deviceInfo.storageType + << deviceInfo.eigType + << deviceInfo.verifyType + << deviceInfo.identifyType + << deviceInfo.busType + << deviceInfo.deviceStatus + << deviceInfo.OpsStatus; + arg.endStructure(); + return arg; +} +const QDBusArgument &operator >>(const QDBusArgument &arg, DeviceInfo &deviceInfo) +{ + arg.beginStructure(); + arg >> deviceInfo.id + >> deviceInfo.shortName + >> deviceInfo.fullName + >> deviceInfo.driverEnable + >> deviceInfo.deviceNum + >> deviceInfo.deviceType + >> deviceInfo.storageType + >> deviceInfo.eigType + >> deviceInfo.verifyType + >> deviceInfo.identifyType + >> deviceInfo.busType + >> deviceInfo.deviceStatus + >> deviceInfo.OpsStatus; + arg.endStructure(); + return arg; +} + +void registerMetaType() +{ + qRegisterMetaType("DeviceInfo"); + qDBusRegisterMetaType(); +} + + +QString GetDefaultDevice(const QString &userName) +{ + //QString configPath = QString("/home/%1/" UKUI_BIOMETRIC_CONFIG_PATH).arg(userName); + QString configPath = QDir::homePath() + "/" + UKUI_BIOMETRIC_CONFIG_PATH; + QSettings settings(configPath, QSettings::IniFormat); + qDebug() << "configure path: " << settings.fileName(); + + QString defaultDevice = settings.value("DefaultDevice").toString(); + if(defaultDevice.isEmpty()) + { + QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat); + defaultDevice = sysSettings.value("DefaultDevice").toString(); + } + + return defaultDevice; +} + +int GetLastDevice(const QString &userName) +{ + int nLastDevId = -1; + QSettings sysSettings(QString(SHARE_BIOMETRIC_CONFIG_PATH).arg(userName), QSettings::IniFormat); + sysSettings.beginGroup("Common"); + if (sysSettings.allKeys().contains("LastDeviceId")) { + nLastDevId = sysSettings.value("LastDeviceId").toInt(); + } + sysSettings.endGroup(); + return nLastDevId; +} + +void SetLastDevice(const QString &userName, int drvid) +{ + if (drvid < 0) { + return; + } + QString desConfPath = QString(SHARE_BIOMETRIC_CONFIG_PATH).arg(userName); + QFile fileConf(desConfPath); + if (fileConf.exists()) { + QSettings sysSettings(desConfPath, QSettings::IniFormat); + sysSettings.beginGroup("Common"); + sysSettings.setValue("LastDeviceId", drvid); + sysSettings.endGroup(); + } else { + QSettings sysSettings(desConfPath, QSettings::IniFormat); + sysSettings.beginGroup("Common"); + sysSettings.setValue("LastDeviceId", drvid); + sysSettings.endGroup(); + sysSettings.sync(); + QFile file(desConfPath); + file.setPermissions(QFile::WriteUser | QFile::ReadUser | QFile::WriteOther | QFile::ReadOther); + } +} + +static int getValueFromSettings(const QString &userName, const QString &key, int defaultValue = 3) +{ + //从家目录下的配置文件中获取 + //QString configPath = QString("/home/%1/" UKUI_BIOMETRIC_CONFIG_PATH).arg(userName); + QString configPath = QDir::homePath() + "/" + UKUI_BIOMETRIC_CONFIG_PATH; + QSettings settings(configPath, QSettings::IniFormat); + QString valueStr = settings.value(key).toString(); + + //如果没有获取到,则从系统配置文件中获取 + if(valueStr.isEmpty()) + { + QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat); + valueStr = sysSettings.value(key).toString(); + } + + bool ok; + int value = valueStr.toInt(&ok); + if( (value == 0 && !ok) || valueStr.isEmpty() ) + { + value = defaultValue; + } + return value; +} + +bool GetHiddenSwitchButton() +{ + QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat); + if(sysSettings.contains("HiddenSwitchButton")) + return sysSettings.value("HiddenSwitchButton").toBool(); + else + return false; +} + +int GetFailedTimes() +{ + QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat); + if(sysSettings.contains("MaxFailedTimes")) + return sysSettings.value("MaxFailedTimes").toInt(); + else + return 3; +} + +bool GetAuthEnable() +{ + bool isEnable = false; + QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat); + if(sysSettings.contains("EnableAuth")) + isEnable = sysSettings.value("EnableAuth").toBool(); + else + isEnable = false; + + if(isEnable && sysSettings.allKeys().contains("EnableAuthApp")){ + int isEnableApp = sysSettings.value("EnableAuthApp").toInt(); + isEnable = isEnableApp & (1<<1); + } + + return isEnable; +} + +bool GetQRCodeEnable() +{ + bool isEnable = false; + QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat); + sysSettings.beginGroup("Functions"); + if (sysSettings.allKeys().contains("EnableQRCode")) { + isEnable = sysSettings.value("EnableQRCode").toBool(); + } + sysSettings.endGroup(); + return isEnable; +} + +int GetMaxFailedAutoRetry(const QString &userName) +{ + return getValueFromSettings(userName, "MaxFailedAutoRetry"); +} + +int GetMaxTimeoutAutoRetry(const QString &userName) +{ + return getValueFromSettings(userName, "MaxTimeoutAutoRetry"); +} diff --git a/BiometricAuth/biometricdeviceinfo.h b/BiometricAuth/biometricdeviceinfo.h new file mode 100644 index 0000000..c9604be --- /dev/null +++ b/BiometricAuth/biometricdeviceinfo.h @@ -0,0 +1,272 @@ +/** + * Copyright (C) 2018 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, 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 BIOMETRICDEVICEINFO_H +#define BIOMETRICDEVICEINFO_H + +#include +#include + +#define BIOMETRIC_DBUS_SERVICE "org.ukui.Biometric" +#define BIOMETRIC_DBUS_PATH "/org/ukui/Biometric" +#define BIOMETRIC_DBUS_INTERFACE "org.ukui.Biometric" + +#define UKUI_BIOMETRIC_IMAGES_PATH "/usr/share/ukui-biometric/images/" +#define UKUI_BIOMETRIC_CONFIG_PATH ".biometric_auth/ukui_biometric.conf" +#define UKUI_BIOMETRIC_SYS_CONFIG_PATH "/etc/biometric-auth/ukui-biometric.conf" +#define SHARE_BIOMETRIC_CONFIG_PATH "/var/lib/lightdm-data/%1/ukui-biometric.conf" //greeter、screensaver、polkit share conf + +#define BIOMETRIC_PAM_DOUBLE "BIOMETRIC_PAM_DOUBLE" +#define BIOMETRIC_PAM "BIOMETRIC_PAM" +#define BIOMETRIC_PAM_QRCODE "BIOMETRIC_PAM_QRCODE" +#define BIOMETRIC_IGNORE "BIOMETRIC_IGNORE" +#define BIOMETRIC_SUCCESS "BIOMETRIC_SUCCESS" + +#define REMOTE_QRCODE_TYPE (8) + +/** + * @brief 设备类型 + */ +class DeviceType : public QObject +{ + Q_OBJECT +public: + DeviceType(); + enum Type { + FingerPrint, + FingerVein, + Iris, + Face, + VoicePrint, + __MAX_NR_TYPES + }; + Q_ENUM(Type) + /** + * @brief 获取设备类型的字符串表现形式 + * @param deviceType 设备类型 + * @return + */ + static QString getDeviceType(int deviceType); + + /** + * @brief 获取设备类型的国际化字符串 + * @param deviceType 设备类型 + * @return + */ + static QString getDeviceType_tr(int deviceType); +}; + +/** + * @brief StatusChanged D-Bus 信号触发时的状态变化类型 + */ +enum StatusType { + STATUS_DEVICE, + STATUS_OPERATION, + STATUS_NOTIFY +}; + +/** + * @brief 识别、终止操作等DBus调用的结果,即返回值里的 result + */ +enum DBusResult { + DBUS_RESULT_SUCCESS = 0, + DBUS_RESULT_NOTMATCH = -1, + DBUS_RESULT_ERROR = -2, + DBUS_RESULT_DEVICEBUSY = -3, + DBUS_RESULT_NOSUCHDEVICE = -4, + DBUS_RESULT_PERMISSIONDENIED = -5 +}; + +/** + * @brief 识别操作(Identify)的ops状态 + */ +/* 定义操作类型 */ +typedef enum { + OPS_TYPE_COMM = 0, + OPS_TYPE_OPEN, + OPS_TYPE_ENROLL, + OPS_TYPE_VERIFY, + OPS_TYPE_IDENTIFY, + OPS_TYPE_CAPTURE, + OPS_TYPE_SEARCH, + OPS_TYPE_CLEAN, + OPS_TYPE_GET_FLIST, + OPS_TYPE_RENAME, + OPS_TYPE_CLOSE, +}BioOpsType; + +/* + * 定义各种操作结果 + */ +typedef enum { + OPS_COMM_SUCCESS = OPS_TYPE_COMM * 100, /** 空闲状态 **/ + OPS_COMM_FAIL, /** 操作失败 **/ + OPS_COMM_NO_MATCH = OPS_COMM_FAIL, /** 不匹配 **/ + OPS_COMM_ERROR, /** 通用操作错误 **/ + OPS_COMM_STOP_BY_USER, /** 用户取消 **/ + OPS_COMM_TIMEOUT, /** 操作超时 **/ + OPS_COMM_OUT_OF_MEM, /** 无法分配内存 **/ + OPS_COMM_MAX, + + OPS_OPEN_SUCCESS = OPS_TYPE_OPEN * 100, /** 打开设备完成 **/ + OPS_OPEN_FAIL, /** 打开设备失败 **/ + OPS_OPEN_ERROR, /** 打开设备遇到错误 **/ + OPS_OPEN_MAX, + + OPS_ENROLL_SUCCESS = OPS_TYPE_ENROLL * 100, /** 录入信息成功 **/ + OPS_ENROLL_FAIL, /** 录入失败 **/ + OPS_ENROLL_ERROR, /** 录入过程中遇到错误 **/ + OPS_ENROLL_STOP_BY_USER, /** 录入被用户中断 **/ + OPS_ENROLL_TIMEOUT, /** 操作超时 **/ + OPS_ENROLL_MAX, + + OPS_VERIFY_MATCH = OPS_TYPE_VERIFY * 100, /** 认证匹配 **/ + OPS_VERIFY_NO_MATCH, /** 认证不匹配 **/ + OPS_VERIFY_ERROR, /** 认证过程中遇到错误 **/ + OPS_VERIFY_STOP_BY_USER, /** 认证被用户中断 **/ + OPS_VERIFY_TIMEOUT, /** 操作超时 **/ + OPS_VERIFY_MAX, + + OPS_IDENTIFY_MATCH = OPS_TYPE_IDENTIFY * 100, /** 识别到指定特征 **/ + OPS_IDENTIFY_NO_MATCH, /** 未识别出指定特征 **/ + OPS_IDENTIFY_ERROR, /** 识别过程中遇到错误 **/ + OPS_IDENTIFY_STOP_BY_USER, /** 识别被用户中断 **/ + OPS_IDENTIFY_TIMEOUT, /** 操作超时 **/ + OPS_IDENTIFY_MAX, + + OPS_CAPTURE_SUCCESS = OPS_TYPE_CAPTURE * 100, /** 捕获成功 **/ + OPS_CAPTURE_FAIL, /** 捕获失败 **/ + OPS_CAPTURE_ERROR, /** 捕获过程中遇到错误 **/ + OPS_CAPTURE_STOP_BY_USER, /** 捕获被用户中断 **/ + OPS_CAPTURE_TIMEOUT, /** 操作超时 **/ + OPS_CAPTURE_MAX, + + OPS_SEARCH_MATCH = OPS_TYPE_SEARCH * 100, /** 搜索到指定特征 **/ + OPS_SEARCH_NO_MATCH, /** 未搜索到指定特征 **/ + OPS_SEARCH_ERROR, /** 搜索过程中遇到错误 **/ + OPS_SEARCH_STOP_BY_USER, /** 搜索被用户中断 **/ + OPS_SEARCH_TIMEOUT, /** 操作超时 **/ + OPS_SEARCH_MAX, + + OPS_CLEAN_SUCCESS = OPS_TYPE_CLEAN * 100, /** 清理特征成功 **/ + OPS_CLEAN_FAIL, /** 清理失败 **/ + OPS_CLEAN_ERROR, /** 清理过程中遇到错误 **/ + OPS_CLEAN_STOP_BY_USER, /** 清理被用户中断 **/ + OPS_CLEAN_TIMEOUT, /** 操作超时 **/ + OPS_CLEAN_MAX, + + OPS_GET_FLIST_SUCCESS = OPS_TYPE_GET_FLIST * 100, /** 获取特征列表完成 **/ + OPS_GET_FLIST_FAIL, /** 获取特征列表失败 **/ + OPS_GET_FLIST_ERROR, /** 获取特征列表过程中遇到错误 **/ + OPS_GET_FLIST_STOP_BY_USER, /** 获取特征列表被用户中断 **/ + OPS_GET_FLIST_TIMEOUT, /** 获取特征列表超时 **/ + OPS_GET_FLIST_MAX, + + OPS_RENAME_SUCCESS = OPS_TYPE_RENAME * 100, /** 重命名特征完成 **/ + OPS_RENAME_FAIL, /** 重命名特征失败 **/ + OPS_RENAME_ERROR, /** 重命名特征过程中遇到错误 **/ + OPS_RENAME_STOP_BY_USER, /** 重命名特征被用户中断 **/ + OPS_RENAME_TIMEOUT, /** 重命名特征超时 **/ + OPS_RENAME_MAX, + + OPS_CLOSE_SUCCESS = OPS_TYPE_CLOSE * 100, /** 关闭设备完成 **/ + OPS_CLOSE_FAIL, /** 关闭设备失败 **/ + OPS_CLOSE_ERROR, /** 关闭设备过程中遇到错误 **/ + OPS_CLOSE_MAX, +}OpsResult; + +/** + * @brief 设备的信息 + */ +struct DeviceInfo +{ + int id; + QString shortName; + QString fullName; + int driverEnable; + int deviceNum; + int deviceType; + int storageType; + int eigType; + int verifyType; + int identifyType; + int busType; + int deviceStatus; + int OpsStatus; +}; + +class QDBusArgument; + +QDBusArgument &operator <<(QDBusArgument &arg, const DeviceInfo &deviceInfo); +const QDBusArgument &operator >>(const QDBusArgument &arg, DeviceInfo &deviceInfo); + +void registerMetaType(); + +typedef std::shared_ptr DeviceInfoPtr; +typedef QList DeviceList; +typedef QMap DeviceMap; + +QDebug operator <<(QDebug stream, const DeviceInfo &deviceInfo); + +Q_DECLARE_METATYPE(DeviceInfo) + +/** + * @brief 获取默认设备 + * @return + */ +QString GetDefaultDevice(const QString &userName); + +/** + * @brief 获取上次选择的设备 + * @return + */ +int GetLastDevice(const QString &userName); + +void SetLastDevice(const QString &userName, int drvid); + +/** + * @brief 获取失败后自动重新开始的最大次数 + * @param userName + * @return + */ +int GetMaxFailedAutoRetry(const QString &userName); + +/** + * @brief 获取超时后自动重新开始的最大次数 + * @param userName + * @return + */ +int GetMaxTimeoutAutoRetry(const QString &userName); +bool GetHiddenSwitchButton(); +int GetFailedTimes(); +bool GetAuthEnable(); +bool GetQRCodeEnable(); + +enum LOGINOPT_TYPE { + LOGINOPT_TYPE_PASSWORD = 0, // 密码 + LOGINOPT_TYPE_FACE, // 人脸 + LOGINOPT_TYPE_FINGERPRINT, // 指纹 + LOGINOPT_TYPE_IRIS, // 虹膜 + LOGINOPT_TYPE_VOICEPRINT, // 声纹 + LOGINOPT_TYPE_FINGERVEIN, // 指静脉 + LOGINOPT_TYPE_QRCODE, // 二维码 + LOGINOPT_TYPE_OTHERS, // 其他 + LOGINOPT_TYPE_COUNT +}; + +#endif // BIOMETRICDEVICEINFO_H diff --git a/BiometricAuth/biometricdeviceswidget.cpp b/BiometricAuth/biometricdeviceswidget.cpp new file mode 100644 index 0000000..856b750 --- /dev/null +++ b/BiometricAuth/biometricdeviceswidget.cpp @@ -0,0 +1,280 @@ +/** + * Copyright (C) 2018 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, 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 "biometricdeviceswidget.h" +#include +#include +#include +#include +#include +#include + + +BiometricDevicesWidget::BiometricDevicesWidget(BiometricProxy *proxy, int uid,QWidget *parent) + : QWidget(parent), + proxy(proxy), + m_uid(uid) +{ + initUI(); + if(proxy && proxy->isValid()) + { + connect(proxy, &BiometricProxy::USBDeviceHotPlug, + this, &BiometricDevicesWidget::onUSBDeviceHotPlug); + updateDevice(); + } + + resize(500, 500); +} + +void BiometricDevicesWidget::initUI() +{ + lblPrompt = new QLabel(this); + lblPrompt->setObjectName(QStringLiteral("lblBioetricDevicesPrompt")); + lblPrompt->setText(tr("Please select the biometric device")); + lblPrompt->setAlignment(Qt::AlignHCenter); + + lblDeviceType = new QLabel(this); + lblDeviceType->setObjectName(QStringLiteral("lblDeviceType")); + lblDeviceType->setText(tr("Device type:")); + lblDeviceType->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + + QStyledItemDelegate* itemDelegate = new QStyledItemDelegate(); + + cmbDeviceType = new QComboBox(this); + cmbDeviceType->view()->parentWidget()->setWindowFlags(Qt::Popup|Qt::FramelessWindowHint); + cmbDeviceType->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground); + cmbDeviceType->setObjectName(QStringLiteral("cmbDeviceType")); + cmbDeviceType->setMaxVisibleItems(5); + cmbDeviceType->setItemDelegate(itemDelegate); + connect(cmbDeviceType, SIGNAL(currentIndexChanged(int)), + this, SLOT(onCmbDeviceTypeCurrentIndexChanged(int))); + + lblDeviceName = new QLabel(this); + lblDeviceName->setObjectName(QStringLiteral("lblDeviceName")); + lblDeviceName->setText(tr("Device name:")); + lblDeviceName->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + + cmbDeviceName = new QComboBox(this); + cmbDeviceName->view()->parentWidget()->setWindowFlags(Qt::Popup|Qt::FramelessWindowHint); + cmbDeviceName->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground); + cmbDeviceName->setObjectName(QStringLiteral("cmbDeviceName")); + cmbDeviceName->setMaxVisibleItems(5); + cmbDeviceName->setItemDelegate(itemDelegate); + + btnOK = new QPushButton(tr("OK"), this); + btnOK->setObjectName(QStringLiteral("OKButton")); + btnOK->setCursor(Qt::PointingHandCursor); + connect(btnOK, &QPushButton::clicked, + this, &BiometricDevicesWidget::onOKButtonClicked); +} + +void BiometricDevicesWidget::setUser(int user) +{ + m_uid = user; +} + +void BiometricDevicesWidget::resizeEvent(QResizeEvent */*event*/) +{ + lblPrompt->setGeometry(0, 0, width(), 40); + lblDeviceType->setGeometry(100, lblPrompt->geometry().bottom() + 40, + 120, 20); + cmbDeviceType->setGeometry(100, lblDeviceType->geometry().bottom() + 15, + 300, 40); + lblDeviceName->setGeometry(100, cmbDeviceType->geometry().bottom() + 80, + 120, 20); + cmbDeviceName->setGeometry(100, lblDeviceName->geometry().bottom() + 15, + 300, 40); + btnOK->setGeometry(100, cmbDeviceName->geometry().bottom() + 80, 140, 38); + +} + +void BiometricDevicesWidget::updateDevice() +{ + deviceMap.clear(); + DeviceList deviceList = proxy->GetDevList(); + for(auto pDeviceInfo : deviceList) + { + qDebug() << *pDeviceInfo; + if(proxy->GetUserDevFeatureCount(m_uid,pDeviceInfo->id) > 0) + deviceMap[pDeviceInfo->deviceType].push_back(pDeviceInfo); + } + cmbDeviceType->clear(); + for(int type : deviceMap.keys()) + { + QString iconPath = QString(UKUI_BIOMETRIC_IMAGES_PATH"icon/%1.png") + .arg(DeviceType::getDeviceType(type)); + qDebug() << iconPath; + cmbDeviceType->addItem(QIcon(iconPath), DeviceType::getDeviceType_tr(type), type); + } + if(deviceMap.size() > 0) + { + int index = deviceMap.keys().at(0); + setCurrentDevice(deviceMap[index].at(0)); + } + +} + + +void BiometricDevicesWidget::setCurrentDevice(int drvid) +{ + DeviceInfoPtr pDeviceInfo = findDeviceById(drvid); + if(pDeviceInfo) + { + setCurrentDevice(pDeviceInfo); + } +} + +void BiometricDevicesWidget::setCurrentDevice(const QString &deviceName) +{ + DeviceInfoPtr pDeviceInfo = findDeviceByName(deviceName); + if(pDeviceInfo) + { + setCurrentDevice(pDeviceInfo); + } +} + +void BiometricDevicesWidget::setCurrentDevice(const DeviceInfoPtr &pDeviceInfo) +{ + this->currentDevice = pDeviceInfo; + cmbDeviceType->setCurrentText(DeviceType::getDeviceType_tr(pDeviceInfo->deviceType)); + cmbDeviceName->setCurrentText(pDeviceInfo->shortName); +} + +bool BiometricDevicesWidget::deviceExists(int drvid) +{ + return (findDeviceById(drvid) != nullptr); +} + +bool BiometricDevicesWidget::deviceExists(const QString &deviceName) +{ + return (findDeviceByName(deviceName) != nullptr); +} + +DeviceInfoPtr BiometricDevicesWidget::findDeviceById(int drvid) +{ + for(int type : deviceMap.keys()) + { + DeviceList &deviceList = deviceMap[type]; + auto iter = std::find_if(deviceList.begin(), deviceList.end(), + [&](DeviceInfoPtr ptr){ + return ptr->id == drvid; + }); + if(iter != deviceList.end()) + { + return *iter; + } + } + return DeviceInfoPtr(); +} + +DeviceInfoPtr BiometricDevicesWidget::findDeviceByName(const QString &name) +{ + for(int type : deviceMap.keys()) + { + DeviceList &deviceList = deviceMap[type]; + auto iter = std::find_if(deviceList.begin(), deviceList.end(), + [&](DeviceInfoPtr ptr){ + return ptr->shortName == name; + }); + if(iter != deviceList.end()) + { + return *iter; + } + } + return DeviceInfoPtr(); +} + +void BiometricDevicesWidget::onCmbDeviceTypeCurrentIndexChanged(int index) +{ + if(index < 0 || index >= deviceMap.keys().size()) + { + return; + } + int type = cmbDeviceType->itemData(index).toInt(); + cmbDeviceName->clear(); + for(auto &deviceInfo : deviceMap.value(type)) + { + cmbDeviceName->addItem(deviceInfo->shortName); + } +} + +void BiometricDevicesWidget::onOKButtonClicked() +{ + int type = cmbDeviceType->currentData().toInt(); + int index = cmbDeviceName->currentIndex(); + qDebug() << type << index; + DeviceInfoPtr deviceInfo = deviceMap.value(type).at(index); + Q_EMIT deviceChanged(deviceInfo); + hide(); +} + +void BiometricDevicesWidget::onUSBDeviceHotPlug(int drvid, int action, int /*devNum*/) +{ + int savedDeviceId = currentDevice->id; + int savedCount = 0; + for(int type : deviceMap.keys()) + savedCount += deviceMap.value(type).count(); + + switch(action) + { + case ACTION_ATTACHED: + { + //插入设备后,需要更新设备列表 + deviceMap.clear(); + updateDevice(); + setCurrentDevice(savedDeviceId); + break; + } + case ACTION_DETACHED: + { + DeviceInfoPtr pDeviceInfo = findDeviceById(drvid); + if(pDeviceInfo) + { + int type = pDeviceInfo->deviceType; + deviceMap[type].removeOne(pDeviceInfo); + int index = cmbDeviceName->findText(pDeviceInfo->shortName); + cmbDeviceName->removeItem(index); + + //如果该类型的设备全被移除,删除该类型相关的列表 + if(deviceMap[type].isEmpty()) + { + deviceMap.remove(type); + index = cmbDeviceType->findData(type); + cmbDeviceType->removeItem(index); + } + } + if(savedDeviceId != drvid) + { + setCurrentDevice(savedDeviceId); + } + break; + } + } + + int count = 0; + for(int type : deviceMap.keys()) + count += deviceMap.value(type).count(); + + //设备数量发生了变化 + if(count != savedCount) + { + Q_EMIT deviceCountChanged(count); + } +} + + diff --git a/BiometricAuth/biometricdeviceswidget.h b/BiometricAuth/biometricdeviceswidget.h new file mode 100644 index 0000000..d606aef --- /dev/null +++ b/BiometricAuth/biometricdeviceswidget.h @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2018 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, 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 BIOMETRICDEVICESWIDGET_H +#define BIOMETRICDEVICESWIDGET_H + +#include +#include "biometricproxy.h" + +class QLabel; +class QPushButton; +class QComboBox; + + +class BiometricDevicesWidget : public QWidget +{ + Q_OBJECT +public: + explicit BiometricDevicesWidget(BiometricProxy *proxy, int uid,QWidget *parent = nullptr); + void setCurrentDevice(int drvid); + void setCurrentDevice(const QString &deviceName); + void setCurrentDevice(const DeviceInfoPtr &pDeviceInfo); + DeviceInfoPtr findDeviceById(int drvid); + DeviceInfoPtr findDeviceByName(const QString &name); + bool deviceExists(int drvid); + bool deviceExists(const QString &deviceName); + void setUser(int user); + +protected: + void resizeEvent(QResizeEvent *event); + +Q_SIGNALS: + void deviceChanged(const DeviceInfoPtr &pDeviceInfo); + void deviceCountChanged(int newCount); + +public Q_SLOTS: + void onOKButtonClicked(); + +private Q_SLOTS: + void onCmbDeviceTypeCurrentIndexChanged(int index); + void onUSBDeviceHotPlug(int drvid, int action, int devNum); + +private: + void initUI(); + void updateDevice(); + +private: + typedef QMap QButtonMap; + + QLabel *lblPrompt; + QLabel *lblDeviceType; + QLabel *lblDeviceName; + QComboBox *cmbDeviceType; + QComboBox *cmbDeviceName; + QPushButton *btnOK; + QPushButton *btnCancel; + + BiometricProxy *proxy; + DeviceMap deviceMap; + DeviceInfoPtr currentDevice; + int m_uid; +}; + +#endif // BIOMETRICDEVICESWIDGET_H diff --git a/BiometricAuth/biometricproxy.cpp b/BiometricAuth/biometricproxy.cpp new file mode 100644 index 0000000..85637a4 --- /dev/null +++ b/BiometricAuth/biometricproxy.cpp @@ -0,0 +1,212 @@ +/** + * Copyright (C) 2018 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, 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 "biometricproxy.h" +#include + +BiometricProxy::BiometricProxy(QObject *parent) + : QDBusAbstractInterface(BIOMETRIC_DBUS_SERVICE, + BIOMETRIC_DBUS_PATH, + BIOMETRIC_DBUS_INTERFACE, + QDBusConnection::systemBus(), + parent) +{ + registerMetaType(); + setTimeout(2147483647); +} + +QDBusPendingCall BiometricProxy::Identify(int drvid, int uid, int indexStart, int indexEnd) +{ + QList argList; + argList << drvid << uid << indexStart << indexEnd; + return asyncCallWithArgumentList(QStringLiteral("Identify"), argList); +} + +int BiometricProxy::GetFeatureCount(int uid, int indexStart, int indexEnd) +{ + QDBusMessage result = call(QStringLiteral("GetDevList")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return 0; + } + auto dbusArg = result.arguments().at(1).value(); + QList variantList; + dbusArg >> variantList; + int res = 0; + for(int i = 0; i < variantList.size(); i++) + { + + DeviceInfoPtr pDeviceInfo = std::make_shared(); + + auto arg = variantList.at(i).value(); + arg >> *pDeviceInfo; + + QDBusMessage FeatureResult = call(QStringLiteral("GetFeatureList"),pDeviceInfo->id,uid,indexStart,indexEnd); + if(FeatureResult.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetFeatureList error:" << FeatureResult.errorMessage(); + return 0; + } + res += FeatureResult.arguments().takeFirst().toInt(); + } + return res; +} + +int BiometricProxy::StopOps(int drvid, int waiting) +{ + QDBusReply reply = call(QStringLiteral("StopOps"), drvid, waiting); + if(!reply.isValid()) + { + qWarning() << "StopOps error:" << reply.error(); + return -1; + } + return reply.value(); +} + +int BiometricProxy::GetUserDevCount(int uid) +{ + QDBusMessage result = call(QStringLiteral("GetDevList")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return 0; + } + auto dbusArg = result.arguments().at(1).value(); + QList variantList; + DeviceList deviceList; + dbusArg >> variantList; + for(int i = 0; i < variantList.size(); i++) + { + DeviceInfoPtr pDeviceInfo = std::make_shared(); + + auto arg = variantList.at(i).value(); + arg >> *pDeviceInfo; + + int count = GetUserDevFeatureCount(uid,pDeviceInfo->id); + + if(count>0) + deviceList.push_back(pDeviceInfo); + } + + return deviceList.count(); +} + +int BiometricProxy::GetUserDevFeatureCount(int uid,int drvid) +{ + StopOps(drvid); + QDBusMessage FeatureResult = call(QStringLiteral("GetFeatureList"),drvid,uid,0,-1); + if(FeatureResult.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetFeatureList error:" << FeatureResult.errorMessage(); + return 0; + } + return FeatureResult.arguments().takeFirst().toInt(); +} + +DeviceList BiometricProxy::GetDevList() +{ + QDBusMessage result = call(QStringLiteral("GetDevList")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return DeviceList(); + } + auto dbusArg = result.arguments().at(1).value(); + QList variantList; + DeviceList deviceList; + dbusArg >> variantList; + for(int i = 0; i < variantList.size(); i++) + { + DeviceInfoPtr pDeviceInfo = std::make_shared(); + + auto arg = variantList.at(i).value(); + arg >> *pDeviceInfo; + + deviceList.push_back(pDeviceInfo); + + } + + return deviceList; +} + +int BiometricProxy::GetDevCount() +{ + QDBusMessage result = call(QStringLiteral("GetDevList")); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return 0; + } + int count = result.arguments().at(0).value(); + return count; +} + +QString BiometricProxy::GetDevMesg(int drvid) +{ + QDBusMessage result = call(QStringLiteral("GetDevMesg"), drvid); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevMesg error:" << result.errorMessage(); + return ""; + } + return result.arguments().at(0).toString(); +} + +QString BiometricProxy::GetNotifyMesg(int drvid) +{ + QDBusMessage result = call(QStringLiteral("GetNotifyMesg"), drvid); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetNotifyMesg error:" << result.errorMessage(); + return ""; + } + return result.arguments().at(0).toString(); +} + +QString BiometricProxy::GetOpsMesg(int drvid) +{ + QDBusMessage result = call(QStringLiteral("GetOpsMesg"), drvid); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetOpsMesg error:" << result.errorMessage(); + return ""; + } + return result.arguments().at(0).toString(); +} + +StatusReslut BiometricProxy::UpdateStatus(int drvid) +{ + StatusReslut status; + QDBusMessage result = call(QStringLiteral("UpdateStatus"), drvid); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "UpdateStatus error:" << result.errorMessage(); + status.result = -1; + return status; + } + + status.result = result.arguments().at(0).toInt(); + status.enable = result.arguments().at(1).toInt(); + status.devNum = result.arguments().at(2).toInt(); + status.devStatus = result.arguments().at(3).toInt(); + status.opsStatus = result.arguments().at(4).toInt(); + status.notifyMessageId = result.arguments().at(5).toInt(); + + return status; +} diff --git a/BiometricAuth/biometricproxy.h b/BiometricAuth/biometricproxy.h new file mode 100644 index 0000000..ac03881 --- /dev/null +++ b/BiometricAuth/biometricproxy.h @@ -0,0 +1,139 @@ +/** + * Copyright (C) 2018 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, 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 BIOMETRICPROXY_H +#define BIOMETRICPROXY_H + +#include +#include +#include +#include "biometricdeviceinfo.h" + +/** + * @brief UpdateStauts调用返回的结果 + */ +struct StatusReslut +{ + int result; + int enable; + int devNum; + int devStatus; + int opsStatus; + int notifyMessageId; +}; + +/** + * @brief USB设备插拔动作 + */ +enum USBDeviceAction +{ + ACTION_ATTACHED = 1, + ACTION_DETACHED = -1 +}; + +/** + * @brief DBus代理类,负责调用对应的DBus接口 + */ +class BiometricProxy : public QDBusAbstractInterface +{ + Q_OBJECT +public: + explicit BiometricProxy(QObject *parent = nullptr); + +public Q_SLOTS: + /** + * @brief 使用指定id的设备进行用户认证 + * @param drvid 驱动(设备)id + * @param uid 用户id + * @param indexStart 用于认证的特征索引范围 + * @param indexEnd + * @return 结果: (结果,用户id) + */ + QDBusPendingCall Identify(int drvid, int uid, int indexStart = 0, int indexEnd = -1); + /** + * @brief 终止设备上正在进行的操作 + * @param drvid 设备id + * @param waiting 等待时间(秒) + * @return + */ + int StopOps(int drvid, int waiting = 3000); + /** + * @brief 获取当前用户已连接设备对应特征数目 + * @param uid 用户id + * @param indexStart 用于认证的特征索引范围 + * @param indexEnd + * @return + */ + int GetFeatureCount(int uid, int indexStart = 0, int indexEnd = -1); + /** + * @brief 获取已连接的设备列表 + * @return + */ + DeviceList GetDevList(); + /** + * @brief 获取设备数量 + * @return + */ + int GetDevCount(); + /** + * @brief 获取设备消息 + * @param drvid 驱动id + * @return + */ + QString GetDevMesg(int drvid); + /** + * @brief GetNotifyMesg 获取通知消息 + * @param drvid 驱动id + * @return + */ + QString GetNotifyMesg(int drvid); + /** + * @brief GetOpsMesg 获取操作消息 + * @param drvid 驱动id + * @return + */ + QString GetOpsMesg(int drvid); + /** + * @brief UpdateStatus 获取更新的设备状态 + * @param drvid 驱动id + * @return 结果: + */ + StatusReslut UpdateStatus(int drvid); + int GetUserDevCount(int uid); + int GetUserDevFeatureCount(int uid,int drvid); + + +Q_SIGNALS: + /** + * @brief 设备状态发生变化 + * @param drvid 设备id + * @param status 设备状态 + */ + void StatusChanged(int drvid, int status); + /** + * @brief USB设备热插拔 + * @param drvid 设备id + * @param action 插拔动作(1:插入,-1:拔出) + * @param deviceNum 插拔动作后该驱动拥有的设备数量 + */ + void USBDeviceHotPlug(int drvid, int action, int deviceNum); + void FrameWritten(int drvid); +}; + +#endif // BIOMETRICPROXY_H diff --git a/BiometricAuth/giodbus.cpp b/BiometricAuth/giodbus.cpp new file mode 100644 index 0000000..9e0490e --- /dev/null +++ b/BiometricAuth/giodbus.cpp @@ -0,0 +1,54 @@ +#include "giodbus.h" +#include +#include +#include + +int get_server_gvariant_stdout (int drvid) +{ + GDBusMessage *method_call_message; + GDBusMessage *method_reply_message; + GUnixFDList *fd_list; + GError **error = NULL; + + gint fd,dup_fd; + const gchar * response; + fd = -1; + dup_fd = -1; + method_call_message = NULL; + method_reply_message = NULL; + GDBusConnection *con = g_bus_get_sync(G_BUS_TYPE_SYSTEM,NULL,NULL); + method_call_message = g_dbus_message_new_method_call ("org.ukui.Biometric", + "/org/ukui/Biometric", + "org.ukui.Biometric", + "GetFrameFd"); + + g_dbus_message_set_body (method_call_message, g_variant_new ("(i)", drvid)); + method_reply_message = g_dbus_connection_send_message_with_reply_sync (con, + method_call_message, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + -1, + NULL, /* out_serial */ + NULL, /* cancellable */ + error); + if (method_reply_message == NULL) + goto out; + + if (g_dbus_message_get_message_type (method_reply_message) == G_DBUS_MESSAGE_TYPE_ERROR) + { + g_dbus_message_to_gerror (method_reply_message, error); + goto out; + } + g_print("%s",g_dbus_message_print(method_reply_message,0)); + + fd_list = g_dbus_message_get_unix_fd_list(method_reply_message); + fd = g_unix_fd_list_get(fd_list,0,error); + g_print("get fd : %d\n", fd); + dup_fd = dup(fd); + g_print("dup fd : %d\n", dup_fd); + +out: + g_object_unref (method_call_message); + g_object_unref (method_reply_message); + return dup_fd; + +} diff --git a/BiometricAuth/giodbus.h b/BiometricAuth/giodbus.h new file mode 100644 index 0000000..13e0880 --- /dev/null +++ b/BiometricAuth/giodbus.h @@ -0,0 +1,6 @@ +#ifndef GIODBUS_H +#define GIODBUS_H + +int get_server_gvariant_stdout(int drvid); + +#endif diff --git a/BiometricAuth/main.cpp b/BiometricAuth/main.cpp new file mode 100644 index 0000000..6215ae1 --- /dev/null +++ b/BiometricAuth/main.cpp @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2018 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, 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 +#include +#include "biometricproxy.h" +#include "biometricauthwidget.h" +#include "biometricdeviceswidget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + BiometricProxy proxy; + BiometricAuthWidget biometricAuthWidget(&proxy); + biometricAuthWidget.hide(); + BiometricDevicesWidget biometricDeviceWidget(&proxy); + QObject::connect(&biometricDeviceWidget, &BiometricDevicesWidget::deviceChanged, + &a, [&](const DeviceInfoPtr &pDeviceInfo){ + biometricAuthWidget.startAuth(pDeviceInfo, 1000); + biometricAuthWidget.show(); + }); + QObject::connect(&biometricDeviceWidget, &BiometricDevicesWidget::deviceCountChanged, + &a, [&](int count){ + qDebug() << "device count changed: " << count; + }); + biometricDeviceWidget.show(); + + return a.exec(); +} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9e63621 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,67 @@ +cmake_minimum_required(VERSION 2.6) +project(ukui-screensaver) + +find_package(Qt5 COMPONENTS Core Widgets DBus X11Extras Xml Network Svg) +find_package(PkgConfig REQUIRED) +find_package(OpenCV REQUIRED) +find_package(PkgConfig) +pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0) +pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0) + +# 是否是intel项目 +option (USE_INTEL "intel项目" OFF) +# 用于测试替换用的变量 +set(TEST_ON 1) +set(TEST_OF 0) +set(VAR "VAR_NEW") + +# 加入一个配置头文件,用于处理 CMake 对源码的设置 +configure_file ( + "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/config.h" +) + +set(TS_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/i18n_ts/zh_CN.ts + ${CMAKE_CURRENT_SOURCE_DIR}/i18n_ts/es.ts + ${CMAKE_CURRENT_SOURCE_DIR}/i18n_ts/fr.ts + ${CMAKE_CURRENT_SOURCE_DIR}/i18n_ts/bo_CN.ts + ${CMAKE_CURRENT_SOURCE_DIR}/i18n_ts/pt.ts + ${CMAKE_CURRENT_SOURCE_DIR}/i18n_ts/ru.ts + ${CMAKE_CURRENT_SOURCE_DIR}/i18n_ts/tr.ts + ) +add_custom_command( + OUTPUT ${TS_FILES} + COMMAND lupdate src/ screensaver/ -ts ${TS_FILES} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + ) +add_custom_target( + i18n_ts + DEPENDS ${TS_FILES} + ) +add_compile_options(-fPIC) + +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror") +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_INSTALL_PREFIX /usr) + +set(Debug ON) +if(Debug) + set(CMAKE_BUILD_TYPE "Debug") +endif() + +#add_subdirectory(BioAuth) +add_subdirectory(BiometricAuth) +add_subdirectory(VirtualKeyboard) +add_subdirectory(src) +add_subdirectory(i18n_ts) +add_subdirectory(set4kScale) +add_subdirectory(data) +add_subdirectory(screensaver) +add_subdirectory(screensaver-focus-helper) +add_subdirectory(Common) +add_subdirectory(KylinNM) + +add_dependencies(ukui-screensaver-dialog BiometricAuth VirtualKeyboard Common) +add_dependencies(ukui-screensaver-default Common) diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt new file mode 100644 index 0000000..5390d95 --- /dev/null +++ b/Common/CMakeLists.txt @@ -0,0 +1,22 @@ +qt5_wrap_cpp(Common_SRC + autoresize.h + checkbutton.h + commonfunc.h + ) + +set(Common_SRC + ${Common_SRC} + autoresize.cpp + checkbutton.cpp + commonfunc.cpp + ) + +include_directories( + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ${Qt5DBus_INCLUDE_DIRS} + ) + + +add_library(Common STATIC ${Common_SRC}) +target_link_libraries(Common Qt5::Core Qt5::DBus Qt5::Widgets) diff --git a/Common/autoresize.cpp b/Common/autoresize.cpp new file mode 100644 index 0000000..c5301e9 --- /dev/null +++ b/Common/autoresize.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#include "autoresize.h" + +AutoResize::AutoResize(QWidget* obj,int baseWidth,int baseHeight): + obj(obj), + baseWidth(baseWidth), + baseHeight(baseHeight) +{ + +} + +AutoResize::~AutoResize(void) +{ +} + diff --git a/Common/autoresize.h b/Common/autoresize.h new file mode 100644 index 0000000..610a2f9 --- /dev/null +++ b/Common/autoresize.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#ifndef AUTORESIZE_H +#define AUTORESIZE_H + +#include + +struct AutoResizeOriginalData +{ + QRect data_rect; + QFont data_font; +}; +class AutoResize +{ +public: + AutoResize(QWidget* obj,int baseWidth,int baseHeight); + ~AutoResize(void); +private: + QWidget *obj; + int baseWidth; + int baseHeight; + +}; + +#endif diff --git a/Common/checkbutton.cpp b/Common/checkbutton.cpp new file mode 100644 index 0000000..14ae327 --- /dev/null +++ b/Common/checkbutton.cpp @@ -0,0 +1,186 @@ +/* -*- 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 "checkbutton.h" + +checkButton::checkButton(QWidget *parent) + :QFrame(parent) +{ + this->setFixedSize(QSize(52, 24)); + checked = false; + + borderColorOff = QColor("#cccccc"); + + bgColorOff = QColor("#ffffff"); + bgColorOn = QColor("#0078d7"); + + sliderColorOff = QColor("#cccccc"); + sliderColorOn = QColor("#ffffff"); + + space = 4; + + + step = width() / 50; + startX = 0; + endX= 0; + + timer = new QTimer(this); + timer->setInterval(5); + connect(timer, SIGNAL(timeout()), this, SLOT(updatevalue())); + setWindowFlags(Qt::FramelessWindowHint); + setAttribute(Qt::WA_TranslucentBackground, true); + + +} + +void checkButton::paintEvent(QPaintEvent *){ + //启用反锯齿 + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + + drawBg(&painter); + drawSlider(&painter); +} + + +void checkButton::drawBg(QPainter *painter){ + painter->save(); + + if (!checked){ + painter->setPen(QColor(255,255,255,30)); + painter->setBrush(QColor(255,255,255,30)); + } + else{ + painter->setPen(Qt::NoPen); + painter->setBrush(bgColorOn); + } + + //circle in + QRect rect(0, 0, width(), height()); + //半径为高度的一半 + int radius = rect.height() / 2; + //圆的宽度为高度 + int circleWidth = rect.height(); + + QPainterPath path; + path.moveTo(radius, rect.left()); + path.arcTo(QRectF(rect.left(), rect.top(), circleWidth, circleWidth), 90, 180); + path.lineTo(rect.width() - radius, rect.height()); + path.arcTo(QRectF(rect.width() - rect.height(), rect.top(), circleWidth, circleWidth), 270, 180); + path.lineTo(radius, rect.top()); + + painter->drawPath(path); + + painter->restore(); + +} + + +void checkButton::drawSlider(QPainter *painter){ + painter->save(); + painter->setPen(Qt::NoPen); + + if (!checked){ + painter->setBrush(sliderColorOff); + } + else + painter->setBrush(sliderColorOn); + + //circle in + QRect rect(0, 0, width(), height()); + int sliderWidth = rect.height() - space * 2; + QRect sliderRect(startX + space, space, sliderWidth, sliderWidth); + painter->drawEllipse(sliderRect); + + painter->restore(); +} + +void checkButton::mousePressEvent(QMouseEvent *){ + checked = !checked; + emit checkedChanged(checked); + + step = width() / 50; + + if (checked){ + + endX = width() - height(); + } + else{ + endX = 0; + } + timer->start(); +} + +void checkButton::resizeEvent(QResizeEvent *){ + step = width() / 50; + + if (checked){ + startX = width() - height(); + } + else + startX = 0; + + update(); +} + +void checkButton::updatevalue(){ + if (checked) + if (startX < endX){ + startX = startX + step; + } + else{ + startX = endX; + timer->stop(); + } + else{ + if (startX > endX){ + startX = startX - step; + } + else{ + startX = endX; + timer->stop(); + } + } + update(); +} + + +void checkButton::setChecked(bool checked){ + if (this->checked != checked){ + this->checked = checked; + emit checkedChanged(checked); + update(); + } + + step = width() / 50; + + if (checked){ + endX = width() - height(); + } + else{ + endX = 0; + } + timer->start(); +} + +bool checkButton::isChecked(){ + return this->checked; +} + diff --git a/Common/checkbutton.h b/Common/checkbutton.h new file mode 100644 index 0000000..d6167c9 --- /dev/null +++ b/Common/checkbutton.h @@ -0,0 +1,73 @@ +/* -*- 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 CHECKBUTTON_H +#define CHECKBUTTON_H +#include +#include +#include +#include +#include +#include + +class checkButton : public QFrame +{ + Q_OBJECT +public: + checkButton(QWidget *parent = 0); + void setChecked(bool checked); + + bool isChecked(); + +protected: + void mousePressEvent(QMouseEvent *); + void resizeEvent(QResizeEvent *); + void paintEvent(QPaintEvent *); + +private: + bool checked; + + QColor borderColorOff; + QColor bgColorOff; + QColor bgColorOn; + QColor sliderColorOff; + QColor sliderColorOn; + int space; //滑块离背景间隔 + int rectRadius; //圆角角度 + int step; //移动步长 + int startX; + int endX; + QTimer * timer; + + void drawBg(QPainter *painter); + void drawSlider(QPainter *painter); + + +private Q_SLOTS: + void updatevalue(); + + +Q_SIGNALS: + void checkedChanged(bool checked); + + +}; + +#endif // CHECKBUTTON_H diff --git a/Common/commonfunc.cpp b/Common/commonfunc.cpp new file mode 100644 index 0000000..150bd5c --- /dev/null +++ b/Common/commonfunc.cpp @@ -0,0 +1,77 @@ +/* -*- 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 +#include +#include +#include +#include +#include "commonfunc.h" + +bool ispicture(QString filepath) +{ + QFileInfo file(filepath); + if(file.exists() == false) + return false; + + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile(filepath); + return mime.name().startsWith("image/"); +} + +QString getSystemVersion() +{ + QSettings settings("/etc/lsb-release", QSettings::IniFormat); + QString release = settings.value("DISTRIB_RELEASE").toString(); + QString description = settings.value("DISTRIB_DESCRIPTION").toString(); + if(description.right(3) == "LTS") + release = release + " LTS"; + return release; +} + +QString getSystemDistrib() +{ + QSettings settings("/etc/lsb-release", QSettings::IniFormat); + QString distribId = settings.value("DISTRIB_ID").toString(); + return distribId; +} + +bool getUseFirstDevice() +{ + QSettings settings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat); + return settings.value("UseFirstDevice").toBool(); +} + +commonFunc::commonFunc() +{ + +} + +QString ElideText(QFont font,int width,QString strInfo) +{ + QFontMetrics fontMetrics(font); + //如果当前字体下,字符串长度大于指定宽度 + if(fontMetrics.width(strInfo) > width) + { + strInfo= QFontMetrics(font).elidedText(strInfo, Qt::ElideRight, width); + } + return strInfo; +} + diff --git a/Common/commonfunc.h b/Common/commonfunc.h new file mode 100644 index 0000000..3e23bb3 --- /dev/null +++ b/Common/commonfunc.h @@ -0,0 +1,39 @@ +/* -*- 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 COMMONFUNC_H +#define COMMONFUNC_H + +#include +#include + +bool ispicture(QString filepath); +QString getSystemVersion(); +QString getSystemDistrib(); +bool getUseFirstDevice(); +QString ElideText(QFont font,int width,QString strInfo); + +class commonFunc +{ +public: + commonFunc(); +}; + +#endif // COMMONFUNC_H diff --git a/KylinNM/CMakeLists.txt b/KylinNM/CMakeLists.txt new file mode 100644 index 0000000..f9577ea --- /dev/null +++ b/KylinNM/CMakeLists.txt @@ -0,0 +1,95 @@ +find_package(Qt5 COMPONENTS Core Widgets REQUIRED) +find_package(X11 REQUIRED) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) +#pkg_check_modules(X11 REQUIRED x11) + +qt5_wrap_ui(Kylin_NM_SRC + src/confform.ui + src/kylinnm.ui + src/oneconnform.ui + src/onelancform.ui + wireless-security/dlgconnhidwifi.ui + wireless-security/dlgconnhidwifisecfast.ui + wireless-security/dlgconnhidwifisectunneltls.ui + wireless-security/dlgconnhidwifisecpeap.ui + wireless-security/dlgconnhidwifisectls.ui + wireless-security/dlgconnhidwifisecleap.ui + wireless-security/dlgconnhidwifisecpwd.ui + wireless-security/dlgconnhidwifiwep.ui + wireless-security/dlgconnhidwifileap.ui + wireless-security/dlgconnhidwifiwpa.ui + hot-spot/dlghotspotcreate.ui + ) + +#qt5_wrap_cpp(Kylin_NM_SRC +# src/backthread.h +# src/confform.h +# src/ksimplenm.h +# src/kylin-dbus-interface.h +# src/kylin-network-interface.h +# src/loadingdiv.h +# src/kylinnm.h +# src/oneconnform.h +# src/onelancform.h +# src/switchbutton.h +# src/utils.h +# wireless-security/dlgconnhidwifi.h +# wireless-security/dlgconnhidwifisecfast.h +# wireless-security/dlgconnhidwifisectunneltls.h +# wireless-security/dlgconnhidwifisecpeap.h +# wireless-security/dlgconnhidwifisectls.h +# wireless-security/dlgconnhidwifisecleap.h +# wireless-security/dlgconnhidwifisecpwd.h +# wireless-security/dlgconnhidwifiwep.h +# wireless-security/dlgconnhidwifileap.h +# wireless-security/dlgconnhidwifiwpa.h +# wireless-security/kylinheadfile.h +# hot-spot/dlghotspotcreate.h +# ) + +qt5_add_resources(Kylin_NM_SRC + nmqrc.qrc + res.qrc) + +set(Kylin_NM_SRC + ${Kylin_NM_SRC} + src/backthread.cpp + src/confform.cpp + src/ksimplenm.cpp + src/kylin-dbus-interface.cpp + src/kylin-network-interface.c + src/loadingdiv.cpp + src/kylinnm.cpp + src/oneconnform.cpp + src/onelancform.cpp + src/switchbutton.cpp + src/utils.cpp + src/swipegesturerecognizer.cpp + wireless-security/dlgconnhidwifi.cpp + wireless-security/dlgconnhidwifisecfast.cpp + wireless-security/dlgconnhidwifisectunneltls.cpp + wireless-security/dlgconnhidwifisecpeap.cpp + wireless-security/dlgconnhidwifisectls.cpp + wireless-security/dlgconnhidwifisecleap.cpp + wireless-security/dlgconnhidwifisecpwd.cpp + wireless-security/dlgconnhidwifiwep.cpp + wireless-security/dlgconnhidwifileap.cpp + wireless-security/dlgconnhidwifiwpa.cpp + wireless-security/kylinheadfile.cpp + hot-spot/dlghotspotcreate.cpp + nmqrc.qrc + ) + +include_directories( + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ${Qt5DBus_INCLUDE_DIRS} + ) + +find_package(KF5WindowSystem) + +add_library(Kylin-nm STATIC ${Kylin_NM_SRC}) +target_link_libraries(Kylin-nm Qt5::Core Qt5::Widgets KF5::WindowSystem Qt5::DBus Qt5::X11Extras) diff --git a/KylinNM/README.md b/KylinNM/README.md new file mode 100644 index 0000000..a59ec5e --- /dev/null +++ b/KylinNM/README.md @@ -0,0 +1,15 @@ +# NAME + kylin-nm - kylin network monitor used in ubuntu-kylin operation system + +# DESCRIPTION + kylin-nm is a Qt based applet and uses some interface provided by NetworkManager. + It provides a GUI for users to connect or disconnect wired or wireless network which managed by NetworkManager. + Users can also create new wired network and configure a old network. + By click button at left bottom in the main window, a network configure window of NetworkManager will show in the screen. + Users can get some information about network directly by clicking one item in the network list, these information shown in extension area. + +# BUILD KYLIN-NM + down the source sode + install dependency packages(see cntrol files in the debian directory) + execute debuild command in the root directory of project + execute sudo dpkg -i packagename.deb to install diff --git a/KylinNM/hot-spot/dlghotspotcreate.cpp b/KylinNM/hot-spot/dlghotspotcreate.cpp new file mode 100644 index 0000000..a64e249 --- /dev/null +++ b/KylinNM/hot-spot/dlghotspotcreate.cpp @@ -0,0 +1,155 @@ +/* + * 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 setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setStyleSheet("background-color:white;"); + + ui->lbLeftup->setStyleSheet("QLabel{background-color:#266ab5;}"); + ui->lbLeftupIcon->setStyleSheet("QLabel{background-image:url(:/res/h/no-pwd-wifi.png);background-color:transparent;}"); + ui->lbLeftupTitle->setStyleSheet("QLabel{font-size:12px;color:#ffffff;background-color:transparent;}"); + ui->btnCancel->setStyleSheet("QPushButton{border:1px solid #aaaaaa;background-color:#f5f5f5;}" + "QPushButton:Hover{border:2px solid #629ee8;background-color:#eeeeee;}" + "QPushButton:Pressed{border:1px solid #aaaaaa;background-color:#d8d8d8;}"); + ui->btnOk->setStyleSheet("QPushButton{border:1px solid #aaaaaa;background-color:#f5f5f5;}" + "QPushButton:Hover{border:2px solid #629ee8;background-color:#eeeeee;}" + "QPushButton:Pressed{border:1px solid #aaaaaa;background-color:#d8d8d8;}"); + ui->checkBoxPwd->setStyleSheet("QCheckBox::indicator {width: 18px; height: 9px;}" + "QCheckBox::indicator:checked {image: url(:/res/h/show-pwd.png);}" + "QCheckBox::indicator:unchecked {image: url(:/res/h/hide-pwd.png);}"); + + ui->lbLeftupTitle->setText(tr("Create Hotspot")); //创建个人热点 + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi 安全性: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnOk->setText(tr("Ok")); //确定 + ui->btnOk->setEnabled(false); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->setCurrentIndex(1); + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialog())); +} + +DlgHotspotCreate::~DlgHotspotCreate() +{ + delete ui; +} + +void DlgHotspotCreate::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgHotspotCreate::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; + this->setWindowOpacity(1); +} +void DlgHotspotCreate::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + this->setWindowOpacity(0.9); + event->accept(); + } +} + +void DlgHotspotCreate::on_btnCancel_clicked() +{ + this->close(); + emit btnHotspotState(); +} + +void DlgHotspotCreate::on_btnOk_clicked() +{ + //nmcli device wifi hotspot [ifname ifname] [con-name name] [ssid SSID] [band {a | bg}] [channel channel] [password password] + //example: nmcli device wifi hotspot ifname wlan0 con-name MyHostspot ssid MyHostspotSSID password 12345678 + QString str; + if(ui->cbxSecurity->currentIndex() == 0 ){ + str = "nmcli device wifi hotspot ifname " + wirelessCardName + " con-name " + ui->leNetName->text() + " ssid " + ui->leNetName->text() + "SSID"; + }else{ + str = "nmcli device wifi hotspot ifname " + wirelessCardName + " con-name " + ui->leNetName->text() + " ssid " + ui->leNetName->text() + " password " + ui->lePassword->text(); + } + Utils::m_system(str.toUtf8().data()); +// int status = system(str.toUtf8().data()); +// if (status != 0){ syslog(LOG_ERR, "execute 'nmcli device wifi hotspot' in function 'on_btnOk_clicked' failed");} + + this->close(); + emit updateHotspotList(); +} + +void DlgHotspotCreate::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword ->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgHotspotCreate::on_leNetName_textEdited(const QString &arg1) +{ + if(ui->cbxSecurity->currentIndex() == 0 ){ + if (ui->leNetName->text() == ""){ + ui->btnOk->setEnabled(false); + } else { + ui->btnOk->setEnabled(true); + } + }else{ + if (ui->leNetName->text() == "" || ui->lePassword->text().size() < 5){ + ui->btnOk->setEnabled(false); + } else { + ui->btnOk->setEnabled(true); + } + } +} + +void DlgHotspotCreate::on_lePassword_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == "" || ui->lePassword->text().size() < 5){ + ui->btnOk->setEnabled(false); + } else { + ui->btnOk->setEnabled(true); + } +} + +void DlgHotspotCreate::changeDialog() +{ + if(ui->cbxSecurity->currentIndex()==0){ + ui->lbPassword->setEnabled(false); + ui->lePassword->setEnabled(false); + ui->checkBoxPwd->setEnabled(false); + } else { + ui->lbPassword->setEnabled(true); + ui->lePassword->setEnabled(true); + ui->checkBoxPwd->setEnabled(true); + } +} diff --git a/KylinNM/hot-spot/dlghotspotcreate.h b/KylinNM/hot-spot/dlghotspotcreate.h new file mode 100644 index 0000000..11a884d --- /dev/null +++ b/KylinNM/hot-spot/dlghotspotcreate.h @@ -0,0 +1,71 @@ +/* + * 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 + +#include +#include +#include + +namespace Ui { +class DlgHotspotCreate; +} + +class DlgHotspotCreate : public QDialog +{ + Q_OBJECT + +public: + explicit DlgHotspotCreate(QString wiFiCardName, QWidget *parent = nullptr); + ~DlgHotspotCreate(); + +public Q_SLOTS: + void changeDialog(); + +private Q_SLOTS: + void on_btnCancel_clicked(); + + void on_btnOk_clicked(); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_lePassword_textEdited(const QString &arg1); + +private: + Ui::DlgHotspotCreate *ui; + + QString wirelessCardName; + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + bool isPress; + QPoint winPos; + QPoint dragPos; + +Q_SIGNALS: + void updateHotspotList(); + void btnHotspotState(); +}; + +#endif // DLGHOTSPOTCREATE_H diff --git a/KylinNM/hot-spot/dlghotspotcreate.ui b/KylinNM/hot-spot/dlghotspotcreate.ui new file mode 100644 index 0000000..989108f --- /dev/null +++ b/KylinNM/hot-spot/dlghotspotcreate.ui @@ -0,0 +1,169 @@ + + + DlgHotspotCreate + + + + 0 + 0 + 432 + 250 + + + + Dialog + + + + + 0 + 0 + 120 + 32 + + + + + + + + + + 9 + 9 + 16 + 16 + + + + + + + + + + 34 + 6 + 80 + 20 + + + + + + + + + + 215 + 210 + 90 + 30 + + + + + + + + + + 315 + 210 + 90 + 30 + + + + + + + + + + 76 + 60 + 90 + 20 + + + + + + + + + + 175 + 55 + 200 + 32 + + + + + + + 76 + 105 + 90 + 20 + + + + + + + + + + 175 + 100 + 200 + 32 + + + + + + + 76 + 150 + 90 + 20 + + + + + + + + + + 175 + 145 + 200 + 32 + + + + QLineEdit::Password + + + + + + 350 + 157 + 18 + 9 + + + + + + + + + + diff --git a/KylinNM/kylin-nm.pri b/KylinNM/kylin-nm.pri new file mode 100644 index 0000000..e124796 --- /dev/null +++ b/KylinNM/kylin-nm.pri @@ -0,0 +1,70 @@ +SOURCES += \ + $$PWD/src/backthread.cpp \ + $$PWD/src/confform.cpp \ + $$PWD/src/ksimplenm.cpp \ + $$PWD/src/kylin-dbus-interface.cpp \ + $$PWD/src/kylin-network-interface.c \ + $$PWD/src/loadingdiv.cpp \ + $$PWD/src/kylinnm.cpp \ + $$PWD/src/oneconnform.cpp \ + $$PWD/src/onelancform.cpp \ + $$PWD/src/switchbutton.cpp \ + $$PWD/src/utils.cpp \ + $$PWD/wireless-security/dlgconnhidwifi.cpp \ + $$PWD/wireless-security/dlgconnhidwifisecfast.cpp \ + $$PWD/wireless-security/dlgconnhidwifisectunneltls.cpp \ + $$PWD/wireless-security/dlgconnhidwifisecpeap.cpp \ + $$PWD/wireless-security/dlgconnhidwifisectls.cpp \ + $$PWD/wireless-security/dlgconnhidwifisecleap.cpp \ + $$PWD/wireless-security/dlgconnhidwifisecpwd.cpp \ + $$PWD/wireless-security/dlgconnhidwifiwep.cpp \ + $$PWD/wireless-security/dlgconnhidwifileap.cpp \ + $$PWD/wireless-security/dlgconnhidwifiwpa.cpp \ + $$PWD/wireless-security/kylinheadfile.cpp \ + $$PWD/hot-spot/dlghotspotcreate.cpp + +HEADERS += \ + $$PWD/src/backthread.h \ + $$PWD/src/confform.h \ + $$PWD/src/ksimplenm.h \ + $$PWD/src/kylin-dbus-interface.h \ + $$PWD/src/kylin-network-interface.h \ + $$PWD/src/loadingdiv.h \ + $$PWD/src/kylinnm.h \ + $$PWD/src/oneconnform.h \ + $$PWD/src/onelancform.h \ + $$PWD/src/switchbutton.h \ + $$PWD/src/utils.h \ + $$PWD/wireless-security/dlgconnhidwifi.h \ + $$PWD/wireless-security/dlgconnhidwifisecfast.h \ + $$PWD/wireless-security/dlgconnhidwifisectunneltls.h \ + $$PWD/wireless-security/dlgconnhidwifisecpeap.h \ + $$PWD/wireless-security/dlgconnhidwifisectls.h \ + $$PWD/wireless-security/dlgconnhidwifisecleap.h \ + $$PWD/wireless-security/dlgconnhidwifisecpwd.h \ + $$PWD/wireless-security/dlgconnhidwifiwep.h \ + $$PWD/wireless-security/dlgconnhidwifileap.h \ + $$PWD/wireless-security/dlgconnhidwifiwpa.h \ + $$PWD/wireless-security/kylinheadfile.h \ + $$PWD/hot-spot/dlghotspotcreate.h + +FORMS += \ + $$PWD/src/confform.ui \ + $$PWD/src/kylinnm.ui \ + $$PWD/src/oneconnform.ui \ + $$PWD/src/onelancform.ui \ + $$PWD/wireless-security/dlgconnhidwifi.ui \ + $$PWD/wireless-security/dlgconnhidwifisecfast.ui \ + $$PWD/wireless-security/dlgconnhidwifisectunneltls.ui \ + $$PWD/wireless-security/dlgconnhidwifisecpeap.ui \ + $$PWD/wireless-security/dlgconnhidwifisectls.ui \ + $$PWD/wireless-security/dlgconnhidwifisecleap.ui \ + $$PWD/wireless-security/dlgconnhidwifisecpwd.ui \ + $$PWD/wireless-security/dlgconnhidwifiwep.ui \ + $$PWD/wireless-security/dlgconnhidwifileap.ui \ + $$PWD/wireless-security/dlgconnhidwifiwpa.ui \ + $$PWD/hot-spot/dlghotspotcreate.ui + +RESOURCES += \ + $$PWD/nmqrc.qrc + diff --git a/KylinNM/kylin-nm.pro b/KylinNM/kylin-nm.pro new file mode 100644 index 0000000..b8af2ba --- /dev/null +++ b/KylinNM/kylin-nm.pro @@ -0,0 +1,129 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-10-19T15:29:47 +# +#------------------------------------------------- + +QT += core gui x11extras dbus + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = kylin-nm +TEMPLATE = app +LANGUAGE = C++ + +CONFIG += c++11 + +# CONFIG += link_pkgconfig +# PKGCONFIG += gsettings-qt +LIBS += -L/usr/lib/ -lgsettings-qt -lX11 + +target.path = /usr/bin +target.source += $$TARGET +desktop.path = /etc/xdg/autostart/ +desktop.files = kylin-nm.desktop + +INSTALLS += target \ + desktop + +# 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) + + +SOURCES += \ + src/backthread.cpp \ + src/confform.cpp \ + src/ksimplenm.cpp \ + src/kylin-dbus-interface.cpp \ + src/kylin-network-interface.c \ + src/loadingdiv.cpp \ + src/main.cpp \ + src/kylinnm.cpp \ + src/oneconnform.cpp \ + src/onelancform.cpp \ + src/switchbutton.cpp \ + src/utils.cpp \ + wireless-security/dlgconnhidwifi.cpp \ + wireless-security/dlgconnhidwifisecfast.cpp \ + wireless-security/dlgconnhidwifisectunneltls.cpp \ + wireless-security/dlgconnhidwifisecpeap.cpp \ + wireless-security/dlgconnhidwifisectls.cpp \ + wireless-security/dlgconnhidwifisecleap.cpp \ + wireless-security/dlgconnhidwifisecpwd.cpp \ + wireless-security/dlgconnhidwifiwep.cpp \ + wireless-security/dlgconnhidwifileap.cpp \ + wireless-security/dlgconnhidwifiwpa.cpp \ + wireless-security/kylinheadfile.cpp \ + hot-spot/dlghotspotcreate.cpp + + +HEADERS += \ + src/backthread.h \ + src/confform.h \ + src/ksimplenm.h \ + src/kylin-dbus-interface.h \ + src/kylin-network-interface.h \ + src/loadingdiv.h \ + src/kylinnm.h \ + src/oneconnform.h \ + src/onelancform.h \ + src/switchbutton.h \ + src/utils.h \ + wireless-security/dlgconnhidwifi.h \ + wireless-security/dlgconnhidwifisecfast.h \ + wireless-security/dlgconnhidwifisectunneltls.h \ + wireless-security/dlgconnhidwifisecpeap.h \ + wireless-security/dlgconnhidwifisectls.h \ + wireless-security/dlgconnhidwifisecleap.h \ + wireless-security/dlgconnhidwifisecpwd.h \ + wireless-security/dlgconnhidwifiwep.h \ + wireless-security/dlgconnhidwifileap.h \ + wireless-security/dlgconnhidwifiwpa.h \ + wireless-security/kylinheadfile.h \ + hot-spot/dlghotspotcreate.h + +FORMS += \ + src/confform.ui \ + src/kylinnm.ui \ + src/oneconnform.ui \ + src/onelancform.ui \ + wireless-security/dlgconnhidwifi.ui \ + wireless-security/dlgconnhidwifisecfast.ui \ + wireless-security/dlgconnhidwifisectunneltls.ui \ + wireless-security/dlgconnhidwifisecpeap.ui \ + wireless-security/dlgconnhidwifisectls.ui \ + wireless-security/dlgconnhidwifisecleap.ui \ + wireless-security/dlgconnhidwifisecpwd.ui \ + wireless-security/dlgconnhidwifiwep.ui \ + wireless-security/dlgconnhidwifileap.ui \ + wireless-security/dlgconnhidwifiwpa.ui \ + hot-spot/dlghotspotcreate.ui + +RESOURCES += \ + nmqrc.qrc + +unix { + UI_DIR = .ui + MOC_DIR = .moc + OBJECTS_DIR = .obj +} + +TRANSLATIONS = translations/kylin-nm_zh_CN.ts \ + translations/kylin-nm_tr.ts \ + translations/kylin-nm_bo.ts + +DISTFILES += diff --git a/KylinNM/nmqrc.qrc b/KylinNM/nmqrc.qrc new file mode 100644 index 0000000..f2349b6 --- /dev/null +++ b/KylinNM/nmqrc.qrc @@ -0,0 +1,102 @@ + + + res/s/conning-b/1.png + res/s/conning-b/2.png + res/s/conning-b/3.png + res/s/conning-b/4.png + res/s/conning-b/5.png + res/s/conning-b/6.png + res/s/conning-b/7.png + res/s/conning-b/8.png + res/s/conning-b/9.png + res/s/conning-b/10.png + res/s/conning-b/11.png + res/s/conning-b/12.png + res/g/down_arrow.png + res/g/checkbox-checked.svg + res/g/checkbox-unchecked.svg + res/s/rescan/1.png + res/s/rescan/2.png + res/s/rescan/3.png + res/s/rescan/4.png + res/s/rescan/5.png + res/s/rescan/6.png + res/s/rescan/7.png + res/s/rescan/8.png + res/s/rescan/9.png + res/s/rescan/10.png + res/s/rescan/11.png + res/s/rescan/12.png + res/h/hide-pwd.png + res/h/right-pwd.png + res/h/show-pwd.png + res/h/no-pwd-wifi.png + res/x/fly-mode-off.svg + res/x/fly-mode-on.svg + res/x/hot-spot-off.svg + res/x/hot-spot-on.svg + res/x/net-list-bg.svg + res/x/wifi-list-bg.svg + res/x/load-down.png + res/x/load-up.png + res/l/network-offline.png + res/l/network-offline.svg + res/l/network-online.png + res/l/network-online.svg + res/w/wifi-full.png + res/w/wifi-full-pwd.png + res/w/wifi-high.png + res/w/wifi-high-pwd.png + res/w/wifi-low.png + res/w/wifi-low-pwd.png + res/w/wifi-medium.png + res/w/wifi-medium-pwd.png + res/w/wifi-none.png + res/w/wifi-none-pwd.png + res/s/conning-a/1.png + res/s/conning-a/2.png + res/s/conning-a/3.png + res/s/conning-a/4.png + res/s/conning-a/5.png + res/s/conning-a/6.png + res/s/conning-a/7.png + res/s/conning-a/8.png + qss/style.qss + res/g/close_black.png + res/g/close_white.png + res/s/conning-s/1.png + res/s/conning-s/2.png + res/s/conning-s/3.png + res/s/conning-s/4.png + res/s/conning-s/5.png + res/s/conning-s/6.png + res/s/conning-s/7.png + res/s/conning-s/8.png + res/s/conning-s/9.png + res/s/conning-s/10.png + res/s/conning-s/11.png + res/s/conning-s/12.png + res/x/setup.png + res/x/pb-wifi-n.png + res/x/pb-wifi-y.png + res/x/pb-conn-dis.png + res/l/pb-network-online.png + res/l/pb-network-info.png + res/l/pb-network-offline.png + res/x/pb-newConn.png + res/x/pb-close.png + res/l/pb-top-network-offline.png + res/w/pb-all-wifi-offline.png + res/w/pb-top-wifi-offline.png + res/w/wifi-full-off.png + res/w/wifi-high-off.png + res/w/wifi-low-off.png + res/w/wifi-medium-off.png + res/w/wifi-low-pwd-off.png + res/w/wifi-full-pwd-off.png + res/w/wifi-high-pwd-off.png + res/w/wifi-medium-pwd-off.png + res/w/wifi-none-off.png + res/w/wifi-none-pwd-off.png + + diff --git a/KylinNM/qss/style.qss b/KylinNM/qss/style.qss new file mode 100644 index 0000000..741e632 --- /dev/null +++ b/KylinNM/qss/style.qss @@ -0,0 +1,10 @@ +QScrollBar:vertical{margin:0px 2px 0px 2px;width:10px;background:rgba(48,48,51,0);border-radius:6px;} +QScrollBar::up-arrow:vertical{height:0px;} +QScrollBar::sub-line:vertical{border:0px solid;height:0px} +QScrollBar::sub-page:vertical{background:transparent;} +QScrollBar::handle:vertical{width:6px;background:rgba(72,72,76,1);border-radius:3px;} +QScrollBar::handle:vertical:hover{width:6px;background:rgba(97,97,102,1);border-radius:3px;} +QScrollBar::handle:vertical:pressed{width:6px;background:rgba(133,133,140,1);border-radius:3px;} +QScrollBar::add-page:vertical{background:transparent;} +QScrollBar::add-line:vertical{border:0px solid;height:0px} +QScrollBar::down-arrow:vertical{height:0px;} diff --git a/KylinNM/res.qrc b/KylinNM/res.qrc new file mode 100644 index 0000000..7646d2b --- /dev/null +++ b/KylinNM/res.qrc @@ -0,0 +1 @@ + diff --git a/KylinNM/res/g/checkbox-checked.svg b/KylinNM/res/g/checkbox-checked.svg new file mode 100644 index 0000000..b9ee316 --- /dev/null +++ b/KylinNM/res/g/checkbox-checked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/KylinNM/res/g/checkbox-unchecked.svg b/KylinNM/res/g/checkbox-unchecked.svg new file mode 100644 index 0000000..0df442d --- /dev/null +++ b/KylinNM/res/g/checkbox-unchecked.svg @@ -0,0 +1,3 @@ + + + diff --git a/KylinNM/res/g/close_black.png b/KylinNM/res/g/close_black.png new file mode 100644 index 0000000..237e555 Binary files /dev/null and b/KylinNM/res/g/close_black.png differ diff --git a/KylinNM/res/g/close_white.png b/KylinNM/res/g/close_white.png new file mode 100644 index 0000000..0943a4b Binary files /dev/null and b/KylinNM/res/g/close_white.png differ diff --git a/KylinNM/res/g/down_arrow.png b/KylinNM/res/g/down_arrow.png new file mode 100644 index 0000000..c7a343b Binary files /dev/null and b/KylinNM/res/g/down_arrow.png differ diff --git a/KylinNM/res/h/hide-pwd.png b/KylinNM/res/h/hide-pwd.png new file mode 100644 index 0000000..c1d3044 Binary files /dev/null and b/KylinNM/res/h/hide-pwd.png differ diff --git a/KylinNM/res/h/no-pwd-wifi.png b/KylinNM/res/h/no-pwd-wifi.png new file mode 100644 index 0000000..dbec54a Binary files /dev/null and b/KylinNM/res/h/no-pwd-wifi.png differ diff --git a/KylinNM/res/h/right-pwd.png b/KylinNM/res/h/right-pwd.png new file mode 100644 index 0000000..1bbc00d Binary files /dev/null and b/KylinNM/res/h/right-pwd.png differ diff --git a/KylinNM/res/h/show-pwd.png b/KylinNM/res/h/show-pwd.png new file mode 100644 index 0000000..08c4de5 Binary files /dev/null and b/KylinNM/res/h/show-pwd.png differ diff --git a/KylinNM/res/l/network-offline.png b/KylinNM/res/l/network-offline.png new file mode 100644 index 0000000..a288fc3 Binary files /dev/null and b/KylinNM/res/l/network-offline.png differ diff --git a/KylinNM/res/l/network-offline.svg b/KylinNM/res/l/network-offline.svg new file mode 100644 index 0000000..ca9dcea --- /dev/null +++ b/KylinNM/res/l/network-offline.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/KylinNM/res/l/network-online.png b/KylinNM/res/l/network-online.png new file mode 100644 index 0000000..b8c5fe4 Binary files /dev/null and b/KylinNM/res/l/network-online.png differ diff --git a/KylinNM/res/l/network-online.svg b/KylinNM/res/l/network-online.svg new file mode 100644 index 0000000..7f10bfd --- /dev/null +++ b/KylinNM/res/l/network-online.svg @@ -0,0 +1 @@ +gnome-dev-ethernet32 \ No newline at end of file diff --git a/KylinNM/res/l/pb-network-info.png b/KylinNM/res/l/pb-network-info.png new file mode 100644 index 0000000..23fa16c Binary files /dev/null and b/KylinNM/res/l/pb-network-info.png differ diff --git a/KylinNM/res/l/pb-network-offline.png b/KylinNM/res/l/pb-network-offline.png new file mode 100644 index 0000000..77be9f0 Binary files /dev/null and b/KylinNM/res/l/pb-network-offline.png differ diff --git a/KylinNM/res/l/pb-network-online.png b/KylinNM/res/l/pb-network-online.png new file mode 100644 index 0000000..d65dcd5 Binary files /dev/null and b/KylinNM/res/l/pb-network-online.png differ diff --git a/KylinNM/res/l/pb-top-network-offline.png b/KylinNM/res/l/pb-top-network-offline.png new file mode 100644 index 0000000..b5822b9 Binary files /dev/null and b/KylinNM/res/l/pb-top-network-offline.png differ diff --git a/KylinNM/res/s/conning-a/1.png b/KylinNM/res/s/conning-a/1.png new file mode 100644 index 0000000..cd0fafa Binary files /dev/null and b/KylinNM/res/s/conning-a/1.png differ diff --git a/KylinNM/res/s/conning-a/2.png b/KylinNM/res/s/conning-a/2.png new file mode 100644 index 0000000..38b549a Binary files /dev/null and b/KylinNM/res/s/conning-a/2.png differ diff --git a/KylinNM/res/s/conning-a/3.png b/KylinNM/res/s/conning-a/3.png new file mode 100644 index 0000000..c002abd Binary files /dev/null and b/KylinNM/res/s/conning-a/3.png differ diff --git a/KylinNM/res/s/conning-a/4.png b/KylinNM/res/s/conning-a/4.png new file mode 100644 index 0000000..ec398d0 Binary files /dev/null and b/KylinNM/res/s/conning-a/4.png differ diff --git a/KylinNM/res/s/conning-a/5.png b/KylinNM/res/s/conning-a/5.png new file mode 100644 index 0000000..df58230 Binary files /dev/null and b/KylinNM/res/s/conning-a/5.png differ diff --git a/KylinNM/res/s/conning-a/6.png b/KylinNM/res/s/conning-a/6.png new file mode 100644 index 0000000..44fbf5d Binary files /dev/null and b/KylinNM/res/s/conning-a/6.png differ diff --git a/KylinNM/res/s/conning-a/7.png b/KylinNM/res/s/conning-a/7.png new file mode 100644 index 0000000..1dcfb6d Binary files /dev/null and b/KylinNM/res/s/conning-a/7.png differ diff --git a/KylinNM/res/s/conning-a/8.png b/KylinNM/res/s/conning-a/8.png new file mode 100644 index 0000000..0178595 Binary files /dev/null and b/KylinNM/res/s/conning-a/8.png differ diff --git a/KylinNM/res/s/conning-b/1.png b/KylinNM/res/s/conning-b/1.png new file mode 100644 index 0000000..6255abf Binary files /dev/null and b/KylinNM/res/s/conning-b/1.png differ diff --git a/KylinNM/res/s/conning-b/10.png b/KylinNM/res/s/conning-b/10.png new file mode 100644 index 0000000..37e465b Binary files /dev/null and b/KylinNM/res/s/conning-b/10.png differ diff --git a/KylinNM/res/s/conning-b/11.png b/KylinNM/res/s/conning-b/11.png new file mode 100644 index 0000000..d4f8d0e Binary files /dev/null and b/KylinNM/res/s/conning-b/11.png differ diff --git a/KylinNM/res/s/conning-b/12.png b/KylinNM/res/s/conning-b/12.png new file mode 100644 index 0000000..1fa952b Binary files /dev/null and b/KylinNM/res/s/conning-b/12.png differ diff --git a/KylinNM/res/s/conning-b/2.png b/KylinNM/res/s/conning-b/2.png new file mode 100644 index 0000000..a226b69 Binary files /dev/null and b/KylinNM/res/s/conning-b/2.png differ diff --git a/KylinNM/res/s/conning-b/3.png b/KylinNM/res/s/conning-b/3.png new file mode 100644 index 0000000..31b1b89 Binary files /dev/null and b/KylinNM/res/s/conning-b/3.png differ diff --git a/KylinNM/res/s/conning-b/4.png b/KylinNM/res/s/conning-b/4.png new file mode 100644 index 0000000..eddd9a8 Binary files /dev/null and b/KylinNM/res/s/conning-b/4.png differ diff --git a/KylinNM/res/s/conning-b/5.png b/KylinNM/res/s/conning-b/5.png new file mode 100644 index 0000000..b0a7062 Binary files /dev/null and b/KylinNM/res/s/conning-b/5.png differ diff --git a/KylinNM/res/s/conning-b/6.png b/KylinNM/res/s/conning-b/6.png new file mode 100644 index 0000000..a970490 Binary files /dev/null and b/KylinNM/res/s/conning-b/6.png differ diff --git a/KylinNM/res/s/conning-b/7.png b/KylinNM/res/s/conning-b/7.png new file mode 100644 index 0000000..c58bde1 Binary files /dev/null and b/KylinNM/res/s/conning-b/7.png differ diff --git a/KylinNM/res/s/conning-b/8.png b/KylinNM/res/s/conning-b/8.png new file mode 100644 index 0000000..f3980b3 Binary files /dev/null and b/KylinNM/res/s/conning-b/8.png differ diff --git a/KylinNM/res/s/conning-b/9.png b/KylinNM/res/s/conning-b/9.png new file mode 100644 index 0000000..80a8f7e Binary files /dev/null and b/KylinNM/res/s/conning-b/9.png differ diff --git a/KylinNM/res/s/conning-s/1.png b/KylinNM/res/s/conning-s/1.png new file mode 100644 index 0000000..6974725 Binary files /dev/null and b/KylinNM/res/s/conning-s/1.png differ diff --git a/KylinNM/res/s/conning-s/10.png b/KylinNM/res/s/conning-s/10.png new file mode 100644 index 0000000..964a300 Binary files /dev/null and b/KylinNM/res/s/conning-s/10.png differ diff --git a/KylinNM/res/s/conning-s/11.png b/KylinNM/res/s/conning-s/11.png new file mode 100644 index 0000000..d4659b5 Binary files /dev/null and b/KylinNM/res/s/conning-s/11.png differ diff --git a/KylinNM/res/s/conning-s/12.png b/KylinNM/res/s/conning-s/12.png new file mode 100644 index 0000000..cb0272e Binary files /dev/null and b/KylinNM/res/s/conning-s/12.png differ diff --git a/KylinNM/res/s/conning-s/1x/1.png b/KylinNM/res/s/conning-s/1x/1.png new file mode 100644 index 0000000..258bd70 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/1.png differ diff --git a/KylinNM/res/s/conning-s/1x/10.png b/KylinNM/res/s/conning-s/1x/10.png new file mode 100644 index 0000000..88398b8 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/10.png differ diff --git a/KylinNM/res/s/conning-s/1x/11.png b/KylinNM/res/s/conning-s/1x/11.png new file mode 100644 index 0000000..7157960 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/11.png differ diff --git a/KylinNM/res/s/conning-s/1x/12.png b/KylinNM/res/s/conning-s/1x/12.png new file mode 100644 index 0000000..60b88e9 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/12.png differ diff --git a/KylinNM/res/s/conning-s/1x/2.png b/KylinNM/res/s/conning-s/1x/2.png new file mode 100644 index 0000000..45eedb2 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/2.png differ diff --git a/KylinNM/res/s/conning-s/1x/3.png b/KylinNM/res/s/conning-s/1x/3.png new file mode 100644 index 0000000..96cfdad Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/3.png differ diff --git a/KylinNM/res/s/conning-s/1x/4.png b/KylinNM/res/s/conning-s/1x/4.png new file mode 100644 index 0000000..c8a9a98 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/4.png differ diff --git a/KylinNM/res/s/conning-s/1x/5.png b/KylinNM/res/s/conning-s/1x/5.png new file mode 100644 index 0000000..0595e6b Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/5.png differ diff --git a/KylinNM/res/s/conning-s/1x/6.png b/KylinNM/res/s/conning-s/1x/6.png new file mode 100644 index 0000000..274f5a8 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/6.png differ diff --git a/KylinNM/res/s/conning-s/1x/7.png b/KylinNM/res/s/conning-s/1x/7.png new file mode 100644 index 0000000..c49a271 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/7.png differ diff --git a/KylinNM/res/s/conning-s/1x/8.png b/KylinNM/res/s/conning-s/1x/8.png new file mode 100644 index 0000000..94946d6 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/8.png differ diff --git a/KylinNM/res/s/conning-s/1x/9.png b/KylinNM/res/s/conning-s/1x/9.png new file mode 100644 index 0000000..87f7419 Binary files /dev/null and b/KylinNM/res/s/conning-s/1x/9.png differ diff --git a/KylinNM/res/s/conning-s/2.png b/KylinNM/res/s/conning-s/2.png new file mode 100644 index 0000000..eb6a4a4 Binary files /dev/null and b/KylinNM/res/s/conning-s/2.png differ diff --git a/KylinNM/res/s/conning-s/3.png b/KylinNM/res/s/conning-s/3.png new file mode 100644 index 0000000..f985e8c Binary files /dev/null and b/KylinNM/res/s/conning-s/3.png differ diff --git a/KylinNM/res/s/conning-s/4.png b/KylinNM/res/s/conning-s/4.png new file mode 100644 index 0000000..e8645dc Binary files /dev/null and b/KylinNM/res/s/conning-s/4.png differ diff --git a/KylinNM/res/s/conning-s/5.png b/KylinNM/res/s/conning-s/5.png new file mode 100644 index 0000000..089e671 Binary files /dev/null and b/KylinNM/res/s/conning-s/5.png differ diff --git a/KylinNM/res/s/conning-s/6.png b/KylinNM/res/s/conning-s/6.png new file mode 100644 index 0000000..aee7edf Binary files /dev/null and b/KylinNM/res/s/conning-s/6.png differ diff --git a/KylinNM/res/s/conning-s/7.png b/KylinNM/res/s/conning-s/7.png new file mode 100644 index 0000000..914deea Binary files /dev/null and b/KylinNM/res/s/conning-s/7.png differ diff --git a/KylinNM/res/s/conning-s/8.png b/KylinNM/res/s/conning-s/8.png new file mode 100644 index 0000000..b3de287 Binary files /dev/null and b/KylinNM/res/s/conning-s/8.png differ diff --git a/KylinNM/res/s/conning-s/9.png b/KylinNM/res/s/conning-s/9.png new file mode 100644 index 0000000..ffbdb73 Binary files /dev/null and b/KylinNM/res/s/conning-s/9.png differ diff --git a/KylinNM/res/s/rescan/1.png b/KylinNM/res/s/rescan/1.png new file mode 100644 index 0000000..19c4f77 Binary files /dev/null and b/KylinNM/res/s/rescan/1.png differ diff --git a/KylinNM/res/s/rescan/10.png b/KylinNM/res/s/rescan/10.png new file mode 100644 index 0000000..2b4c501 Binary files /dev/null and b/KylinNM/res/s/rescan/10.png differ diff --git a/KylinNM/res/s/rescan/11.png b/KylinNM/res/s/rescan/11.png new file mode 100644 index 0000000..c43ee8c Binary files /dev/null and b/KylinNM/res/s/rescan/11.png differ diff --git a/KylinNM/res/s/rescan/12.png b/KylinNM/res/s/rescan/12.png new file mode 100644 index 0000000..b3c08be Binary files /dev/null and b/KylinNM/res/s/rescan/12.png differ diff --git a/KylinNM/res/s/rescan/2.png b/KylinNM/res/s/rescan/2.png new file mode 100644 index 0000000..4062892 Binary files /dev/null and b/KylinNM/res/s/rescan/2.png differ diff --git a/KylinNM/res/s/rescan/3.png b/KylinNM/res/s/rescan/3.png new file mode 100644 index 0000000..d6a64bc Binary files /dev/null and b/KylinNM/res/s/rescan/3.png differ diff --git a/KylinNM/res/s/rescan/4.png b/KylinNM/res/s/rescan/4.png new file mode 100644 index 0000000..f92092f Binary files /dev/null and b/KylinNM/res/s/rescan/4.png differ diff --git a/KylinNM/res/s/rescan/5.png b/KylinNM/res/s/rescan/5.png new file mode 100644 index 0000000..279fd34 Binary files /dev/null and b/KylinNM/res/s/rescan/5.png differ diff --git a/KylinNM/res/s/rescan/6.png b/KylinNM/res/s/rescan/6.png new file mode 100644 index 0000000..cea2f89 Binary files /dev/null and b/KylinNM/res/s/rescan/6.png differ diff --git a/KylinNM/res/s/rescan/7.png b/KylinNM/res/s/rescan/7.png new file mode 100644 index 0000000..f9b384a Binary files /dev/null and b/KylinNM/res/s/rescan/7.png differ diff --git a/KylinNM/res/s/rescan/8.png b/KylinNM/res/s/rescan/8.png new file mode 100644 index 0000000..3930bef Binary files /dev/null and b/KylinNM/res/s/rescan/8.png differ diff --git a/KylinNM/res/s/rescan/9.png b/KylinNM/res/s/rescan/9.png new file mode 100644 index 0000000..bd22fa1 Binary files /dev/null and b/KylinNM/res/s/rescan/9.png differ diff --git a/KylinNM/res/w/pb-all-wifi-offline.png b/KylinNM/res/w/pb-all-wifi-offline.png new file mode 100644 index 0000000..fb2cb35 Binary files /dev/null and b/KylinNM/res/w/pb-all-wifi-offline.png differ diff --git a/KylinNM/res/w/pb-top-wifi-offline.png b/KylinNM/res/w/pb-top-wifi-offline.png new file mode 100644 index 0000000..89310de Binary files /dev/null and b/KylinNM/res/w/pb-top-wifi-offline.png differ diff --git a/KylinNM/res/w/wifi-full-off.png b/KylinNM/res/w/wifi-full-off.png new file mode 100644 index 0000000..54e83d6 Binary files /dev/null and b/KylinNM/res/w/wifi-full-off.png differ diff --git a/KylinNM/res/w/wifi-full-pwd-off.png b/KylinNM/res/w/wifi-full-pwd-off.png new file mode 100644 index 0000000..7949090 Binary files /dev/null and b/KylinNM/res/w/wifi-full-pwd-off.png differ diff --git a/KylinNM/res/w/wifi-full-pwd.png b/KylinNM/res/w/wifi-full-pwd.png new file mode 100644 index 0000000..292c031 Binary files /dev/null and b/KylinNM/res/w/wifi-full-pwd.png differ diff --git a/KylinNM/res/w/wifi-full.png b/KylinNM/res/w/wifi-full.png new file mode 100644 index 0000000..a858240 Binary files /dev/null and b/KylinNM/res/w/wifi-full.png differ diff --git a/KylinNM/res/w/wifi-high-off.png b/KylinNM/res/w/wifi-high-off.png new file mode 100644 index 0000000..cc5fa77 Binary files /dev/null and b/KylinNM/res/w/wifi-high-off.png differ diff --git a/KylinNM/res/w/wifi-high-pwd-off.png b/KylinNM/res/w/wifi-high-pwd-off.png new file mode 100644 index 0000000..2ca3038 Binary files /dev/null and b/KylinNM/res/w/wifi-high-pwd-off.png differ diff --git a/KylinNM/res/w/wifi-high-pwd.png b/KylinNM/res/w/wifi-high-pwd.png new file mode 100644 index 0000000..3b1f477 Binary files /dev/null and b/KylinNM/res/w/wifi-high-pwd.png differ diff --git a/KylinNM/res/w/wifi-high.png b/KylinNM/res/w/wifi-high.png new file mode 100644 index 0000000..f6ab167 Binary files /dev/null and b/KylinNM/res/w/wifi-high.png differ diff --git a/KylinNM/res/w/wifi-low-off.png b/KylinNM/res/w/wifi-low-off.png new file mode 100644 index 0000000..60e238a Binary files /dev/null and b/KylinNM/res/w/wifi-low-off.png differ diff --git a/KylinNM/res/w/wifi-low-pwd-off.png b/KylinNM/res/w/wifi-low-pwd-off.png new file mode 100644 index 0000000..1c6860d Binary files /dev/null and b/KylinNM/res/w/wifi-low-pwd-off.png differ diff --git a/KylinNM/res/w/wifi-low-pwd.png b/KylinNM/res/w/wifi-low-pwd.png new file mode 100644 index 0000000..9cc769e Binary files /dev/null and b/KylinNM/res/w/wifi-low-pwd.png differ diff --git a/KylinNM/res/w/wifi-low.png b/KylinNM/res/w/wifi-low.png new file mode 100644 index 0000000..3631505 Binary files /dev/null and b/KylinNM/res/w/wifi-low.png differ diff --git a/KylinNM/res/w/wifi-medium-off.png b/KylinNM/res/w/wifi-medium-off.png new file mode 100644 index 0000000..c823649 Binary files /dev/null and b/KylinNM/res/w/wifi-medium-off.png differ diff --git a/KylinNM/res/w/wifi-medium-pwd-off.png b/KylinNM/res/w/wifi-medium-pwd-off.png new file mode 100644 index 0000000..a9e96d8 Binary files /dev/null and b/KylinNM/res/w/wifi-medium-pwd-off.png differ diff --git a/KylinNM/res/w/wifi-medium-pwd.png b/KylinNM/res/w/wifi-medium-pwd.png new file mode 100644 index 0000000..cc2d363 Binary files /dev/null and b/KylinNM/res/w/wifi-medium-pwd.png differ diff --git a/KylinNM/res/w/wifi-medium.png b/KylinNM/res/w/wifi-medium.png new file mode 100644 index 0000000..82cdf40 Binary files /dev/null and b/KylinNM/res/w/wifi-medium.png differ diff --git a/KylinNM/res/w/wifi-none-off.png b/KylinNM/res/w/wifi-none-off.png new file mode 100644 index 0000000..65dceb2 Binary files /dev/null and b/KylinNM/res/w/wifi-none-off.png differ diff --git a/KylinNM/res/w/wifi-none-pwd-off.png b/KylinNM/res/w/wifi-none-pwd-off.png new file mode 100644 index 0000000..0cdd769 Binary files /dev/null and b/KylinNM/res/w/wifi-none-pwd-off.png differ diff --git a/KylinNM/res/w/wifi-none-pwd.png b/KylinNM/res/w/wifi-none-pwd.png new file mode 100644 index 0000000..c3fd701 Binary files /dev/null and b/KylinNM/res/w/wifi-none-pwd.png differ diff --git a/KylinNM/res/w/wifi-none.png b/KylinNM/res/w/wifi-none.png new file mode 100644 index 0000000..b4927dc Binary files /dev/null and b/KylinNM/res/w/wifi-none.png differ diff --git a/KylinNM/res/x/fly-mode-off.svg b/KylinNM/res/x/fly-mode-off.svg new file mode 100644 index 0000000..408b7b0 --- /dev/null +++ b/KylinNM/res/x/fly-mode-off.svg @@ -0,0 +1,19 @@ + + + + +画板 1 + + + + + diff --git a/KylinNM/res/x/fly-mode-on.svg b/KylinNM/res/x/fly-mode-on.svg new file mode 100644 index 0000000..9f5e543 --- /dev/null +++ b/KylinNM/res/x/fly-mode-on.svg @@ -0,0 +1,14 @@ + + + + +画板 1 + + diff --git a/KylinNM/res/x/hot-spot-off.svg b/KylinNM/res/x/hot-spot-off.svg new file mode 100644 index 0000000..cf39cad --- /dev/null +++ b/KylinNM/res/x/hot-spot-off.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/KylinNM/res/x/hot-spot-on.svg b/KylinNM/res/x/hot-spot-on.svg new file mode 100644 index 0000000..2041db9 --- /dev/null +++ b/KylinNM/res/x/hot-spot-on.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/KylinNM/res/x/load-down.png b/KylinNM/res/x/load-down.png new file mode 100644 index 0000000..a96298a Binary files /dev/null and b/KylinNM/res/x/load-down.png differ diff --git a/KylinNM/res/x/load-up.png b/KylinNM/res/x/load-up.png new file mode 100644 index 0000000..e5ec581 Binary files /dev/null and b/KylinNM/res/x/load-up.png differ diff --git a/KylinNM/res/x/net-list-bg.svg b/KylinNM/res/x/net-list-bg.svg new file mode 100644 index 0000000..c17c1fd --- /dev/null +++ b/KylinNM/res/x/net-list-bg.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/KylinNM/res/x/pb-close.png b/KylinNM/res/x/pb-close.png new file mode 100644 index 0000000..c5cc8ad Binary files /dev/null and b/KylinNM/res/x/pb-close.png differ diff --git a/KylinNM/res/x/pb-conn-dis.png b/KylinNM/res/x/pb-conn-dis.png new file mode 100644 index 0000000..3726203 Binary files /dev/null and b/KylinNM/res/x/pb-conn-dis.png differ diff --git a/KylinNM/res/x/pb-newConn.png b/KylinNM/res/x/pb-newConn.png new file mode 100644 index 0000000..86a18e0 Binary files /dev/null and b/KylinNM/res/x/pb-newConn.png differ diff --git a/KylinNM/res/x/pb-wifi-n.png b/KylinNM/res/x/pb-wifi-n.png new file mode 100644 index 0000000..54e83d6 Binary files /dev/null and b/KylinNM/res/x/pb-wifi-n.png differ diff --git a/KylinNM/res/x/pb-wifi-y.png b/KylinNM/res/x/pb-wifi-y.png new file mode 100644 index 0000000..a858240 Binary files /dev/null and b/KylinNM/res/x/pb-wifi-y.png differ diff --git a/KylinNM/res/x/setup.png b/KylinNM/res/x/setup.png new file mode 100644 index 0000000..fe242f8 Binary files /dev/null and b/KylinNM/res/x/setup.png differ diff --git a/KylinNM/res/x/wifi-list-bg.svg b/KylinNM/res/x/wifi-list-bg.svg new file mode 100644 index 0000000..43f1866 --- /dev/null +++ b/KylinNM/res/x/wifi-list-bg.svg @@ -0,0 +1,15 @@ + + + + +画板 1 + + + + + + + diff --git a/KylinNM/src/backthread.cpp b/KylinNM/src/backthread.cpp new file mode 100644 index 0000000..5747fc8 --- /dev/null +++ b/KylinNM/src/backthread.cpp @@ -0,0 +1,461 @@ +/* + * 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 +#include +#include +#include +#include + +#include +#include +#include + +#include "kylinnm.h" //逼不得已,引入kylinnm头文件 + +BackThread::BackThread(QObject *parent) : QObject(parent) +{ + cmdConnWifi = new QProcess(this); + connect(cmdConnWifi , SIGNAL(readyReadStandardOutput()) , this , SLOT(on_readoutput())); + connect(cmdConnWifi , SIGNAL(readyReadStandardError()) , this , SLOT(on_readerror())); + cmdConnWifi->start("bash"); + cmdConnWifi->waitForStarted(); +} + +BackThread::~BackThread() +{ + cmdConnWifi->close(); +} + +//get the connection state of wired and wireles network +IFace* BackThread::execGetIface() +{ + IFace *iface = new IFace(); + + QString tmpPath = "/tmp/kylin-nm-iface-" + QDir::home().dirName(); + QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli -f TYPE,DEVICE,STATE device > " + tmpPath; + Utils::m_system(cmd.toUtf8().data()); + + // int status = system(cmd.toUtf8().data()); + // if (status != 0){ syslog(LOG_ERR, "execute 'nmcli device' in function 'execGetIface' failed");} + + QFile file(tmpPath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + // print information if can not open file ~/.config/kylin-nm-iface + syslog(LOG_ERR, "Can't open the file ~/.config/kylin-nm-iface!"); + qDebug()<<"Can't open the file ~/.config/kylin-nm-iface!"; + } + QString txt = file.readAll(); + QStringList txtList = txt.split("\n"); + file.close(); + + iface->lstate = 2; + iface->wstate = 2; + + for (int i = 1; i < txtList.size(); i ++) { + QString line = txtList.at(i); + if (line != "") { + int index1 = line.indexOf(" "); + QString type = line.left(index1); + QString lastStr = line.mid(index1).trimmed(); + int index2 = lastStr.indexOf(" "); + QString iname = lastStr.left(index2); + QString istateStr = lastStr.mid(index2).trimmed(); + + if (type == "ethernet" && iface->lstate != 0) { + // if type is wired network + iface->lname = iname; + + if (istateStr == "unmanaged") { + iface->lstate = 2; //switch of wired device is off + } + if (istateStr == "disconnected" || istateStr == "unavailable") { + iface->lstate = 1; //wired network is disconnected + } + if (istateStr == "connected") { + iface->lstate = 0; //wired network is connected + } + } + if (type == "wifi" && iface->wstate != 0) { + // if type is wireless network + iface->wname = iname; + + if (istateStr == "unmanaged" || istateStr == "unavailable") { + iface->wstate = 2; //switch of wireless device is off + } + if (istateStr == "disconnected") { + iface->wstate = 1; //wireless network is disconnected + } + if (istateStr == "connected") { + iface->wstate = 0; //wireless network is connected + } + } + } + } + + return iface; +} + +//turn on the switch of network +void BackThread::execEnNet() +{ + char *chr = "nmcli networking on"; + Utils::m_system(chr); + + // int status = system("nmcli networking on"); + // if (status != 0){ syslog(LOG_ERR, "execute 'nmcli networking on' in function 'execEnNet' failed");} + while (1) { + if (execGetIface()->lstate != 2) { + sleep(3); + emit enNetDone(); + emit btFinish(); + break; + } + sleep(1); + } +} + +//turn off the switch of wireless network first, then turn off the switch of network +void BackThread::execDisNet() +{ + if (execGetIface()->wstate != 2) { + char *chr = "nmcli radio wifi off"; + Utils::m_system(chr); + + // int status = system("nmcli radio wifi off"); + // if (status != 0){ syslog(LOG_ERR, "execute 'nmcli radio wifi off' in function 'execDisNet' failed");} + while (1) { + if (execGetIface()->wstate == 2) { + emit disWifiDone(); + emit btFinish(); + break; + } + sleep(1); + } + } + + char *chr1 = "nmcli networking off"; + Utils::m_system(chr1); + // int status1 = system("nmcli networking off"); + // if (status1 != 0){ syslog(LOG_ERR, "execute 'nmcli networking off' in function 'execDisNet' failed");} + while (1) { + if (execGetIface()->lstate == 2) { + emit disNetDone(); + emit btFinish(); + break; + } + sleep(1); + } +} + +//turn on the switch of wireless network +void BackThread::execEnWifi() +{ + //if (execGetIface()->lstate == 2){ + // char *chr = "nmcli networking on"; + // Utils::m_system(chr); + // //int status = system("nmcli networking on"); + // //if (status != 0){ syslog(LOG_ERR, "execute 'nmcli networking on' in function 'execEnWifi' failed");} + // while(1){ + // if (execGetIface()->lstate != 2){ + // emit launchLanDone(); + // break; + // } + // sleep(1); + // } + //} + + char *chr1 = "nmcli radio wifi on"; + Utils::m_system(chr1); + //int status1 = system("nmcli radio wifi on"); + //if (status1 != 0){ syslog(LOG_ERR, "execute 'nmcli radio wifi on' in function 'execEnWifi' failed");} + while (1) { + if (execGetIface()->wstate != 2) { + KylinDBus objKyDbus; + while (1) { + if (objKyDbus.getAccessPointsNumber() > 0) { + // objKyDbus.getAccessPointsNumber()>0 standard can get wireless accesspoints now + KylinNM::reflashWifiUi(); + emit enWifiDone(); + emit btFinish(); + break; + } + sleep(2); + } + break; + } + sleep(1); + } +} + +//turn off the switch of wireless network +void BackThread::execDisWifi() +{ + char *chr = "nmcli radio wifi off"; + Utils::m_system(chr); + // int status = system("nmcli radio wifi off"); + // if (status != 0){ syslog(LOG_ERR, "execute 'nmcli radio wifi off' in function 'execDisWifi' failed");} + while (1) { + if (execGetIface()->wstate == 2) { + KylinNM::reflashWifiUi(); + emit disWifiDone(); + emit btFinish(); + break; + } + sleep(1); + } +} + +//to connect wired network +void BackThread::execConnLan(QString connName) +{ + disConnLanOrWifi("ethernet"); + + KylinDBus objKyDbus; + if (objKyDbus.isWiredCableOn) { + // only if wired cable is plug in, can connect wired network + QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli connection up \"" + connName.replace("\"","\\\"") + "\""; + Utils::m_system(cmd.toUtf8().data()); + // int status = system(cmd.toUtf8().data()); + // if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection up' in function 'execConnLan' failed");} + qDebug()<<"debug: in function execConnLan, wired net state is: "<lstate); + syslog(LOG_DEBUG, "In function execConnLan, wired net state is: %d", execGetIface()->lstate); + emit connDone(0); + } else { + qDebug()<<"connect wired network failed for without wired cable plug in."; + syslog(LOG_DEBUG, "connect wired network failed for without wired cable plug in."); + emit connDone(1); + } + + emit btFinish(); +} + +//to connected wireless network need a password +void BackThread::execConnWifiPWD(QString connName, QString password) +{ + //disConnLanOrWifi("wifi"); + QString tmpPath = "/tmp/kylin-nm-btoutput-" + QDir::home().dirName(); + QString cmdStr = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli device wifi connect \"" + connName.replace("\"","\\\"") + "\" password \"" + password.replace("\"","\\\"") + "\" > " + tmpPath; + Utils::m_system(cmdStr.toUtf8().data()); + // int status = system(cmdStr.toUtf8().data()); + // if (status != 0){ syslog(LOG_ERR, "execute 'nmcli device wifi connect' in function 'execConnWifiPWD' failed");} + QFile file(tmpPath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + syslog(LOG_DEBUG, "Can't open the file /tmp/kylin-nm-btoutput !"); + qDebug()<<"Can't open the file /tmp/kylin-nm-btoutput !"<wstate); + syslog(LOG_DEBUG, "In function execConnWifiPWD, wireless net state is: %d", execGetIface()->wstate); + } else { + emit connDone(1); + } + emit btFinish(); +} + +//to connected wireless network driectly do not need a password +void BackThread::execConnWifi(QString connName) +{ + //disConnLanOrWifi("wifi"); + + QString cmdStr = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli connection up \"" + connName.replace("\"","\\\"") + "\"\n"; + cmdConnWifi->write(cmdStr.toUtf8().data()); +} + +void BackThread::on_readoutput() +{ + QString str = cmdConnWifi->readAllStandardOutput(); + cmdConnWifi->close(); + qDebug()<<"on_readoutput: "<< str; + if (str.indexOf("successfully") != -1) { + emit connDone(0); //send this signal if connect net successfully + qDebug()<<"debug: in function on_readoutput, wireless net state is: "<wstate); + syslog(LOG_DEBUG, "In function on_readoutput, wireless net state is: %d", execGetIface()->wstate); + } else if(str.indexOf("unknown") != -1) { + emit connDone(2); + } else { + emit connDone(1); + } + + emit btFinish(); +} +void BackThread::on_readerror() +{ + QString str = cmdConnWifi->readAllStandardError(); + cmdConnWifi->close(); + qDebug()<<"on_readerror: "<< str; + if (str.indexOf("successfully") != -1) { + emit connDone(0); + } else if(str.indexOf("unknown") != -1 || str.indexOf("not exist") != -1) { + emit connDone(2); //send this signal if the network we want to connect has not a configuration file + } else { + emit connDone(1); //send this signal if connect net failed + } + + emit btFinish(); +} + +//get property of connected network +QString BackThread::getConnProp(QString connName) +{ + QString tmpPath = "/tmp/kylin-nm-connprop-" + QDir::home().dirName(); + QString cmd = "export LANG='zh_CN.UTF-8';export LANGUAGE='zh_CN';nmcli connection show \"" + connName.replace("\"","\\\"") + "\" > " + tmpPath; + Utils::m_system(cmd.toUtf8().data()); + // int status = system(cmd.toUtf8().data()); + // if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'getConnProp' failed");} + + QFile file(tmpPath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + syslog(LOG_ERR, "Can't open the file /tmp/kylin-nm-connprop!"); + qDebug()<<"Can't open the file /tmp/kylin-nm-connprop!"< " + tmpPath; + Utils::m_system(cmd.toUtf8().data()); + // int status = system(cmd.toUtf8().data()); + // if (status != 0){ syslog(LOG_ERR, "execute 'ethtool' in function 'execChkLanWidth' failed");} + + QFile file(tmpPath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + syslog(LOG_ERR, "Can't open the file /tmp/kylin-nm-bandwidth!"); + qDebug()<<"Can't open the file /tmp/kylin-nm-bandwidth!"< +#include +#include +#include +#include +#include +#include + +class IFace{ +public: + QString lname; + QString wname; + int lstate; // 0已连接 1未连接 2已关闭 + int wstate; // 0已连接 1未连接 2已关闭 +}; + +class BackThread : public QObject +{ + Q_OBJECT +public: + explicit BackThread(QObject *parent = nullptr); + ~BackThread(); + + IFace* execGetIface(); + QString getConnProp(QString connName); + QString execChkLanWidth(QString ethName); + QProcess *cmdConnWifi = nullptr; + +public Q_SLOTS: + void execEnNet(); + void execDisNet(); + void execEnWifi(); + void execDisWifi(); + void execConnLan(QString connName); + void execConnWifi(QString connName); + void execConnWifiPWD(QString connName, QString password); + + void disConnSparedNetSlot(QString type); + void disConnLanOrWifi(QString type); + + void on_readoutput(); + void on_readerror(); + +Q_SIGNALS: + void enNetDone(); + void disNetDone(); + void enWifiDone(); + void launchLanDone(); + void disWifiDone(); + + void connDone(int connFlag); + + void btFinish(); + void disFinish(); + void ttFinish(); +}; + +#endif // BACKTHREAD_H diff --git a/KylinNM/src/confform.cpp b/KylinNM/src/confform.cpp new file mode 100644 index 0000000..493c50a --- /dev/null +++ b/KylinNM/src/confform.cpp @@ -0,0 +1,552 @@ +/* + * 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 +#include +#include + +extern QString llname, lwname; + +ConfForm::ConfForm(QWidget *parent) : + QWidget(parent), + ui(new Ui::ConfForm) +{ + ui->setupUi(this); + this->setWindowFlags(Qt::FramelessWindowHint); //Qt::WindowStaysOnTopHint + this->setWindowTitle(tr("edit network"));//"网络设置" + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:16px;border:none;}"); +// KylinDBus mkylindbus; + + QString strTrans; + strTrans = QString::number(1, 10, 2); + QString sty = "#centralWidget{border:1px solid rgba(255,255,255,0.05);border-radius:16px;background:rgba(255,255,255," + strTrans + ");}"; + ui->centralWidget->setStyleSheet(sty); + + labelQss = "QLabel{border:0px;color:rgba(38,38,38,1);background-color:transparent;}"; + cbxQss = "QComboBox{padding-left:20px;font-size:13px;color:rgba(38,38,38,1);" + "border:1px solid rgba(255, 255, 255, 0.05);border-radius:4px;background:rgba(255,255,255,0.08);}" + "QComboBox::drop-down{border:0px;width:30px;}" + "QComboBox::down-arrow{image:url(:/res/g/down_arrow.png);}" + "QComboBox QAbstractItemView {margin:0px 0px 0px 0px;padding: 0px 0px;border-radius:0px;background-color:#48484C;outline:0px;}" + "QComboBox QAbstractItemView::item{padding-left:17px;border-radius:0px;font-size:13px;color:rgba(255,255,255,0.91);height: 32px;background-color:#48484C;outline:0px;}" + "QComboBox QAbstractItemView::item:hover{padding-left:17px;border-radius:0px;font-size:13px;color:rgba(255,255,255,0.91);background-color:#3D6BE5;outline:0px;}"; + leQss = "QLineEdit{padding-left:20px;color:rgba(38,38,38,1);background:rgba(245,245,245,1);}"; + btnOffQss = "QPushButton{border:1px solid rgba(44,44,44,1);border-radius:4px;background-color:rgba(255,255,255,0.12);color:rgba(44,44,44,1);font-size:14px;}"; + // "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(255,255,255,0.2);}" + // "QPushButton:Pressed{border-radius:4px;background-color:rgba(255,255,255,0.08);}"; + btnOnQss = "QPushButton{border:0px;border-radius:4px;background-color:rgba(61,107,229,1);color:white;font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(107,142,235,1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(50,87,202,1);}"; + lineQss = "background:rgba(255,255,255,0.08);"; + + // ui->centralWidget->setStyleSheet("#centralWidget{border:1px solid #297a97;background-color:#ffffff;}"); + ui->wdHead->setStyleSheet("#wdHead{border:none}"); + ui->wgManual->setStyleSheet("#wgManual{border:none}"); + ui->wdBottom->setStyleSheet("#wdBottom{border:none}"); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:14px;color:rgba(38,38,38,1);background-color:transparent;}"); + ui->lbName->setStyleSheet(labelQss); + ui->lbTxt1->setStyleSheet(labelQss); + ui->lbTxt2->setStyleSheet(labelQss); + ui->lbTxt3->setStyleSheet(labelQss); + ui->lbTxt4->setStyleSheet(labelQss); + ui->lbTxt5->setStyleSheet(labelQss); + ui->lbTxt6->setStyleSheet(labelQss); + + //YYF + ui->btnClose->setStyleSheet("border-image:url(:/res/x/pb-close.png);"); + connect(ui->btnClose,&QPushButton::clicked,ui->btnCancel,&QPushButton::clicked); + ui->isDHCP->setStyleSheet("QCheckBox::indicator {width: 16px; height: 16px;}" + "QCheckBox::indicator:checked {image: url(:/res/g/checkbox-checked.svg);}" + "QCheckBox::indicator:unchecked {image: url(:/res/g/checkbox-unchecked.svg);}"); + ui->notDHCP->setStyleSheet("QCheckBox::indicator {width: 16px; height: 16px;}" + "QCheckBox::indicator:checked {image: url(:/res/g/checkbox-checked.svg);}" + "QCheckBox::indicator:unchecked {image: url(:/res/g/checkbox-unchecked.svg);}"); + + ui->cbType->setStyleSheet(cbxQss); + ui->cbType->setView(new QListView()); + ui->cbType->hide(); + ui->cbMask->setStyleSheet(cbxQss); + ui->cbMask->setView(new QListView()); + + ui->leName->setStyleSheet(leQss); + ui->leAddr->setStyleSheet(leQss); + ui->leGateway->setStyleSheet(leQss); + ui->leDns->setStyleSheet(leQss); + ui->leDns2->setStyleSheet(leQss); + + ui->btnCancel->setStyleSheet(btnOffQss); + ui->btnOk->setStyleSheet(btnOnQss); + ui->btnCreate->setStyleSheet(btnOnQss); + ui->lineUp->setStyleSheet(lineQss); + ui->lineDown->setStyleSheet(lineQss); + ui->lineUp->hide(); + ui->lineDown->hide(); + + ui->lbName->setText(tr("LAN name: "));//"网络名称:" + ui->lbTxt1->setText(tr("Method: "));//"编辑IP设置:" + ui->lbTxt2->setText(tr("Address: "));//"IP地址:" + ui->lbTxt3->setText(tr("Netmask: "));//"子网掩码:" + ui->lbTxt4->setText(tr("Gateway: "));//"默认网关:" + ui->lbTxt5->setText(tr("DNS 1: "));//"首选DNS:" + ui->lbTxt6->setText(tr("DNS 2: "));//"备选DNS:" + + ui->lbLeftupTitle->setText(tr("Edit Conn"));//"网络设置" + ui->cbType->addItem(tr("Auto(DHCP)"));//"自动(DHCP)" + ui->cbType->addItem(tr("Manual"));//"手动" + ui->isDHCP->setText(tr("Auto(DHCP)")); + ui->notDHCP->setText(tr("Manual")); + + connect(ui->cbType, SIGNAL(currentIndexChanged(int)), this, SLOT(cbTypeChanged(int))); + + ui->cbMask->addItem("255.255.255.0"); //24 + ui->cbMask->addItem("255.255.254.0"); //23 + ui->cbMask->addItem("255.255.252.0"); //22 + ui->cbMask->addItem("255.255.0.0"); //16 + ui->cbMask->addItem("255.0.0.0"); //8 +// ui->cbMask->setWindowFlags(Qt::X11BypassWindowManagerHint); + ui->cbMask->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbMask->view()->setParent(this); + ui->cbMask->view()->hide(); + + ui->cbMask->installEventFilter(this); + ui->cbMask->view()->installEventFilter(this); + + connect(ui->cbMask->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ +// qDebug() << "-----------------------pressed:" << index.row(); +// qDebug() << "-----------------------itemText:" << ui->cbMask->itemText(index.row()); + Q_EMIT ui->cbMask->setCurrentIndex(index.row()); + ui->cbMask->view()->hide(); + }); + +// connect(ui->cbMask->view(), &QAbstractItemView::entered, this, [=](QModelIndex index){ +// qDebug() << "-----------------------entered:" << index.row(); +// }); + + ui->cbMask->view()->setGeometry(QRect(ui->cbMask->geometry().left(), ui->wgManual->geometry().top() + ui->cbMask->geometry().bottom(), ui->cbMask->view()->width(), ui->cbMask->view()->height())); + + ui->btnCancel->setText(tr("Cancel"));//"取消" + ui->btnOk->setText(tr("Save"));//"保存" + ui->btnCreate->setText(tr("Ok"));//"确定" + + ui->btnCancel->setFocusPolicy(Qt::NoFocus); + ui->btnOk->setFocusPolicy(Qt::NoFocus); + ui->btnCreate->setFocusPolicy(Qt::NoFocus); + + // IP的正则格式限制 + QRegExp rx("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"); + ui->leAddr->setValidator(new QRegExpValidator(rx, this)); + ui->leGateway->setValidator(new QRegExpValidator(rx, this)); + ui->leDns->setValidator(new QRegExpValidator(rx, this)); + ui->leDns2->setValidator(new QRegExpValidator(rx, this)); + +} + +void ConfForm::setMainWindow(KylinNM *mainwindow) +{ + this->mw = mainwindow; +} + +ConfForm::~ConfForm() +{ + delete ui; +} + +bool ConfForm::eventFilter(QObject *obj, QEvent *ev) +{ + if(obj == ui->cbMask) + { + if(ev->type() == QEvent::MouseButtonPress) + { + ui->cbMask->view()->setVisible(!ui->cbMask->view()->isVisible()); + if(ui->cbMask->view()->isVisible()) + ui->cbMask->view()->setFocus(); + } + } else if (obj != ui->cbMask->view()) + { + ui->cbMask->view()->hide(); + } + return false; +} + +void ConfForm::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void ConfForm::mouseReleaseEvent(QMouseEvent *event) +{ + this->isPress = false; +} +void ConfForm::mouseMoveEvent(QMouseEvent *event) +{ + if (this->isPress) { + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +void ConfForm::tabletStyle(bool isTablet) +{ + isTabletStyle = isTablet; + + ui->leName->resize(290+194*isTabletStyle,48); + ui->leName->resize(290+194*isTabletStyle,48); + ui->btnOk->move(312+194*isTabletStyle,25); + ui->btnCreate->move(312+194*isTabletStyle,25); + ui->btnCancel->move(180+194*isTabletStyle,25); + ui->btnClose->move(408+194*isTabletStyle,8); + ui->isDHCP->move(180+194*isTabletStyle,130); + ui->notDHCP->move(356+194*isTabletStyle,130); + + ui->wdBottom->setFixedWidth(446+194*isTabletStyle); + ui->wdHead->setFixedWidth(446+194*isTabletStyle); + ui->wgManual->setFixedWidth(446+194*isTabletStyle); + ui->upTitle->setFixedWidth(446+194*isTabletStyle); +} + +//网络配置参数设置界面的显示内容 +void ConfForm::setProp(QString connName, QString v4method, QString addr, QString mask, QString gateway, QString dns, bool isActConf) +{ + this->isActConf = isActConf; + ui->leName->setText(connName); + + if (v4method == "auto" || v4method == "") { + ui->isDHCP->setChecked(true); + ui->notDHCP->setChecked(false); + ui->cbType->setCurrentIndex(0); + cbTypeChanged(0); + } else { + ui->isDHCP->setChecked(false); + ui->notDHCP->setChecked(true); + ui->cbType->setCurrentIndex(1); + cbTypeChanged(1); + } + + ui->leAddr->setText(addr); + ui->leGateway->setText(gateway); + + // 配置中有多个DNS,只处理前两个 + if (dns.indexOf(",") != -1) { + QStringList dnss = dns.split(","); + ui->leDns->setText(dnss.at(0)); + ui->leDns2->setText(dnss.at(1)); + } else { + ui->leDns->setText(dns); + ui->leDns2->setText(""); + } + + if (mask == "24") { + ui->cbMask->setCurrentIndex(0); + } else if(mask == "23") { + ui->cbMask->setCurrentIndex(1); + } else if(mask == "22") { + ui->cbMask->setCurrentIndex(2); + } else if(mask == "16") { + ui->cbMask->setCurrentIndex(3); + } else if(mask == "8") { + ui->cbMask->setCurrentIndex(4); + } else { + ui->cbMask->setCurrentIndex(0); + } +} + +//点击了创建新的网络的按钮 +void ConfForm::on_btnCreate_clicked() +{ + if (mw->lanNameList.contains(ui->leName->text())) { + qWarning() << "Warn : 已有同名LAN存在:" << ui->leName->text(); + // ui->tipLabel->show(); + return; + } + KylinDBus kylindbus; + kylindbus.getWiredCardName(); + QString mIfname = kylindbus.dbusLanCardName; + + if (mIfname == "") { + QString tip(tr("Can not create new wired network for without wired card")); +// kylindbus.showDesktopNotify(tip); + this->hide(); + return; + } + + QString name = ui->leName->text(); + QString cmdStr = "nmcli connection add con-name \"" + name.replace("\"","\\\"") + "\" type ethernet"; //由于样机存在veth虚拟网卡,故不指定有线设备,将自动选择 + Utils::m_system(cmdStr.toUtf8().data()); + //int status = system(cmdStr.toUtf8().data()); + //if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection add con-name' in function 'on_btnCreate_clicked' failed");} + + if (ui->cbType->currentIndex() == 1) { + //config the ipv4 and netmask and gateway if select Manual + this->isCreateNewNet = true; + this->on_btnOk_clicked(); + } else { + QString txt(tr("New network already created")); +// kylindbus.showDesktopNotify(txt); + } + + this->hide(); +} + +//点击了保存更改网络设置的按钮 +void ConfForm::on_btnOk_clicked() +{ + QString mask = ""; + if (ui->cbMask->currentIndex() == 0) { + mask = "24"; + } else if(ui->cbMask->currentIndex() == 1) { + mask = "23"; + } else if(ui->cbMask->currentIndex() == 2) { + mask = "22"; + } else if(ui->cbMask->currentIndex() == 3) { + mask = "16"; + } else if(ui->cbMask->currentIndex() == 4) { + mask = "8"; + } else { + mask = "24"; + } + + if (ui->cbType->currentIndex() == 0) { + QString name = ui->leName->text(); + name.replace("\"","\\\""); + kylin_network_set_automethod(name.toUtf8().data()); + } else { + QString dnss = ui->leDns->text(); + if (ui->leDns2->text() != "") { + dnss.append(","); + dnss.append(ui->leDns2->text()); + } + QString name = ui->leName->text(); + name.replace("\"","\\\""); + kylin_network_set_manualall(name.toUtf8().data(), ui->leAddr->text().toUtf8().data(), mask.toUtf8().data(), ui->leGateway->text().toUtf8().data(), dnss.toUtf8().data()); + } + + KylinDBus kylindbus; + + this->hide(); + + QString txt(tr("New network settings already finished")); + kylindbus.showDesktopNotify(txt); + + if (!this->isCreateNewNet) { + if (this->isActConf == true) { + // 如果是修改当前连接的网络,则修改设置后简略重连网络 + //QString cmd = "/usr/share/kylin-nm/shell/connup.sh '" + ui->leName->text() + "'"; + kylindbus.connectWiredNet(ui->leName->text()); //reconnect this wired network + + QString m_txt(tr("New settings already effective")); + kylindbus.showDesktopNotify(m_txt); //show desktop notify + } + + //需要更新一下有线网界面 + qDebug()<<"debug: request refresh Lan list"; + emit requestRefreshLanList(0); + } + this->isCreateNewNet = false; +} + +//点击取消按钮 +void ConfForm::on_btnCancel_clicked() +{ + this->hide(); +} + +//根据需要设置的种类(自动或手动等)显示界面内容 +void ConfForm::cbTypeChanged(int index) +{ + if (isShowSaveBtn) { + ui->leName->setEnabled(false); + ui->btnOk->show(); //显示保存按钮 + ui->btnCreate->hide(); //隐藏创建按钮 + ui->lbLeftupTitle->setText(tr("Edit Network")); + } + + if (index == 0) { + ui->lineUp->hide(); + ui->lineDown->hide(); + ui->wgManual->hide(); + ui->centralWidget->resize(446+194*isTabletStyle, 443); + ui->wdBottom->move(0, 347); + + this->setEnableOfBtn(); + + this->resize(446+194*isTabletStyle,443); + } + if (index == 1) { + ui->lineUp->show(); + ui->lineDown->show(); + ui->wgManual->show(); + ui->centralWidget->resize(446+194*isTabletStyle, 576); + ui->wdBottom->move(0, 480); + + this->setEnableOfBtn(); + + this->resize(446+194*isTabletStyle, 576); + } + if (index == 3) { + ui->isDHCP->setChecked(true); + ui->notDHCP->setChecked(false); + ui->btnOk->setStyleSheet(btnOffQss); + ui->btnOk->setEnabled(false); + ui->btnCreate->setStyleSheet(btnOffQss); + ui->btnCreate->setEnabled(false); + + ui->leName->setEnabled(true); + ui->btnOk->hide(); + ui->btnCreate->show(); + ui->lbLeftupTitle->setText(tr("Add Wired Network")); + isShowSaveBtn = false; + + ui->lineUp->hide(); + ui->lineDown->hide(); + ui->wgManual->hide(); + ui->centralWidget->resize(446+194*isTabletStyle, 443); + ui->wdBottom->move(0, 347); + this->resize(446+194*isTabletStyle, 443); + } +} + +//编辑网络名称 +void ConfForm::on_leName_textEdited(const QString &arg1) +{ + this->setEnableOfBtn(); +} + +//编辑网络ip +void ConfForm::on_leAddr_textEdited(const QString &arg1) +{ + this->setEnableOfBtn(); +} + +//编辑网络网关 +void ConfForm::on_leGateway_textEdited(const QString &arg1) +{ + this->setEnableOfBtn(); +} + +//编辑网络DNS +void ConfForm::on_leDns_textEdited(const QString &arg1) +{ + this->setEnableOfBtn(); +} + +//编辑网络备用DNS +void ConfForm::on_leDns2_textEdited(const QString &arg1) +{ + // this->setEnableOfBtn(); +} + +//设置界面按钮是否可点击 +void ConfForm::setEnableOfBtn() +{ + if (ui->leName->text().size() == 0 ) { + this->setBtnEnableFalse(); + return; + } + + if (ui->cbType->currentIndex() == 1) { + if (!this->getTextEditState(ui->leAddr->text()) ) { + this->setBtnEnableFalse(); + return; + } + + if (!this->getTextEditState(ui->leGateway->text()) ) { + this->setBtnEnableFalse(); + return; + } + + if (!this->getTextEditState(ui->leDns->text()) ) { + this->setBtnEnableFalse(); + return; + } + } + + ui->btnOk->setStyleSheet(btnOnQss); + ui->btnOk->setEnabled(true); + + ui->btnCreate->setStyleSheet(btnOnQss); + ui->btnCreate->setEnabled(true); +} + +//文本的输入要符合ip的格式要求 +bool ConfForm::getTextEditState(QString text) +{ + QRegExp rx("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"); + + bool match = false; + match = rx.exactMatch(text); + // qDebug()<<"the match result is: " << match; + + return match; +} + +//设置创建或保存按钮不可点击 +void ConfForm::setBtnEnableFalse() +{ + ui->btnOk->setStyleSheet(btnOffQss); + ui->btnOk->setEnabled(false); + + ui->btnCreate->setStyleSheet(btnOffQss); + ui->btnCreate->setEnabled(false); +} + +void ConfForm::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} + +void ConfForm::on_isDHCP_clicked() +{ + ui->isDHCP->setEnabled(false); + ui->notDHCP->setEnabled(true); + ui->notDHCP->setChecked(false); + ui->cbType->setCurrentIndex(0); + cbTypeChanged(0); +} + +void ConfForm::on_notDHCP_clicked() +{ + ui->notDHCP->setEnabled(false); + ui->isDHCP->setEnabled(true); + ui->isDHCP->setChecked(false); + ui->cbType->setCurrentIndex(1); + cbTypeChanged(1); +} diff --git a/KylinNM/src/confform.h b/KylinNM/src/confform.h new file mode 100644 index 0000000..73999d4 --- /dev/null +++ b/KylinNM/src/confform.h @@ -0,0 +1,102 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +namespace Ui { +class ConfForm; +} +class KylinNM; + +class ConfForm : public QWidget +{ + Q_OBJECT + +public: + explicit ConfForm(QWidget *parent = 0); + ~ConfForm(); + + void setProp(QString connName, QString v4method, QString addr, QString mask, QString gateway, QString dns, bool isActConf ); + void setMainWindow(KylinNM *mainwindow); + +public Q_SLOTS: + void tabletStyle(bool isTablet);//YYF 平板桌面模式特有设置 + void cbTypeChanged(int index); + +protected: + void paintEvent(QPaintEvent *event); + bool eventFilter(QObject *obj, QEvent *ev) override; + +private Q_SLOTS: + void on_btnOk_clicked(); + void on_btnCancel_clicked(); + + void on_btnCreate_clicked(); + + void on_leName_textEdited(const QString &arg1); + + void on_leAddr_textEdited(const QString &arg1); + + void on_leGateway_textEdited(const QString &arg1); + + void on_leDns_textEdited(const QString &arg1); + + void on_leDns2_textEdited(const QString &arg1); + + void setEnableOfBtn(); + bool getTextEditState(QString text); + void setBtnEnableFalse(); + + void on_isDHCP_clicked(); + + void on_notDHCP_clicked(); + +private: + Ui::ConfForm *ui; + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + bool isPress; + QPoint winPos; + QPoint dragPos; + bool isActConf; //是否对已经连接的网络进行的更改 + bool isCreateNewNet = false; //是否是创建的新网络 + bool isShowSaveBtn = true; //是否显示保存按钮,即是否是编辑网络界面 + + bool isTabletStyle=false;//YYF 平板桌面模式特有设置 + + QString labelQss, cbxQss, leQss, lineQss, btnOnQss, btnOffQss; + + KylinNM *mw = nullptr; + +Q_SIGNALS: + void requestRefreshLanList(int updateType); +}; + +#endif // CONFFORM_H diff --git a/KylinNM/src/confform.ui b/KylinNM/src/confform.ui new file mode 100644 index 0000000..08ff5b4 --- /dev/null +++ b/KylinNM/src/confform.ui @@ -0,0 +1,434 @@ + + + ConfForm + + + + 0 + 0 + 446 + 576 + + + + + + + + + 0 + 0 + 446 + 581 + + + + + + 0 + 200 + 446 + 280 + + + + + + 175 + 15 + 250 + 32 + + + + + 10 + + + + + + + 175 + 60 + 250 + 32 + + + + + 10 + + + + + + + 175 + 105 + 250 + 32 + + + + + 10 + + + + + + + 175 + 150 + 250 + 32 + + + + + 10 + + + + + + + 20 + 20 + 80 + 20 + + + + + Noto Sans CJK SC + 11 + + + + + + + + + + 20 + 65 + 80 + 20 + + + + + Noto Sans CJK SC + 11 + + + + + + + + + + 20 + 110 + 80 + 20 + + + + + Noto Sans CJK SC + 11 + + + + + + + + + + 20 + 155 + 80 + 20 + + + + + Noto Sans CJK SC + 11 + + + + + + + + + + 175 + 195 + 250 + 32 + + + + + 10 + + + + + + + 20 + 200 + 80 + 20 + + + + + Noto Sans CJK SC + 11 + + + + + + + + + + + 0 + 0 + 446 + 200 + + + + + + 170 + 60 + 182 + 32 + + + + + 10 + + + + + + + 20 + 135 + 80 + 20 + + + + + Noto Sans CJK SC + 11 + + + + + + + + + + 20 + 90 + 80 + 20 + + + + + Noto Sans CJK SC + 11 + + + + + + + + + + 135 + 75 + 290 + 48 + + + + + 10 + + + + + + + 0 + 0 + 446 + 48 + + + + + + 408 + 8 + 24 + 24 + + + + + + + + + + 24 + 10 + 240 + 22 + + + + + + + + + + + 180 + 130 + 111 + 28 + + + + + + + + + + 356 + 130 + 50 + 28 + + + + + + + + + + + 0 + 480 + 446 + 96 + + + + + + 312 + 25 + 112 + 48 + + + + + 10 + + + + + + + + + + 180 + 25 + 112 + 48 + + + + + 10 + + + + + + + + + + 312 + 25 + 112 + 48 + + + + + + + + + + + 10 + 200 + 426 + 1 + + + + Qt::Horizontal + + + + + + 10 + 480 + 426 + 1 + + + + Qt::Horizontal + + + + + + + diff --git a/KylinNM/src/ksimplenm.cpp b/KylinNM/src/ksimplenm.cpp new file mode 100644 index 0000000..d5be6e3 --- /dev/null +++ b/KylinNM/src/ksimplenm.cpp @@ -0,0 +1,79 @@ +/* + * 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 +#include +#include + +#define MAX_LEN 2048 +#define MAX_PATH 1024 + +KSimpleNM::KSimpleNM(QObject *parent) : QObject(parent) +{ + runShellProcess = new QProcess(this); + + connect(runShellProcess, &QProcess::readyRead, this, &KSimpleNM::readProcess); + connect(runShellProcess, SIGNAL(finished(int)), this, SLOT(finishedProcess(int))); +} + +//获取有线网络列表数据 +void KSimpleNM::execGetLanList() +{ + if (isExecutingGetWifiList) { + syslog(LOG_DEBUG, "It is running getting wifi list when getting lan list"); + qDebug()<<"debug: it is running getting wifi list when getting lan list"; + isUseOldLanSlist = true; + } + isExecutingGetLanList = true; + shellOutput = ""; + type = 0; + qDebug() << "runShellProcess->start ---1"; + runShellProcess->start("nmcli -f type,device,name connection show"); + qDebug() << "runShellProcess->start ---2"; +} + +//获取无线网络列表数据 +void KSimpleNM::execGetWifiList() +{ + isExecutingGetWifiList = true; + shellOutput = ""; + type = 1; + runShellProcess->start("nmcli -f in-use,signal,security,freq,bssid,ssid,dbus-path device wifi"); +} + +//读取获取到的结果 +void KSimpleNM::readProcess() +{ + QString output = runShellProcess->readAll(); + shellOutput += output; +} + +//读取完所有列表数据后发信号,将数据发往mainwindow用于显示网络列表 +void KSimpleNM::finishedProcess(int msg) +{ + QStringList slist = shellOutput.split("\n"); + if (type == 0) { + emit getLanListFinished(slist); + isExecutingGetLanList = false; + } else { + emit getWifiListFinished(slist); + isExecutingGetWifiList = false; + } +} diff --git a/KylinNM/src/ksimplenm.h b/KylinNM/src/ksimplenm.h new file mode 100644 index 0000000..fd1a427 --- /dev/null +++ b/KylinNM/src/ksimplenm.h @@ -0,0 +1,53 @@ +/* + * 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 + +#include +#include +#include + +class KSimpleNM : public QObject +{ + Q_OBJECT +public: + explicit KSimpleNM(QObject *parent = nullptr); + + QProcess *runShellProcess = nullptr; + QString shellOutput; + int type; + bool isExecutingGetLanList = false; //是否正在执行获取有线网列表 + bool isExecutingGetWifiList = false; //是否正在执行获取无线网列表 + bool isUseOldLanSlist = false; //是否应该要用上一次获取的有线列表 + + void execGetLanList(); + void execGetWifiList(); + +Q_SIGNALS: + void getLanListFinished(QStringList slist); + void getWifiListFinished(QStringList slist); + +public Q_SLOTS: + void readProcess(); + void finishedProcess(int msg); +}; + +#endif // KSIMPLENM_H diff --git a/KylinNM/src/kylin-dbus-interface.cpp b/KylinNM/src/kylin-dbus-interface.cpp new file mode 100644 index 0000000..ddaba02 --- /dev/null +++ b/KylinNM/src/kylin-dbus-interface.cpp @@ -0,0 +1,1105 @@ +/* + * 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 + +#include +#include + + +namespace { + +void quitThread(QThread *thread) +{ + Q_ASSERT(thread); + if (thread) { + thread->quit(); + if (!thread->wait(2000)) { + thread->terminate(); + thread->wait(); + } + } +} + +} // namespace + +KylinDBus::KylinDBus(KylinNM *mainWindow, QObject *parent) :QObject(parent) +{ + this->mw = mainWindow; + + getObjectPath(); //获取dbus中 lan 与 WiFi 的device路径 + getPhysicalCarrierState(0); //初始化获取网线插入状态 + getLanHwAddressState(); //获取有线网Mac地址 + getWiredCardName(); //获取有线网卡名称 + //initTaskbarGsetting(); //初始化taskbar的GSetting方法 + getWifiSwitchState(); //初始化wifi开关GSetting通信方法 + initTransparentState(); //初始化窗口透明度的GSetting方法 + + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString("/org/freedesktop/NetworkManager"), + QString("org.freedesktop.NetworkManager"), + QString("PropertiesChanged"), this, SLOT(onPropertiesChanged(QVariantMap) ) ); + + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString("/org/freedesktop/NetworkManager"), + QString("org.freedesktop.NetworkManager"), + QString("DeviceAdded"), mw, SLOT(onNetworkDeviceAdded(QDBusObjectPath) ) ); + + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString("/org/freedesktop/NetworkManager"), + QString("org.freedesktop.NetworkManager"), + QString("DeviceRemoved"), mw, SLOT(onNetworkDeviceRemoved(QDBusObjectPath) ) ); + + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString("/org/freedesktop/NetworkManager/Settings"), + QString("org.freedesktop.NetworkManager.Settings"), + QString("NewConnection"), this, SLOT(onNewConnection(QDBusObjectPath) ) ); + + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString("/org/freedesktop/NetworkManager/Settings"), + QString("org.freedesktop.NetworkManager.Settings"), + QString("ConnectionRemoved"), this, SLOT(onConnectionRemoved(QDBusObjectPath) ) ); + + if (wiredPath.path() != "") { + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString(wiredPath.path()), + QString("org.freedesktop.NetworkManager.Device.Wired"), + QString("PropertiesChanged"), this, SLOT(onLanPropertyChanged(QVariantMap) ) ); + } else { + qDebug()<<"Can not find wired device object path when using dbus."; + } + + if (wirelessPath.path() != "") { + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString(wirelessPath.path()), + QString("org.freedesktop.NetworkManager.Device.Wireless"), + QString("PropertiesChanged"), this, SLOT(onWifiPropertyChanged(QVariantMap) ) ); + + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString(wirelessPath.path()), + QString("org.freedesktop.NetworkManager.Device.Wireless"), + QString("AccessPointAdded"), this, SLOT(onAccessPointAdded(QDBusObjectPath) ) ); + getWirelessCardName();//获取无线网卡名称 + } else { + qDebug()<<"Can not find wireless device object path when using dbus."; + } + + time = new QTimer(this); + time->setTimerType(Qt::PreciseTimer); + QObject::connect(time, SIGNAL(timeout()), this, SLOT(slot_timeout())); + + QObject::connect(this, SIGNAL(updateWiredList(int)), mw, SLOT(onBtnNetListClicked(int))); + + mUtils = new Utils(); + mUtilsThread = new QThread(this); + mUtils->moveToThread(mUtilsThread); + connect(mUtilsThread, &QThread::finished, mUtils, &Utils::deleteLater); + connect(this, SIGNAL(requestSendDesktopNotify(QString)), mUtils, SLOT(onRequestSendDesktopNotify(QString)), Qt::QueuedConnection); + QTimer::singleShot(1, this, [=] { + mUtilsThread->start(); + }); +} + +KylinDBus::~KylinDBus() +{ + quitThread(mUtilsThread); +} + + +/////////////////////////////////////////////////////////////////////////////// +//下方使用Dbus 进程通信方法 + +//获取dbus中 lan 与 WiFi 的device路径 +void KylinDBus::getObjectPath() +{ + foreach (QDBusObjectPath mPath, multiWiredPaths) { + multiWiredPaths.removeOne(mPath); + } + + QDBusInterface m_interface( "org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.NetworkManager", + QDBusConnection::systemBus() ); + + //先获取所有的网络设备的设备路径 + QDBusReply> obj_reply = m_interface.call("GetAllDevices"); + if (!obj_reply.isValid()) { + qDebug()<<"execute dbus method 'GetAllDevices' is invalid in func getObjectPath()"; + } + + QList obj_paths = obj_reply.value(); + + //再判断有无有线设备和无线设备的路径 + foreach (QDBusObjectPath obj_path, obj_paths) { + QDBusInterface interface( "org.freedesktop.NetworkManager", + obj_path.path(), + "org.freedesktop.DBus.Introspectable", + QDBusConnection::systemBus() ); + + QDBusReply reply = interface.call("Introspect"); + if (!reply.isValid()) { + qDebug()<<"execute dbus method 'Introspect' is invalid in func getObjectPath()"; + } + + if(reply.value().indexOf("org.freedesktop.NetworkManager.Device.Wired") != -1) { + //表明有有线网设备 + wiredPath = obj_path; + multiWiredPaths.append(obj_path); + } else if (reply.value().indexOf("org.freedesktop.NetworkManager.Device.Wireless") != -1) { + //表明有wifi设备 + wirelessPath = obj_path; + isWirelessCardOn = true; + } + } +} + +//获取是否连接有线网网线 +void KylinDBus::getPhysicalCarrierState(int n) +{ + multiWiredCableState.clear(); + + foreach (QDBusObjectPath localPath, multiWiredPaths) { + QDBusInterface interface( "org.freedesktop.NetworkManager", + localPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + //Carrier值为true,插了网线;为false,未插网线 + QDBusReply reply = interface.call("Get", "org.freedesktop.NetworkManager.Device.Wired", "Carrier"); + + try { + if (reply.value().toString() == "true") { + //isWiredCableOn = true; + QDBusReply managed = interface.call("Get", "org.freedesktop.NetworkManager.Device", "Managed"); + //针对intel特殊环境的二次判断,当设备未托管时,即时carrier为true,仍认为有线设备未连接 + if (managed.value().toString() == "true") { + //isWiredCableOn = true; + multiWiredCableState.append("true"); + } else { + multiWiredCableState.append("false"); + } + } else if (reply.value().toString() == "false") { + //isWiredCableOn = false; + multiWiredCableState.append("false"); + //if (n == 1){ this->mw->onPhysicalCarrierChanged(isWiredCableOn);} + } else { + throw -1; //出现异常 + } + } catch(...) { + syslog(LOG_ERR, "Error occurred when get the property 'Carrier' of Wired"); + qDebug()<<"Error occurred when get the property 'Carrier' of Wired"; + } + } + + isWiredCableOn = false; + foreach (QString state, multiWiredCableState) { + if (state == "true") { + isWiredCableOn = true; + } + } + + if (n == 1) { this->mw->onPhysicalCarrierChanged(isWiredCableOn);} +} + +//获取有线网Mac地址 +void KylinDBus::getLanHwAddressState() +{ + QDBusInterface lanInterface( "org.freedesktop.NetworkManager", + wiredPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + QDBusReply lanReply = lanInterface.call("Get", "org.freedesktop.NetworkManager.Device.Wired", "HwAddress"); + if (!lanReply.isValid()) { + qDebug()<<"can not get the attribute 'HwAddress' in func getLanHwAddressState()"; + } else { + dbusLanMac = lanReply.value().toString(); + } +} + +//获取有线网卡名称 +void KylinDBus::getWiredCardName() +{ + if (wiredPath.path() == "") { + dbusLanCardName = ""; + } else { + QDBusInterface lanInterface( "org.freedesktop.NetworkManager", + wiredPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + QDBusReply lanReply = lanInterface.call("Get", "org.freedesktop.NetworkManager.Device", "Interface"); + if (!lanReply.isValid()) { + qDebug()<<"can not get the attribute 'Interface' in func getWiredCardName()"; + dbusLanCardName = ""; + } else { + dbusLanCardName = lanReply.value().toString(); + } + } +} + +//获取无线网卡名称 +void KylinDBus::getWirelessCardName() +{ + QDBusInterface lanInterface( "org.freedesktop.NetworkManager", + wirelessPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + QDBusReply lanReply = lanInterface.call("Get", "org.freedesktop.NetworkManager.Device", "Interface"); + if (!lanReply.isValid()) { + qDebug()<<"can not get the attribute 'Interface' in func getWirelessCardName()"; + } else { + dbusWiFiCardName = lanReply.value().toString(); + } +} + +//获取没有连接的有线网ip +void KylinDBus::getLanIp(QString netName) +{ + QDBusInterface m_interface("org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager/Settings", + "org.freedesktop.NetworkManager.Settings", + QDBusConnection::systemBus() ); + QDBusReply> m_reply = m_interface.call("ListConnections"); + + QList m_objNets = m_reply.value(); + foreach (QDBusObjectPath objNet, m_objNets) { + QDBusInterface m_interface("org.freedesktop.NetworkManager", + objNet.path(), + "org.freedesktop.NetworkManager.Settings.Connection", + QDBusConnection::systemBus()); + QDBusMessage result = m_interface.call("GetSettings"); //get information of this network + + const QDBusArgument &dbusArg1st = result.arguments().at( 0 ).value(); + //DBus type : a{sa{sv}}, a map with a key of QString, which maps to another map of QString,QVariant + QMap> map; + dbusArg1st >> map; + + for (QString outside_key : map.keys() ) { + QMap outsideMap = map.value(outside_key); + if (outside_key == "connection") { + for (QString search_key : outsideMap.keys()) { + if (search_key == "id") { + //const QDBusArgument &dbusArg2nd = innerMap.value(inner_key).value(); + if (netName == outsideMap.value(search_key).toString()) { + // qDebug()<<"aaaaaa"< innerMap = map.value(key); + //qDebug() << "Key: " << key; + if (key == "ipv4") { + for (QString inner_key : innerMap.keys()) { + if (inner_key == "address-data") { + const QDBusArgument &dbusArg2nd = innerMap.value(inner_key).value(); + QMap m_map; + + dbusArg2nd.beginArray(); + while (!dbusArg2nd.atEnd()) { + dbusArg2nd >> m_map;// append map to a vector here if you want to keep it + } + dbusArg2nd.endArray(); + + //qDebug()<<" " << m_map.value("address").toString(); + dbusLanIpv4 = m_map.value("address").toString(); + } + } + } + + if (key == "ipv6") { + for (QString inner_key : innerMap.keys()) { + if (inner_key == "address-data"){ + const QDBusArgument &dbusArg2nd = innerMap.value(inner_key).value(); + QMap m_map; + + dbusArg2nd.beginArray(); + while (!dbusArg2nd.atEnd()) { + dbusArg2nd >> m_map;// append map to a vector here if you want to keep it + } + dbusArg2nd.endArray(); + + //qDebug()<<" " << m_map.value("address").toString(); + dbusLanIpv6 = m_map.value("address").toString(); + } + } + } + } //end for(QString key : map.keys() ) + + } + } + } //end for (QString search_key : outsideMap.keys()) + } + } // end for(QString outside_key : map.keys() ) + + } //end foreach (QDBusObjectPath objNet, m_objNets) +} + +//获取已经连接的有线网ip +void KylinDBus::getConnectNetIp() +{ + QDBusInterface interface( "org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + //获取已经连接了那些网络,及这些网络对应的网络类型(ethernet or wifi) + QDBusMessage result = interface.call("Get", "org.freedesktop.NetworkManager", "ActiveConnections"); + QList outArgs = result.arguments(); + QVariant first = outArgs.at(0); + QDBusVariant dbvFirst = first.value(); + QVariant vFirst = dbvFirst.variant(); + QDBusArgument dbusArgs = vFirst.value(); + + QDBusObjectPath objPath; + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + dbusArgs >> objPath; + + QDBusInterface interfacePro( "org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + QDBusReply reply = interfacePro.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Type"); + if (reply.value().toString() == "ethernet" || reply.value().toString() == "802-3-ethernet") { + //ipv4的路径信息和ip信息 + QDBusInterface interfaceIp4( "org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + QDBusMessage replyIp4 = interfaceIp4.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Ip4Config"); + QList outArgsIp4 = replyIp4.arguments(); + QVariant firstIp4 = outArgsIp4.at(0); + QDBusVariant dbvFirstIp4 = firstIp4.value(); + QVariant vFirstIp4 = dbvFirstIp4.variant(); + QDBusObjectPath dbusPathIp4 = vFirstIp4.value(); + + QDBusInterface interfaceIpv4( "org.freedesktop.NetworkManager", + dbusPathIp4.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + QDBusMessage replyIpv4 = interfaceIpv4.call("Get", "org.freedesktop.NetworkManager.IP4Config", "AddressData"); + + QList outArgsIpv4 = replyIpv4.arguments(); + if(outArgsIp4.count() >= 0){ + QVariant firstIpv4 = outArgsIpv4.at(0); + QDBusVariant dbvFirstIpv4 = firstIpv4.value(); + QVariant vFirstIpv4 = dbvFirstIpv4.variant(); + + const QDBusArgument &dbusArgIpv4 = vFirstIpv4.value(); + QList mDatasIpv4; + dbusArgIpv4 >> mDatasIpv4; + + foreach (QVariantMap mDataIpv4, mDatasIpv4) { + dbusActiveLanIpv4 = mDataIpv4.value("address").toString(); + } + } + //ipv6的路径信息和ip信息 + QDBusInterface interfaceIp6( "org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + QDBusMessage replyIp6 = interfaceIp6.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Ip6Config"); + QList outArgsIp6 = replyIp6.arguments(); + QVariant firstIp6 = outArgsIp6.at(0); + QDBusVariant dbvFirstIp6 = firstIp6.value(); + QVariant vFirstIp6 = dbvFirstIp6.variant(); + QDBusObjectPath dbusPathIp6 = vFirstIp6.value(); + + QDBusInterface interfaceIpv6( "org.freedesktop.NetworkManager", + dbusPathIp6.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + QDBusMessage replyIpv6 = interfaceIpv6.call("Get", "org.freedesktop.NetworkManager.IP6Config", "AddressData"); + + QList outArgsIpv6 = replyIpv6.arguments(); + if(outArgsIp6.count() >= 0){ + QVariant firstIpv6 = outArgsIpv6.at(0); + QDBusVariant dbvFirstIpv6 = firstIpv6.value(); + QVariant vFirstIpv6 = dbvFirstIpv6.variant(); + + const QDBusArgument &dbusArgIpv6 = vFirstIpv6.value(); + QList mDatasIpv6; + dbusArgIpv6 >> mDatasIpv6; + + foreach (QVariantMap mDataIpv6, mDatasIpv6) { + dbusActiveLanIpv6 = mDataIpv6.value("address").toString(); + } + } + } + } + dbusArgs.endArray(); +} + +//获取wifi的mac地址 +void KylinDBus::getWifiMac(QString netName) +{ + dbusWifiMac = ""; + + QDBusInterface interface( "org.freedesktop.NetworkManager", + wirelessPath.path(), + "org.freedesktop.NetworkManager.Device.Wireless", + QDBusConnection::systemBus() ); + + QDBusReply> reply = interface.call("GetAllAccessPoints"); //get accesspoint for each wifi + QList objPaths = reply.value(); + + foreach (QDBusObjectPath objPath, objPaths) { + QDBusInterface ssid_interface( "org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + QDBusReply ssid_replys = ssid_interface.call("Get", "org.freedesktop.NetworkManager.AccessPoint", "Ssid"); + QString str_name = ssid_replys.value().toString(); + + if (str_name == netName) { + //if the ssid of the accesspoint is just the netName, we can get this hardware address + QDBusInterface path_interface( "org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + QDBusReply path_reply = path_interface.call("Get", "org.freedesktop.NetworkManager.AccessPoint", "HwAddress"); + dbusWifiMac = path_reply.value().toString(); + } + } +} + +//获取当前能获取到的wifi的数量, 每个accesspoint 代表一个wifi +int KylinDBus::getAccessPointsNumber() +{ + QDBusInterface interface( "org.freedesktop.NetworkManager", + wirelessPath.path(), + "org.freedesktop.NetworkManager.Device.Wireless", + QDBusConnection::systemBus() ); + + QDBusReply> reply = interface.call("GetAllAccessPoints"); + QList objPaths = reply.value(); + + return objPaths.size(); +} + +//新增了一个网络,伴随着多了一个网络配置文件 +void KylinDBus::onNewConnection(QDBusObjectPath objPath) +{ + QDBusInterface m_interface("org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.NetworkManager.Settings.Connection", + QDBusConnection::systemBus()); + QDBusMessage result = m_interface.call("GetSettings"); + + const QDBusArgument &dbusArg1st = result.arguments().at( 0 ).value(); + QMap> map; + dbusArg1st >> map; + + for(QString key : map.keys() ) { + if (key == "802-3-ethernet") { + emit this->updateWiredList(0); //send this signal to update wired network list + syslog(LOG_DEBUG, "A new wired network was created."); + qDebug()<<"A new wired network was created."; + } + } +} + +//减少了一个网络,伴随着减少了一个网络配置文件 +void KylinDBus::onConnectionRemoved(QDBusObjectPath objPath) +{ + syslog(LOG_DEBUG, "An old network was removed from configure directory."); + qDebug()<<"An old network was removed from configure directory."; + + if (mw->is_btnNetList_clicked == 1) { + emit this->updateWiredList(0); //send this signal to update wired network list + } +} + +//应用启动时,获取已经连接的网络信息,包括该网络的路径和类型 +void KylinDBus::initConnectionInfo() +{ + QDBusInterface interface( "org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + //获取已经连接了那些网络,及这些网络对应的网络类型(ethernet or wifi) + QDBusMessage result = interface.call("Get", "org.freedesktop.NetworkManager", "ActiveConnections"); + QList outArgs = result.arguments(); + QVariant first = outArgs.at(0); + QDBusVariant dbvFirst = first.value(); + QVariant vFirst = dbvFirst.variant(); + QDBusArgument dbusArgs = vFirst.value(); + + QDBusObjectPath objPath; + // qDebug()<<" "; + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + dbusArgs >> objPath; + oldPaths.append(objPath); + // qDebug() <<"debug: *****path is: "<< objPath.path(); + + QDBusInterface interface( "org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + QDBusReply reply = interface.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Type"); + // qDebug()<<"debug: *****connection type is: "< m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled"); + qDebug()<<"debug: *****初始的无线网络开关状态是: "<(); + QList newPaths; + dbusArg >> newPaths; + QStringList newPathInfo; + qDebug()<<" "; + foreach (QDBusObjectPath objPath, newPaths) { + qDebug()<<"dbug: bbbbb "< reply = interface.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Type"); + qDebug()<<"dbug: ccccc "<onExternalConnectionChange(oldPathInfo.at(i)); + } else { + for (int j=0; jonExternalConnectionChange(oldPathInfo.at(i)); + } + } + } + } + } + + // 第三步 同上一次获取的已连接网络相比较,处理相比于上次增加的网络连接 + for (int i=0; ionExternalConnectionChange(newPathInfo.at(i)); + } else { + for (int j=0; jonExternalConnectionChange(newPathInfo.at(i)); + } + } + } + } + + bool isChangeOldPathInfo = true; + for (int k=0; konExternalWifiSwitchChange(true); + setBtnWifiGsetting(true); + } + if (oldWifiSwitchState == true && newWifiSwitchState == false) { + qDebug()<<"debug: wifi开关已经关闭"; + is_wificonnected = false; + mw->onExternalWifiSwitchChange(false); + setBtnWifiGsetting(false); + } + + oldWifiSwitchState = newWifiSwitchState; //更新状态用于下一次 + } + } +} + +//有线网属性变化时,执行该函数。由于可能在短时间收到几条相同属性变化信息,所以在短时间内,执行一次 +void KylinDBus::onLanPropertyChanged(QVariantMap qvm) +{ + if (!isRunningFunction) { + syslog(LOG_DEBUG, "kylin-nm receive a signal 'Device.Wired PropertiesChanged' about interface."); + qDebug()<<"kylin-nm receive a signal 'Device.Wired PropertiesChanged' about interface."; + isRunningFunction = true; //function onLanPropertyChanged is running + time->start(3000); + + QString str = qvm.value("Carrier").toString(); + if (str == "false" || str == "true") { + getPhysicalCarrierState(1); + } + } else { a = 0; } +} +void KylinDBus::slot_timeout() +{ + isRunningFunction = false; + time->stop(); +} + +//无线网属性变化时,执行该函数 +void KylinDBus::onWifiPropertyChanged(QVariantMap qvm) +{ + //qDebug()<<"debug: *************"<> m_reply = m_interface.call("ListConnections"); + + QDBusObjectPath active_connection; + active_connection.setPath("/"); + + QList m_objNets = m_reply.value(); + foreach (QDBusObjectPath objNet, m_objNets) { + QDBusInterface m_interface("org.freedesktop.NetworkManager", + objNet.path(), + "org.freedesktop.NetworkManager.Settings.Connection", + QDBusConnection::systemBus()); + QDBusMessage result = m_interface.call("GetSettings"); + + const QDBusArgument &dbusArg1st = result.arguments().at( 0 ).value(); + QMap> map; + dbusArg1st >> map; + + for (QString outside_key : map.keys() ) { + QMap outsideMap = map.value(outside_key); + if (outside_key == "connection") { + for (QString search_key : outsideMap.keys()) { + if (search_key == "id") { + if (netName == outsideMap.value(search_key).toString()) { + + QDBusInterface m_interface("org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.NetworkManager", + QDBusConnection::systemBus() ); + QDBusReply connectionReply = m_interface.call("ActivateConnection", + QVariant::fromValue(objNet), + QVariant::fromValue(wiredPath), + QVariant::fromValue(active_connection)); + } + } + } + } + } // end for(QString outside_key : map.keys() ) + + } //end foreach (QDBusObjectPath objNet, m_objNets) +} + +//显示桌面通知 +void KylinDBus::showDesktopNotify(QString message) +{ + //锁屏不发送该通知 +// emit requestSendDesktopNotify(message); +} + +//获取任务栏位置,上下左右 +int KylinDBus::getTaskBarPos(QString str) +{ + QDBusInterface interface( "com.ukui.panel.desktop", + "/", + "com.ukui.panel.desktop", + QDBusConnection::sessionBus() ); + + QDBusReply reply = interface.call("GetPanelPosition", str); + if (reply.isValid()) { + return reply; + } else { + return 0; //如果没有成功获取,返回一个默认值 + } +} + +//获取任务栏高度 +int KylinDBus::getTaskBarHeight(QString str) +{ + QDBusInterface interface( "com.ukui.panel.desktop", + "/", + "com.ukui.panel.desktop", + QDBusConnection::sessionBus() ); + + QDBusReply reply = interface.call("GetPanelSize", str); + if (reply.isValid()) { + return reply; + } else { + return 46; //如果没有成功获取,返回一个默认值 + } +} + +/////////////////////////////////////////////////////////////////////////////// +//下方使用Gsetting 进程通信方法 + +//创建获取任务栏信息的GSetting对象 +void KylinDBus::initTaskbarGsetting() +{ + if (QGSettings::isSchemaInstalled("org.ukui.panel.settings")) { + m_tastbar_gsettings = new QGSettings("org.ukui.panel.settings"); + } + if (QGSettings::isSchemaInstalled("org.kylinnm.settings")) { + m_nm_gsettings = new QGSettings("org.kylinnm.settings"); + if (m_nm_gsettings->keys().contains("wifiswitch")) { + m_nm_gsettings->set("wifiswitch",oldWifiSwitchState); + } + } +} + +//使用GSetting方法获取任务栏高度 +int KylinDBus::getTaskbarHeight() +{ + if (!m_tastbar_gsettings) { + return 46; + } + + QStringList keys = m_tastbar_gsettings->keys(); + if (keys.contains("panelsize")) { + int hh = m_tastbar_gsettings->get("panelsize").toInt(); + return hh; + } else { + return 46; + } +} + +//使用GSetting方法写入WIFW信号强度 +void KylinDBus::setWifiSignal(int wifiSignal, QString wifiname) +{ if(!m_tastbar_gsettings || !m_nm_gsettings) + return; + + if (m_tastbar_gsettings->keys().contains("wifisignal")) { + m_tastbar_gsettings->set("wifisignal",wifiSignal); + } + if (m_nm_gsettings->keys().contains("wifisignal")) { + m_nm_gsettings->set("wifisignal",wifiSignal); + } + if (m_nm_gsettings->keys().contains("wifiname")) { + m_nm_gsettings->set("wifiname",wifiname); + } +} +//使用GSetting方法获取任务栏位置,上下左右 +int KylinDBus::getTaskbarPos() +{ + if (!m_tastbar_gsettings) { + return 0; + } + + QStringList keys = m_tastbar_gsettings->keys(); + if (keys.contains("panelposition")) { + int pp = m_tastbar_gsettings->get("panelposition").toInt(); + return pp; + } else { + return 0; + } +} + +//创建监听wifi打开或关闭信息的GSetting对象 +void KylinDBus::getWifiSwitchState() +{ + if (QGSettings::isSchemaInstalled("org.ukui.control-center.wifi.switch")) { + + m_gsettings = new QGSettings("org.ukui.control-center.wifi.switch"); + + // 监听key的value是否发生了变化 + connect(m_gsettings, &QGSettings::changed, this, [=] (const QString &key) { + + if (key == "switch") { + if (isWirelessCardOn) { + bool judge = getSwitchStatus(key); + if (judge) { + mw->onBtnWifiClicked(2); //打开wifi开关 + qDebug()<<"receive a signal to turn on wifi switch from control-center"; + syslog(LOG_DEBUG, "receive a signal to turn on wifi switch from control-center"); + } else { + if (!is_wificonnected) { + return; + } + mw->onBtnWifiClicked(3); //关闭wifi开关 + qDebug()<<"receive a signal to turn off wifi switch from control-center"; + syslog(LOG_DEBUG, "receive a signal to turn off wifi switch from control-center"); + } + } + } + }); + } +} + +//收到控制面板发来的消息后,获取wifi开关信息 +bool KylinDBus::getSwitchStatus(QString key) { + if (!m_gsettings) { + return true; + } + const QStringList list = m_gsettings->keys(); + if (!list.contains(key)) { + return true; + } + bool res = m_gsettings->get(key).toBool(); + return res; +} + +//通知控制面板wifi开关的信息 +void KylinDBus::setWifiSwitchState(bool signal) +{ + if (!m_gsettings) { + return ; + } + + const QStringList list = m_gsettings->keys(); + + if (!list.contains("switchor")) { + return ; + } + m_gsettings->set("switchor",signal); + + if (!m_nm_gsettings) { + return ; + } + if (m_nm_gsettings->keys().contains("wifiswitch")) { + m_nm_gsettings->set("wifiswitch",signal); + } +} + +void KylinDBus::setWifiConnStatus(bool is_wifi_connected) +{ +// qDebug()<<"WIFI连接状态:"<keys().contains("wificonn")) { + m_nm_gsettings->set("wificonn",is_wifi_connected); + } +} + +void KylinDBus::setLanConnStatus(bool is_lan_connected) +{ +// qDebug()<<"LAN连接状态:"<keys().contains("lanconn")) { + m_nm_gsettings->set("lanconn",is_lan_connected); + } +} + +//通知控制面板无线网卡的状态信息 +void KylinDBus::setWifiCardState(bool signal) +{ + if (!m_gsettings) { + return ; + } + + const QStringList list = m_gsettings->keys(); + + if (!list.contains("wificard")) { + return ; + } + m_gsettings->set("wificard",signal); +} + +//创建获取窗口透明度信息的GSetting的对象 +void KylinDBus::initTransparentState() +{ + if (QGSettings::isSchemaInstalled("org.ukui.control-center.personalise")) { + m_transparency_gsettings = new QGSettings("org.ukui.control-center.personalise"); + } +} + +//创建WIFI开关状态的GSetting的对象 +void KylinDBus::initBtnWifiGsetting() +{ + if (QGSettings::isSchemaInstalled("org.ukui.control-center.wifi.switch")) { + m_btnWifi_gsettings = new QGSettings("org.ukui.control-center.wifi.switch"); + } +} +void KylinDBus::setBtnWifiGsetting(bool bl) +{ + if(m_btnWifi_gsettings->get("switch").toBool()!=bl) + { + m_btnWifi_gsettings->set("switch",bl); + } +} + +//根据Dbus路径获取wifi的ssid(排除空格干扰) +QString KylinDBus::getWifiSsid(QString accessPointPath) +{ + QDBusInterface interface( "org.freedesktop.NetworkManager", + accessPointPath, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + QDBusMessage result = interface.call("Get", "org.freedesktop.NetworkManager.AccessPoint", "Ssid"); + if (result.arguments().isEmpty()) return ""; + return result.arguments().at(0).value().variant().toString(); +} + +//获取已经连接无线网络的ssid和uuid +QList KylinDBus::getAtiveWifiBSsidUuid(QStringList wifilist) +{ + QList strBSsidUuid; + + QDBusInterface interface( "org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + //获取已经连接了那些网络,及这些网络对应的网络类型(ethernet or wifi) + QDBusMessage result = interface.call("Get", "org.freedesktop.NetworkManager", "ActiveConnections"); + QList outArgs = result.arguments(); + QVariant first = outArgs.at(0); + QDBusVariant dbvFirst = first.value(); + QVariant vFirst = dbvFirst.variant(); + QDBusArgument dbusArgs = vFirst.value(); + + QDBusObjectPath objPath; + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + dbusArgs >> objPath; + + QDBusInterface interfaceType( "org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + QDBusReply reply = interfaceType.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Type"); + + if (reply.value().toString() == "wifi" || reply.value().toString() == "802-11-wireless") { + QDBusInterface interfaceInfo( "org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + + //获取已经连接wifi的uuid + QDBusReply replyUuid = interfaceInfo.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Uuid"); + //qDebug() << "wifi uuid : "<< replyUuid.value().toString(); + strBSsidUuid.append(replyUuid.value().toString()); + + + //再获取bssid + QDBusMessage resultConnection = interfaceInfo.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Connection"); + + QList outArgsConnection = resultConnection.arguments(); + QVariant firstConnection = outArgsConnection.at(0); + QDBusVariant dbvFirstConnection = firstConnection.value(); + QVariant vFirstConnection = dbvFirstConnection.variant(); + QDBusObjectPath dbusArgsConnection = vFirstConnection.value(); + + QDBusInterface interfaceSet("org.freedesktop.NetworkManager", + dbusArgsConnection.path(), + "org.freedesktop.NetworkManager.Settings.Connection", + QDBusConnection::systemBus()); + QDBusMessage resultSet = interfaceSet.call("GetSettings"); + + const QDBusArgument &dbusArg1stSet = resultSet.arguments().at( 0 ).value(); + QMap> mapSet; + dbusArg1stSet >> mapSet; + + for (QString setKey : mapSet.keys() ) { + QMap subSetMap = mapSet.value(setKey); + if (setKey == "802-11-wireless") { + for (QString searchKey : subSetMap.keys()) { + if (searchKey == "seen-bssids") { + //qDebug() << "wifi bssid : "<keys(); + if (keys.contains("transparency")) { + double tp = m_transparency_gsettings->get("transparency").toDouble(); + return tp; + } else { + return 0.7; + } +} diff --git a/KylinNM/src/kylin-dbus-interface.h b/KylinNM/src/kylin-dbus-interface.h new file mode 100644 index 0000000..b62c4c5 --- /dev/null +++ b/KylinNM/src/kylin-dbus-interface.h @@ -0,0 +1,135 @@ +/* + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class KylinNM; +class Utils; + +class KylinDBus : public QObject +{ + Q_OBJECT +public: + explicit KylinDBus(KylinNM *mw = 0, QObject *parent = nullptr); + ~KylinDBus(); + + void getObjectPath(); + int getAccessPointsNumber(); + void showDesktopNotify(QString message); + void initConnectionInfo(); + void connectWiredNet(QString netName); + void getConnectNetIp(); + + int getTaskBarPos(QString str); + int getTaskBarHeight(QString str); + void initTaskbarGsetting(); + int getTaskbarHeight(); + int getTaskbarPos(); + + void getWifiSwitchState(); + bool getSwitchStatus(QString key); + void setWifiSwitchState(bool signal); + void setWifiCardState(bool signal); + + void initTransparentState(); + double getTransparentData(); + + void initBtnWifiGsetting(); + void setBtnWifiGsetting(bool bl); + QString getWifiSsid(QString accessPointPath); + QList getAtiveWifiBSsidUuid(QStringList wifilist); + + QDBusObjectPath wiredPath; //有线设备的路径 + QDBusObjectPath wirelessPath; //无线设备的路径 + QList multiWiredPaths; //已连接网络的对象路径列表 + + QList multiWiredCableState; + bool isWiredCableOn = false; //是否插入了网线 + bool isWirelessCardOn = false; //是否插入了无线网卡 + + QString dbusLanCardName = ""; + QString dbusLanIpv4 = ""; + QString dbusLanIpv6 = ""; + QString dbusActiveLanIpv4 = ""; + QString dbusActiveLanIpv6 = ""; + QString dbusLanGateway = ""; + QString dbusLanMac = ""; + QString dbusWiFiCardName = ""; + QString dbusWifiMac = ""; + +public Q_SLOTS: + void onNewConnection(QDBusObjectPath objPath); + void onConnectionRemoved(QDBusObjectPath objPath); + void onPropertiesChanged(QVariantMap qvm); + void onLanPropertyChanged(QVariantMap qvm); + void onWifiPropertyChanged(QVariantMap qvm); + void onAccessPointAdded(QDBusObjectPath objPath); + void getPhysicalCarrierState(int n); + void getLanHwAddressState(); + void getWiredCardName(); + void getWirelessCardName(); + void getLanIp(QString netName); + void getWifiMac(QString netName); + void slot_timeout(); + void setWifiSignal(int wifiSignal, QString wifiname); + void setWifiConnStatus(bool is_wifi_connected); + void setLanConnStatus(bool is_lan_connected); + +private: + KylinNM *mw; + Utils *mUtils; + QThread *mUtilsThread; + + int a = 0; + bool isRunningFunction = false; + QTimer *time = nullptr; + QList oldPaths; //已连接网络的对象路径列表 + QStringList oldPathInfo; //某个已连接网络对象路径对应的网络类型(ethernet or wifi) + bool oldWifiSwitchState; //上一次获取到的wifi开关状态 + + QGSettings *m_tastbar_gsettings = nullptr; + QGSettings *m_nm_gsettings = nullptr; + QGSettings *m_gsettings = nullptr; + QGSettings *m_transparency_gsettings = nullptr; + QGSettings *m_btnWifi_gsettings = nullptr; + + bool is_wificonnected = false; + +Q_SIGNALS: + void updateWiredList(int n); + void requestSendDesktopNotify(QString message); +}; + +#endif // KYLINDBUSINTERFACE_H diff --git a/KylinNM/src/kylin-network-interface.c b/KylinNM/src/kylin-network-interface.c new file mode 100644 index 0000000..623f457 --- /dev/null +++ b/KylinNM/src/kylin-network-interface.c @@ -0,0 +1,997 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//获取网络接口名 +ifname *kylin_network_get_ifacename() +{ + int i = 0; + int sockfd; + struct ifconf ifconf; + struct ifreq *ifreq; + unsigned char buf[1024]; + + //初始化ifconf + ifconf.ifc_len = 1024; + //字符串指针ifconf.ifc_buf指向buf + ifconf.ifc_buf = buf; + + if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + perror("socket error"); + return 0; + } + + //获取所有接口信息 + ioctl(sockfd, SIOCGIFCONF, &ifconf); + // printf("%s\n",ifconf.ifc_buf); + + //逐个获取Ip地址 + //结构体指针ifreq指向buf,即ifconf.ifc_buf + ifreq = (struct ifreq*)buf; + int number=ifconf.ifc_len/sizeof(struct ifreq); + // printf("%d\n",number); + + ifname *ifn=(ifname *)malloc(sizeof(ifname)*(number+1)); + + for(i = number; i>0; i--) + { + // printf("name = [%s] \n",ifreq->ifr_name); + + int j=number-i; + ifn[j].if_name=(char *)malloc(sizeof(char)*10); + strcpy(ifn[j].if_name,ifreq->ifr_name); + // ifn[j].if_name=ifreq->ifr_name; + // printf("if_name[%d]:%s\n",j,if_name[j]); + + ifreq++; + } + ifn[number].if_name=NULL; + + + return ifn; +} + +//获取所有网络连接 +conlist *kylin_network_get_conlist_info() +{ + int status = system("nmcli connection show > /tmp/conlist.txt"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'kylin_network_get_conlist_info' failed");} + char *filename="/tmp/conlist.txt"; + + FILE *confp; + int connum=0; + char ConStrLine[1024]; + if((confp=fopen(filename,"r"))==NULL) + { + printf("error!"); + + } + fgets(ConStrLine,1024,confp); + while(!feof(confp)) + { + fgets(ConStrLine,1024,confp); + connum++; + } + // printf("%d\n",connum); + fclose(confp); + conlist *clist=(conlist *)malloc(sizeof(conlist)*connum); + + int count=0; + FILE *fp; + char StrLine[1024]; + if((fp=fopen(filename,"r"))==NULL) + { + printf("error!"); + + } + fgets(StrLine,1024,fp); + while(!feof(fp)) + { + if(count==connum-1)break; + + fgets(StrLine,1024,fp); + + char *index=StrLine; + char conname[100]; + + //截取连接名称 + int num=0; + for(index;*index!='\n';index++) + { + if(*index==' ') + { + if(*(index+1)==' ') + break; + } + num++; + } + + // printf("连接名称长度:%d\n",num); + clist[count].con_name=(char *)malloc(sizeof(char)*(num+1)); + strncpy(conname,StrLine,num+1); + conname[num]='\0'; + strncpy(clist[count].con_name,conname,num+1); + // printf("%s\n",clist[count].con_name); + + //截取连接类型 + char type[100]; + for(index;*index!='\n';index++) + { + if(*index==' ') + { + if(*(index+1)=' ') + if(*(index+2)!=' ') + break; + + } + } + char *index1=index+2; + for(index1;*index1!='\n';index1++) + { + if(*index1==' ') + { + if(*(index1+1)==' ') + break; + } + } + int num1=0; + char *index2=index1+2; + for(index2;*index2!='\n';index2++) + { + if(*index2==' ')break; + num1++; + } + clist[count].type=(char *)malloc(sizeof(char)*(num1+1)); + strncpy(type,index1+2,num1+1); + type[num1]='\0'; + strncpy(clist[count].type,type,num1+1); + // printf("%s\n",clist[count].type); + count++; + } + fclose(fp); + + clist[count].con_name=NULL; + clist[count].type=NULL; + + return clist; +} + +//获取当前活动网络连接 +activecon *kylin_network_get_activecon_info() +{ + struct passwd *pwd; + pwd = getpwuid(getuid()); + char *name = pwd->pw_name; + char *tmpPrefix = "/tmp/kylin-nm-activecon-"; + char *chr = "nmcli connection show -active > "; + + char *cmd; + asprintf(&cmd, "%s%s%s", chr, tmpPrefix, name); + char *path; + asprintf(&path, "%s%s", tmpPrefix, name); + int status = system(cmd); + //int status = system("nmcli connection show -active > /tmp/activecon.txt"); + if (status != 0) + syslog(LOG_ERR, "execute 'nmcli connection show -active' in function 'kylin_network_get_activecon_info' failed"); + free(cmd); + + char *filename = path; + + FILE *activefp; + int activenum=0; + char activeStrLine[1024]; + if((activefp=fopen(filename,"r"))==NULL) + { + printf("error!"); + } + fgets(activeStrLine,1024,activefp); + while(!feof(activefp)) + { + fgets(activeStrLine,1024,activefp); + activenum++; + } + // printf("%d\n",activenum); + fclose(activefp); + activecon *activelist=(activecon *)malloc(sizeof(activecon)*activenum); + + int count=0; + FILE *fp; + char StrLine[1024]; + if((fp=fopen(filename,"r"))==NULL) + { + printf("error!"); + + } + free(path); + + fgets(StrLine,1024,fp); + while(!feof(fp)) + { + if(count==activenum-1)break; + + fgets(StrLine,1024,fp); + + char *index=StrLine; + char conname[100]; + + //截取连接名称 + int num=0; + for(index;*index!='\n';index++) + { + if(*index==' ') + { + if(*(index+1)==' ') + break; + } + num++; + } + + // printf("连接名称长度:%d\n",num); + activelist[count].con_name=(char *)malloc(sizeof(char)*(num+1)); + strncpy(conname,StrLine,num+1); + conname[num]='\0'; + strncpy(activelist[count].con_name,conname,num+1); + // printf("%s\n",activelist[count].con_name); + + //截取连接类型 + char type[100]; + for(index;*index!='\n';index++) + { + if(*index==' ') + { + if(*(index+1)=' ') + if(*(index+2)!=' ') + break; + + } + } + char *index1=index+2; + for(index1;*index1!='\n';index1++) + { + if(*index1==' ') + { + if(*(index1+1)==' ') + break; + } + } + int num1=0; + char *index2=index1+2; + for(index2;*index2!='\n';index2++) + { + if(*index2==' ')break; + num1++; + } + activelist[count].type=(char *)malloc(sizeof(char)*(num1+1)); + strncpy(type,index1+2,num1+1); + type[num1]='\0'; + strncpy(activelist[count].type,type,num1+1); + // printf("%s\n",activelist[count].type); + + //截取连接所属设备 + char *index3=index2; + char dev[100]; + for(index3;*index3!='\n';index3++) + { + if(*index3==' ') + { + if(*(index3+1)!=' ') + break; + } + } + int num2=0; + char *index4=index3+1; + for(index4;*index4!='\n';index4++) + { + if(*index4==' ')break; + num2++; + } + activelist[count].dev=(char *)malloc(sizeof(char)*(num2+1)); + strncpy(dev,index3+1,num2+1); + dev[num2]='\0'; + strncpy(activelist[count].dev,dev,num2+1); + // printf("%s\n",activelist[count].dev); + count++; + } + fclose(fp); + + activelist[count].con_name=NULL; + activelist[count].type=NULL; + activelist[count].dev=NULL; + + return activelist; +} + +//创建新的以太网连接 +void kylin_network_create_new_ethernet(char *con_name,char *if_name) +{ + char str[100]; + char *net_type="ethernet"; + sprintf(str,"nmcli connection add con-name \"%s\" ifname %s type %s",con_name,if_name,net_type); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection add con-name' in function 'kylin_network_create_new_ethernet' failed");} +} + +// 创建新的wifi连接配置 +void kylin_network_create_new_wifi(char *con_name, char *if_name) +{ + char str[200]; + sprintf(str, "nmcli connection add con-name \"%s\" ifname \"%s\" type wifi ssid \"%s\"", + con_name, if_name, con_name); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection add con-name' in function 'kylin_network_create_new_wifi' failed");} +} + +//删除以太网连接 +void kylin_network_del_ethernet_con(char *con_name) +{ + char str[100]; + sprintf(str,"nmcli connection delete \"%s\"",con_name); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection delete' in function 'kylin_network_del_ethernet_con' failed");} +} + +//设置动态分配ip +void kylin_network_set_automethod(char *con_name) +{ + char str[100]; + char *automethod="auto"; + sprintf(str,"nmcli connection modify \"%s\" ipv4.method %s ipv4.address '' ipv4.gateway ''",con_name,automethod); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection modify' in function 'kylin_network_set_automethod' failed");} +} + +//设置手动分配ip +void kylin_network_set_manualmethod(char *con_name,char *ip) +{ + char str[100]; + char *method="manual"; + sprintf(str,"nmcli connection modify \"%s\" ipv4.method %s ipv4.address %s",con_name,method,ip); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection modify' in function 'kylin_network_set_manualmethod' failed");} +} + +// 设置手动分配all +void kylin_network_set_manualall(char *con_name, char *addr, char *mask, char *gateway, char *dns){ + char str[200]; + sprintf(str, "nmcli connection modify \"%s\" ipv4.method manual ipv4.address %s/%s ipv4.gateway %s ipv4.dns %s", + con_name, addr, mask, gateway, dns); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection modify' in function 'kylin_network_set_manualall' failed");} +} + +//设置是否自动连接 +void kylin_network_set_autoconnect(char *con_name,bool autocon) +{ + char str[200]; + if(autocon==false) + { + char *ac="no"; + sprintf(str,"export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli connection modify \"%s\" connection.autoconnect %s",con_name,ac); + } + else{ + char *ac="yes"; + sprintf(str,"export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli connection modify \"%s\" connection.autoconnect %s",con_name,ac); + } + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection modify' in function 'kylin_network_set_autoconnect' failed");} +} + +//修改ip +void kylin_network_mod_ip(char *con_name,char *ip) +{ + char str[100]; + sprintf(str,"nmcli connection modify \"%s\" ipv4.address %s",con_name,ip); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection modify' in function 'kylin_network_mod_ip' failed");} +} + +//修改网关 +void kylin_network_mod_gateway(char *con_name,char *gw) +{ + char str[100]; + sprintf(str,"nmcli connection modify \"%s\" ipv4.gateway %s",con_name,gw); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection modify' in function 'kylin_network_mod_gateway' failed");} +} + +//修改dns +void kylin_network_mod_dns(char *con_name,char *dns) +{ + char str[100]; + sprintf(str,"nmcli connection modify \"%s\" ipv4.dns %s",con_name,dns); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection modify' in function 'kylin_network_mod_dns' failed");} +} + +//连接以太网 +void kylin_network_set_con_up(char *con_name) +{ + char str[100]; + sprintf(str,"nmcli connection up \"%s\"",con_name); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection up' in function 'kylin_network_set_con_up' failed");} +} + +//断开以太网 +void kylin_network_set_con_down(char *con_name) +{ + char str[100]; + sprintf(str,"nmcli connection down \"%s\"",con_name); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection down' in function 'kylin_network_set_con_down' failed");} +} + +//连接wifi +void kylin_network_set_wifi_up(char *con_name,char *passwd) +{ + char str[100]; + sprintf(str,"export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli device wifi connect \"%s\" password \"%s\"", con_name,passwd); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli device wifi connect' in function 'kylin_network_set_wifi_up' failed");} +} + +//断开wifi连接 +void kylin_network_set_wifi_down(char *if_name) +{ + char str[100]; + sprintf(str,"nmcli device disconnect \"%s\"",if_name); + int status = system(str); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli device disconnect' in function 'kylin_network_set_wifi_down' failed");} +} + +//获取wifi列表信息 +wifilist *kylin_network_get_wifilist_info() +{ + int status = system("nmcli device wifi > /tmp/wflist.txt"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli device wifi' in function 'kylin_network_get_wifilist_info' failed");} + char *filename="/tmp/wflist.txt"; + + FILE *wffp; + int wfnum=0; + char WfStrLine[1024]; + if((wffp=fopen(filename,"r"))==NULL) + { + printf("error!"); + + } + fgets(WfStrLine,1024,wffp); + while(!feof(wffp)) + { + fgets(WfStrLine,1024,wffp); + wfnum++; + } + // printf("wifi数量:%d\n",wfnum); + fclose(wffp); + //wifi实际数量是wfnum-1 + wifilist *wflist=(wifilist *)malloc(sizeof(wifilist)*wfnum); + + int count=0; + FILE *fp; + char StrLine[1024]; + if((fp=fopen(filename,"r"))==NULL) + { + printf("error!"); + + } + fgets(StrLine,1024,fp); + while(!feof(fp)) + { + if(count==wfnum-1)break; + + fgets(StrLine,1024,fp); + + // printf("%s\n",StrLine+3); + char *index=StrLine+3; + + //截取ssid + char *str1="Infra"; + int num=0; + for(index;strcmp(index+5,"\n")!=0;index++) + { + int result=strncmp(index,str1,5); + if(result==0) + { + // printf("%s\n",index); + break; + + } + num++; + + } + char ssid[100]; + char *ssidindex=index-1; + int ssidnum=0; + for(ssidindex;*ssidindex==' ';ssidindex--)ssidnum++; + // printf("空格数量:%d\n",ssidnum); + // if(ssidnum==1) + strncpy(ssid,StrLine+3,num-1); + ssid[num-ssidnum]='\0'; + // printf("-6666--%s---\n",ssid); + + wflist[count].ssid=(char *)malloc(sizeof(char)*(num-ssidnum)); + strncpy(wflist[count].ssid,ssid,num-ssidnum+1); + // printf("第%d个:%s ",count,wflist[count].ssid); + + + //截取信号强度 + char *str2="Mbit/s"; + for(index;strcmp(index+6,"\n")!=0;index++) + { + int result=strncmp(index,str2,6); + if(result==0) + { + // printf("%s\n",index); + break; + } + } + + char signal[10]; + char *signalindex=index+8; + int signalnum=0; + for(signalindex;*signalindex!=' ';signalindex++)signalnum++; + strncpy(signal,index+8,signalnum); + signal[signalnum]='\0'; + // printf("-7777--%s---\n",signal); + + wflist[count].signal=atoi(signal); + // printf("%d ",wflist[count].signal); + + //截取安全性 + char *str3="WPA"; + for(index;strcmp(index+3,"\n")!=0;index++) + { + int result=strncmp(index,str3,3); + if(result==0) + { + // printf("%s\n",index); + break; + } + } + + char safety[20]; + char *safetyindex=index; + int safetynum=0; + for(safetyindex;strcmp(safetyindex+2,"\n")!=0;safetyindex++) + { + int result=strncmp(safetyindex," ",2); + if(result==0)break; + safetynum++; + } + strncpy(safety,index,safetynum+1); + safety[safetynum+1]='\0'; + // printf("-8888--%s---\n",safety); + + wflist[count].safety=(char *)malloc(sizeof(char)*(safetynum+1)); + strncpy(wflist[count].safety,safety,safetynum+2); + // printf("%s\n",wflist[count].safety); + + count++; + + } + + fclose(fp); + + wflist[count].ssid=NULL; + wflist[count].signal=0; + wflist[count].safety=NULL; + + return wflist; +} + +//启用联网 +void kylin_network_enable_networking() +{ + int status = system("nmcli networking on"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli networking on' in function 'kylin_network_enable_networking' failed");} +} + +//禁用联网 +void kylin_network_disable_networking() +{ + int status = system("nmcli networking off"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli networking off' in function 'kylin_network_disable_networking' failed");} +} + +//启用wifi +void kylin_network_enable_wifi() +{ + int status = system("nmcli radio wifi on;sleep 3"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli radio wifi on' in function 'kylin_network_enable_wifi' failed");} +} + +//禁用wifi +void kylin_network_disable_wifi() +{ + int status = system("nmcli radio wifi off;sleep 2"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli radio wifi off' in function 'kylin_network_disable_wifi' failed");} +} + +//获取ip地址 +int kylin_network_get_ipaddr(char *if_name,char *ipaddr) +{ + int sock_ip; + struct sockaddr_in sin_ip; + struct ifreq ifr_ip; + if((sock_ip=socket(AF_INET,SOCK_STREAM,0))<0) + { + perror("sockket error"); + return -1; + } + + strcpy(ifr_ip.ifr_name,if_name); + + if(ioctl(sock_ip,SIOCGIFADDR,&ifr_ip)<0)//直接获取ip地址 + { + perror("Not setup interface\n"); + return -1; + } + + memcpy(&sin_ip,&ifr_ip.ifr_addr,sizeof(sin_ip)); + strcpy(ipaddr,inet_ntoa(sin_ip.sin_addr));//#include + close(sock_ip); + return 0; + +} + +//获取广播地址 +int kylin_network_get_brdaddr(char *if_name,char *brdaddr) +{ + int sock_brdaddr; + struct sockaddr_in sin_brd; + struct ifreq ifr_brd; + if((sock_brdaddr=socket(AF_INET,SOCK_STREAM,0))<0) + { + perror("sockket error"); + return -1; + } + + strcpy(ifr_brd.ifr_name,if_name); + + if(ioctl(sock_brdaddr,SIOCGIFBRDADDR,&ifr_brd)<0)//直接获取广播地址 + { + perror("Not setup interface\n"); + return -1; + } + + memcpy(&sin_brd,&ifr_brd.ifr_broadaddr,sizeof(sin_brd)); + strcpy(brdaddr,inet_ntoa(sin_brd.sin_addr)); + close(sock_brdaddr); + return 0; + +} + +//获取子网掩码 +int kylin_network_get_netmask(char *if_name,char *netmask) +{ + int sock_mask; + struct sockaddr_in sin_netmask; + struct ifreq ifr_mask; + if((sock_mask=socket(AF_INET,SOCK_STREAM,0))<0) + { + perror("sockket error"); + return -1; + } + + strcpy(ifr_mask.ifr_name,if_name); + + if(ioctl(sock_mask,SIOCGIFNETMASK,&ifr_mask)<0)//直接获取子网掩码 + { + perror("Not setup interface\n"); + return -1; + } + + memcpy(&sin_netmask,&ifr_mask.ifr_netmask,sizeof(sin_netmask)); + strcpy(netmask,inet_ntoa(sin_netmask.sin_addr)); + close(sock_mask); + return 0; + +} + +//获取MAC +int kylin_network_get_mac(char *if_name,char *macaddr) +{ + int sock_mac; + struct ifreq ifr_mac; + struct sockaddr_in sin_mac; + struct ether_addr ethaddr;//#include + + sock_mac=socket(AF_INET,SOCK_STREAM,0); + + strcpy(ifr_mac.ifr_name,if_name); + + if(-1==ioctl(sock_mac,SIOCGIFHWADDR,&ifr_mac)) + { + perror("Not setup interface\n"); + return -1; + } + memcpy(ðaddr,&ifr_mac.ifr_hwaddr.sa_data,sizeof(ethaddr)); + strcpy(macaddr,ether_ntoa(ðaddr));//#include + + // strcpy(macaddr,ether_ntoa((struct ether_addr*)ifr_mac.ifr_hwaddr.sa_data)); + + close(sock_mac); + return 0; + +} + +//获取MTU +int kylin_network_get_mtu(char *if_name) +{ + int sock_mtu; +// struct sockaddr_in sin_ip; + struct ifreq ifr_MTU; + if((sock_mtu=socket(AF_INET,SOCK_STREAM,0))<0) + { + perror("sockket error"); + return -1; + } + + strcpy(ifr_MTU.ifr_name,if_name); + + if(ioctl(sock_mtu,SIOCGIFMTU,&ifr_MTU)) + { + perror("Not setup interface\n"); + return -1; + } + + int mtu=ifr_MTU.ifr_mtu; + // printf("%d\n",ifr_MTU.ifr_mtu); + // printf("%d\n",mtu); + + close(sock_mtu); + return mtu; + +} + +static void getBuf(char *bufstr) +{ + //O_RDONLY以只读方式打开文件 + int fd=open("/proc/net/dev", O_RDONLY); + if(-1==fd) + { + printf("/proc/net/dev not exists!\n"); + } + + char buf[1024*2]; + //将读写位置移到文件开头 + lseek(fd,0,SEEK_SET); + int nBytes=read(fd,buf,sizeof(buf)-1); + if(-1==nBytes) + { + perror("read error"); + close(fd); + } + + buf[nBytes]='\0'; + strcpy(bufstr,buf); +} + +//总计上传下载数据量 +long *kylin_network_get_bytes(char *if_name) +{ + char buf[1024*2]; + getBuf(buf); + + //返回第一次指向if_name位置的指针 + char *pDev=strstr(buf,if_name); + if(NULL==pDev) + { + printf("don't find dev %s\n",if_name); + return NULL; + } + + char *p; + char *value; + int i=0; + static long rtbyt[2]; + /*去除空格,制表符,换行符等不需要的字段*/ + for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) + { + i++; + value = (char*)malloc(20); + strcpy(value, p); + /*得到的字符串中的第二个字段是接收流量*/ + if(i == 2) + { + rtbyt[0] = atol(value); + } + /*得到的字符串中的第十个字段是发送流量*/ + if(i == 10) + { + rtbyt[1] = atol(value); + break; + } + free(value); + } + return rtbyt; +} + +//总计上传下载数据包 +long *kylin_network_get_packets(char *if_name) +{ + char buf[1024*2]; + getBuf(buf); + + //返回第一次指向if_name位置的指针 + char *pDev=strstr(buf,if_name); + if(NULL==pDev) + { + printf("don't find dev %s\n",if_name); + return NULL; + } + + char *p; + char *value; + int i=0; + static long rtpkt[2]; + /*去除空格,制表符,换行符等不需要的字段*/ + for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) + { + i++; + value = (char*)malloc(20); + strcpy(value, p); + /*得到的字符串中的第三个字段是接收流量*/ + if(i == 3) + { + rtpkt[0] = atol(value); + } + /*得到的字符串中的第十一个字段是发送流量*/ + if(i == 11) + { + rtpkt[1] = atol(value); + break; + } + free(value); + } + return rtpkt; +} + +//总计上传下载错误数据包数量 +long *kylin_network_get_errs(char *if_name) +{ + char buf[1024*2]; + getBuf(buf); + + //返回第一次指向if_name位置的指针 + char *pDev=strstr(buf,if_name); + if(NULL==pDev) + { + printf("don't find dev %s\n",if_name); + return NULL; + } + + char *p; + char *value; + int i=0; + static long rterrs[2]; + /*去除空格,制表符,换行符等不需要的字段*/ + for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) + { + i++; + value = (char*)malloc(20); + strcpy(value, p); + /*得到的字符串中的第四个字段是接收流量*/ + if(i == 4) + { + rterrs[0] = atol(value); + } + /*得到的字符串中的第十二个字段是发送流量*/ + if(i == 12) + { + rterrs[1] = atol(value); + break; + } + free(value); + } + return rterrs; +} + +//总计上传下载丢弃数据包数量 +long *kylin_network_get_drop(char *if_name) +{ + char buf[1024*2]; + getBuf(buf); + + //返回第一次指向if_name位置的指针 + char *pDev=strstr(buf,if_name); + if(NULL==pDev) + { + printf("don't find dev %s\n",if_name); + return NULL; + } + + char *p; + char *value; + int i=0; + static long rtdrop[2]; + /*去除空格,制表符,换行符等不需要的字段*/ + for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) + { + i++; + value = (char*)malloc(20); + strcpy(value, p); + /*得到的字符串中的第五个字段是接收流量*/ + if(i == 5) + { + rtdrop[0] = atol(value); + } + /*得到的字符串中的第十三个字段是发送流量*/ + if(i == 13) + { + rtdrop[1] = atol(value); + break; + } + free(value); + } + return rtdrop; +} + +//总计上传下载过载数据包数量 +long *kylin_network_get_fifo(char *if_name) +{ + char buf[1024*2]; + getBuf(buf); + + //返回第一次指向if_name位置的指针 + char *pDev=strstr(buf,if_name); + if(NULL==pDev) + { + printf("don't find dev %s\n",if_name); + return NULL; + } + + char *p; + char *value; + int i=0; + static long rtfifo[2]; + /*去除空格,制表符,换行符等不需要的字段*/ + for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) + { + i++; + value = (char*)malloc(20); + strcpy(value, p); + /*得到的字符串中的第六个字段是接收流量*/ + if(i == 6) + { + rtfifo[0] = atol(value); + } + /*得到的字符串中的第十四个字段是发送流量*/ + if(i == 14) + { + rtfifo[1] = atol(value); + break; + } + free(value); + } + return rtfifo; +} diff --git a/KylinNM/src/kylin-network-interface.h b/KylinNM/src/kylin-network-interface.h new file mode 100644 index 0000000..1b44dab --- /dev/null +++ b/KylinNM/src/kylin-network-interface.h @@ -0,0 +1,267 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef struct +{ + char *if_name; +}ifname; + +typedef struct +{ + char *ssid;//wifi名称 + int signal;//信号强度 + char *safety;//安全性 + +}wifilist;//存放wifi信息的结构体 + +typedef struct +{ + char *con_name;//网络连接名称 + char *type;//网络连接类型 +}conlist;//存放所有网络连接 + +typedef struct +{ + char *con_name;//活动网络连接名称 + char *type;//活动网络连接类型 + char *dev;//活动网络所属设备 +}activecon;//存放当前活动网络连接 + +/* + * Get the network interface name. + * return the struct pointer. + */ +ifname *kylin_network_get_ifacename(); + +/* + * Get the all network connection. + * return the struct pointer. + */ +conlist *kylin_network_get_conlist_info(); + +/* + * Get the active network connection. + * return the struct pointer. + */ +activecon *kylin_network_get_activecon_info(); + +/* + * Create a new Ethernet connection. + * @con_name is the connection name. + * @if_name is the interface name. + */ +void kylin_network_create_new_ethernet(char *con_name,char *if_name); + +/* + * Create a new Wifi connection. + * @con_name is the connection name. + * @if_name is the interface name. + */ +void kylin_network_create_new_wifi(char *con_name, char *if_name); + +/* + * Delete ethernet connection. + * @con_name is the connection name. + */ +void kylin_network_del_ethernet_con(char *con_name); + +/* + * Set up dynamic IP allocation. + * @con_name is the connection name. + */ +void kylin_network_set_automethod(char *con_name); + +/* + * Set up manual IP assignment. + * @con_name is the connection name. + * @ip is the ip address(for example,"192.168.68.160/16") + */ +void kylin_network_set_manualmethod(char *con_name,char *ip); + +/* + * Set up manual all prop. + */ +void kylin_network_set_manualall(char *con_name, char *addr, char *mask, char *gateway, char *dns); + +/* + * Sets whether the connection is automatic. + * @con_name is the connection name. + * @autocon is the automatic connection option. + */ +void kylin_network_set_autoconnect(char *con_name,bool autocon); + +/* + * Modify the ip address. + * @con_name is the connection name. + * @ip is the ip address(for example,"192.168.68.160/16") + */ +void kylin_network_mod_ip(char *con_name,char *ip); + +/* + * Modify the gateway. + * @con_name is the connection name. + * @gw is the gateway address. + */ +void kylin_network_mod_gateway(char *con_name,char *gw); + +/* + * Modify the dns address. + * @con_name is the connection name. + * @dns is the dns address. + */ +void kylin_network_mod_dns(char *con_name,char *dns); + +/* + * Connect the ethernet. + * @con_name is the connection name. + */ +void kylin_network_set_con_up(char *con_name); + +/* + * Disconnect the ethernet. + * @con_name is the connection name. + */ +void kylin_network_set_con_down(char *con_name); + +/* + * Connect the wifi. + * @con_name is the wifi name. + * @passwd is the wifi password. + */ +void kylin_network_set_wifi_up(char *con_name,char *passwd); + +/* + * Disconnect the wifi. + * @if_name is the network interface name. + */ +void kylin_network_set_wifi_down(char *if_name); + +/* + * Get wifi list information. + * Return the struct pointer. + */ +wifilist *kylin_network_get_wifilist_info(); + +/* + * Enable networking. + */ +void kylin_network_enable_networking(); + +/* + * Disable networking. + */ +void kylin_network_disable_networking(); + +/* + * Enable wifi. + */ +void kylin_network_enable_wifi(); + +/* + * Disable wifi. + */ +void kylin_network_disable_wifi(); + +/* Get the ip address. + * @if_name is the interface name. + * @ipaddr is used to save the ip address. + */ +int kylin_network_get_ipaddr(char *if_name,char *ipaddr); + +/* + * Get the broadcast address. + * @if_name is the interface name. + * @brdaddr is used to save the broadcast address. + */ +int kylin_network_get_brdaddr(char *if_name,char *brdaddr); + +/* + * Get the subnet mask. + * @if_name is the interface name. + * @netmask is used to save the subnet mask. + */ +int kylin_network_get_netmask(char *if_name,char *netmask); + +/* + * Get MAC address. + * @if_name is the interface name. + * @macaddr is used to save the MAC address. + */ +int kylin_network_get_mac(char *if_name,char *macaddr); + +/* Get the MTU. + * @if_name is the interface name. + * return the MTU value. + */ +int kylin_network_get_mtu(char *if_name); + +/* + * Total upload and download data volume. + * @if_name is the network interface name. + * return the address of the first element of a one-dimensional long integer array. + */ +long *kylin_network_get_bytes(char *if_name); + +/* + * Total upload and download data packets. + * @if_name is the network interface name. + * return the address of the first element of a one-dimensional long integer array. + */ +long *kylin_network_get_packets(char *if_name); + +/* + * Total wrong data packets number of uploading and downloading. + * @if_name is the network interface name. + * return the address of the first element of a one-dimensional long integer array. + */ +long *kylin_network_get_errs(char *if_name); + +/* + * Total discarded data packets number of uploading and downloading. + * @if_name is the network interface name. + * return the address of the first element of a one-dimensional long integer array. + */ +long *kylin_network_get_drop(char *if_name); + +/* + * Total overloaded data packets number of uploading and downloading. + * @if_name is the network interface name. + * return the address of the first element of a one-dimensional long integer array. + */ +long *kylin_network_get_fifo(char *if_name); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/KylinNM/src/kylinnm.cpp b/KylinNM/src/kylinnm.cpp new file mode 100644 index 0000000..3446f2e --- /dev/null +++ b/KylinNM/src/kylinnm.cpp @@ -0,0 +1,2801 @@ +/* + * 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 +#include +#include +#include + +#include "kylinnm.h" +#include "ui_kylinnm.h" +#include "swipegesturerecognizer.h" + +QString llname, lwname, hideWiFiConn; +int currentActWifiSignalLv, count_loop; + +bool KylinNM::m_is_reflashWifiUi = false; +QMutex mutexIsReflashWifi; + +KylinNM::KylinNM(QWidget *parent) : + QWidget(parent), + ui(new Ui::KylinNM) +{ + ui->setupUi(this); + qDebug() << "99999999999999999999999999--------------9"; + //checkSingle(); + + syslog(LOG_DEBUG, "Using the icon theme named 'ukui-icon-theme-default'"); + //QIcon::setThemeName("ukui-icon-theme-default"); + + // 如果使用Qt::Popup 任务栏不显示且保留X事件如XCB_FOCUS_OUT, 但如果indicator点击鼠标右键触发,XCB_FOCUS_OUT事件依然会失效 + // 如果使用Qt::ToolTip, Qt::Tool + Qt::WindowStaysOnTopHint, Qt::X11BypassWindowManagerHint等flag则会导致X事件失效 + // this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint); + this->setWindowFlags(Qt::FramelessWindowHint);//QTool + this->setAttribute(Qt::WA_TranslucentBackground);//设置窗口背景透明 + + //UseQssFile::setStyle("style.qss"); + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("#centralWidget{border:none;border-radius:16px;}"); + + ui->centralWidget->setStyleSheet("#centralWidget{border:none;border-radius:16px;background:rgba(255,255,255,1);}"); + + editQssString(); //编辑部分控件QSS + createTopLanUI(); //创建顶部有线网item + createTopWifiUI(); //创建顶部无线网item + createOtherUI(); //创建上传下载控件,列表区无item时的说明控件 + createListAreaUI(); //创建列表区域的控件 + createLeftAreaUI(); //创建左侧区域控件 + + lname = "-1"; + wname = "-1"; + llname = "-1"; + lwname = "-1"; + hideWiFiConn = "Connect to Hidden Wi-Fi Network"; + currentActWifiSignalLv = -1; + count_loop = 0; + + createTrayIcon(); + connect(trayIcon, &QSystemTrayIcon::activated, this, &KylinNM::iconActivated); + connect(mShowWindow,SIGNAL(triggered()),this,SLOT(on_showWindowAction())); + connect(mAdvConf,SIGNAL(triggered()),this,SLOT(on_btnAdvConf_clicked())); + trayIcon->show(); + + objKyDBus = new KylinDBus(this); + objKyDBus->initBtnWifiGsetting(); + objKyDBus->initConnectionInfo(); + + objKyDBus->initTaskbarGsetting(); +// objKyDBus->setWifiSignal(-1, ""); + + objNetSpeed = new NetworkSpeed(); + + this->confForm = new ConfForm(this->parentWidget()); + this->confForm->setMainWindow(this); + this->confForm->hide(); + + this->ksnm = new KSimpleNM(); + connect(ksnm, SIGNAL(getLanListFinished(QStringList)), this, SLOT(getLanListDone(QStringList))); + connect(ksnm, SIGNAL(getWifiListFinished(QStringList)), this, SLOT(getWifiListDone(QStringList))); + + loading = new LoadingDiv(this); + connect(loading, SIGNAL(toStopLoading() ), this, SLOT(on_checkOverTime() )); + + checkIsWirelessDeviceOn(); //检测无线网卡是否插入 + getInitLanSlist(); //初始化有线网列表 + initNetwork(); //初始化网络 + initTimer(); //初始化定时器 + + connect(ui->btnNetList, &QPushButton::clicked, this, &KylinNM::onBtnNetListClicked); + connect(btnWireless, &SwitchButton::clicked,this, &KylinNM::onBtnWifiClicked); + + //auto app = static_cast(QCoreApplication::instance()); + //app->setStyle(new CustomStyle()); //设置自定义主题 + + ui->btnNetList->setAttribute(Qt::WA_Hover,true); + ui->btnNetList->installEventFilter(this); + ui->btnWifiList->setAttribute(Qt::WA_Hover,true); + ui->btnWifiList->installEventFilter(this); + + SwipeGestureRecognizer *fftRecognizer = new SwipeGestureRecognizer(this); + Qt::GestureType fftType = QGestureRecognizer::registerRecognizer(fftRecognizer); +// grabGesture(fftType); + connect(fftRecognizer, &SwipeGestureRecognizer::onSwipeGesture, this, &KylinNM::onSwipeGesture); +} + +KylinNM::~KylinNM() +{ + trayIcon->deleteLater(); + trayIconMenu->deleteLater(); + delete ui; +} + +void KylinNM::onSwipeGesture(int dx, int dy) +{ + // qDebug() << "info: [KylinNM] onSwipeGesture dy=" << dy; + if(scrollAreal->isVisible()) { + // qDebug() << "info: [KylinNM] onSwipeGesture before moved " << scrollAreal->verticalScrollBar()->value(); + scrollAreal->verticalScrollBar()->setValue(scrollAreal->verticalScrollBar()->value() - dy/5); + // qDebug() << "info: [KylinNM] onSwipeGesture after moved " << scrollAreal->verticalScrollBar()->value(); + } else if (scrollAreaw->isVisible()) { + // qDebug() << "info: [KylinNM] onSwipeGesture before moved " << scrollAreaw->verticalScrollBar()->value(); + scrollAreaw->verticalScrollBar()->setValue(scrollAreaw->verticalScrollBar()->value() - dy/5); + // qDebug() << "info: [KylinNM] onSwipeGesture after moved " << scrollAreaw->verticalScrollBar()->value(); + } +} + +void KylinNM::checkSingle() +{ + int fd = 0; + try { + QStringList homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation); + QString lockPath = homePath.at(0) + "/.config/kylin-nm-lock"; + fd = open(lockPath.toUtf8().data(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + + if (fd < 0) { + throw -1; + } + } catch(...) { + fd = open("/tmp/kylin-nm-lock", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); + if (fd < 0) { + exit(0); + } + } + + + if (lockf(fd, F_TLOCK, 0)) { + syslog(LOG_ERR, "Can't lock single file, kylin-network-manager is already running!"); + qDebug()<<"Can't lock single file, kylin-network-manager is already running!"; + exit(0); + } +} + +bool KylinNM::nativeEvent(const QByteArray &eventType, void *message, long *result) +{ + Q_UNUSED(result); + if (eventType != "xcb_generic_event_t") { + return false; + } + + xcb_generic_event_t *event = (xcb_generic_event_t*)message; + + switch (event->response_type & ~0x80) { + case XCB_FOCUS_OUT: + //this->hide(); + break; + } + + return false; +} + +bool KylinNM::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == ui->btnNetList) { + if (event->type() == QEvent::HoverEnter) { + if (!is_btnNetList_clicked) { + ui->lbNetListBG->setStyleSheet(btnBgHoverQss); + } + return true; + } else if(event->type() == QEvent::HoverLeave) { + if (!is_btnNetList_clicked) { + ui->lbNetListBG->setStyleSheet(btnBgLeaveQss); + } + return true; + } + } + + if (obj == ui->btnWifiList) { + if (event->type() == QEvent::HoverEnter) { + if (!is_btnWifiList_clicked) { + ui->lbWifiListBG->setStyleSheet(btnBgHoverQss); + } + return true; + } else if(event->type() == QEvent::HoverLeave) { + if (!is_btnWifiList_clicked) { + ui->lbWifiListBG->setStyleSheet(btnBgLeaveQss); + } + return true; + } + } + + return QWidget::eventFilter(obj,event); +} + +/////////////////////////////////////////////////////////////////////////////// + +void KylinNM::tabletStyle()//平板桌面模式特有设置 +{ + this->setFixedWidth(446+194*isTabletStyle); + ui->centralWidget->setFixedWidth(446+194*isTabletStyle); + ui->btnNetList->setFixedWidth(223+97*isTabletStyle); + ui->btnWifiList->setFixedWidth(223+97*isTabletStyle); + ui->btnWifiList->move(223+97*isTabletStyle,0); + ui->lbWifiListBG->move(223+97*isTabletStyle,0); + ui->lbNetListImg->move(16+95*isTabletStyle,17); + ui->lbWifiListImg->move(288+144*isTabletStyle,17); + scrollAreal->resize(W_SCROLL_AREA+194*isTabletStyle, H_SCROLL_AREA); + scrollAreaw->resize(W_SCROLL_AREA+194*isTabletStyle, H_SCROLL_AREA); + lbNetListText->move(98+48*isTabletStyle,2); + lbWifiListText->move(98+48*isTabletStyle,2); + confForm->tabletStyle(isTabletStyle); + btnWireless->move(385+194*isTabletStyle,73); + lbNoItemTip->move(this->width()/2 - lbNoItemTip->width()/2, this->height()/2+30); + if(isTabletStyle) + { + btnOffQss = "QLabel{min-width: 320px; min-height: 56px;max-width:320px; max-height: 56px;border-radius: 16px; background-color:rgba(255,255,255,0);}"; + btnOnQss = "QLabel{min-width: 320px; min-height: 56px;max-width:320px; max-height: 56px;border-radius: 16px; background-color:rgba(61,107,229,1);}"; + } + else + { + btnOffQss = "QLabel{min-width: 221px; min-height: 56px;max-width:221px; max-height: 56px;border-radius: 16px; background-color:rgba(255,255,255,0)}"; + btnOnQss = "QLabel{min-width: 221px; min-height: 56px;max-width:221px; max-height: 56px;border-radius: 16px; background-color:rgba(61,107,229,1);}"; + } + if(scrollAreal->isHidden())//首次运行初始化大按钮状态 + { + ui->btnNetList->setStyleSheet(btnOffQss); + ui->btnWifiList->setStyleSheet(btnOnQss); + ui->lbNetListBG->setStyleSheet(btnOffQss); + ui->lbWifiListBG->setStyleSheet(btnOnQss); + ui->lbNetListImg->setStyleSheet("QLabel{border-image:url(:/res/l/pb-network-offline.png);background-position:center;background-repeat:no-repeat;}"); + ui->lbWifiListImg->setStyleSheet("QLabel{border-image:url(:/res/x/pb-wifi-y.png);background-position:center;background-repeat:no-repeat;}"); + lbNetListText->setStyleSheet("QLabel{color:rgba(38, 38, 38, 0.75);background-color:transparent;}"); + lbWifiListText->setStyleSheet("QLabel{color:rgba(47, 179, 232, 1);background-color:transparent;}"); + } +} + +// 初始化控件、网络、定时器 + +// 初始化界面各控件 +void KylinNM::editQssString() +{ + btnOffQss = "QLabel{min-width: 221px; min-height: 56px;max-width:221px; max-height: 56px;border-radius: 16px; background-color:rgba(38,38,38,0.15)}"; + btnOnQss = "QLabel{min-width: 221px; min-height: 56px;max-width:221px; max-height: 56px;border-radius: 16px; background-color:rgba(255,255,255,0.2)}"; + btnBgOffQss = "QLabel{min-width: 48px; min-height: 22px;max-width:48px; max-height: 22px;border-radius: 16px; background-color:rgba(38,38,38,0.15)}"; + btnBgOnQss = "QLabel{min-width: 48px; min-height: 22px;max-width:48px; max-height: 22px;border-radius: 16px; background-color:rgba(255,255,255,0.2);}"; + btnBgHoverQss = "QLabel{border-radius: 16px; background-color:rgba(38,38,38,0.2)}"; + btnBgLeaveQss = "QLabel{border-radius: 16px; background-color:rgba(38,38,38,0.15)}"; + leftBtnQss = "QPushButton{border:0px;border-radius:4px;background-color:rgba(255,255,255,0);}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(255,255,255,0.12);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(255,255,255,0.12);}"; +// funcBtnQss = "QPushButton{border:0px;border-radius:4px;background-color:rgba(255,255,255,0);color:rgba(107,142,235,0.97);font-size:14px;}" +// "QPushButton:Hover{border:0px;border-radius:4px;background-color:rgba(255,255,255,0);color:rgba(151,175,241,0.97);font-size:14px;}" +// "QPushButton:Pressed{border-radius:4px;background-color:rgba(255,255,255,0);color:rgba(61,107,229,0.97);font-size:14px;}"; + funcBtnQss="QPushButton{border:0px;border-radius:4px;background-color:rgba(255,255,255,0);color:rgba(38,38,38,1);font-size:14px;text-align:left;}"; +} + +void KylinNM::createTopLanUI() +{ + topLanListWidget = new QWidget(ui->centralWidget); + topLanListWidget->move(W_LEFT_AREA, Y_TOP_ITEM); + topLanListWidget->resize(W_TOP_LIST_WIDGET, H_NORMAL_ITEM + H_GAP_UP + X_ITEM); + /*顶部的一个item*/ + lbTopLanList = new QLabel(topLanListWidget); + lbTopLanList->setText(tr("Inactivated LAN"));//"可用网络列表" + lbTopLanList->resize(W_MIDDLE_WORD, H_MIDDLE_WORD); + lbTopLanList->move(X_MIDDLE_WORD, H_NORMAL_ITEM + H_GAP_UP); + lbTopLanList->setStyleSheet("QLabel{font-size:14px;color:rgba(38, 38, 38, 0.45);}"); + lbTopLanList->show(); + /*新建有线网按钮*/ +// btnCreateNet = new QPushButton(ui->centralWidget); +// btnCreateNet->resize(W_BTN_FUN, H_BTN_FUN); +// btnCreateNet->move(X_BTN_FUN, Y_BTN_FUN); +// btnCreateNet->setText(" "+tr("New LAN"));//"新建网络" +// btnCreateNet->setIcon(QIcon(":/res/x/pb-newConn.png")); +// btnCreateNet->setStyleSheet(funcBtnQss); +// btnCreateNet->setFocusPolicy(Qt::NoFocus); +// btnCreateNet->show(); +// connect(btnCreateNet,SIGNAL(clicked()),this,SLOT(onBtnCreateNetClicked())); +} + +void KylinNM::createTopWifiUI() +{ + topWifiListWidget = new QWidget(ui->centralWidget); + topWifiListWidget->move(W_LEFT_AREA, Y_TOP_ITEM); + topWifiListWidget->resize(W_TOP_LIST_WIDGET+194*isTabletStyle, H_NORMAL_ITEM + H_GAP_UP + X_ITEM); + /*顶部的一个item*/ + lbTopWifiList = new QLabel(topWifiListWidget); + lbTopWifiList->setText(tr("Other WLAN"));//"可用网络列表" + lbTopWifiList->resize(W_MIDDLE_WORD, H_MIDDLE_WORD); + lbTopWifiList->move(X_MIDDLE_WORD, H_NORMAL_ITEM + H_GAP_UP); + lbTopWifiList->setStyleSheet("QLabel{font-size:14px;color:rgba(38, 38, 38, 0.45);}"); + lbTopWifiList->show(); + +// /*新建无线网按钮*/ +// if(!btnAddNet){ +// btnAddNet = new QPushButton(ui->centralWidget); +// connect(btnAddNet,SIGNAL(clicked()),this,SLOT(onBtnAddNetClicked())); +// } +// btnAddNet->resize(W_BTN_FUN, H_BTN_FUN); +// btnAddNet->move(X_BTN_FUN, Y_BTN_FUN); +// btnAddNet->setText(" "+tr("Hide WiFi"));//"加入网络" +// btnAddNet->setIcon(QIcon(":/res/x/pb-newConn.png")); +// btnAddNet->setStyleSheet(funcBtnQss); +// btnAddNet->setFocusPolicy(Qt::NoFocus); +} + +void KylinNM::createOtherUI() +{ + lbLoadDown = new QLabel(ui->centralWidget); + lbLoadDown->move(X_ITEM + 129, Y_TOP_ITEM + 32); + lbLoadDown->resize(65, 20); + lbLoadDownImg = new QLabel(ui->centralWidget); + lbLoadDownImg->move(X_ITEM + 112, Y_TOP_ITEM + 35); + lbLoadDownImg->resize(16, 16); + + lbLoadUp = new QLabel(ui->centralWidget); + lbLoadUp->move(X_ITEM + 187, Y_TOP_ITEM + 32); + lbLoadUp->resize(65, 20); + lbLoadUpImg = new QLabel(ui->centralWidget); + lbLoadUpImg->move(X_ITEM + 170, Y_TOP_ITEM + 35); + lbLoadUpImg->resize(16, 16); + +//YYF lbLoadDownImg->setStyleSheet("QLabel{background-image:url(:/res/x/load-down.png);}"); +//YYF lbLoadUpImg->setStyleSheet("QLabel{background-image:url(:/res/x/load-up.png);}"); + + lbNoItemTip = new QLabel(ui->centralWidget); + lbNoItemTip->resize(W_NO_ITEM_TIP, H_NO_ITEM_TIP); + lbNoItemTip->move(this->width()/2 - W_NO_ITEM_TIP/2 + W_LEFT_AREA/2, this->height()/2); + lbNoItemTip->setStyleSheet("QLabel{border:none;background:transparent;font-size:14px;color:rgba(38, 38, 38, 0.45);}"); + lbNoItemTip->setText(tr("No usable network in the list"));//列表暂无可连接网络 + lbNoItemTip->setAlignment(Qt::AlignCenter); + lbNoItemTip->hide(); +} + +void KylinNM::createListAreaUI() +{ + scrollAreal = new QScrollArea(ui->centralWidget); + scrollAreal->move(W_LEFT_AREA, Y_TOP_ITEM + H_NORMAL_ITEM + H_GAP_UP + X_ITEM + H_GAP_DOWN); + scrollAreal->resize(W_SCROLL_AREA, H_SCROLL_AREA); + scrollAreal->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollAreal->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + scrollAreaw = new QScrollArea(ui->centralWidget); + scrollAreaw->move(W_LEFT_AREA, Y_TOP_ITEM + H_NORMAL_ITEM + H_GAP_UP + X_ITEM + H_GAP_DOWN); + scrollAreaw->resize(W_SCROLL_AREA, H_SCROLL_AREA); + scrollAreaw->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollAreaw->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + lanListWidget = new QWidget(scrollAreal); + wifiListWidget = new QWidget(scrollAreaw); + lbLanList = new QLabel(lanListWidget); + lbWifiList = new QLabel(wifiListWidget); + + ui->lbNetwork->setStyleSheet("QLabel{font-size:14px;color:rgba(38, 38, 38, 0.45);}"); + ui->lbNetwork->show(); + + topLanListWidget->setStyleSheet("QWidget{border:none;}"); + topLanListWidget->setStyleSheet("background-color:transparent;"); + + topWifiListWidget->setStyleSheet("QWidget{border:none;}"); + topWifiListWidget->setStyleSheet("background-color:transparent;"); + + lbLoadUp->setStyleSheet("QLabel{font-size:14px;color:rgba(38, 38, 38, 0.45);}"); + lbLoadDown->setStyleSheet("QLabel{font-size:14px;color:rgba(38, 38, 38, 0.45);}"); +//YYF lbLoadUp->setText("0KB/s"); +//YYF lbLoadDown->setText("0KB/s "); +//YYF this->on_setNetSpeed(); + scrollAreal->setStyleSheet("QScrollArea{border:none;}"); + scrollAreal->viewport()->setStyleSheet("background-color:transparent;"); + //scrollAreal->verticalScrollBar()->setStyleSheet(scrollBarQss); + scrollAreal->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + + scrollAreaw->setStyleSheet("QScrollArea{border:none;}"); + scrollAreaw->viewport()->setStyleSheet("background-color:transparent;"); + //scrollAreaw->verticalScrollBar()->setStyleSheet(scrollBarQss); + scrollAreaw->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); +} + +void KylinNM::createLeftAreaUI() +{ + btnWireless = new SwitchButton(this); + // btnWireless->setStyleSheet("SwitchButton{border:none;background-color:rgba(255,255,255,0.12);}"); + ui->btnNetList->setFocusPolicy(Qt::NoFocus); + QString txtEthernet(tr("LAN")); + ui->lbNetListBG->setStyleSheet(btnOffQss); + lbNetListText =new QLabel(ui->lbNetListBG); + lbNetListText->setFocusPolicy(Qt::NoFocus); + lbNetListText->setText(tr("LAN")); + lbNetListText->move(98,2); + lbNetListText->setStyleSheet("QLabel{color:rgba(47, 179, 232, 1);background-color:transparent;}"); + ui->lbNetListImg->setStyleSheet("QLabel{border-image:url(:/res/l/pb-network-online.png);background-position:center;background-repeat:no-repeat;}"); + + ui->btnWifiList->setFocusPolicy(Qt::NoFocus); + QString txtWifi(tr("WLAN")); + ui->lbWifiListBG->setStyleSheet(btnOffQss); + lbWifiListText =new QLabel(ui->lbWifiListBG); + lbWifiListText->setFocusPolicy(Qt::NoFocus); + lbWifiListText->setText(tr("WLAN")); + lbWifiListText->move(98,2); + lbWifiListText->setStyleSheet("QLabel{color:rgba(38, 38, 38, 0.75);background-color:transparent;}"); + ui->lbWifiListImg->setStyleSheet("QLabel{border-image:url(:/res/x/pb-wifi-n.png);background-position:center;background-repeat:no-repeat;}"); + + ui->btnNet->hide(); + + btnWireless->move(385,73); + + ui->btnHotspot->setStyleSheet(leftBtnQss); + ui->btnHotspot->setFocusPolicy(Qt::NoFocus); + QString txtHotSpot(tr("HotSpot")); + ui->btnHotspot->hide(); + ui->lbHotImg->hide(); + ui->lbHotImg->setStyleSheet("QLabel{background-image:url(:/res/x/hot-spot-off.svg);}"); + ui->lbHotBG->hide(); + ui->lbHotBG->setStyleSheet(btnOffQss); + + ui->btnFlyMode->setStyleSheet(leftBtnQss); + ui->btnFlyMode->setFocusPolicy(Qt::NoFocus); + QString txtFlyMode(tr("FlyMode")); + ui->btnFlyMode->hide(); + ui->lbFlyImg->hide(); + ui->lbFlyImg->setStyleSheet("QLabel{background-image:url(:/res/x/fly-mode-off.svg);}"); + ui->lbFlyBG->hide(); + ui->lbFlyBG->setStyleSheet(btnOffQss); + + ui->btnAdvConf->setStyleSheet(leftBtnQss); + ui->btnAdvConf->setFocusPolicy(Qt::NoFocus); + QString txtAdvanced(tr("Advanced")); + //ui->lbBtnConfImg->setStyleSheet("QLabel{background-image:url(:/res/x/setup.png);}"); + ui->btnConfImg->setStyleSheet("QPushButton{background-image:url(:/res/x/setup.png);}"); + //ui->btnConfImg->setIcon(QIcon::fromTheme("settings-app-symbolic.svg", QIcon(":/res/x/setup.png")) ); +} + +// 初始化有线网列表 +void KylinNM::getInitLanSlist() +{ + const int BUF_SIZE = 1024; + char buf[BUF_SIZE]; + + FILE * p_file = NULL; + + p_file = popen("export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli -f type,device,name connection show", "r"); + if (!p_file) { + syslog(LOG_ERR, "Error occurred when popen cmd 'nmcli connection show'"); + qDebug()<<"Error occurred when popen cmd 'nmcli connection show"; + } + while (fgets(buf, BUF_SIZE, p_file) != NULL) { + QString strSlist = ""; + QString line(buf); + strSlist = line.trimmed(); + if (strSlist.indexOf("UUID") != -1 || strSlist.indexOf("NAME") != -1) { + oldLanSlist.append(strSlist); + } + if (strSlist.indexOf("802-3-ethernet") != -1 || strSlist.indexOf("ethernet") != -1) { + oldLanSlist.append(strSlist); + } + } + pclose(p_file); +} + +// 初始化网络 +void KylinNM::initNetwork() +{ + BackThread *bt = new BackThread(); + IFace *iface = bt->execGetIface(); + + wname = iface->wname; + lwname = iface->wname; + lname = iface->lname; + llname = iface->lname; + + mwBandWidth = bt->execChkLanWidth(lname); + + // 开关状态 + qDebug()<<"==="; + qDebug()<<"state of network: '0' is connected, '1' is disconnected, '2' is net device switch off"; + syslog(LOG_DEBUG, "state of network: '0' is connected, '1' is disconnected, '2' is net device switch off"); + qDebug()<<"current network state: lan state ="<lstate<<", wifi state ="<wstate ; + syslog(LOG_DEBUG, "current network state: wired state =%d, wifi state =%d", iface->lstate, iface->wstate); + qDebug()<<"==="; + + //ui->lbBtnNetBG->setStyleSheet(btnOnQss); + if (iface->wstate == 0 || iface->wstate == 1 || iface->wstate == 3) { + // ui->lbBtnWifiBG->setStyleSheet(btnBgOnQss); + //ui->lbBtnWifiBall->move(X_RIGHT_WIFI_BALL, Y_WIFI_BALL); + btnWireless->setSwitchStatus(true); + } else { + btnWireless->setSwitchStatus(false); + //ui->lbBtnWifiBG->setStyleSheet(btnBgOffQss); + //ui->lbBtnWifiBall->move(X_LEFT_WIFI_BALL, Y_WIFI_BALL); + } + + // 初始化网络列表 + if (iface->wstate != 2) { + if (iface->wstate == 0) { + connWifiDone(3); + } else { + if (iface->lstate == 0) { + connLanDone(3); + } + } + on_btnWifiList_clicked(); + + ui->btnNetList->setStyleSheet("QPushButton{border:0px solid rgba(255,255,255,0);background-color:rgba(255,255,255,0);}"); + ui->btnWifiList->setStyleSheet("QPushButton{border:none;}"); + } else { + objKyDBus->setWifiSwitchState(false); //通知控制面板wifi未开启 + if (iface->lstate != 2) { + if (iface->lstate == 0) { + connLanDone(3); + } + onBtnNetListClicked(); + + ui->btnNetList->setStyleSheet("QPushButton{border:0px solid rgba(255,255,255,0);background-color:rgba(255,255,255,0);}"); + ui->btnWifiList->setStyleSheet("QPushButton{border:none;}"); + } else { + /*没看懂这段断开连接是什么意思,暂时关闭这段操作,会导致页面卡顿、某些情景还会自动断开网络 +// BackThread *m_bt = new BackThread(); +// IFace *m_iface = m_bt->execGetIface(); + +// m_bt->disConnLanOrWifi("ethernet"); +// sleep(1); +// m_bt->disConnLanOrWifi("ethernet"); +// sleep(1); +// m_bt->disConnLanOrWifi("ethernet"); + +// delete m_iface; +// m_bt->deleteLater(); + */ + + char *chr = "nmcli networking on"; + Utils::m_system(chr); + } + } + //第一次加载时,加载完lan列表会继续加载WIFI列表,先加载lan后加载WIFI是为了保证在加载WIFI时打开的计时器不会被直接关闭 + onBtnNetListClicked(); + //平板上默认展示wifi界面 +// on_btnWifiList_clicked(); +} + +// 初始化定时器 +void KylinNM::initTimer() +{ + //循环检测wifi列表的变化,可用于更新wifi列表 + checkWifiListChanged = new QTimer(this); + checkWifiListChanged->setTimerType(Qt::PreciseTimer); + QObject::connect(checkWifiListChanged, SIGNAL(timeout()), this, SLOT(on_checkWifiListChanged())); + checkWifiListChanged->start(7000); + + //网线插入时定时执行 + wiredCableUpTimer = new QTimer(this); + wiredCableUpTimer->setTimerType(Qt::PreciseTimer); + QObject::connect(wiredCableUpTimer, SIGNAL(timeout()), this, SLOT(onCarrierUpHandle())); + + //网线拔出时定时执行 + wiredCableDownTimer = new QTimer(this); + wiredCableDownTimer->setTimerType(Qt::PreciseTimer); + QObject::connect(wiredCableDownTimer, SIGNAL(timeout()), this, SLOT(onCarrierDownHandle())); + + //定时处理异常网络,即当点击Lan列表按钮时,若lstate=2,但任然有有线网连接的情况 + deleteLanTimer = new QTimer(this); + deleteLanTimer->setTimerType(Qt::PreciseTimer); + QObject::connect(deleteLanTimer, SIGNAL(timeout()), this, SLOT(onDeleteLan())); + + //定时获取网速 + setNetSpeed = new QTimer(this); + setNetSpeed->setTimerType(Qt::PreciseTimer); +//YYF QObject::connect(setNetSpeed, SIGNAL(timeout()), this, SLOT(on_setNetSpeed())); + setNetSpeed->start(3000); +} + + +/////////////////////////////////////////////////////////////////////////////// +// 任务栏托盘管理、托盘图标处理 + +void KylinNM::createTrayIcon() +{ + trayIcon = new QSystemTrayIcon(); + + trayIconMenu = new QMenu(); + + mShowWindow = new QAction(tr("Show KylinNM"),this); + mAdvConf = new QAction(tr("Advanced"),this); + mAdvConf->setIcon(QIcon::fromTheme("document-page-setup", QIcon(":/res/x/setup.png")) ); + + trayIconMenu->addAction(mShowWindow); + //trayIconMenu->addSeparator(); + trayIconMenu->addAction(mAdvConf); + //trayIconMenu->setAttribute(Qt::WA_TranslucentBackground);//设置窗口背景透明 + //trayIconMenu->setWindowOpacity(0.8); + trayIcon->setContextMenu(trayIconMenu); + + // 初始化托盘所有Icon + iconLanOnline = QIcon::fromTheme("network-wired-symbolic"); + iconLanOffline = QIcon::fromTheme("network-wired-offline-symbolic"); + iconWifiFull = QIcon::fromTheme("network-wireless-signal-excellent-symbolic"); + iconWifiHigh = QIcon::fromTheme("network-wireless-signal-good-symbolic"); + iconWifiMedium = QIcon::fromTheme("network-wireless-signal-ok"); + iconWifiLow = QIcon::fromTheme("network-wireless-signal-low"); + + loadIcons.append(QIcon::fromTheme("kylin-network-1")); + loadIcons.append(QIcon::fromTheme("kylin-network-2")); + loadIcons.append(QIcon::fromTheme("kylin-network-3")); + loadIcons.append(QIcon::fromTheme("kylin-network-4")); + loadIcons.append(QIcon::fromTheme("kylin-network-5")); + loadIcons.append(QIcon::fromTheme("kylin-network-6")); + loadIcons.append(QIcon::fromTheme("kylin-network-7")); + loadIcons.append(QIcon::fromTheme("kylin-network-8")); + loadIcons.append(QIcon::fromTheme("kylin-network-9")); + loadIcons.append(QIcon::fromTheme("kylin-network-10")); + loadIcons.append(QIcon::fromTheme("kylin-network-11")); + loadIcons.append(QIcon::fromTheme("kylin-network-12")); + + iconTimer = new QTimer(this); + connect(iconTimer, SIGNAL(timeout()), this, SLOT(iconStep())); + + setTrayIcon(iconLanOnline); +} + +void KylinNM::iconStep() +{ + if (currentIconIndex < 0) { + currentIconIndex = 11; + } + setTrayIcon(loadIcons.at(currentIconIndex)); + currentIconIndex --; +} + +void KylinNM::setTrayIcon(QIcon icon) +{ + trayIcon->setIcon(icon); +} + +void KylinNM::setTrayLoading(bool isLoading) +{ + if (isLoading) { + currentIconIndex = 11; + iconTimer->start(60); + } else { + iconTimer->stop(); + } +} + +void KylinNM::updateNetList() +{ + QString strTrans; + strTrans = QString::number(1, 10, 2); + //QString sty = "#centralWidget{background:rgba(19,19,20," + strTrans + ");}"; //YYF + QString sty = "#centralWidget{background:rgba(255,255,255," + strTrans + ");}"; + ui->centralWidget->setStyleSheet(sty); + + this->showNormal(); + if (is_btnNetList_clicked == 1) { + onBtnNetListClicked(0); + } + is_stop_check_net_state = 1; + if (is_btnWifiList_clicked == 1) { + BackThread *loop_bt = new BackThread(); + IFace *loop_iface = loop_bt->execGetIface(); + + if (loop_iface->wstate != 2) { + is_update_wifi_list = 1; + this->ksnm->execGetWifiList(); //更新wifi列表 + } + + delete loop_iface; + loop_bt->deleteLater(); + } + is_stop_check_net_state = 0; +} + +void KylinNM::updateWifiList() +{ + //每次展示都要显示无线 + on_btnWifiList_clicked(); +} + +void KylinNM::iconActivated(QSystemTrayIcon::ActivationReason reason) +{ + switch (reason) { + case QSystemTrayIcon::Trigger: + case QSystemTrayIcon::MiddleClick: + + handleIconClicked(); + + if (this->isHidden()) { + QString strTrans; + strTrans = QString::number(1, 10, 2); + //QString sty = "#centralWidget{background:rgba(19,19,20," + strTrans + ");}"; //YYF + QString sty = "#centralWidget{background:rgba(255,255,255," + strTrans + ");}"; + ui->centralWidget->setStyleSheet(sty); + + this->showNormal(); + if (is_btnNetList_clicked == 1) { + onBtnNetListClicked(0); + } + is_stop_check_net_state = 1; + if (is_btnWifiList_clicked == 1) { + BackThread *loop_bt = new BackThread(); + IFace *loop_iface = loop_bt->execGetIface(); + + if (loop_iface->wstate != 2) { + is_update_wifi_list = 1; + this->ksnm->execGetWifiList(); //更新wifi列表 + } + + delete loop_iface; + loop_bt->deleteLater(); + } + is_stop_check_net_state = 0; + } else { + //this->hide(); + } + break; + case QSystemTrayIcon::DoubleClick: + //this->hide(); + break; + case QSystemTrayIcon::Context: + //右键点击托盘图标弹出菜单 + showTrayIconMenu(); + break; + default: + break; + } +} + +void KylinNM::handleIconClicked() +{ + tabletStyle(); + if(isTabletStyle)//平板桌面模式 + { + //在屏幕中央显示 + QRect availableGeometry = qApp->primaryScreen()->availableGeometry(); + this->move((availableGeometry.width() - this->width())/2, (availableGeometry.height() - this->height())/2); + return; + } + + QRect availableGeometry = qApp->primaryScreen()->availableGeometry(); + QRect screenGeometry = qApp->primaryScreen()->geometry(); + + QDesktopWidget* desktopWidget = QApplication::desktop(); + QRect deskMainRect = desktopWidget->availableGeometry(0);//获取可用桌面大小 + QRect screenMainRect = desktopWidget->screenGeometry(0);//获取设备屏幕大小 + QRect deskDupRect = desktopWidget->availableGeometry(1);//获取可用桌面大小 + QRect screenDupRect = desktopWidget->screenGeometry(1);//获取设备屏幕大小 + + int n = objKyDBus->getTaskBarPos("position"); + int m = objKyDBus->getTaskBarHeight("height"); + int d = 2; //窗口边沿到任务栏距离 + + if (screenGeometry.width() == availableGeometry.width() && screenGeometry.height() == availableGeometry.height()) { + if (n == 0) { + //任务栏在下侧 + this->move(availableGeometry.x() + availableGeometry.width() - this->width(), screenMainRect.y() + availableGeometry.height() - this->height() - m - d); + } else if(n == 1) { + //任务栏在上侧 + this->move(availableGeometry.x() + availableGeometry.width() - this->width(), screenMainRect.y() + screenGeometry.height() - availableGeometry.height() + m + d); + } else if (n == 2) { + //任务栏在左侧 + if (screenGeometry.x() == 0) {//主屏在左侧 + this->move(m + d, screenMainRect.y() + screenMainRect.height() - this->height()); + } else {//主屏在右侧 + this->move(screenMainRect.x() + m + d, screenMainRect.y() + screenMainRect.height() - this->height()); + } + } else if (n == 3) { + //任务栏在右侧 + if (screenGeometry.x() == 0) {//主屏在左侧 + this->move(screenMainRect.width() - this->width() - m - d, screenMainRect.y() + screenMainRect.height() - this->height()); + } else {//主屏在右侧 + this->move(screenMainRect.x() + screenMainRect.width() - this->width() - m - d, screenMainRect.y() + screenMainRect.height() - this->height()); + } + } + } else if(screenGeometry.width() == availableGeometry.width() ) { + if (trayIcon->geometry().y() > availableGeometry.height()/2) { + //任务栏在下侧 + this->move(availableGeometry.x() + availableGeometry.width() - this->width(), screenMainRect.y() + availableGeometry.height() - this->height() - d); + } else { + //任务栏在上侧 + this->move(availableGeometry.x() + availableGeometry.width() - this->width(), screenMainRect.y() + screenGeometry.height() - availableGeometry.height() + d); + } + } else if (screenGeometry.height() == availableGeometry.height()) { + if (trayIcon->geometry().x() > availableGeometry.width()/2) { + //任务栏在右侧 + this->move(availableGeometry.x() + availableGeometry.width() - this->width() - d, screenMainRect.y() + screenGeometry.height() - this->height()); + } else { + //任务栏在左侧 + this->move(screenGeometry.width() - availableGeometry.width() + d, screenMainRect.y() + screenGeometry.height() - this->height()); + } + } +} + +void KylinNM::showTrayIconMenu() +{ + QRect availableGeometry = qApp->primaryScreen()->availableGeometry(); + QRect screenGeometry = qApp->primaryScreen()->geometry(); + + QDesktopWidget* desktopWidget = QApplication::desktop(); + // QRect deskMainRect = desktopWidget->availableGeometry(0);//获取可用桌面大小 + QRect screenMainRect = desktopWidget->screenGeometry(0);//获取设备屏幕大小 + // QRect deskDupRect = desktopWidget->availableGeometry(1);//获取可用桌面大小 + QRect screenDupRect = desktopWidget->screenGeometry(1);//获取设备屏幕大小 + + QPoint cursorPoint = QCursor::pos();//返回相对显示器的全局坐标 + int cursor_x = cursorPoint.x(); + int cursor_y = cursorPoint.y(); + + int n = objKyDBus->getTaskBarPos("position"); + int m = objKyDBus->getTaskBarHeight("height"); + int d = 0; //窗口边沿到任务栏距离 + int s = 80; //窗口边沿到屏幕边沿距离 + + if (screenGeometry.width() == availableGeometry.width() && screenGeometry.height() == availableGeometry.height()) { + if (n == 0) { //任务栏在下侧 + trayIconMenu->move(availableGeometry.x() + cursor_x - trayIconMenu->width()/2, screenMainRect.y() + availableGeometry.height() - trayIconMenu->height() - m - d); + } else if(n == 1) { //任务栏在上侧 + trayIconMenu->move(availableGeometry.x() + cursor_x - trayIconMenu->width()/2, screenMainRect.y() + screenGeometry.height() - availableGeometry.height() + m + d); + } else if (n == 2) { //任务栏在左侧 + trayIconMenu->move(m + d, cursor_y - trayIconMenu->height()/2); + //if (screenGeometry.x() == 0){//主屏在左侧 + // trayIconMenu->move(screenGeometry.width() - availableGeometry.width() + m + d, screenMainRect.y() + screenMainRect.height() - trayIconMenu->height() - s); + //}else{//主屏在右侧 + // trayIconMenu->move(screenGeometry.width() - availableGeometry.width() + m + d,screenDupRect.y() + screenDupRect.height() - trayIconMenu->height() - s); + //} + } else if (n == 3) { //任务栏在右侧 + trayIconMenu->move(screenMainRect.width() - trayIconMenu->width() - m - d, cursor_y - trayIconMenu->height()/2); + //if (screenGeometry.x() == 0){//主屏在左侧 + // trayIconMenu->move(screenMainRect.width() + screenDupRect.width() - trayIconMenu->width() - m - d, screenDupRect.y() + screenDupRect.height() - trayIconMenu->height() - s); + //}else{//主屏在右侧 + // trayIconMenu->move(availableGeometry.x() + availableGeometry.width() - trayIconMenu->width() - m - d, screenMainRect.y() + screenMainRect.height() - trayIconMenu->height() - s); + //} + } + } else if(screenGeometry.width() == availableGeometry.width() ) { + if (trayIcon->geometry().y() > availableGeometry.height()/2) { //任务栏在下侧 + trayIconMenu->move(availableGeometry.x() + cursor_x - trayIconMenu->width()/2, screenMainRect.y() + availableGeometry.height() - trayIconMenu->height() - d); + } else { //任务栏在上侧 + trayIconMenu->move(availableGeometry.x() + cursor_x - trayIconMenu->width()/2, screenMainRect.y() + screenGeometry.height() - availableGeometry.height() + d); + } + } else if (screenGeometry.height() == availableGeometry.height()) { + if (trayIcon->geometry().x() > availableGeometry.width()/2) { //任务栏在右侧 + trayIconMenu->move(availableGeometry.x() + availableGeometry.width() - trayIconMenu->width() - d, cursor_y - trayIconMenu->height()/2); + } else { //任务栏在左侧 + trayIconMenu->move(screenGeometry.width() - availableGeometry.width() + d, cursor_y - trayIconMenu->height()/2); + } + } +} + +void KylinNM::on_showWindowAction() +{ + handleIconClicked(); + this->showNormal(); +} + + +/////////////////////////////////////////////////////////////////////////////// +//加载动画,获取当前连接的网络和状态并设置图标 + +void KylinNM::startLoading() +{ +// loading->startLoading(); + setTrayLoading(true); +} + +void KylinNM::stopLoading() +{ + loading->stopLoading(); + setTrayLoading(false); + getActiveInfo(); +} + +void KylinNM::on_checkOverTime() +{ + QString cmd = "kill -9 $(pidof nmcli)"; //杀掉当前正在进行的有关nmcli命令的进程 + int status = system(cmd.toUtf8().data()); + if (status != 0) { + qDebug()<<"execute 'kill -9 $(pidof nmcli)' in function 'on_checkOverTime' failed"; + syslog(LOG_ERR, "execute 'kill -9 $(pidof nmcli)' in function 'on_checkOverTime' failed"); + } + this->stopLoading(); //超时停止等待动画 + is_stop_check_net_state = 0; +} + +void KylinNM::getActiveInfo() +{ + QString actLanName = "--"; + QString actWifiName = "--"; + + activecon *act = kylin_network_get_activecon_info(); + int index = 0; + while (act[index].con_name != NULL) { + if (QString(act[index].type) == "ethernet" || QString(act[index].type) == "802-3-ethernet") { + actLanName = QString(act[index].con_name); + } + if (QString(act[index].type) == "wifi" || QString(act[index].type) == "802-11-wireless") { + actWifiName = QString(act[index].con_name); + } + index ++; + } + + + //ukui3.0中获取currentActWifiSignalLv的值 + if (activeWifiSignalLv > 75) { + currentActWifiSignalLv = 1; + } else if(activeWifiSignalLv > 55 && activeWifiSignalLv <= 75) { + currentActWifiSignalLv = 2; + } else if(activeWifiSignalLv > 35 && activeWifiSignalLv <= 55) { + currentActWifiSignalLv = 3; + } else if( activeWifiSignalLv <= 35) { + currentActWifiSignalLv = 4; + } + + // 设置图标 + if (actLanName != "--") { + setTrayIcon(iconLanOnline); + } else if (actWifiName != "--") { + switch (currentActWifiSignalLv) { + case 1: + setTrayIcon(iconWifiFull); + break; + case 2: + setTrayIcon(iconWifiHigh); + break; + case 3: + setTrayIcon(iconWifiMedium); + break; + case 4: + setTrayIcon(iconWifiLow); + break; + default: + setTrayIcon(iconWifiFull); + break; + } + } else { + setTrayIcon(iconLanOffline); + } +} + + +/////////////////////////////////////////////////////////////////////////////// +//网络设备管理 + +//网线插拔处理,由kylin-dbus-interface.cpp调用 +void KylinNM::onPhysicalCarrierChanged(bool flag) +{ + this->startLoading(); + if (flag) { + is_stop_check_net_state = 1; + qDebug()<<"插入了有线网的网线"; + syslog(LOG_DEBUG,"wired physical cable is already plug in"); + wiredCableUpTimer->start(2000); + } else { + qDebug()<<"拔出了有线网的网线"; + syslog(LOG_DEBUG,"wired physical cable is already plug out"); + + BackThread *bt = new BackThread(); + IFace *iface = bt->execGetIface(); + if (iface->lstate != 0) { + is_stop_check_net_state = 1; + wiredCableDownTimer->start(2000); + } + delete iface; + bt->deleteLater(); + } +} + +void KylinNM::onCarrierUpHandle() +{ + wiredCableUpTimer->stop(); + //BackThread *up_bt = new BackThread(); + //up_bt->disConnLanOrWifi("ethernet"); + //sleep(1); + //up_bt->disConnLanOrWifi("ethernet"); + //sleep(1); + //up_bt->disConnLanOrWifi("ethernet"); + //up_bt->deleteLater(); + + this->stopLoading(); + onBtnNetListClicked(1); + is_stop_check_net_state = 0; +} + +void KylinNM::onCarrierDownHandle() +{ + wiredCableDownTimer->stop(); + this->stopLoading(); + onBtnNetListClicked(0); + is_stop_check_net_state = 0; +} + +void KylinNM::onDeleteLan() +{ + deleteLanTimer->stop(); + BackThread *btn_bt = new BackThread(); + btn_bt->disConnLanOrWifi("ethernet"); + sleep(1); + btn_bt->disConnLanOrWifi("ethernet"); + sleep(1); + btn_bt->disConnLanOrWifi("ethernet"); + btn_bt->deleteLater(); + + this->stopLoading(); + onBtnNetListClicked(0); + is_stop_check_net_state = 0; +} + +//无线网卡插拔处理 +void KylinNM::onNetworkDeviceAdded(QDBusObjectPath objPath) +{ + //仅处理无线网卡插入情况 + objKyDBus->isWirelessCardOn = false; + objKyDBus->getObjectPath(); + + if (objKyDBus->wirelessPath.path() == objPath.path()) { //证明添加的是无线网卡 + is_wireless_adapter_ready = 0; + if (objKyDBus->isWirelessCardOn) { + syslog(LOG_DEBUG,"wireless device is already plug in"); + qDebug()<<"wireless device is already plug in"; + is_wireless_adapter_ready = 1; + onBtnWifiClicked(4); + } + } +} + +void KylinNM::onNetworkDeviceRemoved(QDBusObjectPath objPath) +{ + //仅处理无线网卡拔出情况 + if (objKyDBus->wirelessPath.path() == objPath.path()) { + objKyDBus->isWirelessCardOn = false; + objKyDBus->getObjectPath(); //检查是不是还有无线网卡 + if (!objKyDBus->isWirelessCardOn) { + syslog(LOG_DEBUG,"wireless device is already plug out"); + qDebug()<<"wireless device is already plug out"; + is_wireless_adapter_ready = 0; + onBtnWifiClicked(5); + } else { + syslog(LOG_DEBUG,"wireless device is already plug out, but one more wireless exist"); + qDebug()<<"wireless device is already plug out, but one more wireless exist"; + } + } +} + +void KylinNM::checkIsWirelessDeviceOn() +{ + //启动时判断是否有无线网卡 + //KylinDBus kDBus3; + if (objKyDBus->isWirelessCardOn) { + is_wireless_adapter_ready = 1; + } else { + is_wireless_adapter_ready = 0; + } +} + +void KylinNM::getLanBandWidth() +{ + BackThread *bt = new BackThread(); + IFace *iface = bt->execGetIface(); + + lname = iface->lname; + + mwBandWidth = bt->execChkLanWidth(lname); +} + +//检测网络设备状态 +bool KylinNM::checkLanOn() +{ + BackThread *bt = new BackThread(); + IFace *iface = bt->execGetIface(); + + if (iface->lstate == 2) { + return false; + } else { + return true; + } + + delete iface; + bt->deleteLater(); +} + +bool KylinNM::checkWlOn() +{ + BackThread *bt = new BackThread(); + IFace *iface = bt->execGetIface(); + + bool ret = true; + if (iface->wstate == 2) { + ret = false; + } + + delete iface; + bt->deleteLater(); + return ret; +} + + +/////////////////////////////////////////////////////////////////////////////// +//有线网与无线网按钮响应 + +void KylinNM::on_btnNet_clicked() +{ + if (checkLanOn()) { + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + bt->moveToThread(t); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), bt, SLOT(execDisNet())); + connect(bt, SIGNAL(disNetDone()), this, SLOT(disNetDone())); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + t->start(); + + } else { + is_stop_check_net_state = 1; + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + bt->moveToThread(t); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), bt, SLOT(execEnNet())); + connect(bt, SIGNAL(enNetDone()), this, SLOT(enNetDone())); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + t->start(); + } + + this->startLoading(); +} + +void KylinNM::onBtnWifiClicked(int flag) +{ + qDebug()<<"Value of flag passed into function 'onBtnWifiClicked' is: "<setWifiSwitchState(false); + lbTopWifiList->hide(); +// btnAddNet->hide(); + + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + bt->moveToThread(t); + btnWireless->setSwitchStatus(true); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), bt, SLOT(execDisWifi())); + connect(bt, SIGNAL(disWifiDone()), this, SLOT(disWifiDone())); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + + /**锁屏多线程信号槽消息传递异常,暂时以定时器方式检测,需调整pam验证的fork方式 + */ + QTimer *timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, [=]{ + if(m_is_reflashWifiUi) { + disWifiDone(); + mutexIsReflashWifi.lock(); + m_is_reflashWifiUi = false; + mutexIsReflashWifi.unlock(); + timer->stop(); + } + }); + timer->start(200); + QTimer::singleShot(8*1000, this, [=]{ + if(timer->isActive()) + timer->stop(); + }); + /**锁屏多线程信号槽消息传递异常,暂时以定时器方式检测,需调整pam验证的fork方式 + */ + t->start(); + this->startLoading(); + } + } else { + if (is_fly_mode_on == 0) { + //on_btnWifiList_clicked(); + is_stop_check_net_state = 1; + qDebug() << "aaa222"; + objKyDBus->setWifiCardState(true); + objKyDBus->setWifiSwitchState(true); + //lbTopWifiList->show(); + //btnAddNet->show(); + + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + bt->moveToThread(t); + btnWireless->setSwitchStatus(true); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), bt, SLOT(execEnWifi())); + connect(bt, SIGNAL(enWifiDone()), this, SLOT(enWifiDone())); + connect(bt, SIGNAL(launchLanDone()), this, SLOT(launchLanDone())); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + + /**锁屏多线程信号槽消息传递异常,暂时以定时器方式检测,需调整pam验证的fork方式 + */ + QTimer *timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, [=]{ + if(m_is_reflashWifiUi) { + enWifiDone(); + mutexIsReflashWifi.lock(); + m_is_reflashWifiUi = false; + mutexIsReflashWifi.unlock(); + timer->stop(); + } + }); + timer->start(200); + QTimer::singleShot(8*1000, this, [=]{ + if(timer->isActive()) + timer->stop(); + }); + t->start(); + this->startLoading(); + } + } + } else if(flag == 2) { + if (is_fly_mode_on == 0) { + //on_btnWifiList_clicked(); + is_stop_check_net_state = 1; + lbTopWifiList->show(); +// btnAddNet->show(); + + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + btnWireless->setSwitchStatus(true); + bt->moveToThread(t); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), bt, SLOT(execEnWifi())); + connect(bt, SIGNAL(enWifiDone()), this, SLOT(enWifiDone())); + connect(bt, SIGNAL(launchLanDone()), this, SLOT(launchLanDone())); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + t->start(); + this->startLoading(); + } + } else if(flag == 3) { + is_stop_check_net_state = 1; + lbTopWifiList->hide(); +// btnAddNet->hide(); + + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + btnWireless->setSwitchStatus(true); + bt->moveToThread(t); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), bt, SLOT(execDisWifi())); + connect(bt, SIGNAL(disWifiDone()), this, SLOT(disWifiDone())); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + t->start(); + this->startLoading(); + } else { + qDebug()<<"receive an invalid value in function onBtnWifiClicked"; + syslog(LOG_DEBUG, "receive an invalid value in function onBtnWifiClicked"); + } + + } else { + lbTopWifiList->hide(); +// btnAddNet->hide(); + + if (flag == 0) { + objKyDBus->setWifiSwitchState(false); + objKyDBus->setWifiCardState(false); + } + + QString txt(tr("No wireless card detected")); //未检测到无线网卡 + objKyDBus->showDesktopNotify(txt); + qDebug()<<"No wireless card detected"; + syslog(LOG_DEBUG, "No wireless card detected"); + //QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';notify-send '" + txt + "' -t 3800"; + //int status = system(cmd.toUtf8().data()); + //if (status != 0){ syslog(LOG_ERR, "execute 'notify-send' in function 'onBtnWifiClicked' failed");} + + disWifiStateKeep(); + } + +} + +void KylinNM::onBtnNetListClicked(int flag) +{ + this->is_btnNetList_clicked = 1; + this->is_btnWifiList_clicked = 0; + + ui->lbNetListBG->setStyleSheet(btnOnQss); + ui->lbWifiListBG->setStyleSheet(btnOffQss); + + BackThread *bt = new BackThread(); + IFace *iface = bt->execGetIface(); + + lbLoadDown->show(); + lbLoadUp->show(); + lbLoadDownImg->show(); + lbLoadUpImg->show(); + if (iface->lstate != 0) { + lbLoadDown->hide(); + lbLoadUp->hide(); + lbLoadDownImg->hide(); + lbLoadUpImg->hide(); + } + + lbNoItemTip->hide(); + + ui->lbNetwork->setText(tr("Activated LAN")); + btnWireless->hide(); + //ui->lbBtnWifiBG->hide(); + //ui->lbBtnWifiBall->hide(); + + // 强行设置为打开 + if (flag == 1) { + this->startLoading(); + this->ksnm->execGetLanList(); + this->scrollAreal->show(); + this->topLanListWidget->show(); + this->scrollAreaw->hide(); + this->topWifiListWidget->hide(); + on_btnNetList_pressed(); + return; + } + + if (iface->lstate != 2) { + this->startLoading(); + this->ksnm->execGetLanList(); + } else { + this->startLoading(); + this->ksnm->execGetLanList(); + } + +// btnCreateNet->show(); +// btnAddNet->hide(); + this->scrollAreal->show(); + this->topLanListWidget->show(); + this->scrollAreaw->hide(); + this->topWifiListWidget->hide(); + on_btnNetList_pressed(); + //YYF + ui->lbNetListImg->setStyleSheet("QLabel{border-image:url(:/res/l/pb-network-online.png);background-position:center;background-repeat:no-repeat;}"); + ui->lbWifiListImg->setStyleSheet("QLabel{border-image:url(:/res/x/pb-wifi-n.png);background-position:center;background-repeat:no-repeat;}"); + lbNetListText->setStyleSheet("QLabel{color:rgba(47, 179, 232, 1);background-color:transparent;}"); + lbWifiListText->setStyleSheet("QLabel{color:rgba(38, 38, 38, 0.75);background-color:transparent;}"); + + + delete iface; + bt->deleteLater(); +} + +// 当点击wifi标题的时候执行 +void KylinNM::on_btnWifiList_clicked() +{ + this->is_btnWifiList_clicked = 1; + this->is_btnNetList_clicked = 0; + + BackThread *bt = new BackThread(); + IFace *iface = bt->execGetIface(); + + lbLoadDown->show(); + lbLoadUp->show(); + lbLoadDownImg->show(); + lbLoadUpImg->show(); + if (iface->wstate != 0) { + lbLoadDown->hide(); + lbLoadUp->hide(); + lbLoadDownImg->hide(); + lbLoadUpImg->hide(); + } + + ui->lbNetListBG->setStyleSheet(btnOffQss); + ui->lbWifiListBG->setStyleSheet(btnOnQss); + + lbNoItemTip->hide(); + ui->lbNetwork->setText(tr("Activated WLAN")); + btnWireless->show(); + //ui->lbBtnWifiBG->show(); + //ui->lbBtnWifiBall->show(); + if (iface->wstate == 0 || iface->wstate == 1 || iface->wstate == 3) { + //ui->lbBtnWifiBG->setStyleSheet(btnBgOnQss); + //ui->lbBtnWifiBall->move(X_RIGHT_WIFI_BALL, Y_WIFI_BALL); + btnWireless->setSwitchStatus(true); + } else { + //ui->lbBtnWifiBG->setStyleSheet(btnBgOffQss); + //ui->lbBtnWifiBall->move(X_LEFT_WIFI_BALL, Y_WIFI_BALL); + btnWireless->setSwitchStatus(false); + } + + if (iface->wstate != 2) { + //ui->lbBtnWifiBG->setStyleSheet(btnBgOnQss); + //ui->lbBtnWifiBall->move(X_RIGHT_WIFI_BALL, Y_WIFI_BALL); + btnWireless->setSwitchStatus(true); + lbTopWifiList->show(); +// btnAddNet->show(); + + this->startLoading(); + this->ksnm->execGetWifiList(); + } else { + //ui->lbBtnWifiBG->setStyleSheet(btnBgOffQss); + //ui->lbBtnWifiBall->move(X_LEFT_WIFI_BALL, Y_WIFI_BALL); + btnWireless->setSwitchStatus(false); + delete topWifiListWidget; //清空top列表 + createTopWifiUI(); //创建顶部无线网item + lbTopWifiList->hide(); + ui->lbNetListImg->setStyleSheet("QLabel{border-image:url(:/res/l/pb-network-offline.png);background-position:center;background-repeat:no-repeat;}"); + ui->lbWifiListImg->setStyleSheet("QLabel{border-image:url(:/res/x/pb-wifi-y.png);background-position:center;background-repeat:no-repeat;}"); + lbNetListText->setStyleSheet("QLabel{color:rgba(38, 38, 38, 0.75);background-color:transparent;}"); + lbWifiListText->setStyleSheet("QLabel{color:rgba(47, 179, 232, 1);background-color:transparent;}"); + + // 清空wifi列表 + wifiListWidget = new QWidget(scrollAreaw); + wifiListWidget->resize(W_LIST_WIDGET+173*isTabletStyle, H_WIFI_ITEM_BIG_EXTEND); + scrollAreaw->setWidget(wifiListWidget); + scrollAreaw->move(W_LEFT_AREA, Y_SCROLL_AREA); + + + // 当前连接的wifi + OneConnForm *ccf = new OneConnForm(topWifiListWidget, this, confForm, ksnm); + ccf->setName(tr("Not connected"));//"当前未连接任何 Wifi" + ccf->setSignal("0", "--"); + ccf->setRate("0"); + ccf->setConnedString(1, tr("Disconnected"), "");//"未连接" + ccf->isConnected = false; + ccf->setTopItem(false); + ccf->setAct(true); + ccf->move(L_VERTICAL_LINE_TO_ITEM, 0); + ccf->show(); + + this->lanListWidget->hide(); + this->wifiListWidget->show(); + + getActiveInfo(); + is_stop_check_net_state = 0; + } + +// btnCreateNet->hide(); +// if(is_wireless_adapter_ready == 1) +// { +// btnAddNet->show(); +// } + + this->scrollAreal->hide(); + this->topLanListWidget->hide(); + this->scrollAreaw->show(); + this->topWifiListWidget->show(); + on_btnWifiList_pressed(); + + delete iface; + bt->deleteLater(); +} + +void KylinNM::on_btnNetList_pressed() +{ + //ui->btnNetList->setStyleSheet("#btnNetList{font-size:12px;color:white;border:1px solid rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.5);background:transparent;background-color:rgba(255,255,255,0.1);}"); + //ui->btnWifiList->setStyleSheet("#btnWifiList{font-size:12px;color:white;border:1px solid rgba(255,255,255,0.1);background:transparent;background-color:rgba(0,0,0,0.2);}" + // "#btnWifiList:Pressed{border:1px solid rgba(255,255,255,0.5);background:transparent;background-color:rgba(255,255,255,0.1);}"); +} + +void KylinNM::on_btnWifiList_pressed() +{ + //YYF 复制自tabletStyle方法,后期考虑合并 + ui->btnNetList->setStyleSheet(btnOffQss); + ui->btnWifiList->setStyleSheet(btnOnQss); + ui->lbNetListBG->setStyleSheet(btnOffQss); + ui->lbWifiListBG->setStyleSheet(btnOnQss); + ui->lbNetListImg->setStyleSheet("QLabel{border-image:url(:/res/l/pb-network-offline.png);background-position:center;background-repeat:no-repeat;}"); + ui->lbWifiListImg->setStyleSheet("QLabel{border-image:url(:/res/x/pb-wifi-y.png);background-position:center;background-repeat:no-repeat;}"); + lbNetListText->setStyleSheet("QLabel{color:rgba(38, 38, 38, 0.75);background-color:transparent;}"); + lbWifiListText->setStyleSheet("QLabel{color:rgba(47, 179, 232, 1);background-color:transparent;}"); + + //ui->btnWifiList->setStyleSheet("#btnWifiList{font-size:12px;color:white;border:1px solid rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.5);background:transparent;background-color:rgba(255,255,255,0.1);}"); + //ui->btnNetList->setStyleSheet("#btnNetList{font-size:12px;color:white;border:1px solid rgba(255,255,255,0.1);background:transparent;background-color:rgba(0,0,0,0.2);}" + // "#btnNetList:Pressed{border:1px solid rgba(255,255,255,0.5);background:transparent;background-color:rgba(255,255,255,0.1);}"); +} + + +/////////////////////////////////////////////////////////////////////////////// +//网络列表加载与更新 + +// 获取lan列表回调 +void KylinNM::getLanListDone(QStringList slist) +{ + if (this->ksnm->isUseOldLanSlist) { + slist = oldLanSlist; + this->ksnm->isUseOldLanSlist = false; + } + + delete topLanListWidget; // 清空top列表 + + createTopLanUI(); //创建顶部有线网item + + // 清空lan列表 + lanListWidget = new QWidget(scrollAreal); + lanListWidget->resize(W_LIST_WIDGET, H_NORMAL_ITEM + H_LAN_ITEM_EXTEND); + scrollAreal->setWidget(lanListWidget); + scrollAreal->move(W_LEFT_AREA, Y_SCROLL_AREA); + lanNameList.clear(); + + // 获取当前连接的lan name + QString actLanName = "--"; + activecon *act = kylin_network_get_activecon_info(); + + int index = 0; + while (act[index].con_name != NULL) { + if (QString(act[index].type) == "ethernet" || QString(act[index].type) == "802-3-ethernet") { + actLanName = QString(act[index].con_name); + break; + } + index ++; + } + + // 若当前lan name为"--",设置OneConnForm + OneLancForm *ccf = new OneLancForm(topLanListWidget, this, confForm, ksnm); + topLanListWidget->resize(W_TOP_LIST_WIDGET+173*isTabletStyle, H_NORMAL_ITEM + H_GAP_UP + X_ITEM); + ccf->setFixedWidth(414+194*isTabletStyle); + if (actLanName == "--") { + ccf->setName(tr("Not connected"), "");//"当前未连接任何 以太网" + ccf->setIcon(false); + ccf->setConnedString(1, tr("Disconnected"));//"未连接" + ccf->isConnected = false; + ifLanConnected = false; + lbLoadDown->hide(); + lbLoadUp->hide(); + lbLoadDownImg->hide(); + lbLoadUpImg->hide(); + ccf->setTopItem(false); + ccf->setAct(false); + } + else + ccf->setAct(true); + ccf->move(L_VERTICAL_LINE_TO_ITEM, 0); + ccf->show(); + // 填充可用网络列表 + QString headLine; + if(slist.count() > 0) + headLine = slist.at(0); + else + headLine = ""; + int indexDevice, indexName; + headLine = headLine.trimmed(); + + bool isChineseExist = headLine.contains(QRegExp("[\\x4e00-\\x9fa5]+")); + if (isChineseExist) { + indexDevice = headLine.indexOf("设备") + 2; + indexName = headLine.indexOf("名称") + 4; + } else { + indexDevice = headLine.indexOf("DEVICE"); + indexName = headLine.indexOf("NAME"); + } + + QString order = "a"; //为避免同名情况,这里给每一个有线网设定一个唯一标志 + for(int i = 1, j = 0; i < slist.size(); i ++) { + QString line = slist.at(i); + QString ltype = line.mid(0, indexDevice).trimmed(); + QString nname = line.mid(indexName).trimmed(); + + if (ltype != "802-11-wireless" && ltype != "wifi" && ltype != "" && ltype != "--") { + lanNameList.append(nname); + // 当前连接的lan + if (nname == actLanName) { + //objKyDBus->getConnectNetIp(); + actLanName = "--"; + if (mwBandWidth == "Unknown!") { getLanBandWidth(); } + + connect(ccf, SIGNAL(selectedOneLanForm(QString, QString)), this, SLOT(oneTopLanFormSelected(QString, QString))); + connect(ccf, SIGNAL(disconnActiveLan()), this, SLOT(activeLanDisconn())); + ccf->setName(nname, nname + order); + ccf->setIcon(true); + ccf->setLanInfo(objKyDBus->dbusActiveLanIpv4, objKyDBus->dbusActiveLanIpv6, mwBandWidth, objKyDBus->dbusLanMac); + ccf->setConnedString(1, tr("NetOn,"));//"已连接" + ccf->isConnected = true; + ifLanConnected = true; + lbLoadDown->show(); + lbLoadUp->show(); + lbLoadDownImg->show(); + lbLoadUpImg->show(); + ccf->setTopItem(false); + currSelNetName = ""; + objKyDBus->dbusActiveLanIpv4 = ""; + objKyDBus->dbusActiveLanIpv6 = ""; + syslog(LOG_DEBUG, "already insert an active lannet in the top of lan list"); + } else { + objKyDBus->getLanIp(nname); + OneLancForm *ocf = new OneLancForm(lanListWidget, this, confForm, ksnm); +// connect(ocf, SIGNAL(selectedOneLanForm(QString, QString)), this, SLOT(oneLanFormSelected(QString, QString))); + ocf->setName(nname, nname + order); + ocf->setIcon(false); //YYF + ocf->setLine(true); + ocf->setLanInfo(objKyDBus->dbusLanIpv4, objKyDBus->dbusLanIpv6, tr("Disconnected"), objKyDBus->dbusLanMac); + ocf->setConnedString(0, tr("Disconnected"));//"未连接" + ocf->move(L_VERTICAL_LINE_TO_ITEM, j * H_NORMAL_ITEM); + lanListWidget->resize(W_LIST_WIDGET+194*isTabletStyle, lanListWidget->height() + H_NORMAL_ITEM); + ocf->setFixedWidth(W_LIST_WIDGET+194*isTabletStyle); //YYF + ocf->setSelected(false, false); + ocf->show(); + j ++; + } + order += "a"; + } + } + + QList itemList = lanListWidget->findChildren(); + int n = itemList.size(); + if (n >= 1) { + OneLancForm *lastItem = itemList.at(n-1); + lastItem->setLine(false); + lbNoItemTip->hide(); + } else { + if (!ifLanConnected) { + lbNoItemTip->hide(); +// lbTopLanList->hide(); +// btnCreateNet->hide(); + } else { + lbNoItemTip->show(); + lbNoItemTip->setText(tr("No Other Wired Network Scheme")); + } + } + + this->lanListWidget->show(); + this->topLanListWidget->show(); + this->wifiListWidget->hide(); + this->topWifiListWidget->hide(); + + this->stopLoading(); + oldLanSlist = slist; + is_stop_check_net_state = 0; +} + +// 获取wifi列表回调 +void KylinNM::getWifiListDone(QStringList slist) +{ + qDebug()<<"debug: oldWifiSlist.size()="< 1) { + actWifiuuid = currConnWifiBSsidUuid.at(0); + for (int i=1; isetName(tr("Not connected"));//"当前未连接任何 Wifi" + ccf->setSignal("0", "--"); + activeWifiSignalLv = 0; + ccf->setConnedString(1, tr("Disconnected"), "");//"未连接" + ccf->isConnected = false; + ifWLanConnected = false; + lbLoadDown->hide(); + lbLoadUp->hide(); + lbLoadDownImg->hide(); + lbLoadUpImg->hide(); + ccf->setTopItem(false); + } + ccf->setAct(true); + ccf->move(L_VERTICAL_LINE_TO_ITEM, 0); + ccf->show(); + // 填充可用网络列表 + QString headLine = slist.at(0); + int indexSignal,indexSecu, indexFreq, indexBSsid, indexName, indexPath; + headLine = headLine.trimmed(); + + bool isChineseExist = headLine.contains(QRegExp("[\\x4e00-\\x9fa5]+")); + if (isChineseExist) { + indexSignal = headLine.indexOf("SIGNAL"); + indexSecu = headLine.indexOf("安全性"); + indexFreq = headLine.indexOf("频率") + 4; + indexBSsid = headLine.indexOf("BSSID") + 6; + indexName = indexBSsid + 19; + indexPath = headLine.indexOf("DBUS-PATH"); + } else { + indexSignal = headLine.indexOf("SIGNAL"); + indexSecu = headLine.indexOf("SECURITY"); + indexFreq = headLine.indexOf("FREQ"); + indexBSsid = headLine.indexOf("BSSID"); + indexName = indexBSsid + 19; + indexPath = headLine.indexOf("DBUS-PATH"); + } + QStringList wnames; + int count = 0; + QString actWifiBssid = " "; + for (int i = 1; i < slist.size(); i ++) { + QString line = slist.at(i); + QString wbssid = line.mid(indexBSsid, 17).trimmed(); + QString wname = line.mid(indexName, indexPath - indexName).trimmed(); + + if (actWifiBssidList.contains(wbssid)) { + actWifiName = wname; + } + if ("*" == line.mid(0,indexSignal).trimmed()){ + actWifiBssid = wbssid; + } + } + + if (actWifiBssidList.size()==1 && actWifiBssidList.at(0)=="--") { + actWifiId = actWifiName; + actWifiName = "--"; + } + for (int i = 1, j = 0; i < slist.size(); i ++) { + QString line = slist.at(i); + //QString wsignal = line.mid(0, indexRate).trimmed(); + //QString wrate = line.mid(indexRate, indexSecu - indexRate).trimmed(); + QString wsignal = line.mid(indexSignal, 3).trimmed(); + QString wsecu = line.mid(indexSecu, indexFreq - indexSecu).trimmed(); + QString wbssid = line.mid(indexBSsid, 17).trimmed(); + QString wname = line.mid(indexName, indexPath - indexName).trimmed(); + + bool isContinue = false; + foreach (QString addName, wnames) { + // 重复的网络名称,跳过不处理 + if(addName == wname){ isContinue = true; } + } + if(isContinue){ continue; } + + if (actWifiName != "--" && actWifiName == wname) { + if (!actWifiBssidList.contains(wbssid)) { + continue; //若当前热点ssid名称和已经连接的wifi的ssid名称相同,但bssid不同,则跳过 + } + } + + if (wname != "" && wname != "--") { + // 当前连接的wifi + if (wname == actWifiName) { + connect(ccf, SIGNAL(selectedOneWifiForm(QString,int)), this, SLOT(oneTopWifiFormSelected(QString,int))); + connect(ccf, SIGNAL(disconnActiveWifi()), this, SLOT(activeWifiDisconn())); + QString path = line.mid(indexPath).trimmed(); + QString m_name = this->objKyDBus->getWifiSsid(QString("/org/freedesktop/NetworkManager/AccessPoint/%1").arg(path.mid(path.lastIndexOf("/") + 1))); +// ccf->setName(m_name); + if (m_name.isEmpty() || m_name == "") { + ccf->setName(wname); + } else { + ccf->setName(m_name); + } + //ccf->setRate(wrate); + int signal = wsignal.toInt() + 11; + ccf->setSignal(QString::number(signal), wsecu); + activeWifiSignalLv = wsignal.toInt(); + objKyDBus->getWifiMac(wname); + ccf->setWifiInfo(wsecu, wsignal, objKyDBus->dbusWifiMac); + ccf->setConnedString(1, tr("NetOn,"), wsecu);//"已连接" + ccf->isConnected = true; + ifWLanConnected = true; + lbLoadDown->show(); + lbLoadUp->show(); + lbLoadDownImg->show(); + lbLoadUpImg->show(); + ccf->setTopItem(false); + currSelNetName = ""; + + syslog(LOG_DEBUG, "already insert an active wifi in the top of wifi list"); + } else { + wifiListWidget->resize(W_LIST_WIDGET+173*isTabletStyle, wifiListWidget->height() + H_NORMAL_ITEM); + + OneConnForm *ocf = new OneConnForm(wifiListWidget, this, confForm, ksnm); + connect(ocf, SIGNAL(selectedOneWifiForm(QString,int)), this, SLOT(oneWifiFormSelected(QString,int))); + connect(ocf,&OneConnForm::onLineEditClicked, this, &KylinNM::onLineEditClicked); + QString path = line.mid(indexPath).trimmed(); + QString m_name = this->objKyDBus->getWifiSsid(QString("/org/freedesktop/NetworkManager/AccessPoint/%1").arg(path.mid(path.lastIndexOf("/") + 1))); +// ocf->setName(m_name); + if (m_name.isEmpty() || m_name == "") { + ocf->setName(wname); + } else { + ocf->setName(m_name); + } + //ocf->setRate(wrate); + ocf->setLine(true); + ocf->setSignal(wsignal, wsecu); + objKyDBus->getWifiMac(wname); + ocf->setWifiInfo(wsecu, wsignal, objKyDBus->dbusWifiMac); + ocf->setConnedString(0, tr("Disconnected"), wsecu); + ocf->move(L_VERTICAL_LINE_TO_ITEM, j * H_NORMAL_ITEM); + ocf->setSelected(false, false); + ocf->show(); + + j ++; + count ++; + } + + wnames.append(wname); + } + } + QList itemList = wifiListWidget->findChildren(); + int n = itemList.size(); + if (n >= 1) { + OneConnForm *lastItem = itemList.at(n-1); + lastItem->setLine(false); + lbNoItemTip->hide(); + } else { + if (ifWLanConnected) { + lbNoItemTip->show(); + lbNoItemTip->setText(tr("No Other Wireless Network Scheme")); + } else { + lbNoItemTip->hide(); + lbTopWifiList->hide(); +// btnAddNet->hide(); + } + } + + this->lanListWidget->hide(); + this->topLanListWidget->hide(); + this->wifiListWidget->show(); + this->topWifiListWidget->show(); + + this->stopLoading(); + is_stop_check_net_state = 0; + + actWifiBssidList.clear(); + wnames.clear(); +} + +// 更新wifi列表 +void KylinNM::updateWifiListDone(QStringList slist) +{ + if (this->ksnm->isExecutingGetLanList){ return;} + + //获取表头信息 + QString lastHeadLine = oldWifiSlist.at(0); + //int lastIndexName = lastHeadLine.indexOf("SSID"); + int lastIndexName, lastIndexPath; + lastHeadLine = lastHeadLine.trimmed(); + bool isChineseInIt = lastHeadLine.contains(QRegExp("[\\x4e00-\\x9fa5]+")); + if (isChineseInIt) { + lastIndexName = lastHeadLine.indexOf("BSSID") + 6 + 19; + } else { + lastIndexName = lastHeadLine.indexOf("BSSID") + 19; + } + lastIndexPath = lastHeadLine.indexOf("DBUS-PATH"); + + QString headLine = slist.at(0); + int indexSecu, indexFreq, indexBSsid, indexName, indexPath; + headLine = headLine.trimmed(); + bool isChineseExist = headLine.contains(QRegExp("[\\x4e00-\\x9fa5]+")); + if (isChineseExist) { + indexSecu = headLine.indexOf("安全性"); + indexFreq = headLine.indexOf("频率") + 4; + indexBSsid = headLine.indexOf("BSSID") + 6; + //indexName = headLine.indexOf("SSID") + 6; + indexName = indexBSsid + 19; + indexPath = headLine.indexOf("DBUS-PATH"); + } else { + indexSecu = headLine.indexOf("SECURITY"); + indexFreq = headLine.indexOf("FREQ"); + indexBSsid = headLine.indexOf("BSSID"); + indexName = indexBSsid + 19; + indexPath = headLine.indexOf("DBUS-PATH"); + } + + //列表中去除已经减少的wifi + for (int i=1; i wifiList = wifiListWidget->findChildren(); + for (int pos = 0; pos < wifiList.size(); pos ++) { + OneConnForm *ocf = wifiList.at(pos); + if (ocf->getName() == lastWname) { + if (ocf->isActive == true){break; + } else { + delete ocf; + //删除元素下面的的所有元素上移 + for (int after_pos = pos+1; after_pos < wifiList.size(); after_pos ++) { + OneConnForm *after_ocf = wifiList.at(after_pos); + if (lastWname == currSelNetName) {after_ocf->move(L_VERTICAL_LINE_TO_ITEM, after_ocf->y() - H_NORMAL_ITEM - H_WIFI_ITEM_BIG_EXTEND);} + else {after_ocf->move(L_VERTICAL_LINE_TO_ITEM, after_ocf->y() - H_NORMAL_ITEM);} + } + wifiListWidget->resize(W_LIST_WIDGET+173*isTabletStyle, wifiListWidget->height() - H_NORMAL_ITEM); + break; + } + } + } + + } //end if (j == slist.size()-1) + } //end (int j=1; j wifiList = wifiListWidget->findChildren(); + int n = wifiList.size(); + int posY = 0; + if (n >= 1) { + OneConnForm *lastOcf = wifiList.at(n-1); + lastOcf->setLine(true); + if (lastOcf->wifiName == currSelNetName) { + posY = lastOcf->y()+H_NORMAL_ITEM + H_WIFI_ITEM_BIG_EXTEND; + } else { + posY = lastOcf->y()+H_NORMAL_ITEM; + } + } + + wifiListWidget->resize(W_LIST_WIDGET+173*isTabletStyle, wifiListWidget->height() + H_NORMAL_ITEM); + OneConnForm *addItem = new OneConnForm(wifiListWidget, this, confForm, ksnm); + connect(addItem, SIGNAL(selectedOneWifiForm(QString,int)), this, SLOT(oneWifiFormSelected(QString,int))); + connect(addItem,&OneConnForm::onLineEditClicked, this, &KylinNM::onLineEditClicked); + QString path = slist.at(i).mid(indexPath).trimmed(); + QString m_name = this->objKyDBus->getWifiSsid(QString("/org/freedesktop/NetworkManager/AccessPoint/%1").arg(path.mid(path.lastIndexOf("/") + 1))); + if (m_name.isEmpty() || m_name == "") { + addItem->setName(wname); + } else { + addItem->setName(m_name); + } + addItem->setLine(false); + addItem->setSignal(wsignal, wsecu); + objKyDBus->getWifiMac(wname); + addItem->setWifiInfo(wsecu, wsignal, objKyDBus->dbusWifiMac); + addItem->setConnedString(0, tr("Disconnected"), wsecu);//"未连接" + addItem->move(L_VERTICAL_LINE_TO_ITEM, posY); + addItem->setSelected(false, false); + addItem->show(); + + count += 1; + } + } + } + + this->lanListWidget->hide(); + this->topLanListWidget->hide(); + this->wifiListWidget->show(); + this->topWifiListWidget->show(); + this->stopLoading(); +} + + +/////////////////////////////////////////////////////////////////////////////// +//主窗口其他按钮点击响应 + +void KylinNM::on_btnAdvConf_clicked() +{ + QProcess *qprocess = new QProcess(this); + qprocess->start("nm-connection-editor &"); + // int status = system("nm-connection-editor &"); + // if (status != 0){ syslog(LOG_ERR, "execute 'nm-connection-editor &' in function 'on_btnAdvConf_clicked' failed");} +} + +void KylinNM::on_btnAdvConf_pressed() +{ + //ui->lbBtnConfBG->setStyleSheet(btnOnQss); +} + +void KylinNM::on_btnAdvConf_released() +{ + //ui->lbBtnConfBG->setStyleSheet(btnOffQss); +} + +void KylinNM::on_btnFlyMode_clicked() +{ + if (is_fly_mode_on == 0) { + ui->lbFlyImg->setStyleSheet("QLabel{background-image:url(:/res/x/fly-mode-on.svg);}"); + ui->lbFlyBG->setStyleSheet(btnOnQss); + is_fly_mode_on = 1; + + onBtnWifiClicked(0); + on_btnWifiList_clicked(); + } else { + ui->lbFlyImg->setStyleSheet("QLabel{background-image:url(:/res/x/fly-mode-off.svg);}"); + ui->lbFlyBG->setStyleSheet(btnOffQss); + is_fly_mode_on = 0; + } +} + +void KylinNM::on_btnHotspot_clicked() +{ + if (is_wireless_adapter_ready == 1) { + if (is_hot_sopt_on == 0) { + ui->lbHotImg->setStyleSheet("QLabel{background-image:url(:/res/x/hot-spot-on.svg);}"); + ui->lbHotBG->setStyleSheet(btnOnQss); + is_hot_sopt_on = 1; + + QApplication::setQuitOnLastWindowClosed(false); + DlgHotspotCreate *hotCreate = new DlgHotspotCreate(objKyDBus->dbusWiFiCardName); + connect(hotCreate,SIGNAL(updateHotspotList()),this,SLOT(on_btnWifiList_clicked() )); + connect(hotCreate,SIGNAL(btnHotspotState()),this,SLOT(on_btnHotspotState() )); + hotCreate->show(); + } else { + on_btnHotspotState(); + + BackThread objBT; + objBT.disConnLanOrWifi("wifi"); + + sleep(2); + on_btnWifiList_clicked(); + } + } +} + +void KylinNM::onBtnAddNetClicked() +{ +// QApplication::setQuitOnLastWindowClosed(false); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, this, this->parentWidget()); + connect(connHidWifi, SIGNAL(reSetWifiList() ), this, SLOT(on_btnWifiList_clicked()) ); + connHidWifi->show(); +} + +void KylinNM::onBtnCreateNetClicked() +{ + QPoint pos = QCursor::pos(); + QRect primaryGeometry; + for (QScreen *screen : qApp->screens()) { + if (screen->geometry().contains(pos)) { + primaryGeometry = screen->geometry(); + } + } + + if (primaryGeometry.isEmpty()) { + primaryGeometry = qApp->primaryScreen()->geometry(); + } + + ConfForm *m_cf = new ConfForm(this->parentWidget()); + m_cf->setMainWindow(this); + m_cf->cbTypeChanged(3); + m_cf->move(primaryGeometry.width() / 2 - m_cf->width() / 2, primaryGeometry.height() / 2 - m_cf->height() / 2); + m_cf->show(); +} + + +/////////////////////////////////////////////////////////////////////////////// +//处理窗口变化、网络状态变化 + +//列表中item的扩展与收缩 +void KylinNM::oneLanFormSelected(QString lanName, QString uniqueName) +{ + QList topLanList = topLanListWidget->findChildren(); + QList lanList = lanListWidget->findChildren(); + + //**********************先处理下方列表********************// + // 下方所有元素回到原位 + for (int i = 0, j = 0;i < lanList.size(); i ++) { + OneLancForm *ocf = lanList.at(i); + if (ocf->isActive == true) { + ocf->move(L_VERTICAL_LINE_TO_ITEM, 0); + } + if (ocf->isActive == false) { + ocf->move(L_VERTICAL_LINE_TO_ITEM, j * H_NORMAL_ITEM); + j ++; + } + } + + //是否与上一次选中同一个网络框 + if (currSelNetName == uniqueName) { + // 缩小所有选项卡 + for (int i = 0;i < lanList.size(); i ++) { + OneLancForm *ocf = lanList.at(i); + if (ocf->uniqueName == uniqueName) { + ocf->setSelected(false, true); + } else { + ocf->setSelected(false, false); + } + } + + currSelNetName = ""; + } else { + int selectY = 0; + for (int i = 0;i < lanList.size(); i ++) { + OneLancForm *ocf = lanList.at(i); + if (ocf->uniqueName == uniqueName) { + selectY = ocf->y(); //获取选中item的y坐标 + break; + } + } + + // 选中元素下面的所有元素下移 H_LAN_ITEM_EXTEND + for (int i = 0;i < lanList.size(); i ++) { + OneLancForm *ocf = lanList.at(i); + if (ocf->y() > selectY) { + ocf->move(L_VERTICAL_LINE_TO_ITEM, ocf->y() + H_LAN_ITEM_EXTEND); + } + } + + for (int i = 0;i < lanList.size(); i ++) { + OneLancForm *ocf = lanList.at(i); + if (ocf->uniqueName == uniqueName) { + ocf->setSelected(true, false); + selectY = ocf->y(); + } else { + ocf->setSelected(false, false); + } + } + + currSelNetName = uniqueName; + } + + QList itemList = lanListWidget->findChildren(); + int n = itemList.size(); + if (n >= 1) { + OneLancForm *lastItem = itemList.at(n-1); + lastItem->setLine(false); + } + + //**********************处理上方列表-界面所有控件回原位********************// + topLanListWidget->resize(W_TOP_LIST_WIDGET, H_NORMAL_ITEM + H_GAP_UP + X_ITEM); // 顶部的item缩小 + lbTopLanList->move(X_MIDDLE_WORD, H_NORMAL_ITEM + H_GAP_UP); +// btnCreateNet->move(X_BTN_FUN, Y_BTN_FUN); + scrollAreal->move(W_LEFT_AREA, Y_SCROLL_AREA); + lbNoItemTip->move(this->width()/2 - W_NO_ITEM_TIP/2 + W_LEFT_AREA/2, this->height()/2); + + OneLancForm *ocf = topLanList.at(0); + ocf->setTopItem(false); +} +void KylinNM::oneTopLanFormSelected(QString lanName, QString uniqueName) +{ + currSelNetName = uniqueName; +} + +void KylinNM::oneWifiFormSelected(QString wifiName, int extendLength) +{ + QListtopWifiList = topWifiListWidget->findChildren(); + QList wifiList = wifiListWidget->findChildren(); + + //******************先处理下方列表****************// + // 下方所有元素回到原位 + for (int i = 0, j = 0;i < wifiList.size(); i ++) { + OneConnForm *ocf = wifiList.at(i); + if (ocf->isActive == true) { + ocf->move(L_VERTICAL_LINE_TO_ITEM, 0); + } + if (ocf->isActive == false) { + ocf->move(L_VERTICAL_LINE_TO_ITEM, j * H_NORMAL_ITEM); + j ++; + } + } + + //是否与上一次选中同一个网络框 + if (currSelNetName == wifiName) { + // 缩小所有选项卡 + for (int i = 0;i < wifiList.size(); i ++) { + OneConnForm *ocf = wifiList.at(i); + if (ocf->wifiName == wifiName) { + if (ocf->wifiName == hideWiFiConn) { + ocf->setHideItem(true, true); + } else { + ocf->setSelected(false, true); + } + } else { + if (ocf->wifiName == hideWiFiConn) { + ocf->setHideItem(true, true); + } else { + ocf->setSelected(false, false); + } + } + + } + currSelNetName = ""; + } else { + int selectY = 0; + for (int i = 0;i < wifiList.size(); i ++) { + OneConnForm *ocf = wifiList.at(i); + if (ocf->wifiName == wifiName) { + selectY = ocf->y(); //获取选中item的y坐标 + this->scrollAreaw->verticalScrollBar()->setValue(selectY); + break; + } + } + + // 选中元素下面的所有元素下移 H_WIFI_ITEM_BIG_EXTEND + for (int i = 0;i < wifiList.size(); i ++) { + OneConnForm *ocf = wifiList.at(i); + if (ocf->y() > selectY) { + ocf->move(L_VERTICAL_LINE_TO_ITEM, ocf->y() + extendLength); + } + } + + for (int i = 0;i < wifiList.size(); i ++) { + OneConnForm *ocf = wifiList.at(i); + if (ocf->wifiName == wifiName) { + if (ocf->wifiName == hideWiFiConn) { + ocf->setHideItem(true, true); + } else { + ocf->setSelected(true, false); + } + } else { + if (ocf->wifiName == hideWiFiConn) { + ocf->setHideItem(true, true); + } else { + ocf->setSelected(false, false); + } + } + } + + currSelNetName = wifiName; + } + + //最后一个item没有下划线 + QList itemList = wifiListWidget->findChildren(); + int n = itemList.size(); + if (n >= 1) { + OneConnForm *lastItem = itemList.at(n-1); + lastItem->setLine(false); + } + + //********************处理上方列表-界面所有控件回原位******************// + // 顶部的item缩小 + topWifiListWidget->resize(W_TOP_LIST_WIDGET+194*isTabletStyle, H_NORMAL_ITEM + H_GAP_UP + X_ITEM); + lbTopWifiList->move(X_MIDDLE_WORD, H_NORMAL_ITEM + H_GAP_UP); +// btnAddNet->move(X_BTN_FUN, Y_BTN_FUN); + scrollAreaw->move(W_LEFT_AREA, Y_SCROLL_AREA); + lbNoItemTip->move(this->width()/2 - W_NO_ITEM_TIP/2 + W_LEFT_AREA/2, this->height()/2); + + OneConnForm *ocf = topWifiList.at(0); + ocf->setTopItem(false); +} +void KylinNM::oneTopWifiFormSelected(QString wifiName, int extendLength) +{ + QListtopWifiList = topWifiListWidget->findChildren(); + QList wifiList = wifiListWidget->findChildren(); + + if (currSelNetName == wifiName) { + // 与上一次选中同一个网络框,缩小当前选项卡 + topWifiListWidget->resize(W_TOP_LIST_WIDGET+194*isTabletStyle, H_NORMAL_ITEM + H_GAP_UP + X_ITEM); + lbTopWifiList->move(X_MIDDLE_WORD, H_NORMAL_ITEM + H_GAP_UP); +// btnAddNet->move(X_BTN_FUN, Y_BTN_FUN); + scrollAreaw->move(W_LEFT_AREA, Y_SCROLL_AREA); + lbNoItemTip->move(this->width()/2 - W_NO_ITEM_TIP/2 + W_LEFT_AREA/2, this->height()/2); + + OneConnForm *ocf = topWifiList.at(0); + ocf->setTopItem(false); + + currSelNetName = ""; + } else { + // 没有与上一次选中同一个网络框,放大当前选项卡 + + for(int i = 0;i < wifiList.size(); i ++) { + // 所有元素回到原位 + OneConnForm *ocf = wifiList.at(i); + ocf->setSelected(false, false); + ocf->move(L_VERTICAL_LINE_TO_ITEM, i * H_NORMAL_ITEM); + } + + topWifiListWidget->resize(W_TOP_LIST_WIDGET+194*isTabletStyle, H_NORMAL_ITEM + H_WIFI_ITEM_BIG_EXTEND + H_GAP_UP + X_ITEM); + lbTopWifiList->move(X_MIDDLE_WORD, H_NORMAL_ITEM + H_WIFI_ITEM_BIG_EXTEND + H_GAP_UP); +// btnAddNet->move(X_BTN_FUN, Y_BTN_FUN + H_WIFI_ITEM_BIG_EXTEND); + scrollAreaw->move(W_LEFT_AREA, Y_SCROLL_AREA + H_WIFI_ITEM_BIG_EXTEND); + lbNoItemTip->move(this->width()/2 - W_NO_ITEM_TIP/2 + W_LEFT_AREA/2, this->height()/2 + 65); + + OneConnForm *ocf = topWifiList.at(0); + ocf->setTopItem(true); + + currSelNetName = wifiName; + } +} + +//断开网络处理 +void KylinNM::activeLanDisconn() +{ + syslog(LOG_DEBUG, "Wired net is disconnected"); + + QString txt(tr("Wired net is disconnected")); + objKyDBus->showDesktopNotify(txt); + //QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';notify-send '" + txt + "...' -t 3800"; + //int status1 = system(cmd.toUtf8().data()); + //if (status1 != 0){ syslog(LOG_ERR, "execute 'notify-send' in function 'execConnWifiPWD' failed");} + + currSelNetName = ""; + //this->startLoading(); + emit this->waitLanStop(); + this->ksnm->execGetLanList(); + QTimer::singleShot(200, this, &KylinNM::onConnectChanged); +} + +void KylinNM::activeWifiDisconn() +{ + QThread *tt = new QThread(); + BackThread *btt = new BackThread(); + btt->moveToThread(tt); + connect(tt, SIGNAL(finished()), tt, SLOT(deleteLater())); + connect(this, SIGNAL(disConnSparedNet(QString)), btt, SLOT(disConnSparedNetSlot(QString)),Qt::DirectConnection); + connect(btt, SIGNAL(disFinish()), this, SLOT(activeGetWifiList()), Qt::DirectConnection); + connect(btt, SIGNAL(ttFinish()), tt, SLOT(quit()),Qt::DirectConnection); + + tt->start(); + activeStartLoading(); + QTimer::singleShot(200, this, &KylinNM::onConnectChanged); +} + +void KylinNM::reflashWifiUi() +{ + mutexIsReflashWifi.lock(); + m_is_reflashWifiUi = true; + mutexIsReflashWifi.unlock(); +} + +void KylinNM::activeStartLoading() +{ + syslog(LOG_DEBUG, "Wi-Fi is disconnected"); + emit this->disConnSparedNet("wifi"); +} +void KylinNM::activeGetWifiList() +{ + emit this->waitWifiStop(); + this->ksnm->execGetWifiList(); +} + +//网络开关处理,打开与关闭网络 +void KylinNM::enNetDone() +{ + BackThread *bt = new BackThread(); + mwBandWidth = bt->execChkLanWidth(lname); + + ui->lbBtnNetBG->setStyleSheet(btnOnQss); + + // 打开网络开关时如果Wifi开关是打开的,设置其样式 + if (checkWlOn()) { + btnWireless->setSwitchStatus(true); + //ui->lbBtnWifiBG->setStyleSheet(btnBgOnQss); + //ui->lbBtnWifiBall->move(X_RIGHT_WIFI_BALL, Y_WIFI_BALL); + } + + onBtnNetListClicked(1); + is_stop_check_net_state = 0; + + qDebug()<<"debug: already turn on the switch of lan network"; + syslog(LOG_DEBUG, "Already turn on the switch of lan network"); +} +void KylinNM::disNetDone() +{ + this->is_btnNetList_clicked = 1; + this->is_btnWifiList_clicked = 0; + + ui->lbNetListBG->setStyleSheet(btnOnQss); + ui->lbWifiListBG->setStyleSheet(btnOffQss); + + ui->lbNetwork->setText("Activated LAN"); + btnWireless->hide(); + //ui->lbBtnWifiBG->hide(); + //ui->lbBtnWifiBall->hide(); + + delete topLanListWidget; // 清空top列表 + createTopLanUI(); //创建顶部有线网item + + // 清空lan列表 + lanListWidget = new QWidget(scrollAreal); + lanListWidget->resize(W_LIST_WIDGET, H_NORMAL_ITEM + H_LAN_ITEM_EXTEND); + scrollAreal->setWidget(lanListWidget); + scrollAreal->move(W_LEFT_AREA, Y_SCROLL_AREA); + + // 当前连接的lan + OneLancForm *ccf = new OneLancForm(topLanListWidget, this, confForm, ksnm); + ccf->setName(tr("Not connected"), "");//"当前未连接任何 以太网" + ccf->setIcon(false); + ccf->setConnedString(1, tr("Disconnected"));//"未连接" + ccf->isConnected = false; + ccf->setTopItem(false); + ccf->setAct(true); + ccf->move(L_VERTICAL_LINE_TO_ITEM, 0); + ccf->show(); + + ui->lbBtnNetBG->setStyleSheet(btnOffQss); + + btnWireless->setSwitchStatus(false); + + this->lanListWidget->show(); + this->wifiListWidget->hide(); + this->scrollAreal->show(); + this->topLanListWidget->show(); + this->scrollAreaw->hide(); + this->topWifiListWidget->hide(); + + on_btnNetList_pressed(); + + qDebug()<<"debug: already turn off the switch of lan network"; + syslog(LOG_DEBUG, "Already turn off the switch of lan network"); + + this->stopLoading(); + QTimer::singleShot(200, this, &KylinNM::onConnectChanged); +} +void KylinNM::launchLanDone() +{ + ui->lbBtnNetBG->setStyleSheet(btnOnQss); +} + +void KylinNM::enWifiDone() +{ + //ui->lbBtnWifiBG->setStyleSheet(btnBgOnQss); + //ui->lbBtnWifiBall->move(X_RIGHT_WIFI_BALL, Y_WIFI_BALL); + + is_update_wifi_list = 0; + if (is_btnWifiList_clicked) { + this->ksnm->execGetWifiList(); + } else { + on_btnWifiList_clicked(); + } + + qDebug()<<"debug: already turn on the switch of wifi network"; + syslog(LOG_DEBUG, "Already turn on the switch of wifi network"); +} +void KylinNM::disWifiDone() +{ + disWifiDoneChangeUI(); + + on_btnWifiList_pressed(); + + qDebug()<<"debug: already turn off the switch of wifi network"; + syslog(LOG_DEBUG, "Already turn off the switch of wifi network"); + + this->stopLoading(); + is_stop_check_net_state = 0; + QTimer::singleShot(200, this, &KylinNM::onConnectChanged); +} +void KylinNM::disWifiStateKeep() +{ + if (this->is_btnNetList_clicked == 1) { + btnWireless->setSwitchStatus(false); + //ui->lbBtnWifiBG->setStyleSheet(btnBgOffQss); + //ui->lbBtnWifiBall->move(X_LEFT_WIFI_BALL, Y_WIFI_BALL); + } + if (this->is_btnWifiList_clicked== 1) { + disWifiDoneChangeUI(); + + // this->stopLoading(); + getActiveInfo(); + } +} +void KylinNM::disWifiDoneChangeUI() +{ + wifiListWidget = new QWidget(scrollAreaw); + wifiListWidget->resize(W_LIST_WIDGET+173*isTabletStyle, H_WIFI_ITEM_BIG_EXTEND); + scrollAreaw->setWidget(wifiListWidget); + scrollAreaw->move(W_LEFT_AREA, Y_SCROLL_AREA); + + lbTopWifiList->move(X_MIDDLE_WORD, H_NORMAL_ITEM + H_GAP_UP); +// btnAddNet->move(X_BTN_FUN, Y_BTN_FUN); + topWifiListWidget->resize(W_TOP_LIST_WIDGET+194*isTabletStyle, H_NORMAL_ITEM + H_GAP_UP + X_ITEM); + + QList wifiList = topWifiListWidget->findChildren(); + for (int i = 0; i < wifiList.size(); i ++) { + OneConnForm *ocf = wifiList.at(i); + if (ocf->isActive == true) { + ocf->setSelected(false, false); + ocf->setName(tr("Not connected"));//"当前未连接任何 Wifi" + ocf->setSignal("0", "--"); + ocf->setConnedString(1, tr("Disconnected"), "");//"未连接" + lbLoadDown->hide(); + lbLoadUp->hide(); + lbLoadDownImg->hide(); + lbLoadUpImg->hide(); + ocf->isConnected = false; + ocf->setTopItem(false); + disconnect(ocf, SIGNAL(selectedOneWifiForm(QString,int)), this, SLOT(oneTopWifiFormSelected(QString,int))); + } else { + ocf->deleteLater(); + } + } + + btnWireless->setSwitchStatus(false); + //ui->lbBtnWifiBG->setStyleSheet(btnBgOffQss); + //ui->lbBtnWifiBall->move(X_LEFT_WIFI_BALL, Y_WIFI_BALL); + + this->lanListWidget->hide(); + this->topLanListWidget->hide(); + this->wifiListWidget->show(); + this->topWifiListWidget->show(); + this->scrollAreal->hide(); + this->scrollAreaw->show(); +} + +void KylinNM::on_btnHotspotState() +{ + ui->lbHotImg->setStyleSheet("QLabel{background-image:url(:/res/x/hot-spot-off.svg);}"); + ui->lbHotBG->setStyleSheet(btnOffQss); + is_hot_sopt_on = 0; +} + +//处理外界对网络的连接与断开 +void KylinNM::onExternalConnectionChange(QString type) +{ + qDebug() <is_btnWifiList_clicked==1 && this->isVisible()) { + BackThread *loop_bt = new BackThread(); + IFace *loop_iface = loop_bt->execGetIface(); + + if (loop_iface->wstate != 2) { + is_update_wifi_list = 1; + this->ksnm->execGetWifiList(); //更新wifi列表 + } + + delete loop_iface; + loop_bt->deleteLater(); + } +} + +void KylinNM::on_setNetSpeed() +{ + if (this->isVisible() && is_stop_check_net_state==0) { + if (is_btnWifiList_clicked == 1) { + if ( objNetSpeed->getCurrentDownloadRates(objKyDBus->dbusWiFiCardName.toUtf8().data(), &start_rcv_rates, &start_tx_rates) == -1) { + start_rcv_rates = end_rcv_rates; + } + } else if(is_btnNetList_clicked == 1) { + if ( objNetSpeed->getCurrentDownloadRates(objKyDBus->dbusLanCardName.toUtf8().data(), &start_rcv_rates, &start_tx_rates) == -1) { + start_tx_rates = end_tx_rates; + } + } + + long int delta_rcv = (start_rcv_rates - end_rcv_rates)/800; + long int delta_tx = (start_tx_rates - end_tx_rates)/8; + if (delta_rcv>=10000 || delta_rcv<0){delta_rcv = 0;} + if (delta_tx>=10000 || delta_tx<0){delta_tx = 0;} + + int rcv_num = delta_rcv/3; + int tx_num = delta_tx/3; + + QString str_rcv; + QString str_tx; + + if (rcv_num < 1000) { + str_rcv = QString::number(rcv_num) + "KB/s."; + } else { + int remainder; + if (rcv_num%1000 < 100) { + remainder = 0; + } else { + remainder = (rcv_num%1000)/100; + } + str_rcv = QString::number(rcv_num/1000) + "." + QString::number(remainder) + "MB/s."; + } + + if (tx_num < 1000) { + str_tx = QString::number(tx_num) + "KB/s"; + } else { + int remainder; + if (tx_num%1000 < 100) { + remainder = 0; + } else { + remainder = (tx_num%1000)/100; + } + str_tx = QString::number(tx_num/1000) + "." + QString::number(remainder) + "MB/s"; + } + + lbLoadDown->setText(str_rcv); + lbLoadUp->setText(str_tx); + + switch (str_rcv.size()) { + case 6: + lbLoadUp->move(X_ITEM + 187, Y_TOP_ITEM + 32); + lbLoadUpImg->move(X_ITEM + 170, Y_TOP_ITEM + 35); + break; + case 7: + lbLoadUp->move(X_ITEM + 194, Y_TOP_ITEM + 32); + lbLoadUpImg->move(X_ITEM + 176, Y_TOP_ITEM + 35); + break; + case 8: + lbLoadUp->move(X_ITEM + 199, Y_TOP_ITEM + 32); + lbLoadUpImg->move(X_ITEM + 186, Y_TOP_ITEM + 35); + break; + default: + break; + } + + end_rcv_rates = start_rcv_rates; + end_tx_rates = start_tx_rates; + } +} + +void KylinNM::connLanDone(int connFlag) +{ + emit this->waitLanStop(); //停止加载动画 + + // Lan连接结果,0点击连接成功 1失败 3开机启动网络工具时已经连接 + if (connFlag == 0) { + syslog(LOG_DEBUG, "Wired net already connected by clicking button"); + this->is_wired_line_ready = 1; + this->is_by_click_connect = 1; + this->ksnm->execGetLanList(); + + QString txt(tr("Conn Ethernet Success")); + objKyDBus->showDesktopNotify(txt); + //QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';notify-send '" + txt + "' -t 3800"; + //int status = system(cmd.toUtf8().data()); + //if (status != 0){ syslog(LOG_ERR, "execute 'notify-send' in function 'connLanDone' failed");} + } + + if (connFlag == 1) { + qDebug()<<"without net line connect to computer"; + this->is_wired_line_ready = 0; //without net line connect to computer + is_stop_check_net_state = 0; + + QString txt(tr("Conn Ethernet Fail")); + objKyDBus->showDesktopNotify(txt); + //QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';notify-send '" + txt + "' -t 3800"; + //int status = system(cmd.toUtf8().data()); + //if (status != 0){ syslog(LOG_ERR, "execute 'notify-send' in function 'connLanDone' failed");} + } + + if (connFlag == 3) { + syslog(LOG_DEBUG, "Launch kylin-nm, Lan already connected"); + this->is_wired_line_ready = 1; + } + + this->stopLoading(); + QTimer::singleShot(200, this, &KylinNM::onConnectChanged); +} + +void KylinNM::connWifiDone(int connFlag) +{ + emit this->waitWifiStop(); //停止加载动画 + // Wifi连接结果,0点击连接成功 1失败 2没有配置文件 3开机启动网络工具时已经连接 + if (connFlag == 0) { + syslog(LOG_DEBUG, "Wi-Fi already connected by clicking button"); + this->is_by_click_connect = 1; + this->ksnm->execGetWifiList(); + + QString txt(tr("Conn Wifi Success")); + objKyDBus->showDesktopNotify(txt); + //QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';notify-send '" + txt + "' -t 3800"; + //int status = system(cmd.toUtf8().data()); + //if (status != 0){ syslog(LOG_ERR, "execute 'notify-send' in function 'connWifiDone' failed");} + } else if (connFlag == 1) { + is_stop_check_net_state = 0; + is_connect_wifi_failed = 1; + + QString txt(tr("Confirm your Wi-Fi password or usable of wireless card")); + objKyDBus->showDesktopNotify(txt); + //QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';notify-send '" + txt + "...' -t 3800"; + //int status1 = system(cmd.toUtf8().data()); + //if (status1 != 0){ syslog(LOG_ERR, "execute 'notify-send' in function 'execConnWifiPWD' failed");} + } else if (connFlag == 3) { + syslog(LOG_DEBUG, "Launch kylin-nm, Wi-Fi already connected"); + } + QTimer::singleShot(200, this, &KylinNM::onConnectChanged); +} + +int KylinNM::getConnectStatus() +{ + int ret = -1; + QString actLanName = "--"; + QString actWifiName = "--"; + + activecon *act = kylin_network_get_activecon_info(); + int index = 0; + while (act[index].con_name != NULL) { + if (QString(act[index].type) == "ethernet" || QString(act[index].type) == "802-3-ethernet") { + actLanName = QString(act[index].con_name); + } + if (QString(act[index].type) == "wifi" || QString(act[index].type) == "802-11-wireless") { + actWifiName = QString(act[index].con_name); + } + index ++; + } + + //ukui3.0中获取currentActWifiSignalLv的值 + if (activeWifiSignalLv > 75) { + currentActWifiSignalLv = 1; + } else if(activeWifiSignalLv > 55 && activeWifiSignalLv <= 75) { + currentActWifiSignalLv = 2; + } else if(activeWifiSignalLv > 35 && activeWifiSignalLv <= 55) { + currentActWifiSignalLv = 3; + } else if( activeWifiSignalLv <= 35) { + currentActWifiSignalLv = 4; + } + + // 设置图标 + if (actLanName != "--") { + ret = 0; + } else if (actWifiName != "--") { + ret = 1; + } else { + ret = -1; + } + + return ret; +} diff --git a/KylinNM/src/kylinnm.h b/KylinNM/src/kylinnm.h new file mode 100644 index 0000000..3ed9ce6 --- /dev/null +++ b/KylinNM/src/kylinnm.h @@ -0,0 +1,353 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "oneconnform.h" +#include "onelancform.h" +#include "hot-spot/dlghotspotcreate.h" +#include "wireless-security/dlgconnhidwifi.h" + +#define W_LEFT_AREA 16 +//#define W_VERTICAL_LINE 1 //左边竖线宽度 +#define W_RIGHT_AREA 438 //41 + 1 + 438 = 480 +#define L_VERTICAL_LINE_TO_ITEM 4 //竖线到item左侧的距离 + +#define X_LEFT_WIFI_BALL 416 //白色小球在左边 +#define X_RIGHT_WIFI_BALL 440 //白色小球在右边 +#define Y_WIFI_BALL 23 //白色小球y坐标 +#define X_ITEM 46 //item到窗口左侧的距离 41 + 1 + 4 = 46 +#define W_ITEM 424 + +#define Y_TOP_ITEM 100 //顶部item、topLanListWidget、topWifiListWidget的y坐标 +#define H_NORMAL_ITEM 56 +#define H_GAP_UP -5 +#define H_MIDDLE_WORD 46 //"显示‘可用网络列表’的label" +#define H_GAP_DOWN 5 //57 + 60 + 10 + 46 + 5 = 178 +#define X_MIDDLE_WORD 0 +#define W_MIDDLE_WORD 260 + +#define H_LAN_ITEM_EXTEND 102 //162 - 60 +#define H_WIFI_ITEM_BIG_EXTEND 90 //150 - 60 +#define H_WIFI_ITEM_SMALL_EXTEND 100 //156 - 56 + +#define Y_SCROLL_AREA 192//列表纵坐标 +#define W_SCROLL_AREA 414 +//#define H_SCROLL_AREA 200 +#define H_SCROLL_AREA H_NORMAL_ITEM*4 //平板中去掉了添加新网络按钮,设置为4倍的item,防止最后一栏被遮挡 + +#define W_TOP_LIST_WIDGET 435 +#define W_LIST_WIDGET 414 + +#define W_BTN_FUN 128 +#define H_BTN_FUN 24 + +#define X_BTN_FUN 36 +#define Y_BTN_FUN 400 //新建网络,加入网络按钮的宽高、x坐标、y坐标 + +#define W_NO_ITEM_TIP 220 +#define H_NO_ITEM_TIP 20 + +class OneConnForm; +class ConfForm; + +namespace Ui { +class KylinNM; +} + +class KylinNM : public QWidget +{ + Q_OBJECT + +public Q_SLOTS: + void onPhysicalCarrierChanged(bool flag); + void onCarrierUpHandle(); + void onCarrierDownHandle(); + void onDeleteLan(); + void onNetworkDeviceAdded(QDBusObjectPath objPath); + void onNetworkDeviceRemoved(QDBusObjectPath objPath); + void getLanBandWidth(); + + void onExternalConnectionChange(QString type); + void onExternalLanChange(); + void onExternalWifiChange(); + void onExternalWifiSwitchChange(bool wifiEnabled); + + void oneLanFormSelected(QString lanName, QString uniqueName); + void oneTopLanFormSelected(QString lanName, QString uniqueName); + void oneWifiFormSelected(QString wifiName, int extendLength); + void oneTopWifiFormSelected(QString wifiName, int extendLength); + + void on_btnHotspot_clicked(); + void on_btnHotspotState(); + + //flag =0或1为普通点击、2为收到打开信息、3为收到关闭信息、4为无线网卡插入、5为无线网卡拔出 + void onBtnWifiClicked(int flag = 0); + + void connLanDone(int connFlag); + void connWifiDone(int connFlag); + + void activeGetWifiList(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +public: + explicit KylinNM(QWidget *parent = 0); + ~KylinNM(); + + void onSwipeGesture(int dx, int dy); + void editQssString(); + void createTopLanUI(); + void createTopWifiUI(); + void createOtherUI(); + void createListAreaUI(); + void createLeftAreaUI(); + + void startLoading(); + void stopLoading(); + + void setTrayIcon(QIcon icon); + void setTrayLoading(bool isLoading); + void getActiveInfo(); + + void initTimer(); + void checkIsWirelessDeviceOn(); + void updateNetList(); + void updateWifiList(); + + int getConnectStatus();//获取网络连接状态,返回值 -1 无连接; 0 有线连接; 1无线连接; 2有线和无线都已连接 + + QIcon iconLanOnline, iconLanOffline; + QIcon iconWifiFull, iconWifiHigh, iconWifiMedium, iconWifiLow; + QIcon iconConnecting; + QList loadIcons; + QString mwBandWidth; + KylinDBus *objKyDBus = nullptr; + NetworkSpeed *objNetSpeed = nullptr; + SwitchButton *btnWireless; + + QStringList lanNameList; + + //状态设置,0为假,1为真 + int is_update_wifi_list = 0; //是否是update wifi列表,而不是load wifi列表 + int is_by_click_connect = 0; //是否是通过点击连接按钮进行的连接 + int is_btnNetList_clicked = 1; //是否处于有线网界面 + int is_btnWifiList_clicked = 0; //是否处于无线网界面 + int is_wired_line_ready = 1; //主机是否连接网线 + int is_wireless_adapter_ready = 1; //主机是否插入无线网卡 + int is_keep_wifi_turn_on_state = 1; //是否要执行wifi开关变为打开样式 + int is_stop_check_net_state = 0; //是否要在进行其他操作时停止检查网络状态 + int is_connect_wifi_failed = 0; //刚才是否连接wifi失败 + int is_fly_mode_on = 0; //是否已经打开飞行模式 + int is_hot_sopt_on = 0; //是否已经打开热点 + + QString currSelNetName = ""; //当前ScrollArea中选中的网络名称 + int currSelNetNum = 0; //当前选中的item序号 + + bool isTabletStyle=false;//YYF 平板桌面模式 + + static void reflashWifiUi(); + static bool m_is_reflashWifiUi; +private: + void tabletStyle();//YYF 平板桌面模式特有设置 + + void checkSingle(); + void initNetwork(); + void createTrayIcon(); + void handleIconClicked(); + void showTrayIconMenu(); + bool checkLanOn(); + bool checkWlOn(); + void getLanList(); + void getWifiList(); + void getInitLanSlist(); + + Ui::KylinNM *ui; + + LoadingDiv *loading = nullptr; + + QDesktopWidget desktop; + KSimpleNM *ksnm = nullptr; + ConfForm *confForm = nullptr; + QWidget *topLanListWidget = nullptr; + QWidget *topWifiListWidget = nullptr; + QWidget *lanListWidget = nullptr; + QWidget *wifiListWidget = nullptr; + QWidget *optWifiWidget = nullptr; + + QLabel *lbLoadDown = nullptr; + QLabel *lbLoadDownImg = nullptr; + QLabel *lbLoadUp = nullptr; + QLabel *lbLoadUpImg = nullptr; + + QLabel *lbNoItemTip = nullptr; + bool ifLanConnected; + bool ifWLanConnected; + + QScrollArea *scrollAreal = nullptr; + QScrollArea *scrollAreaw = nullptr; + QLabel *lbTopLanList = nullptr; + QLabel *lbTopWifiList = nullptr; + QLabel *lbLanList = nullptr; + QLabel *lbWifiList = nullptr; + QPushButton *btnAddNet = nullptr; + QPushButton *btnCreateNet = nullptr; + + QSystemTrayIcon *trayIcon = nullptr; + QMenu *trayIconMenu = nullptr; + QAction *mShowWindow = nullptr; + QAction *mAdvConf = nullptr; + QWidget *widShowWindow = nullptr; + QWidget *widAdvConf = nullptr; + + QString lname, wname; // 以太网卡和无线网卡名称 + + QString btnOffQss, btnOnQss, btnBgOffQss, btnBgOnQss, btnBgHoverQss, btnBgLeaveQss; // 主界面按钮底色 + QString scrollBarQss, leftBtnQss, funcBtnQss; + + QStringList oldLanSlist; //上一次获取Lan列表 + + QStringList oldWifiSlist; //上一次获取wifi列表 + + //平板 + QLabel *lbNetListText=nullptr;//有线网络 + QLabel *lbWifiListText=nullptr;//无线网络 + + + //循环检测网络连接状态 + QTimer *iconTimer = nullptr; + QTimer *wiredCableUpTimer = nullptr; + QTimer *wiredCableDownTimer = nullptr; + QTimer *deleteLanTimer = nullptr; + QTimer *checkWifiListChanged = nullptr; + QTimer *checkIfLanConnect = nullptr; + QTimer *checkIfWifiConnect = nullptr; + QTimer *checkIfNetworkOn = nullptr; + QTimer *setNetSpeed = nullptr; + + int currentIconIndex; + int activeWifiSignalLv; + + long int start_rcv_rates = 0; //保存开始时的流量计数 + long int end_rcv_rates = 0; //保存结束时的流量计数 + long int start_tx_rates = 0; //保存开始时的流量计数 + long int end_tx_rates = 0; //保存结束时的流量计数 + + QString actWifissid = "--";//当前连接wifi的ssid + QString actWifiuuid = "--";//当前连接wifi的uuid + QStringList actWifiBssidList; //当前连接wifi的bssid + +private Q_SLOTS: + void iconActivated(QSystemTrayIcon::ActivationReason reason); + + bool nativeEvent(const QByteArray &eventType, void *message, long *result); + + void on_btnNet_clicked(); + void on_btnWifiList_clicked(); + void onBtnNetListClicked(int flag=0); + + void getLanListDone(QStringList slist); + void getWifiListDone(QStringList slist); + void loadWifiListDone(QStringList slist); + void updateWifiListDone(QStringList slist); + + void on_showWindowAction(); + void on_btnAdvConf_clicked(); + void on_btnNetList_pressed(); + void on_btnWifiList_pressed(); + + void activeLanDisconn(); + void activeWifiDisconn(); + void activeStartLoading(); + void on_btnAdvConf_pressed(); + void on_btnAdvConf_released(); + void on_checkWifiListChanged(); + void on_setNetSpeed(); + void on_checkOverTime(); + + // 后台回调 + void enNetDone(); + void disNetDone(); + void enWifiDone(); + void launchLanDone(); + void disWifiDone(); + void disWifiStateKeep(); + void disWifiDoneChangeUI(); + + void iconStep(); + void on_btnFlyMode_clicked(); + + void onBtnAddNetClicked(); + void onBtnCreateNetClicked(); + +Q_SIGNALS: + void disConnSparedNet(QString type); + + void waitWifiStop(); + void waitLanStop(); + void onLineEditClicked(); + void onConnectChanged(); // 网络连接变化时发送该信号 +}; + +#endif diff --git a/KylinNM/src/kylinnm.ui b/KylinNM/src/kylinnm.ui new file mode 100644 index 0000000..a3aee92 --- /dev/null +++ b/KylinNM/src/kylinnm.ui @@ -0,0 +1,296 @@ + + + KylinNM + + + + 0 + 0 + 441 + 443 + + + + kylin-nm + + + + + 0 + 0 + 442 + 437 + + + + + + 1 + 200 + 37 + 37 + + + + + + + + + + 2 + 200 + 37 + 37 + + + + + + + + + + 385 + 73 + 50 + 24 + + + + + + + + + + 400 + 400 + 37 + 37 + + + + + + + + + + 2 + 348 + 37 + 37 + + + + + + + + + + 2 + 395 + 37 + 37 + + + + + + + + + + 16 + 72 + 171 + 20 + + + + + + + + + + 413 + 75 + 20 + 20 + + + + + + + + + + 11 + 359 + 19 + 19 + + + + + + + + + + 11 + 405 + 19 + 19 + + + + + + + + + + 0 + 0 + 37 + 37 + + + + + + + + + + 221 + 0 + 37 + 37 + + + + + + + + + + 63 + 17 + 24 + 24 + + + + + + + + + + 288 + 16 + 24 + 24 + + + + + + + + + + 2 + 348 + 37 + 37 + + + + + + + + + + 2 + 395 + 37 + 37 + + + + + + + + + + 0 + 0 + 221 + 56 + + + + + + + + + + 221 + 0 + 221 + 56 + + + + + + + + + + 409 + 409 + 19 + 19 + + + + + + + btnConfImg + lbFlyBG + lbHotBG + lbFlyImg + lbHotImg + lbBtnNetBG + btnNet + lbBtnWifiBG + btnAdvConf + btnHotspot + btnFlyMode + lbBtnWifiBall + lbNetListBG + lbWifiListBG + lbWifiListImg + lbNetListImg + btnNetList + btnWifiList + lbNetwork + + + + + + diff --git a/KylinNM/src/loadingdiv.cpp b/KylinNM/src/loadingdiv.cpp new file mode 100644 index 0000000..bf1b0c4 --- /dev/null +++ b/KylinNM/src/loadingdiv.cpp @@ -0,0 +1,75 @@ +/* + * 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 resize(480, 538); + + this->loadingGif = new QLabel(this); + this->loadingGif->resize(96, 96); + this->loadingGif->move(this->width()/2 - 96/2 + 41/2, this->height()/2 + 20); + this->loadingGif->show(); + + this->switchTimer = new QTimer(this); //QTimer对象,控制等待动画播放 + connect(switchTimer, SIGNAL(timeout()), this, SLOT(switchAnimStep())); + + this->raise(); + this->hide(); +} + +//加载动画控件'loadingGif' +void LoadingDiv::switchAnimStep() +{ + QString qpmQss = "QLabel{background-image:url(':/res/s/conning-b/"; + qpmQss.append(QString::number(this->currentPage)); + qpmQss.append(".png');}"); + loadingGif->setStyleSheet(qpmQss); + + this->currentPage --; + + if (this->currentPage < 1) { + this->currentPage = 12; //循环播放 + } + + this->countCurrentTime += FRAMESPEED; + if (this->countCurrentTime >= ALLTIME) { + emit this->toStopLoading(); //发出信号停止主界面和托盘区的等待动画 + } +} + +//开始播放动画 +void LoadingDiv::startLoading() +{ + this->currentPage = 12; + this->countCurrentTime = 0; + this->switchTimer->start(FRAMESPEED); + this->show(); +} + +//结束播放动画 +void LoadingDiv::stopLoading() +{ + this->switchTimer->stop(); + this->hide(); +} diff --git a/KylinNM/src/loadingdiv.h b/KylinNM/src/loadingdiv.h new file mode 100644 index 0000000..f8ee9e3 --- /dev/null +++ b/KylinNM/src/loadingdiv.h @@ -0,0 +1,51 @@ +/* + * 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 +#include +#include +#include +#include +#include + +class LoadingDiv : public QWidget +{ + Q_OBJECT +public: + explicit LoadingDiv(QWidget *parent = nullptr); + +Q_SIGNALS: + void toStopLoading(); + +public Q_SLOTS: + void switchAnimStep(); + void startLoading(); + void stopLoading(); + +private: + QLabel *loadingGif = nullptr; + QTimer *switchTimer = nullptr; + + int currentPage; + int countCurrentTime; +}; + +#endif // LOADINGDIV_H diff --git a/KylinNM/src/main.cpp b/KylinNM/src/main.cpp new file mode 100644 index 0000000..0929685 --- /dev/null +++ b/KylinNM/src/main.cpp @@ -0,0 +1,76 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#define LOG_IDENT "ukui_kylin_nm" + + +int main(int argc, char *argv[]) +{ + //QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + Display *disp = XOpenDisplay(NULL); + Screen *scrn = DefaultScreenOfDisplay(disp); + if (NULL == scrn) { + return 0; + } + int width = scrn->width; + + if (width > 2560) { + #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + #endif + } + if (NULL != disp) { + XCloseDisplay(disp); + } + + QApplication a(argc, argv); + + + openlog(LOG_IDENT, LOG_NDELAY | LOG_NOWAIT | LOG_PID, LOG_USER); + + syslog(LOG_DEBUG, "Kylin Network Manager Is Already Launched"); + + // Internationalization + QString locale = QLocale::system().name(); + QTranslator trans_global; + if (locale == "zh_CN") { + trans_global.load(":/translations/kylin-nm_zh_CN.qm"); + //trans_global.load(":/translations/kylin-nm_bo.qm"); + a.installTranslator(&trans_global); + } + if (locale == "tr_TR") { + trans_global.load(":/translations/kylin-nm_tr.qm"); + a.installTranslator(&trans_global); + } + + KylinNM w; + return a.exec(); +} diff --git a/KylinNM/src/oneconnform.cpp b/KylinNM/src/oneconnform.cpp new file mode 100644 index 0000000..9a82926 --- /dev/null +++ b/KylinNM/src/oneconnform.cpp @@ -0,0 +1,939 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +extern int currentActWifiSignalLv; + +OneConnForm::OneConnForm(QWidget *parent, KylinNM *mainWindow, ConfForm *confForm, KSimpleNM *ksnm) : + QWidget(parent), + ui(new Ui::OneConnForm) +{ + ui->setupUi(this); + + ui->btnConnSub->setText(tr("Connect"));//"设置" + ui->btnConn->setText(tr("Connect"));//"连接" + ui->btnConnPWD->setText(tr("Connect"));//"连接" + ui->btnDisConn->setText(tr("Disconnect"));//"断开连接" + ui->btnHideConn->setText(tr("Connect"));//"连接" + ui->lePassword->setPlaceholderText(tr("Input Password..."));//"输入密码..." + ui->lePassword->setContextMenuPolicy(Qt::NoContextMenu); + ui->lePassword->setTextMargins(0,0,20,0); + + ui->lbConned->setAlignment(Qt::AlignLeft); + ui->lePassword->setEchoMode(QLineEdit::Normal); + ui->btnConnPWD->setEnabled(false); + + leQssLow = "QLineEdit{border:none;background:transparent;font-size:14px;color:rgba(255,255,255,0.57);font-family:Noto Sans CJK SC;}"; + leQssHigh = "QLineEdit{border:none;background:transparent;font-size:14px;color:rgba(255,255,255,0.91);font-family:Noto Sans CJK SC;}"; + + ui->leInfo_1->setStyleSheet(leQssLow); + ui->leInfo_2->setStyleSheet(leQssLow); + ui->leInfo_3->setStyleSheet(leQssLow); + ui->leInfo_1->setEnabled(false); + ui->leInfo_2->setEnabled(false); + ui->leInfo_3->setEnabled(false); + ui->btnInfo->setStyleSheet("QPushButton{border:none;background:transparent;}"); + ui->wbg->setStyleSheet("#wbg{border-radius:8px;background-color:rgba(255,255,255,0);}"); + ui->wbg_2->setStyleSheet("#wbg_2{border-radius:8px;background-color:rgba(38, 38, 38, 0.1)}"); + ui->wbg_3->setStyleSheet("#wbg_3{border-radius:4px;background-color:rgba(255,255,255,0.1);}"); + ui->lbName->setStyleSheet("QLabel{font-size:14px;color:rgba(38,38,38,1);}"); + ui->lbConned->setStyleSheet("QLabel{font-size:14px;color:rgba(255,255,255,0.57);}"); + ui->lePassword->setStyleSheet("QLineEdit{border:2px solid rgba(47, 179, 232, 1);border-radius:4px;" + "background:rgba(255,255,255,1);color:rgba(38, 38, 38, 1);font-size:14px;}"); + ui->checkBoxPwd->setStyleSheet("QCheckBox::indicator {width: 18px; height: 9px;}" + "QCheckBox::indicator:checked {image: url(:/res/h/show-pwd.png);}" + "QCheckBox::indicator:unchecked {image: url(:/res/h/hide-pwd.png);}"); + ui->btnConnSub->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(61,107,229,1);color:white;font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(107,142,235,1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(50,87,202,1);}"); + ui->btnConn->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(61,107,229,1);color:white;font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(107,142,235,1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(50,87,202,1);}"); + ui->btnConnPWD->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(47, 179, 232, 1);color:rgba(255, 255, 255, 1);font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(70, 193, 243, 1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(27, 160, 213, 1);}" + "QPushButton:Disabled{border-radius:4px;background-color:rgba(168, 168, 168, 1)}"); + ui->btnDisConn->setStyleSheet("#btnDisConn{font-family: NotoSansCJKsc-Regular, NotoSansCJKsc;" + "font-weight: 400;color: rgba(38,38,38,0.75);line-height: 20px;font-size:14px;" + "border:0px;background-color:rgba(38,38,38,0.1);border-radius:8px;}" + "#btnDisConn:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:8px;background-color:rgba(38,38,38,0.2);}" + "#btnDisConn:Pressed{border-radius:8px;background-color:rgba(38,38,38,0.06);}");//断开链接按钮 + ui->btnInfo_2->setStyleSheet("border:0px;border-radius:8px;border-image:url(:/res/l/pb-network-info.png);"); + ui->btnHideConn->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(61,107,229,1);color:white;font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(107,142,235,1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(50,87,202,1);}"); + ui->lbWaiting->setStyleSheet("QLabel{border:0px;border-radius:10px;background-color:rgba(61,107,229,1);}"); + ui->lbWaitingIcon->setStyleSheet("QLabel{border:0px;background-color:transparent;}"); + ui->autoConn->setStyleSheet("QCheckBox::indicator {width: 16px; height: 16px;}" + "QCheckBox::indicator:checked {image: url(:/res/g/checkbox-checked.svg);}" + "QCheckBox::indicator:unchecked {image: url(:/res/g/checkbox-unchecked.svg);}"); + + ui->btnInfo->setCursor(QCursor(Qt::PointingHandCursor)); + ui->btnInfo->setFocusPolicy(Qt::NoFocus); + ui->checkBoxPwd->setFocusPolicy(Qt::NoFocus); + ui->btnConnSub->setFocusPolicy(Qt::NoFocus); + ui->btnConn->setFocusPolicy(Qt::NoFocus); + ui->btnConnPWD->setFocusPolicy(Qt::NoFocus); + ui->btnDisConn->setFocusPolicy(Qt::NoFocus); + ui->btnHideConn->setFocusPolicy(Qt::NoFocus); + + ui->wbg->show(); + ui->wbg_2->hide(); + ui->wbg_3->hide(); + ui->lbName->show(); + ui->leInfo_1->hide(); + ui->leInfo_2->hide(); + ui->leInfo_3->hide(); + ui->lePassword->hide(); + ui->checkBoxPwd->hide(); + ui->checkBoxPwd->setChecked(false); + ui->lePassword ->setEchoMode(QLineEdit::Password); + ui->btnConnSub->hide(); + ui->btnConn->hide(); + ui->btnDisConn->hide(); + ui->btnConnPWD->hide(); + ui->btnHideConn->hide(); + ui->line->show(); + ui->autoConn->hide(); + ui->lbWaiting->hide(); + ui->lbWaitingIcon->hide(); + ui->btnInfo->hide(); + + this->mw = mainWindow; + this->cf = confForm; + this->ks = ksnm; + + this->isSelected = false; + this->isActive = false; + + this->setAttribute(Qt::WA_Hover,true); + this->installEventFilter(this); + ui->lePassword->setAttribute(Qt::WA_Hover,true); + ui->lePassword->installEventFilter(this); + ui->btnInfo->setAttribute(Qt::WA_Hover,true); + ui->btnInfo->installEventFilter(this); + + //m_notify = new NotifySend(); + + connect(ui->lePassword, SIGNAL(returnPressed()), this, SLOT(on_btnConnPWD_clicked())); + ui->btnConn->setShortcut(Qt::Key_Return);//将字母区回车键与登录按钮绑定在一起 + + this->waitTimer = new QTimer(this); + connect(waitTimer, SIGNAL(timeout()), this, SLOT(waitAnimStep())); + + connect(mw, SIGNAL(waitWifiStop()), this, SLOT(stopWaiting())); + connect(ui->btnInfo_2,&QPushButton::clicked,this,&OneConnForm::on_btnInfo_2_clicked); + ui->btnInfo_2->hide(); + // connect(ui->autoConn,&QCheckBox::toggled,this,&OneConnForm::on_autoConn_toggled); + + ui->autoConn->setText(tr("Automatically join the network")); +// ui->autoConn->setText(tr("自动连接")); + + ui->lbWaitingIcon->move(316+194*mw->isTabletStyle,20);// YYF + tabletStyle();//平板模式PC桌面样式 +} + +void OneConnForm::tabletStyle()//平板桌面模式特有设置 +{ + this->setFixedWidth(414+194*mw->isTabletStyle); + ui->wbg->setFixedWidth(414+194*mw->isTabletStyle); + ui->wbg_2->setFixedWidth(414+194*mw->isTabletStyle); + ui->wbg_3->setFixedWidth(414+194*mw->isTabletStyle); + ui->lbName->setFixedWidth(190+194*mw->isTabletStyle); + ui->btnInfo->setFixedWidth(230+194*mw->isTabletStyle); + ui->leInfo_1->setFixedWidth(230+194*mw->isTabletStyle); + ui->leInfo_2->setFixedWidth(230+194*mw->isTabletStyle); + ui->leInfo_3->setFixedWidth(230+194*mw->isTabletStyle); + ui->lePassword->setFixedWidth(254+172*mw->isTabletStyle); + ui->checkBoxPwd->move(286+172*mw->isTabletStyle,75); + ui->btnConnPWD->move(318+172*mw->isTabletStyle,56); + ui->btnDisConn->move(316+194*mw->isTabletStyle,8 + 18*mw->isTabletStyle); + ui->btnInfo_2->move(364+194*mw->isTabletStyle,18); + ui->lbName->move(63,18); +} + +OneConnForm::~OneConnForm() +{ + delete ui; +} + +void OneConnForm::mousePressEvent(QMouseEvent *event) +{ + if (event->button() != Qt::LeftButton) { + event->ignore(); + return; + } + // emit selectedOneWifiForm(wifiName, H_WIFI_ITEM_BIG_EXTEND); + ui->wbg_2->setStyleSheet("#wbg_2{border-radius:8px;background-color:rgba(38,38,38,0.1);}"); +} + +void OneConnForm::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() != Qt::LeftButton || !rect().contains(event->pos())) { + event->ignore(); + return; + } + if(ui->lePassword->isVisible()){ + Q_EMIT selectedOneWifiForm(wifiName, H_WIFI_ITEM_BIG_EXTEND); + }else{ + if (!this->isTopItem) { + if (!is_connecting) { + toConnectWirelessNetwork(); + } + } + } + ui->wbg_2->setStyleSheet("#wbg_2{border-radius:8px;background-color:rgba(255,255,255,0);}"); +} + +//事件过滤器 +bool OneConnForm::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == ui->btnInfo) { + if (event->type() == QEvent::HoverEnter) { + ui->leInfo_1->setStyleSheet(leQssHigh); + ui->leInfo_2->setStyleSheet(leQssHigh); + ui->leInfo_3->setStyleSheet(leQssHigh); + return true; + } else if(event->type() == QEvent::HoverLeave) { + ui->leInfo_1->setStyleSheet(leQssLow); + ui->leInfo_2->setStyleSheet(leQssLow); + ui->leInfo_3->setStyleSheet(leQssLow); + return true; + } + } else if (obj == this) { + if(event->type() == QEvent::HoverEnter) { + if (!this->isTopItem) { + if (!this->isSelected) { + //ui->btnConn->show(); + ui->wbg->setStyleSheet("#wbg{border-radius:8px;background-color:rgba(38,38,38,0.05);}"); + ui->wbg->show(); + } + } + return true; + } else if (event->type() == QEvent::HoverLeave) { + ui->btnConn->hide(); + ui->wbg->setStyleSheet("#wbg{border-radius:8px;background-color:rgba(255,255,255,0);}"); + ui->wbg->hide(); + return true; + } + } + + if (obj == ui->lePassword) { + if (event->type() == QEvent::MouseButtonPress) { + Q_EMIT onLineEditClicked(); + } + } + + return QWidget::eventFilter(obj,event); +} + +void OneConnForm::on_autoConn_toggled(bool val) +{ +// kylin_network_set_autoconnect(wifiName.toLatin1().data(),val); +} + +// 是否当前连接的网络,字体设置不同 +void OneConnForm::setAct(bool isAct) +{ + if (isAct) { + ui->lbConned->hide(); + } else { + ui->lbConned->hide(); + } + ui->lbName->move(63,18); + isActive = isAct; +} + +//点击窗口最上面的item时 +void OneConnForm::setTopItem(bool isSelected) +{ + if (isSelected) { + resize(W_ITEM+194*mw->isTabletStyle, H_ITEM_BIG); + ui->wbg_3->show(); + ui->leInfo_1->show(); + ui->leInfo_2->show(); + ui->leInfo_3->show(); + + this->isSelected = true; + } else { + resize(W_ITEM+194*mw->isTabletStyle, H_ITEM); + ui->lePassword->setText(""); + ui->wbg_3->hide(); + ui->leInfo_1->hide(); + ui->leInfo_2->hide(); + ui->leInfo_3->hide(); + + + this->isSelected = false; + } + + ui->wbg->hide(); + ui->wbg_2->hide(); + ui->lbSignal->show(); + ui->lePassword->hide(); + ui->checkBoxPwd->hide(); + ui->line->hide(); + ui->btnConn->hide(); + ui->btnConnPWD->hide(); + ui->btnHideConn->hide(); + ui->btnInfo->show(); + + if (isConnected) { + if (this->isWaiting) { + ui->lbName->setStyleSheet("QLabel{font-size:14px;color:rgba(38,38,38,0.45);}"); + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/pb-top-wifi-offline.png);}"); + ui->btnDisConn->hide(); +// ui->btnInfo_2->hide(); + } else { + ui->lbName->setStyleSheet("QLabel{font-size:14px;color:rgba(47, 179, 232, 1);}"); + setSignalOn(signalStrong,signalHasPw); + ui->btnDisConn->show(); +// ui->btnInfo_2->show(); + } + ui->btnInfo_2->hide(); + } else { + ui->lbName->setStyleSheet("QLabel{font-size:14px;color:rgba(38,38,38,0.45);}"); + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/pb-top-wifi-offline.png);}"); + ui->btnDisConn->hide(); + ui->btnInfo_2->hide(); + } + + this->isTopItem = true; +} +// 点击窗口下面的item时 +void OneConnForm::setSelected(bool isSelected, bool isCurrName) +{ + if (isSelected) { + resize(W_ITEM+194*mw->isTabletStyle, H_ITEM_BIG); + ui->line->move(X_LINE_BIG_EXTEND, Y_LINE_BIG_EXTEND); + ui->wbg->hide(); + ui->wbg_2->hide(); + ui->wbg_3->show(); + ui->leInfo_1->show(); + ui->leInfo_2->show(); + ui->leInfo_3->show(); + ui->btnConn->hide(); + ui->btnConnSub->show(); + + this->isSelected = true; + } else { + resize(W_ITEM+194*mw->isTabletStyle, H_ITEM); + ui->lePassword->setStyleSheet("QLineEdit{border:2px solid rgba(47, 179, 232, 1);border-radius:4px;" + "background:rgba(255,255,255,1);color:rgba(38, 38, 38, 1);font-size:14px;}"); + + ui->line->move(X_LINE, Y_LINE); + ui->wbg->show(); + ui->wbg_2->hide(); + ui->wbg_3->hide(); + ui->leInfo_1->hide(); + ui->leInfo_2->hide(); + ui->leInfo_3->hide(); + + if (isCurrName) { + //ui->btnConn->show(); + } else { + ui->btnConn->hide(); + } + ui->btnConnSub->hide(); + + this->isSelected = false; + } + + ui->lePassword->hide(); + ui->checkBoxPwd->hide(); + ui->btnConnPWD->hide(); + ui->lbSignal->show(); + ui->btnDisConn->hide(); + ui->btnHideConn->hide(); + ui->btnInfo->hide(); + + this->isTopItem = false; +} +// 点击连接隐藏wifi的item时 +void OneConnForm::setHideItem(bool isHideItem, bool isShowHideBtn) +{ + if (isHideItem) { + ui->lbName->move(14, 30); + ui->wbg->hide(); + ui->btnConn->hide(); + } else { + ui->lbName->move(62, 18); + ui->wbg->show(); + //ui->btnConn->show(); + } + + if (isShowHideBtn) { + ui->btnHideConn->show(); + } else{ + ui->btnHideConn->hide(); + } +} + +void OneConnForm::setConnedString(bool showLable, QString str, QString str1) +{ + if (!showLable) { + ui->lbConned->setText(str1); + ui->lbConned->hide(); + } else { + ui->lbConned->setText(str); + } + ui->lbName->move(63, 18); +} + +void OneConnForm::setName(QString name) +{ + ui->lbName->setText(name); + wifiName = name; +} +void OneConnForm::setSpecialName(QString name) +{ + ui->lbName->setText(tr("Connect to Hidden Wi-Fi Network")); //连接到隐藏的 Wi-Fi 网络 + wifiName = name; +} + +QString OneConnForm::getName() +{ + return ui->lbName->text(); +} + +void OneConnForm::setRate(QString rate) +{ +// QString txt(tr("Rate"));//"速率" +// this->setToolTip("  " + txt + ": " + rate + "  "); +// this->setToolTip(txt + ":" + rate); +} + +void OneConnForm::setLine(bool isShow) +{ + if (isShow) { + ui->line->show(); + } else { + ui->line->hide(); + } +} + +void OneConnForm::setSignalOn(QString lv, QString secu) +{ + + int signal = lv.toInt(); + if (secu == "--" || secu == "") { + hasPwd = false; + } else { + hasPwd = true; + } + + if (signal > 75) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-full-pwd.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-full.png);}"); + } + signalLv = 1; + } + if (signal > 55 && signal <= 75) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-high-pwd.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-high.png);}"); + } + signalLv = 2; + } + if (signal > 35 && signal <= 55) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-medium-pwd.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-medium.png);}"); + } + signalLv = 3; + } + if (signal > 15 && signal <= 35) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-low-pwd.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-low.png);}"); + } + signalLv = 4; + } + if (signal <= 15) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-none-pwd.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-none.png);}"); + } + signalLv = 4; + } +} + +void OneConnForm::setSignal(QString lv, QString secu) +{ + signalStrong=lv; + signalHasPw=secu; + + int signal = lv.toInt(); + if (secu == "--" || secu == "") { + hasPwd = false; + } else { + hasPwd = true; + } + + if (signal > 75) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-full-pwd-off.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-full-off.png);}"); + } + signalLv = 1; + } + if (signal > 55 && signal <= 75) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-high-pwd-off.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-high-off.png);}"); + } + signalLv = 2; + } + if (signal > 35 && signal <= 55) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-medium-pwd-off.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-medium-off.png);}"); + } + signalLv = 3; + } + if (signal > 15 && signal <= 35) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-low-pwd-off.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-low-off.png);}"); + } + signalLv = 4; + } + if (signal <= 15) { + if (hasPwd) { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-none-pwd-off.png);}"); + } else { + ui->lbSignal->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/w/wifi-none-off.png);}"); + } + signalLv = 4; + } +} + +void OneConnForm::setWifiInfo(QString str1, QString str2, QString str3) +{ + if (str1 == "--" || str1 == ""){ str1 = tr("None"); }; + + QString strSecurity = QString(tr("WiFi Security:")); + QString strSignal = QString(tr("Signal:")); + QString strMAC = QString(tr("MAC:")); + + ui->leInfo_1->setText(strSecurity + str1); + ui->leInfo_2->setText(strSignal + str2); + ui->leInfo_3->setText(strMAC + str3); +} + +void OneConnForm::slotConnWifi() +{ + //mw->startLoading(); + this->startWaiting(true); + emit sigConnWifi(ui->lbName->text()); +} +void OneConnForm::slotConnWifiPWD() +{ + //mw->startLoading(); + this->startWaiting(true); + emit sigConnWifiPWD(ui->lbName->text(), ui->lePassword->text()); +} + +//点击后断开wifi网络 +void OneConnForm::on_btnDisConn_clicked() +{ + syslog(LOG_DEBUG, "DisConnect button about wifi net is clicked, current wifi name is %s .", ui->lbName->text().toUtf8().data()); + qDebug()<<"DisConnect button about wifi net is clicked, current wifi name is "<lbName->text(); + + this->startWaiting(false); + + mw->is_stop_check_net_state = 1; + mw->on_btnHotspotState(); + QString name = ui->lbName->text(); + kylin_network_set_con_down(name.replace("\"","\\\"").toUtf8().data()); + disconnect(this, SIGNAL(selectedOneWifiForm(QString,int)), mw, SLOT(oneWifiFormSelected(QString,int))); + emit disconnActiveWifi(); +} + +//点击列表item扩展时会出现该按钮 用于连接网络 +void OneConnForm::on_btnConnSub_clicked() +{ + syslog(LOG_DEBUG, "A button named on_btnConnSub about wifi net is clicked."); + qDebug()<<"A button named on_btnConnSub about wifi net is clicked."; + toConnectWirelessNetwork(); +} + +//无需密码的wifi连接 +void OneConnForm::on_btnConn_clicked() +{ +// syslog(LOG_DEBUG, "A button named btnConn about wifi net is clicked."); +// qDebug()<<"A button named btnConn about wifi net is clicked."; +// toConnectWirelessNetwork(); + on_btnInfo_clicked(); +} + +void OneConnForm::toConnectWirelessNetwork() +{ + if (ui->lbConned->text() == "--" || ui->lbConned->text() == " ") { + if (!isWifiConfExist(ui->lbName->text())) { + //没有配置文件,使用有密码的wifi连接 + on_btnConnPWD_clicked(); + return; + } + } + + mw->is_stop_check_net_state = 1; + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + bt->moveToThread(t); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), this, SLOT(slotConnWifi())); + connect(this, SIGNAL(sigConnWifi(QString)), bt, SLOT(execConnWifi(QString))); + connect(bt, &BackThread::connDone, this,[=](int t) { + mw->connWifiDone(t); + }); + connect(bt, SIGNAL(connDone(int)), this, SLOT(slotConnWifiResult(int))); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + t->start(); + is_connecting = true; +} + +//需要密码的wifi连接 +void OneConnForm::on_btnConnPWD_clicked() +{ + syslog(LOG_DEBUG, "A button named btnConnPWD about wifi net is clicked."); + qDebug()<<"A button named btnConnPWD about wifi net is clicked."; + + ui->btnConnPWD->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(47, 179, 232, 1);color:white;font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(70, 193, 243, 1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(27,160,213,1);}" + "QPushButton:Disabled{border-radius:4px;background-color:#BEBEBE;}"); + ui->btnConnPWD->setEnabled(false); + + //调用kylinnm的接口,屏蔽输错密码框后弹出提示框 + QDBusInterface interface("com.kylin.network", + "/com/kylin/network", + "com.kylin.network", + QDBusConnection::sessionBus()); + QDBusMessage result = interface.call("keyRingClear"); + + mw->is_stop_check_net_state = 1; + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + bt->moveToThread(t); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), this, SLOT(slotConnWifiPWD())); + connect(this, SIGNAL(sigConnWifiPWD(QString, QString)), bt, SLOT(execConnWifiPWD(QString, QString))); + connect(bt, SIGNAL(connDone(int)), mw, SLOT(connWifiDone(int))); + connect(bt, SIGNAL(connDone(int)), this, SLOT(slotConnWifiResult(int))); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + ui->lePassword->setEnabled(false); + t->start(); +} + +//点击后弹出连接隐藏wifi网络窗口 +void OneConnForm::on_btnHideConn_clicked() +{ +// QApplication::setQuitOnLastWindowClosed(false); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, mw, this->parentWidget()); + connect(connHidWifi, SIGNAL(reSetWifiList() ), mw, SLOT(on_btnWifiList_clicked()) ); + connHidWifi->show(); +} + +bool OneConnForm::isWifiConfExist(QString netName) +{ + //dbusWifiMac = ""; //这个函数之前是用来获取已经连接的wifi的MAC地址 + + QDBusInterface m_interface("org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager/Settings", + "org.freedesktop.NetworkManager.Settings", + QDBusConnection::systemBus() ); + QDBusReply> m_reply = m_interface.call("ListConnections"); + + QList m_objNets = m_reply.value(); + foreach (QDBusObjectPath objNet, m_objNets){ + QDBusInterface m_interface("org.freedesktop.NetworkManager", + objNet.path(), + "org.freedesktop.NetworkManager.Settings.Connection", + QDBusConnection::systemBus()); + QDBusMessage reply = m_interface.call("GetSettings"); + const QDBusArgument &dbusArg = reply.arguments().at( 0 ).value(); + QMap> map; + dbusArg >> map; + + for(QString key : map.keys() ){ + QMap innerMap = map.value(key); + if (key == "connection") { + for (QString inner_key : innerMap.keys()) { + if (inner_key == "id"){ + if (netName == innerMap.value(inner_key).toString()) { + return true; + } + } + } + } + } + + } // end foreach (QDBusObjectPath objNet, m_objNets) + + return false; +} + +//设置密码隐藏或可见 +void OneConnForm::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword ->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void OneConnForm::on_lePassword_textEdited(const QString &arg1) +{ + ui->lePassword->setStyleSheet("QLineEdit{border:2px solid rgba(47, 179, 232, 1);border-radius:4px;" + "background:rgba(255,255,255,1);color:rgba(38, 38, 38, 1);font-size:14px;}"); + + if (ui->lePassword->text().size() < 8){ + ui->btnConnPWD->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(47, 179, 232, 1);color:white;font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(70, 193, 243, 1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(27,160,213,1);}" + "QPushButton:Disabled{border-radius:4px;background-color:rgba(168, 168, 168, 1)}"); + ui->btnConnPWD->setEnabled(false);//连接时设置为不可点击 + if (ui->lePassword->text().size() == 0){ + ui->lePassword->setStyleSheet("QLineEdit{border:2px solid rgba(47, 179, 232, 1);border-radius:4px;" + "background:rgba(255,255,255,1);color:red;font-size:14px;}"); + } + } else { + ui->btnConnPWD->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(47, 179, 232, 1);color:white;font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(70,193,243,1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(27,160,213,1);}"); + ui->btnConnPWD->setEnabled(true); + } +} + +void OneConnForm::on_btnInfo_2_clicked(){ + on_btnInfo_clicked(); +} + +void OneConnForm::on_btnInfo_clicked() +{ + QPoint pos = QCursor::pos(); + QRect primaryGeometry; + for (QScreen *screen : qApp->screens()) { + if (screen->geometry().contains(pos)) { + primaryGeometry = screen->geometry(); + } + } + + if (primaryGeometry.isEmpty()) { + primaryGeometry = qApp->primaryScreen()->geometry(); + } + + BackThread *bt = new BackThread(); + QString connProp = bt->getConnProp(ui->lbName->text()); + QStringList propList = connProp.split("|"); + QString v4method, addr, mask, gateway, dns; + foreach (QString line, propList) { + if (line.startsWith("method:")) { + v4method = line.split(":").at(1); + } + if (line.startsWith("addr:")) { + addr = line.split(":").at(1); + } + if (line.startsWith("mask:")) { + mask = line.split(":").at(1); + } + if (line.startsWith("gateway:")) { + gateway= line.split(":").at(1); + } + if (line.startsWith("dns:")) { + dns = line.split(":").at(1); + } + } + // qDebug()<<"v4method:"<setProp(ui->lbName->text(), v4method, addr, mask, gateway, dns, this->isActive); + + cf->move(primaryGeometry.width() / 2 - cf->width() / 2, primaryGeometry.height() / 2 - cf->height() / 2); + cf->show(); + cf->raise(); + + bt->deleteLater(); +} + +// Wifi连接结果,0成功 1失败 2没有配置文件 +void OneConnForm::slotConnWifiResult(int connFlag) +{ + mw->connWifiDone(connFlag); + qDebug()<<"Function slotConnWifiResult receives a number: "<currSelNetName = ""; + emit selectedOneWifiForm(ui->lbName->text(), H_WIFI_ITEM_SMALL_EXTEND); + + resize(W_ITEM, H_ITEM_MIDDLE); + ui->wbg->hide(); + ui->wbg_2->show(); + ui->wbg_3->hide(); + ui->leInfo_1->hide(); + ui->leInfo_2->hide(); + ui->leInfo_3->hide(); + ui->btnHideConn->hide(); + ui->btnDisConn->hide(); + ui->btnConn->hide(); + ui->btnConnSub->hide(); + // ui->line->move(X_LINE_SMALL_EXTEND, Y_LINE_SMALL_EXTEND); + + ui->lePassword->show(); + ui->lePassword->setFocus(); + Q_EMIT onLineEditClicked(); + ui->checkBoxPwd->show(); + ui->btnConnPWD->show(); + ui->autoConn->show(); + ui->autoConn->setChecked(true); + this->isSelected = true; + } + + if (connFlag == 1) { + // 使用配置文件连接失败,需要删除该配置文件 + QString txt(tr("Conn Wifi Failed"));//"连接 Wifi 失败" + syslog(LOG_DEBUG, "Try to connect wifi named %s, but failed, will delete it's configuration file", ui->lbName->text().toUtf8().data()); + + //YYF 20200922 +// ui->lePassword->setText(""); + + KylinDBus kylindbus; + kylindbus.showDesktopNotify(txt); + //QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli connection delete '" + ui->lbName->text() + "';notify-send '" + txt + "...' -t 3800"; + QString name = ui->lbName->text(); + QString cmd = "export LANG='en_US.UTF-8';export LANGUAGE='en_US';nmcli connection delete \"" + name.replace("\"","\\\"") + "\""; + int status = system(cmd.toUtf8().data()); + if (status != 0) { + syslog(LOG_ERR, "execute 'nmcli connection delete' in function 'slotConnWifiResult' failed"); + } +// ui->btnConnPWD->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(47, 179, 232, 1);color:white;font-size:14px;}" +// "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(70,193,243,1);}" +// "QPushButton:Pressed{border-radius:4px;background-color:rgba(27,160,213,1);}"); +// ui->btnConnPWD->setEnabled(true); + ui->lePassword->setEnabled(true); + ui->lePassword->setFocus(); + Q_EMIT onLineEditClicked(); + ui->lePassword->selectAll(); + ui->lePassword->setStyleSheet("QLineEdit{border:2px solid rgba(255, 0, 0, 0.5);border-radius:4px;" + "background:palette(base);color:rgba(38, 38, 38, 1);font-size:14px;" + "selection-background-color: rgba(255, 0, 0, 0.5);}"); + } + if (connFlag == 0){ + //连接成功,配置是否自启动 + //若含中文的QString直接转换,会出现乱码,使用如下转换方式解决此问题(必须分两句转换) + QString wifi_name = wifiName; + wifi_name.replace("\"","\\\""); + QByteArray ba = wifi_name.toLocal8Bit(); + char *name = ba.data(); + if (ui->autoConn->isVisible()) { + //仅当首次连接配置时执行此操作 + kylin_network_set_autoconnect(name,ui->autoConn->isChecked()); + } + } + // 设置全局变量,当前连接Wifi的信号强度 + currentActWifiSignalLv = signalLv; + + this->stopWaiting(); + is_connecting = false; + //if (connFlag != 0){ + // mw->stopLoading(); + //} +} + +void OneConnForm::waitAnimStep() +{ + //YYF 平板模式设计稿中没有此图标 +// QString qpmQss = "QLabel{background-image:url(':/res/s/conning-a/"; +// qpmQss.append(QString::number(this->waitPage)); +// qpmQss.append(".png');}"); +// ui->lbWaitingIcon->setStyleSheet(qpmQss); + +// this->waitPage --; +// if (this->waitPage < 1) { +// this->waitPage = TOTAL_PAGE; //循环播放8张图片 +// } + +// this->countCurrentTime += FRAME_SPEED; +// if (this->countCurrentTime >= LIMIT_TIME) { +// QString cmd = "kill -9 $(pidof nmcli)"; //杀掉当前正在进行的有关nmcli命令的进程 +// int status = system(cmd.toUtf8().data()); +// if (status != 0) { +// qDebug()<<"execute 'kill -9 $(pidof nmcli)' in function 'waitAnimStep' failed"; +// syslog(LOG_ERR, "execute 'kill -9 $(pidof nmcli)' in function 'waitAnimStep' failed"); +// } + +// this->stopWaiting(); //动画超出时间限制,强制停止动画 + +// mw->is_stop_check_net_state = 0; +// } +} + +void OneConnForm::startWaiting(bool isConn) +{ + //YYF 平板模式设计稿中没有此图标 +// this->isWaiting = true; +// if (isConn) { +// ui->lbWaiting->setStyleSheet("QLabel{border:0px;border-radius:10px;background-color:rgba(61,107,229,1);}"); +// } else { +// ui->btnDisConn->hide(); +// ui->lbWaiting->setStyleSheet("QLabel{border:0px;border-radius:10px;background-color:rgba(255,255,255,0.12);}"); +// } +// this->countCurrentTime = 0; +// this->waitPage = TOTAL_PAGE; //总共有8张图片 +// this->waitTimer->start(FRAME_SPEED); +// ui->lbWaiting->show(); +// ui->lbWaitingIcon->show(); + +// mw->setTrayLoading(true); +} + +void OneConnForm::stopWaiting() +{ + //YYF 平板模式设计稿中没有此图标 +// this->isWaiting = false; +// this->waitTimer->stop(); +// ui->lbWaiting->hide(); +// ui->lbWaitingIcon->hide(); + +// mw->setTrayLoading(false); +// mw->getActiveInfo(); +} diff --git a/KylinNM/src/oneconnform.h b/KylinNM/src/oneconnform.h new file mode 100644 index 0000000..70bbbd8 --- /dev/null +++ b/KylinNM/src/oneconnform.h @@ -0,0 +1,151 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include "confform.h" +#include "backthread.h" +#include "ksimplenm.h" + +#define FRAME_SPEED 150 +#define LIMIT_TIME 20*1000 +#define TOTAL_PAGE 8 + +#define W_ITEM 414 +#define H_ITEM 60 +#define H_ITEM_BIG 138 +#define H_ITEM_MIDDLE 156 +#define H_WIFI_ITEM_BIG_EXTEND 78 //138 - 60 +#define H_WIFI_ITEM_SMALL_EXTEND 96 //156 - 56 +#define Y_LINE 59 +#define X_LINE 2 +#define Y_LINE_SMALL_EXTEND 105 +#define X_LINE_SMALL_EXTEND 2 +#define Y_LINE_BIG_EXTEND 137 +#define X_LINE_BIG_EXTEND 2 + +class KylinNM; + +namespace Ui { +class OneConnForm; +} + +class OneConnForm : public QWidget +{ + Q_OBJECT + +public: + explicit OneConnForm(QWidget *parent = 0, KylinNM *mw = 0, ConfForm *confForm = 0, KSimpleNM *ksnm = 0); + ~OneConnForm(); + + void setSignal(QString lv, QString secu); + void setSignalOn(QString lv, QString secu); + void setName(QString name); + void setSpecialName(QString name); + QString getName(); + void setRate(QString rate); + void setLine(bool isShow); + void setWifiInfo(QString str1, QString str2, QString str3); + + void setSelected(bool isSelected, bool isCurrName); + void setHideItem(bool isHideItem, bool isShowHideBtn); + void setTopItem(bool isSelected); + void setAct(bool isAct); + + void setConnedString(bool showLable, QString str, QString str1); + + bool isWifiConfExist(QString netName); + + QString wifiName; + bool isSelected; + bool isActive; + bool isConnected; + bool isTopItem; + int signalLv; + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event); + +private Q_SLOTS: + void tabletStyle(); + void on_btnConn_clicked(); + void on_btnConnSub_clicked(); + void on_btnDisConn_clicked(); + void on_btnInfo_2_clicked(); + void toConnectWirelessNetwork(); + void on_autoConn_toggled(bool val); + + void slotConnWifi(); + void slotConnWifiPWD(); + void slotConnWifiResult(int connFlag); + + void on_btnConnPWD_clicked(); + + void on_btnHideConn_clicked(); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_lePassword_textEdited(const QString &arg1); + + void waitAnimStep(); + void startWaiting(bool isConn); + void stopWaiting(); + + void on_btnInfo_clicked(); + +private: + QTimer *waitTimer = nullptr; + int waitPage; + int countCurrentTime; + bool isWaiting = false; + + Ui::OneConnForm *ui = nullptr; + KylinNM *mw = nullptr; + ConfForm *cf = nullptr; + KSimpleNM *ks = nullptr; + bool hasPwd; + + QString leQssLow, leQssHigh; + + QString signalStrong="0"; + QString signalHasPw="--"; + bool is_connecting = false; + +Q_SIGNALS: + void selectedOneWifiForm(QString wifiName, int extendLength); + void connDone(int connFlag); + void disconnActiveWifi(); + + void sigConnWifi(QString); + void sigConnWifiPWD(QString, QString); + + void onLineEditClicked(); +}; + +#endif // ONECONNFORM_H diff --git a/KylinNM/src/oneconnform.ui b/KylinNM/src/oneconnform.ui new file mode 100644 index 0000000..77e347e --- /dev/null +++ b/KylinNM/src/oneconnform.ui @@ -0,0 +1,306 @@ + + + OneConnForm + + + + 0 + 0 + 424 + 156 + + + + Form + + + + + 63 + 8 + 190 + 20 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 14 + 14 + 28 + 28 + + + + + + + + + + 63 + 31 + 140 + 20 + + + + + + + + + + 0 + 0 + 424 + 156 + + + + + + 56 + 56 + 254 + 48 + + + + + + + 286 + 75 + 16 + 8 + + + + + + + + + + 56 + 110 + 414 + 40 + + + + + + + + + + + 326 + 14 + 80 + 40 + + + + + + + + + + 318 + 56 + 80 + 48 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 0 + 0 + 424 + 138 + + + + + + 63 + 64 + 230 + 56 + + + + + + + + + + 63 + 62 + 230 + 20 + + + + + + + 63 + 86 + 230 + 20 + + + + + + + 63 + 110 + 230 + 20 + + + + leInfo_1 + leInfo_2 + leInfo_3 + btnInfo + + + + + 2 + 59 + 421 + 2 + + + + background-color: rgba(255, 255, 255,0.05); + + + Qt::Horizontal + + + + + + 0 + 0 + 414 + 56 + + + + + + + 280 + 20 + 20 + 20 + + + + + + + + + + 280 + 20 + 20 + 20 + + + + + + + + + + 372 + 14 + 16 + 16 + + + + + + + wbg_3 + wbg_2 + lbName + lbSignal + lbConned + line + wbg + btnConnSub + btnConn + btnConnPWD + btnDisConn + btnHideConn + lbWaiting + lbWaitingIcon + btnInfo_2 + + + + diff --git a/KylinNM/src/onelancform.cpp b/KylinNM/src/onelancform.cpp new file mode 100644 index 0000000..b297910 --- /dev/null +++ b/KylinNM/src/onelancform.cpp @@ -0,0 +1,482 @@ +/* + * 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 + +OneLancForm::OneLancForm(QWidget *parent, KylinNM *mainWindow, ConfForm *confForm, KSimpleNM *ksnm) : + QWidget(parent), + ui(new Ui::OneLancForm) +{ + ui->setupUi(this); + + ui->btnConnSub->setText(tr("Connect"));//"设置" + ui->btnConn->setText(tr("Connect"));//"连接" + ui->btnConn->hide();//YYF + ui->btnDisConn->setText(tr("Disconnect"));//"断开连接" + + ui->lbConned->setAlignment(Qt::AlignLeft); + + leQssLow = "QLineEdit{border:none;background:transparent;font-size:14px;color:rgba(255,255,255,0.57);font-family:Noto Sans CJK SC;}"; + leQssHigh = "QLineEdit{border:none;background:transparent;font-size:14px;color:rgba(255,255,255,0.91);font-family:Noto Sans CJK SC;}"; + + ui->leInfo_1->setStyleSheet(leQssLow); + ui->leInfo_2->setStyleSheet(leQssLow); + ui->leInfo_3->setStyleSheet(leQssLow); + ui->leInfo_4->setStyleSheet(leQssLow); + ui->btnInfo->setStyleSheet("QPushButton{border:none;background:transparent;}"); + ui->wbg->setStyleSheet("#wbg{border-radius:8px;background-color:rgba(255,255,255,0.1);border:1px solid red;}");//主窗口(展开) + ui->wbg_2->setStyleSheet("#wbg_2{border-radius:8px;background-color:rgba(255,255,255,0);}");//列表窗口(闭合) + ui->lbName->setStyleSheet("QLabel{font-size:14px;color:rgba(38, 38, 38, 1);}");//列表名称 + ui->lbConned->setStyleSheet("QLabel{font-size:14px;color:rgba(47, 179, 232, 1);}");//已连接 + ui->btnConnSub->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(61,107,229,1);color:white;font-size:14px;}" + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(107,142,235,1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(50,87,202,1);}"); + ui->btnConn->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(61,107,229,1);color:white;font-size:14px;}" //连接按钮 + "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(107,142,235,1);}" + "QPushButton:Pressed{border-radius:4px;background-color:rgba(50,87,202,1);}"); +// ui->btnDisConn->setStyleSheet("QPushButton{border:0px;border-radius:4px;background-color:rgba(255,255,255,0.12);color:white;font-size:14px;}" +// "QPushButton:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:4px;background-color:rgba(255,255,255,0.2);}" +// "QPushButton:Pressed{border-radius:8px;background-color:rgba(255,255,255,0.08);}"); + ui->btnDisConn->setStyleSheet("#btnDisConn{font-family: NotoSansCJKsc-Regular, NotoSansCJKsc;" + "font-weight: 400;color: rgba(38,38,38,0.75);line-height: 20px;font-size:14px;" + "border:0px;background-color:rgba(38,38,38,0.1);border-radius:8px;}" + "#btnDisConn:Hover{border:0px solid rgba(255,255,255,0.2);border-radius:8px;background-color:rgba(38,38,38,0.2);}" + "#btnDisConn:Pressed{border-radius:8px;background-color:rgba(38,38,38,0.06);}");//断开链接按钮 + ui->btnConnCfg->setStyleSheet("border:0px;border-radius:4px;border-image:url(:/res/l/pb-network-info.png);");//链接详情按钮 + connect(ui->btnConnCfg,&QPushButton::clicked,this,&OneLancForm::on_btnInfo_clicked); + ui->btnConnCfg->hide(); + + + ui->btnInfo->setCursor(QCursor(Qt::PointingHandCursor)); + ui->btnInfo->setFocusPolicy(Qt::NoFocus); + ui->btnConnSub->setFocusPolicy(Qt::NoFocus); + ui->btnConn->setFocusPolicy(Qt::NoFocus); + ui->btnDisConn->setFocusPolicy(Qt::NoFocus); + + ui->wbg->hide(); + ui->wbg_2->show(); + ui->lbName->show(); + ui->btnConnSub->hide(); + //YYF ui->btnConn->hide(); + ui->btnDisConn->hide(); + ui->line->show(); + ui->lbWaiting->hide(); + ui->lbWaitingIcon->hide(); + + this->mw = mainWindow; + this->cf = confForm; + this->ks = ksnm; + + this->isSelected = false; + this->isActive = false; + + this->setAttribute(Qt::WA_Hover,true); + this->installEventFilter(this); + ui->btnInfo->setAttribute(Qt::WA_Hover,true); + ui->btnInfo->installEventFilter(this); + + this->waitTimer = new QTimer(this); + connect(waitTimer, SIGNAL(timeout()), this, SLOT(waitAnimStep())); + + connect(mw, SIGNAL(waitLanStop()), this, SLOT(stopWaiting())); + + srand((unsigned)time(NULL)); + + ui->lbWaiting->setStyleSheet("QLabel{border:0px;border-radius:4px;background-color:rgba(61,107,229,1);}"); + //ui->lbWaitingIcon->setStyleSheet("QLabel{border:0px;background-color:transparent;}"); + ui->lbWaitingIcon->setStyleSheet("QLabel{border:0px;background-color:transparent;}"); + ui->lbWaitingIcon->move(316+194*mw->isTabletStyle,20);// YYF + tabletStyle();//平板模式PC桌面样式 +} + +void OneLancForm::tabletStyle()//平板桌面模式特有设置 +{ + ui->lbName->setFixedWidth(190+194*mw->isTabletStyle); + ui->btnInfo->setFixedWidth(414+194*mw->isTabletStyle); + ui->wbg_2->setFixedWidth(414+194*mw->isTabletStyle); + ui->btnDisConn->move(316+194*mw->isTabletStyle,8 + 18*mw->isTabletStyle); + ui->btnConnCfg->move(364+194*mw->isTabletStyle,18 + 18*mw->isTabletStyle); +} + +OneLancForm::~OneLancForm() +{ + delete ui; +} + +void OneLancForm::mousePressEvent(QMouseEvent *event) +{ + if (event->button() != Qt::LeftButton) { + event->ignore(); + return; + } + ui->wbg_2->setStyleSheet("#wbg_2{border-radius:8px;background-color:rgba(38,38,38,0.1);}"); +} + +void OneLancForm::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() != Qt::LeftButton || !rect().contains(event->pos())) { + event->ignore(); + return; + } + if(ui->btnDisConn->isHidden()) { + on_btnConn_clicked();// YYF + } + ui->wbg_2->setStyleSheet("#wbg_2{border-radius:8px;background-color:rgba(255,255,255,0);}"); +} + +//事件过滤器 +bool OneLancForm::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == ui->btnInfo) { + if(event->type() == QEvent::HoverEnter) { + ui->leInfo_1->setStyleSheet(leQssHigh); + ui->leInfo_2->setStyleSheet(leQssHigh); + ui->leInfo_3->setStyleSheet(leQssHigh); + ui->leInfo_4->setStyleSheet(leQssHigh); + return true; + } else if(event->type() == QEvent::HoverLeave) { + ui->leInfo_1->setStyleSheet(leQssLow); + ui->leInfo_2->setStyleSheet(leQssLow); + ui->leInfo_3->setStyleSheet(leQssLow); + ui->leInfo_4->setStyleSheet(leQssLow); + return true; + } + } else if (obj == this) { + if (event->type() == QEvent::HoverEnter) { + if (!this->isTopItem) { + if (!this->isSelected) { + //YYF ui->btnConn->show(); + ui->wbg_2->setStyleSheet("#wbg_2{border-radius:8px;background-color:rgba(38,38,38,0.05);}"); + ui->wbg_2->show(); + } + } + return true; + } else if(event->type() == QEvent::HoverLeave) { + //YYF ui->btnConn->hide(); + ui->wbg_2->setStyleSheet("#wbg_2{border-radius:8px;background-color:rgba(255,255,255,0);}"); + ui->wbg_2->hide(); + return true; + } + } + + return QWidget::eventFilter(obj,event); +} + +// 是否当前连接的网络,字体设置不同 +void OneLancForm::setAct(bool isAct) +{ + if (isAct) { + ui->lbName->setStyleSheet("QLabel{font-size:14px;color:rgba(47, 179, 232, 1);}"); + ui->lbConned->show(); + ui->btnConnSub->hide(); + } else { + ui->lbName->setStyleSheet("QLabel{font-size:14px;color:rgba(38, 38, 38, 0.45);}"); + ui->lbConned->hide(); + ui->btnConnSub->hide(); + } + isActive = isAct; +} + +// 是否选中 +void OneLancForm::setSelected(bool isSelected, bool isCurrName) +{ + if (isSelected) { + resize(W_ITEM, H_ITEM_EXTEND); + ui->wbg->show(); + ui->wbg_2->hide(); + ui->line->move(X_LINE_EXTEND, Y_LINE_EXTEND); + //YYF ui->btnConn->hide(); + ui->btnConnSub->show(); + + this->isSelected = true; + } else { + resize(W_ITEM, H_ITEM); + ui->wbg->hide(); + ui->wbg_2->show(); + ui->line->move(X_LINE, Y_LINE); + if(isCurrName){ + //YYF ui->btnConn->show(); + }else{ + //YYF ui->btnConn->hide(); + } + ui->btnConnSub->hide(); + + this->isSelected = false; + } + + ui->btnDisConn->hide(); + + this->isTopItem = false; +} + +//设置顶部这个item的显示 +void OneLancForm::setTopItem(bool isSelected) +{ +// if (isSelected) { +// resize(W_ITEM, H_ITEM_EXTEND); +// ui->wbg->show(); +// ui->btnConnSub->hide(); +// this->isSelected = true; +// } else { +// resize(W_ITEM, H_ITEM); +// ui->wbg->hide(); +// ui->btnConnSub->hide(); +// this->isSelected = false; +// } + + if (isConnected) { + ui->lbIcon->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/l/pb-network-online.png);}"); + ui->btnDisConn->show(); +// ui->btnConnCfg->show(); + } else { + ui->lbIcon->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/l/pb-top-network-offline.png);}"); +// ui->btnConnCfg->hide(); + ui->btnDisConn->hide(); + } + ui->btnConnCfg->hide(); + + //YYF ui->btnConn->hide(); + ui->wbg_2->hide(); + ui->line->hide(); + + this->isTopItem = true; +} + +//设置网络名称 +void OneLancForm::setName(QString name, QString uniName) +{ + ui->lbName->setText(name); + lanName = name; + uniqueName = uniName; +} + +//根据有线网络连接与否,设置显示'已连接'文字的控件的可见与否 +void OneLancForm::setConnedString(bool showLable, QString str) +{ + if (!showLable) { + ui->lbConned->hide(); + ui->lbName->move(63, 18); + } else { + str="";//YYF 平板模式 + ui->lbConned->setText(str); + ui->lbName->move(63, 18); //YYF + } +} + +//设置item被扩展后出现的网络信息 +void OneLancForm::setLanInfo(QString str1, QString str2, QString str3, QString str4) +{ + if (str1 == "" || str1 == "auto") { + str1 = tr("No Configuration"); + } + + if (str2 == "" || str2 == "auto") { + str2 = tr("No Configuration"); + } + + QString strIPv4 = QString(tr("IPv4:")); + QString strIPv6 = QString(tr("IPv6:")); + QString strBW = QString(tr("BandWidth:")); + QString strMAC = QString(tr("MAC:")); + + ui->leInfo_1->setText(strIPv4 + str1); + ui->leInfo_2->setText(strIPv6 + str2); + ui->leInfo_3->setText(strBW + str3); + ui->leInfo_4->setText(strMAC + str4); +} + +//根据网络是否连接,设置网络状态图标 +void OneLancForm::setIcon(bool isOn) +{ + if (isOn) { + ui->lbIcon->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/l/pb-network-online.png);}"); + } else { + ui->lbIcon->setStyleSheet("QLabel{border-radius:0px;border-image:url(:/res/l/pb-network-offline.png);}"); + } +} + +//设置item下方横线的可见与否 +void OneLancForm::setLine(bool isShow) +{ + if (isShow) { + ui->line->show(); + } else { + ui->line->hide(); + } +} + +void OneLancForm::slotConnLan() +{ + //mw->startLoading(); + this->startWaiting(true); + emit sigConnLan(ui->lbName->text()); +} + +//点击网络断开按钮,执行该函数 +void OneLancForm::on_btnDisConn_clicked() +{ + syslog(LOG_DEBUG, "DisConnect button about lan net is clicked, current wired net name is %s .", ui->lbName->text().toUtf8().data()); + qDebug()<<"DisConnect button about lan net is clicked, current wired net name is "<lbName->text(); + + this->startWaiting(false); + mw->is_stop_check_net_state = 1; + + kylin_network_set_con_down(ui->lbName->text().toUtf8().data()); + + disconnect(this, SIGNAL(selectedOneLanForm(QString, QString)), mw, SLOT(oneTopLanFormSelected(QString, QString))); + + emit disconnActiveLan(); +} + +//点击了连接网络按钮,执行该函数 +void OneLancForm::on_btnConn_clicked() +{ + syslog(LOG_DEBUG, "A button named btnConn about lan net is clicked."); + qDebug()<<"A button named btnConn about lan net is clicked."; + toConnectWiredNetwork(); +} + +//点击了item被扩展中的连接网络按钮,执行该函数 +void OneLancForm::on_btnConnSub_clicked() +{ + syslog(LOG_DEBUG, "A button named btnConnSub about lan net is clicked."); + qDebug()<<"A button named btnConnSub about lan net is clicked."; + toConnectWiredNetwork(); +} + +void OneLancForm::toConnectWiredNetwork() +{ + mw->is_stop_check_net_state = 1; + QThread *t = new QThread(); + BackThread *bt = new BackThread(); + bt->moveToThread(t); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), this, SLOT(slotConnLan())); + connect(this, SIGNAL(sigConnLan(QString)), bt, SLOT(execConnLan(QString))); +// connect(bt, SIGNAL(connDone(int)), mw, SLOT(connLanDone(int))); + connect(bt, &BackThread::connDone, this, [=](int f) { + mw->connLanDone(f); + }); + connect(bt, SIGNAL(btFinish()), t, SLOT(quit())); + t->start(); +} + +//点击列表中item扩展后显示信息的位置时,执行该函数,用于显示网络配置界面 +void OneLancForm::on_btnInfo_clicked() +{ + QPoint pos = QCursor::pos(); + QRect primaryGeometry; + for (QScreen *screen : qApp->screens()) { + if (screen->geometry().contains(pos)) { + primaryGeometry = screen->geometry(); + } + } + + if (primaryGeometry.isEmpty()) { + primaryGeometry = qApp->primaryScreen()->geometry(); + } + + BackThread *bt = new BackThread(); + QString connProp = bt->getConnProp(ui->lbName->text()); + QStringList propList = connProp.split("|"); + QString v4method, addr, mask, gateway, dns; + foreach (QString line, propList) { + if (line.startsWith("method:")) { + v4method = line.split(":").at(1); + } + if (line.startsWith("addr:")) { + addr = line.split(":").at(1); + } + if (line.startsWith("mask:")) { + mask = line.split(":").at(1); + } + if (line.startsWith("gateway:")) { + gateway= line.split(":").at(1); + } + if (line.startsWith("dns:")) { + dns = line.split(":").at(1); + } + } + // qDebug()<setProp(ui->lbName->text(), v4method, addr, mask, gateway, dns, this->isActive); + connect(cf, SIGNAL(requestRefreshLanList(int)), mw, SLOT(onBtnNetListClicked(int))); + + cf->move(primaryGeometry.width() / 2 - cf->width() / 2, primaryGeometry.height() / 2 - cf->height() / 2); + cf->show(); + cf->raise(); + cf->activateWindow(); +} + +void OneLancForm::waitAnimStep() +{ + QString qpmQss = "QLabel{background-image:url(':/res/s/conning-a/"; + qpmQss.append(QString::number(this->waitPage)); + qpmQss.append(".png');}"); + ui->lbWaitingIcon->setStyleSheet(qpmQss); + + this->waitPage --; + if (this->waitPage < 1) { + this->waitPage = TOTAL_PAGE; //循环播放8张图片 + } + + this->countCurrentTime += FRAME_SPEED; + if (this->countCurrentTime >= LIMIT_TIME) { + QString cmd = "kill -9 $(pidof nmcli)"; //杀掉当前正在进行的有关nmcli命令的进程 + int status = system(cmd.toUtf8().data()); + if (status != 0) { + qDebug()<<"execute 'kill -9 $(pidof nmcli)' in function 'waitAnimStep' failed"; + syslog(LOG_ERR, "execute 'kill -9 $(pidof nmcli)' in function 'waitAnimStep' failed"); + } + + this->stopWaiting(); //动画超出时间限制,强制停止动画 + + mw->is_stop_check_net_state = 0; + } +} + +void OneLancForm::startWaiting(bool isConn) +{ + if (isConn) { + ui->lbWaiting->setStyleSheet("QLabel{border:0px;border-radius:4px;background-color:rgba(61,107,229,1);}"); + } else { + ui->btnDisConn->hide(); + ui->lbWaiting->setStyleSheet("QLabel{border:0px;border-radius:4px;background-color:rgba(255,255,255,0.12);}"); + } + this->countCurrentTime = 0; + this->waitPage = TOTAL_PAGE; //总共有8张图片 + this->waitTimer->start(FRAME_SPEED); +// ui->lbWaiting->show(); YYF + ui->lbWaitingIcon->show(); + + mw->setTrayLoading(true); +} + +void OneLancForm::stopWaiting() +{ + this->waitTimer->stop(); + ui->lbWaiting->hide(); + ui->lbWaitingIcon->hide(); + + mw->setTrayLoading(false); + mw->getActiveInfo(); +} diff --git a/KylinNM/src/onelancform.h b/KylinNM/src/onelancform.h new file mode 100644 index 0000000..3d1f196 --- /dev/null +++ b/KylinNM/src/onelancform.h @@ -0,0 +1,117 @@ +/* + * 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 +#include +#include +#include + +#include "confform.h" +#include "kylin-network-interface.h" +#include "backthread.h" +#include "ksimplenm.h" + +#define FRAME_SPEED 150 +#define LIMIT_TIME 20*1000 +#define TOTAL_PAGE 8 + +#define W_ITEM 424 +#define H_ITEM 60 +#define H_ITEM_EXTEND 162 +#define Y_LINE 59 +#define X_LINE 2 +#define Y_LINE_EXTEND 161 +#define X_LINE_EXTEND 2 + +class KylinNM; + +namespace Ui { +class OneLancForm; +} + +class OneLancForm : public QWidget +{ + Q_OBJECT + +public: + explicit OneLancForm(QWidget *parent = 0, KylinNM *mw = 0, ConfForm *confForm = 0, KSimpleNM *ksnm = 0); + ~OneLancForm(); + + void setName(QString name, QString uniName); + void setIcon(bool isOn); + void setLine(bool isShow); + void setLanInfo(QString str1, QString str2, QString str3, QString str4); + + void setSelected(bool isSelected, bool isCurrName); + void setTopItem(bool isSelected); + void setAct(bool isAct); + + void setConnedString(bool showLable, QString str); + + bool isSelected; + bool isTopItem; + bool isActive; + bool isConnected; + QString lanName; + QString uniqueName; + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event); + +private Q_SLOTS: + void on_btnConn_clicked(); + void on_btnConnSub_clicked(); + void on_btnDisConn_clicked(); + void toConnectWiredNetwork(); + + void slotConnLan(); + + void waitAnimStep(); + void startWaiting(bool isConn); + void stopWaiting(); + + void on_btnInfo_clicked(); + +private: + void tabletStyle();//YYF 平板桌面模式特有设置 + + QTimer *waitTimer = nullptr; + int waitPage; + int countCurrentTime; + + Ui::OneLancForm *ui = nullptr; + KylinNM *mw = nullptr; + ConfForm *cf = nullptr; + KSimpleNM *ks = nullptr; + + QString leQssLow, leQssHigh; + +Q_SIGNALS: + void selectedOneLanForm(QString lanName, QString uniqueName); + void connDone(int connFlag); + void disconnActiveLan(); + + void sigConnLan(QString); +}; + +#endif // ONELANCFORM_H diff --git a/KylinNM/src/onelancform.ui b/KylinNM/src/onelancform.ui new file mode 100644 index 0000000..f57060f --- /dev/null +++ b/KylinNM/src/onelancform.ui @@ -0,0 +1,242 @@ + + + OneLancForm + + + + 0 + 0 + 424 + 250 + + + + Form + + + + + 63 + 8 + 190 + 20 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 316 + 18 + 80 + 40 + + + + + + + + + + 63 + 31 + 52 + 20 + + + + + + + + + + 0 + 0 + 424 + 162 + + + + + + 63 + 64 + 238 + 85 + + + + + + + + + + 63 + 62 + 238 + 20 + + + + + + + 63 + 86 + 250 + 20 + + + + + + + 63 + 110 + 238 + 20 + + + + + + + 63 + 134 + 238 + 20 + + + + leInfo_1 + leInfo_2 + leInfo_3 + leInfo_4 + btnInfo + + + + + 14 + 14 + 24 + 24 + + + + + + + + + + 2 + 59 + 421 + 2 + + + + background-color: rgba(255, 255, 255,0.05); + + + Qt::Horizontal + + + + + + 0 + 0 + 340 + 56 + + + + + + + 316 + 14 + 100 + 34 + + + + + + + + + + 356 + 20 + 20 + 20 + + + + + + + + + + 364 + 18 + 16 + 16 + + + + + + + lbName + lbConned + lbIcon + line + wbg + wbg_2 + btnConnSub + btnDisConn + btnConn + lbWaiting + lbWaitingIcon + btnConnCfg + + + + diff --git a/KylinNM/src/swipegesturerecognizer.cpp b/KylinNM/src/swipegesturerecognizer.cpp new file mode 100644 index 0000000..87b553c --- /dev/null +++ b/KylinNM/src/swipegesturerecognizer.cpp @@ -0,0 +1,154 @@ +#include +#include + +#include +#include "swipegesturerecognizer.h" + +SwipeGestureRecognizer::SwipeGestureRecognizer(QObject *parent) : QObject(parent) +{ +} + +bool +SwipeGestureRecognizer::IsValidMove(int dx, int dy) +{ + // The moved distance is to small to count as not just a glitch. + if ((qAbs(dx) < MINIMUM_DISTANCE) && (qAbs(dy) < MINIMUM_DISTANCE)) { + return false; + } + + return true; +} + + +// virtual +QGesture* +SwipeGestureRecognizer::create(QObject* pTarget) +{ + QGesture *pGesture = new QSwipeGesture(pTarget); + return pGesture; +} + + +// virtual +QGestureRecognizer::Result +SwipeGestureRecognizer::recognize(QGesture* pGesture, QObject *pWatched, QEvent *pEvent) +{ + QGestureRecognizer::Result result = QGestureRecognizer::Ignore; + QSwipeGesture *pSwipe = static_cast(pGesture); + + switch(pEvent->type()) { + case QEvent::MouseButtonPress: { + QMouseEvent* pMouseEvent = static_cast(pEvent); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + pSwipe->setProperty("startPoint", pMouseEvent->posF()); +#else + pSwipe->setProperty("startPoint", pMouseEvent->localPos()); +#endif + result = QGestureRecognizer::MayBeGesture; + //qDebug() << "Swipe gesture started (start point=" << pSwipe->property("startPoint").toPointF() << ")"; + } + break; + case QEvent::MouseButtonRelease: { + QMouseEvent* pMouseEvent = static_cast(pEvent); + const QVariant& propValue = pSwipe->property("startPoint"); + QPointF startPoint = propValue.toPointF(); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) + QPointF endPoint = pMouseEvent->posF(); +#else + QPointF endPoint = pMouseEvent->localPos(); +#endif + + // process distance and direction + int dx = endPoint.x() - startPoint.x(); + int dy = endPoint.y() - startPoint.y(); + + //bugfix: startPoint.isNull because we sometimes get false events with startpoint 0 -> wrong swipe detected! + if ( (!IsValidMove(dx, dy)) || ( startPoint.isNull() ) ) { + // Just a click, so no gesture. + result = QGestureRecognizer::CancelGesture; + //qDebug("Swipe gesture canceled"); + } else { + // Compute the angle. + // qDebug() << " startPoint= " << startPoint << " endPoint=" << endPoint << " dx=" << dx << " dy=" << dy; + Q_EMIT onSwipeGesture(dx, dy); + qreal angle = ComputeAngle(dx, dy); + pSwipe->setSwipeAngle(angle); + result = QGestureRecognizer::FinishGesture; + //qDebug("Swipe gesture finished"); + } + } + break; + default: + break; + } + + return result; +} + +void +SwipeGestureRecognizer::reset(QGesture *pGesture) +{ + pGesture->setProperty("startPoint", QVariant(QVariant::Invalid)); + parent::reset(pGesture); +} + +qreal +SwipeGestureRecognizer::ComputeAngle(int dx, int dy) +{ + double PI = 3.14159265; + + // Need to convert from screen coordinates direction + // into classical coordinates direction. + dy = -dy; + + double result = atan2((double)dy, (double)dx) ; + result = (result * 180) / PI; + + // Always return positive angle. + if (result < 0) { + result += 360; + } + + return result; +} + + + +/* +========================================================================== +*/ + +QSwipeGesture::SwipeDirection +SwipeGestureUtil::GetHorizontalDirection(QSwipeGesture *pSwipeGesture) +{ + qreal angle = pSwipeGesture->swipeAngle(); + if (0 <= angle && angle <= 45) { + return QSwipeGesture::Right; + } + + if (135 <= angle && angle <= 225) { + return QSwipeGesture::Left; + } + + if (315 <= angle && angle <= 360) { + return QSwipeGesture::Right; + } + + return QSwipeGesture::NoDirection; +} + +QSwipeGesture::SwipeDirection +SwipeGestureUtil::GetVerticalDirection(QSwipeGesture *pSwipeGesture) +{ + qreal angle = pSwipeGesture->swipeAngle(); + + if (45 < angle && angle < 135) { + return QSwipeGesture::Up; + } + + if (225 < angle && angle < 315) { + return QSwipeGesture::Down; + } + + return QSwipeGesture::NoDirection; +} diff --git a/KylinNM/src/swipegesturerecognizer.h b/KylinNM/src/swipegesturerecognizer.h new file mode 100644 index 0000000..2e51665 --- /dev/null +++ b/KylinNM/src/swipegesturerecognizer.h @@ -0,0 +1,46 @@ +#ifndef SWIPEGESTURERECOGNIZER_H +#define SWIPEGESTURERECOGNIZER_H + +#include +#include +#include +#include "kylinnm.h" + +/** + * @brief The SwipeGestureRecognizer class + * needed because the defalt implementation of swipe is a little bit odd: it only triggers on 3 finger swipes! (5.3) + * + * http://developer.android.com/design/patterns/gestures.html + * http://qt-project.org/doc/qt-5/gestures-overview.html + */ +class SwipeGestureRecognizer :public QObject, public QGestureRecognizer +{ + Q_OBJECT +public: + SwipeGestureRecognizer(QObject *parent = nullptr); +private: + static const int MINIMUM_DISTANCE = 10; + + typedef QGestureRecognizer parent; + + bool IsValidMove(int dx, int dy); + + qreal ComputeAngle(int dx, int dy); + + virtual QGesture* create(QObject* pTarget); + + virtual QGestureRecognizer::Result recognize(QGesture* pGesture, QObject *pWatched, QEvent *pEvent); + + void reset (QGesture *pGesture); +signals: + void onSwipeGesture(int dx, int dy); +}; + + +class SwipeGestureUtil { +public: + static QSwipeGesture::SwipeDirection GetHorizontalDirection(QSwipeGesture *pSwipeGesture); + static QSwipeGesture::SwipeDirection GetVerticalDirection(QSwipeGesture *pSwipeGesture); +}; + +#endif // SWIPEGESTURERECOGNIZER_H diff --git a/KylinNM/src/switchbutton.cpp b/KylinNM/src/switchbutton.cpp new file mode 100644 index 0000000..714e249 --- /dev/null +++ b/KylinNM/src/switchbutton.cpp @@ -0,0 +1,92 @@ +#include "switchbutton.h" + +SwitchButton::SwitchButton(QWidget *parent) : QWidget(parent) +{ + + setFixedSize(50,24); + m_fWidth = (float)width(); + m_fHeight = (float)height(); + m_cTimer = new QTimer(this); + m_cTimer->setInterval(5); + + if(m_bIsOn == 1) { + m_fCurrentValue = m_fWidth - 16 - 4; + } + else { + m_fCurrentValue = 4; + } + connect(m_cTimer,SIGNAL(timeout()),this,SLOT(startAnimation())); + + +} + +void SwitchButton::setSwitchStatus(bool check) { + if(check == true) { + m_bIsOn = 1; + } else { + m_bIsOn = 0; + } + + m_cTimer->start(); //开始播放动画 +} + + +/* 播放按钮开启关闭动画 */ +void SwitchButton::startAnimation() { //滑动按钮动作播放 + int pos = 4; + int size = m_fWidth - 16; + if(m_bIsOn) { + m_fCurrentValue ++; //往右滑动 + if(m_fCurrentValue >= size - pos) { //到达边界停下来 + m_fCurrentValue = size - pos; + m_cTimer->stop(); + } + + } else { + m_fCurrentValue --; + if(m_fCurrentValue <= pos) { //到达最小值,停止继续前进 + m_fCurrentValue = pos; + m_cTimer->stop(); + } + } + update(); +} + +/* 按钮按下处理 */ +void SwitchButton::mousePressEvent(QMouseEvent *event) { + Q_UNUSED(event); + m_bIsOn = !m_bIsOn; + + Q_EMIT clicked(m_bIsOn); + + return QWidget::mousePressEvent(event); +} + +/* 绘制滑动按钮主体 */ +void SwitchButton::paintEvent(QPaintEvent *event) { + Q_UNUSED(event); + QPainter painter(this); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.setRenderHint(QPainter::Antialiasing); //抗锯齿效果 + painter.setPen(Qt::NoPen); + QColor colorActive(61,107,229); + QColor colorInactive(111,111,111); + colorInactive.setAlphaF(0.12); + if(m_bIsOn) { + painter.save(); + painter.setBrush(colorActive); + QRectF active_rect = QRectF(0,0,m_fWidth,m_fHeight); + painter.drawRoundedRect(active_rect, 0.5 * m_fHeight, 0.5 * m_fHeight); //画开启状态 + } else { + painter.save(); + painter.setBrush(colorInactive); + QRectF inactive_rect = QRectF(0 ,0,m_fWidth,m_fHeight); + painter.drawRoundedRect(inactive_rect, 0.5 * m_fHeight, 0.5 * m_fHeight); //画关闭状态 + } + painter.restore(); + painter.save(); + painter.setBrush(Qt::white); + painter.drawEllipse(m_fCurrentValue,4, 16, 16); + painter.restore(); +} + diff --git a/KylinNM/src/switchbutton.h b/KylinNM/src/switchbutton.h new file mode 100644 index 0000000..7c0f1e5 --- /dev/null +++ b/KylinNM/src/switchbutton.h @@ -0,0 +1,32 @@ +#ifndef SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include +#include +#include +#include + +class SwitchButton : public QWidget +{ + Q_OBJECT +public: + explicit SwitchButton(QWidget *parent = nullptr); + void setSwitchStatus(bool check); + +private: + int m_bIsOn = 1; + QTimer *m_cTimer; + float m_fWidth; + float m_fHeight; + float m_fCurrentValue; + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + +Q_SIGNALS: + void clicked(int check); +private Q_SLOTS: + void startAnimation(); + +}; + +#endif // SWITCHBUTTON_H diff --git a/KylinNM/src/utils.cpp b/KylinNM/src/utils.cpp new file mode 100644 index 0000000..7821508 --- /dev/null +++ b/KylinNM/src/utils.cpp @@ -0,0 +1,267 @@ +/* + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// The Utils class + +Utils::Utils(){} + +int Utils::m_system(char *cmd) +{ + int status = 0; + pid_t pid; + + if ((pid = vfork()) <0) { + qDebug()<<"failed to create a subprocess by using vfork"; + syslog(LOG_ERR, "failed to create a subprocess by using vfork"); + status = -1; + } else if (pid==0) { + const char *new_argv[4]; + struct sigaction sa_cld; + sa_cld.sa_handler = SIG_DFL; + sa_cld.sa_flags = 0; + + // 在子进程中放开SIGINT信号 + sigemptyset(&sa_cld.sa_mask); + sigaction (SIGINT, &sa_cld, NULL); + sigaction (SIGQUIT, &sa_cld, NULL); + + new_argv[0] = "sh"; + new_argv[1] = "-c"; + new_argv[2] = cmd; + new_argv[3] = NULL; + + // execl("/bin/sh","sh","-c" ,cmd,(char *)0); + if (execve("/bin/sh",(char *const *) new_argv, NULL) <0) { + qDebug()<<"failed to execve a shell command in function m_system"; + syslog(LOG_ERR, "failed to execve %s! errno: %d\n",cmd, errno); + exit(1); + } else { + exit(0); + } + } else { + waitpid(pid,&status,0); + } + + return status; +} + +void Utils::onRequestSendDesktopNotify(QString message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(QCoreApplication::applicationName()) + <<((unsigned int) 0) + < +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +/////////////////////////////////////////////////////////////////////////////// +// The Utils class, used to do some assist function + +class Utils : public QObject +{ + Q_OBJECT +public: + Utils(); + + static int m_system(char *cmd); + +public Q_SLOTS: + void onRequestSendDesktopNotify(QString message); + +}; + + +/////////////////////////////////////////////////////////////////////////////// +// The UseQssFile class, set control style by using .qss file + +class UseQssFile +{ +public: + static void setStyle(const QString &style) + { + QString styleName = ":/qss/" + style; + + QFile qss(styleName); + qss.open(QFile::ReadOnly); + qApp->setStyleSheet(qss.readAll()); + qss.close(); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// The NetworkSpeed class, get the network upload and download speed + +class NetworkSpeed : public QObject +{ + Q_OBJECT +public: + explicit NetworkSpeed(QObject *parent = nullptr); + + int getCurrentDownloadRates(char *netname,long int * save_rate,long int * tx_rate); //获取当前的流量,参数为将获取到的流量保 +}; + + + + +/////////////////////////////////////////////////////////////////////////////// +// The CustomStyle class, inherit from class QProxyStyle, to change control style customize + +class CustomStyle : public QProxyStyle +{ + Q_OBJECT +public: + explicit CustomStyle(const QString &proxyStyleName = "windows", QObject *parent = nullptr); + + + virtual void drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const; + + virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const; + virtual void drawItemPixmap(QPainter *painter, const QRect &rectangle, int alignment, const QPixmap &pixmap) const; + virtual void drawItemText(QPainter *painter, const QRect &rectangle, int alignment, const QPalette &palette, bool enabled, const QString &text, QPalette::ColorRole textRole = QPalette::NoRole) const; + + virtual void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const; + virtual QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const; + virtual QStyle::SubControl hitTestComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, const QPoint &position, const QWidget *widget = nullptr) const; + virtual QRect itemPixmapRect(const QRect &rectangle, int alignment, const QPixmap &pixmap) const; + virtual QRect itemTextRect(const QFontMetrics &metrics, const QRect &rectangle, int alignment, bool enabled, const QString &text) const; + //virtual int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget); + virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const; + + virtual void polish(QWidget *widget); + virtual void polish(QApplication *application); + virtual void polish(QPalette &palette); + virtual void unpolish(QWidget *widget); + virtual void unpolish(QApplication *application); + + virtual QSize sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget = nullptr) const; + virtual QIcon standardIcon(QStyle::StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const; + virtual QPalette standardPalette() const; + + virtual int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const; + + virtual QRect subControlRect(QStyle::ComplexControl control, const QStyleOptionComplex *option, QStyle::SubControl subControl, const QWidget *widget = nullptr) const; + + virtual QRect subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget = nullptr) const; + +Q_SIGNALS: + +public Q_SLOTS: +}; + +#endif // UTILS_H diff --git a/KylinNM/wireless-security/dlgconnhidwifi.cpp b/KylinNM/wireless-security/dlgconnhidwifi.cpp new file mode 100644 index 0000000..3901449 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifi.cpp @@ -0,0 +1,379 @@ +/* + * 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 + +#include +#include + +DlgConnHidWifi::DlgConnHidWifi(int type, KylinNM *mainWindow, QWidget *parent) : + isUsed(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifi()) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + KylinDBus mkylindbus; + QString strTrans; + strTrans = QString::number(1, 10, 2); + QString sty = "QWidget{border-radius:6px;background-color:rgba(255,255,255,1);border:1px solid rgba(255, 255, 255, 1);}"; + this->setStyleSheet(sty); + //this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + + ui->lbLeftupTitle->setText(tr("Add Hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Wi-Fi name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi安全性: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + QString tmpPath = "/tmp/kylin-nm-connshow-" + QDir::home().dirName(); + QString cmd = "nmcli connection show>" + tmpPath; + int status = system(cmd.toUtf8().data()); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifi' failed");} + QFile file(tmpPath); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if (line.indexOf("wifi") != -1 || line.indexOf("802-11-wireless") != -1) { + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + connect(ui->cbxConn,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeWindow())); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + //ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + //ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + //ui->cbxSecurity->addItem("LEAP"); + //ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + //ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + ui->cbxSecurity->setCurrentIndex(0); + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialog())); + + if (isUsed == 0){ + ui->btnConnect->setEnabled(false); + }else{ + ui->cbxConn->setCurrentIndex(isUsed); + ui->leNetName->setText(ui->cbxConn->currentText()); + ui->lbNetName->setEnabled(false); + ui->leNetName->setEnabled(false); + ui->lbSecurity->setEnabled(false); + ui->cbxSecurity->setEnabled(false); + ui->btnConnect->setEnabled(true); + } + + this->setFixedSize(432,358); + + this->mw = mainWindow; + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 + **/ + ui->cbxConn->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxConn->view()->setParent(this); + ui->cbxConn->view()->hide(); + ui->cbxConn->installEventFilter(this); + + ui->cbxSecurity->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxSecurity->view()->setParent(this); + ui->cbxSecurity->view()->hide(); + ui->cbxSecurity->installEventFilter(this); + + connect(ui->cbxConn->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + Q_EMIT ui->cbxConn->setCurrentIndex(index.row()); + ui->cbxConn->view()->hide(); + }); + + connect(ui->cbxSecurity->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + ui->cbxSecurity->view()->hide(); + Q_EMIT ui->cbxSecurity->setCurrentIndex(index.row()); + }); + + ui->cbxConn->view()->setGeometry(QRect(ui->cbxConn->geometry().left(), ui->cbxConn->geometry().bottom(), ui->cbxConn->view()->width(), ui->cbxConn->view()->height())); + ui->cbxSecurity->view()->setGeometry(QRect(ui->cbxSecurity->geometry().left(), ui->cbxSecurity->geometry().bottom(), ui->cbxSecurity->view()->width(), ui->cbxSecurity->view()->height())); + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- + ** 手动绑定下拉框视图和下拉框 + **/ +} + +DlgConnHidWifi::~DlgConnHidWifi() +{ + delete ui; +} + +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- +** 手动绑定下拉框视图和下拉框 +**/ +bool DlgConnHidWifi::eventFilter(QObject *obj, QEvent *ev) +{ + if(ev->type() == QEvent::MouseButtonPress) + { + if(obj == ui->cbxConn) + { + ui->cbxConn->view()->setVisible(!ui->cbxConn->view()->isVisible()); + if(ui->cbxConn->view()->isVisible()) + ui->cbxConn->view()->setFocus(); + } else if (obj == ui->cbxSecurity) + { + ui->cbxSecurity->view()->setVisible(!ui->cbxSecurity->view()->isVisible()); + if(ui->cbxSecurity->view()->isVisible()) + ui->cbxSecurity->view()->setFocus(); + } + } + return false; +} +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- +** 手动绑定下拉框视图和下拉框 +**/ + +void DlgConnHidWifi::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifi::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifi::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +//切换到其他Wi-Fi安全类型 +void DlgConnHidWifi::changeDialog() +{ + if(ui->cbxSecurity->currentIndex()==0){ + qDebug()<<"it's not need to change dialog"; + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, mw, this->parentWidget()); + connHidWifiWpa->show(); + connect(connHidWifiWpa, SIGNAL(reSetWifiList() ), mw, SLOT(on_btnWifiList_clicked()) ); + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0,this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1,this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(0,this->parentWidget()); + connHidWifiSecTls->show(); + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(1,this->parentWidget()); + connHidWifiSecTls->show(); + } +} + +//同一 Wi-Fi安全类型的窗口变换 +void DlgConnHidWifi::changeWindow(){ + if (ui->cbxConn->currentIndex() == 0){ + isUsed = ui->cbxConn->currentIndex(); + ui->cbxConn->setCurrentIndex(0); + ui->leNetName->setText(""); + ui->lbNetName->setEnabled(true); + ui->leNetName->setEnabled(true); + ui->lbSecurity->setEnabled(true); + ui->cbxSecurity->setEnabled(true); + ui->btnConnect->setEnabled(false); + }else if (ui->cbxConn->currentIndex() >= 1){ + QString tmpPath = "/tmp/kylin-nm-connshow-" + QDir::home().dirName(); + QString name = ui->cbxConn->currentText(); + QString currStr = "nmcli connection show \"" + name.replace("\"","\\\"") + "\" >" + tmpPath; + + int status = system(currStr.toUtf8().data()); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'changeWindow' failed");} + + QFile file(tmpPath); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + file.close(); + if (txt.indexOf("802-11-wireless-security.key-mgmt:") != -1){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(ui->cbxConn->currentIndex(), mw, this->parentWidget()); + connHidWifiWpa->show(); + connect(connHidWifiWpa, SIGNAL(reSetWifiList() ), mw, SLOT(on_btnWifiList_clicked()) ); + }else { + isUsed = ui->cbxConn->currentIndex(); + ui->leNetName->setText(ui->cbxConn->currentText()); + ui->lbNetName->setEnabled(false); + ui->leNetName->setEnabled(false); + ui->lbSecurity->setEnabled(false); + ui->cbxSecurity->setEnabled(false); + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifi::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifi::on_btnConnect_clicked() +{ + QThread *t = new QThread(); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), this, SLOT(slotStartLoading())); + connect(this, SIGNAL(stopSignal()), t, SLOT(quit())); + t->start(); + + QString wifiName = ui->leNetName->text(); + BackThread *bt = new BackThread(); + strWifiname = wifiName; + //点击连接按钮以连接隐藏WiFi + if (isUsed == 0) { + int x = 0; + do { + sleep(1); + QString tmpPath = "/tmp/kylin-nm-btoutput-" + QDir::home().dirName(); + QString cmd = "nmcli device wifi connect \"" + wifiName.replace("\"","\\\"") + "\" password '' hidden yes > " + tmpPath; + + int status = system(cmd.toUtf8().data()); + if (status != 0) + syslog(LOG_ERR, "execute 'nmcli device wifi connect' in function 'on_btnConnect_clicked' failed"); + + QFile file(tmpPath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug()<<"Can't open the file!"<execConnWifi(wifiName); + connect(this, SIGNAL(sendMessage()), this,SLOT(emitSignal() )); + QTimer::singleShot(4*1000, this, SLOT(emitSignal() )); + } + this->close(); +} + +void DlgConnHidWifi::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifi::slotStartLoading() +{ + mw->startLoading(); +} + +void DlgConnHidWifi::on_execSecConn() +{ + QString name = strWifiname; + QString str = "nmcli device wifi connect \"" + name.replace("\"","\\\"") + "\" password ''"; + int status = system(str.toUtf8().data()); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli device wifi connect' in function 'on_execSecConn' failed");} + connect(this, SIGNAL(sendMessage()), this,SLOT(emitSignal() )); + QTimer::singleShot(3*1000, this, SLOT(emitSignal() )); +} + +void DlgConnHidWifi::emitSignal() +{ + emit reSetWifiList(); + mw->stopLoading(); + emit this->stopSignal(); +} + +void DlgConnHidWifi::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifi.h b/KylinNM/wireless-security/dlgconnhidwifi.h new file mode 100644 index 0000000..33d4c42 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifi.h @@ -0,0 +1,86 @@ +/* + * 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 +#include +#include +#include +#include + +class KylinNM; + +namespace Ui { +class DlgConnHidWifi; +} + +class DlgConnHidWifi : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifi(int type, KylinNM *mw = 0, QWidget *parent = 0); + ~DlgConnHidWifi(); + +protected: + void paintEvent(QPaintEvent *event); + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 过滤点击事件 + **/ + bool eventFilter(QObject *obj, QEvent *ev) override; + +public Q_SLOTS: + void changeDialog(); + void changeWindow(); + void emitSignal(); + void on_execSecConn(); + void slotStartLoading(); + +private Q_SLOTS: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_leNetName_textEdited(const QString &arg1); + +Q_SIGNALS: + void reSetWifiList(); + void sendMessage(); + void execSecConn(); + void stopSignal(); + +private: + Ui::DlgConnHidWifi *ui; + int isUsed;//=0 current wifi not used before; >=1 used + KylinNM *mw; + QString strWifiname; +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss; + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFI_H diff --git a/KylinNM/wireless-security/dlgconnhidwifi.ui b/KylinNM/wireless-security/dlgconnhidwifi.ui new file mode 100644 index 0000000..1d23ac6 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifi.ui @@ -0,0 +1,238 @@ + + + DlgConnHidWifi + + + + 0 + 0 + 432 + 358 + + + + Connect to Hidden Wi-Fi Network + + + + + 76 + 80 + 90 + 20 + + + + + 10 + + + + Qt::LeftToRight + + + + + + + + + 175 + 75 + 182 + 32 + + + + + 10 + + + + + + + + + + 76 + 221 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 170 + 182 + 32 + + + + + 10 + + + + + + + + + + 76 + 176 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 215 + 182 + 32 + + + + + 10 + + + + + + + 315 + 310 + 90 + 30 + + + + + 10 + + + + + + + + + + 215 + 310 + 90 + 30 + + + + + 10 + + + + + + + + + + 30 + 30 + 240 + 22 + + + + + 9 + + + + + + + + + + 0 + 0 + 432 + 358 + + + + + + + + + + 10 + 140 + 412 + 1 + + + + + + + Qt::Horizontal + + + + + + 10 + 280 + 412 + 1 + + + + + + + Qt::Horizontal + + + lbBoder + lbConn + cbxConn + lbNetName + cbxSecurity + lbSecurity + leNetName + btnConnect + btnCancel + lbLeftupTitle + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifileap.cpp b/KylinNM/wireless-security/dlgconnhidwifileap.cpp new file mode 100644 index 0000000..5926b12 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifileap.cpp @@ -0,0 +1,290 @@ +/* + * 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 + +DlgConnHidWifiLeap::DlgConnHidWifiLeap(QWidget *parent) : + QDialog(parent), + ui(new Ui::DlgConnHidWifiLeap) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbUserName->setStyleSheet(objQss.labelQss); + ui->lbPassword->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->leUserName->setStyleSheet(objQss.leQss); + ui->lePassword->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->checkBoxPwd->setStyleSheet(objQss.checkBoxQss); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + + ui->lbLeftupTitle->setText(tr("Add hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi安全性: + ui->lbUserName->setText(tr("Username")); //用户名: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + int status = system("nmcli connection show>/tmp/kylin-nm-connshow"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiLeap' failed");} + QFile file("/tmp/kylin-nm-connshow"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if(line.indexOf("wifi") != -1){ + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + ui->cbxSecurity->addItem("LEAP"); + ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + ui->cbxSecurity->setCurrentIndex(4); + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialog())); + + ui->btnConnect->setEnabled(false); + + this->setFixedSize(432,434); + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 + **/ + ui->cbxConn->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxConn->view()->setParent(this); + ui->cbxConn->view()->hide(); + ui->cbxConn->installEventFilter(this); + + ui->cbxSecurity->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxSecurity->view()->setParent(this); + ui->cbxSecurity->view()->hide(); + ui->cbxSecurity->installEventFilter(this); + + connect(ui->cbxConn->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + Q_EMIT ui->cbxConn->setCurrentIndex(index.row()); + ui->cbxConn->view()->hide(); + }); + + connect(ui->cbxSecurity->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + ui->cbxSecurity->view()->hide(); + Q_EMIT ui->cbxSecurity->setCurrentIndex(index.row()); + }); + + ui->cbxConn->view()->setGeometry(QRect(ui->cbxConn->geometry().left(), ui->cbxConn->geometry().bottom(), ui->cbxConn->view()->width(), ui->cbxConn->view()->height())); + ui->cbxSecurity->view()->setGeometry(QRect(ui->cbxSecurity->geometry().left(), ui->cbxSecurity->geometry().bottom(), ui->cbxSecurity->view()->width(), ui->cbxSecurity->view()->height())); + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- + ** 手动绑定下拉框视图和下拉框 + **/ +} + +DlgConnHidWifiLeap::~DlgConnHidWifiLeap() +{ + delete ui; +} + +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- +** 手动绑定下拉框视图和下拉框 +**/ +bool DlgConnHidWifiLeap::eventFilter(QObject *obj, QEvent *ev) +{ + if(ev->type() == QEvent::MouseButtonPress) + { + if(obj == ui->cbxConn) + { + ui->cbxConn->view()->setVisible(!ui->cbxConn->view()->isVisible()); + if(ui->cbxConn->view()->isVisible()) + ui->cbxConn->view()->setFocus(); + } else if (obj == ui->cbxSecurity) + { + ui->cbxSecurity->view()->setVisible(!ui->cbxSecurity->view()->isVisible()); + if(ui->cbxSecurity->view()->isVisible()) + ui->cbxSecurity->view()->setFocus(); + } + } + return false; +} +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- +** 手动绑定下拉框视图和下拉框 +**/ + +void DlgConnHidWifiLeap::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiLeap::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiLeap::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +//切换到其他Wi-Fi安全类型 +void DlgConnHidWifiLeap::changeDialog() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, 0,this->parentWidget()); + connHidWifi->show(); + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, 0, this->parentWidget()); + connHidWifiWpa->show(); + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { + qDebug()<<"it's not need to change dialog"; + } else if(ui->cbxSecurity->currentIndex()==5) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(0, this->parentWidget()); + connHidWifiSecTls->show(); + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(1, this->parentWidget()); + connHidWifiSecTls->show(); + } +} + +void DlgConnHidWifiLeap::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiLeap::on_btnConnect_clicked() +{ + this->close(); +} + +void DlgConnHidWifiLeap::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword ->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiLeap::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == "" || ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leNetName->text() == "" || ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == "" || ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiLeap::on_leUserName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiLeap::on_lePassword_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiLeap::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifileap.h b/KylinNM/wireless-security/dlgconnhidwifileap.h new file mode 100644 index 0000000..de96ce2 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifileap.h @@ -0,0 +1,75 @@ +/* + * 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 +#include + +namespace Ui { +class DlgConnHidWifiLeap; +} + +class DlgConnHidWifiLeap : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiLeap(QWidget *parent = 0); + ~DlgConnHidWifiLeap(); + +protected: + void paintEvent(QPaintEvent *event); + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 过滤点击事件 + **/ + bool eventFilter(QObject *obj, QEvent *ev) override; + +public slots: + void changeDialog(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_leUserName_textEdited(const QString &arg1); + + void on_lePassword_textEdited(const QString &arg1); + +private: + Ui::DlgConnHidWifiLeap *ui; + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFILEAP_H diff --git a/KylinNM/wireless-security/dlgconnhidwifileap.ui b/KylinNM/wireless-security/dlgconnhidwifileap.ui new file mode 100644 index 0000000..b8a5b4b --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifileap.ui @@ -0,0 +1,319 @@ + + + DlgConnHidWifiLeap + + + + 0 + 0 + 432 + 434 + + + + Connect to Hidden Wi-Fi Network + + + + + 175 + 264 + 182 + 32 + + + + + 10 + + + + + + + 175 + 219 + 182 + 32 + + + + + 10 + + + + + + + + + + 215 + 390 + 90 + 30 + + + + + 10 + + + + + + + + + + 76 + 84 + 90 + 20 + + + + + 10 + + + + Qt::LeftToRight + + + + + + + + + 175 + 79 + 182 + 32 + + + + + 10 + + + + + + + + + + 76 + 270 + 90 + 20 + + + + + 10 + + + + + + + + + + 332 + 321 + 18 + 9 + + + + + 10 + + + + + + + + + + 76 + 315 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 180 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 225 + 90 + 20 + + + + + 10 + + + + + + + + + + 315 + 390 + 90 + 30 + + + + + 10 + + + + + + + + + + 175 + 309 + 182 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 175 + 174 + 182 + 32 + + + + + 10 + + + + + + + 0 + 0 + 432 + 434 + + + + + + + + + + 30 + 32 + 140 + 22 + + + + + + + + + + 10 + 134 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 364 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + leUserName + cbxSecurity + btnCancel + lbConn + cbxConn + lbUserName + lbPassword + lbNetName + lbSecurity + btnConnect + lePassword + leNetName + checkBoxPwd + lbLeftupTitle + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifisecfast.cpp b/KylinNM/wireless-security/dlgconnhidwifisecfast.cpp new file mode 100644 index 0000000..b4d07f5 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecfast.cpp @@ -0,0 +1,403 @@ +/* + * 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 + +DlgConnHidWifiSecFast::DlgConnHidWifiSecFast(int type, QWidget *parent) : + WepOrWpa(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifiSecFast) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbAuth->setStyleSheet(objQss.labelQss); + ui->lbAnonyId->setStyleSheet(objQss.labelQss); + ui->checkBoxAutoPCA->setStyleSheet(objQss.checkBoxCAQss); + ui->lbPCAfile->setStyleSheet(objQss.labelQss); + ui->lbInnerAuth->setStyleSheet(objQss.labelQss); + ui->lbUserName->setStyleSheet(objQss.labelQss); + ui->lbPassword->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->cbxAuth->setStyleSheet(objQss.cbxQss); + ui->cbxAuth->setView(new QListView()); + ui->leAnonyId->setStyleSheet(objQss.leQss); + ui->cbxAutoPCA->setStyleSheet(objQss.cbxQss); + ui->cbxAutoPCA->setView(new QListView()); + ui->lePCAfile->setStyleSheet(objQss.leQss); + ui->cbxInnerAuth->setStyleSheet(objQss.cbxQss); + ui->cbxInnerAuth->setView(new QListView()); + ui->leUserName->setStyleSheet(objQss.leQss); + ui->lePassword->setStyleSheet(objQss.leQss); + ui->checkBoxPwd->setStyleSheet(objQss.checkBoxQss); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + + ui->lbLeftupTitle->setText(tr("Add hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi安全性: + ui->lbAuth->setText(tr("Authentication")); //认证: + ui->lbAnonyId->setText(tr("Anonymous identity")); //匿名身份: + ui->checkBoxAutoPCA->setText(tr("Allow automatic PAC pro_visioning")); //自动PAC配置: + ui->lbPCAfile->setText(tr("PAC file"));//PAC文件: + ui->lbInnerAuth->setText(tr("Inner authentication")); //内部认证: + ui->lbUserName->setText(tr("Username")); //用户名: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->checkBoxAutoPCA->setFocusPolicy(Qt::NoFocus); + ui->checkBoxPwd->setFocusPolicy(Qt::NoFocus); + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + int status = system("nmcli connection show>/tmp/kylin-nm-connshow"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiSecFast' failed");} + QFile file("/tmp/kylin-nm-connshow"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if(line.indexOf("wifi") != -1){ + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + ui->cbxSecurity->addItem("LEAP"); + ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + if (WepOrWpa == 0) { + ui->cbxSecurity->setCurrentIndex(5); + } else if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(6); + } + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogSecu())); + + ui->cbxAuth->addItem("TLS"); + ui->cbxAuth->addItem("LEAP"); + ui->cbxAuth->addItem("PWD"); + ui->cbxAuth->addItem("FAST"); + ui->cbxAuth->addItem(tr("Tunneled TLS"));//隧道 TLS + ui->cbxAuth->addItem(tr("Protected EAP (PEAP)")); //受保护的 EAP + ui->cbxAuth->setCurrentIndex(3); + connect(ui->cbxAuth,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogAuth())); + + ui->checkBoxAutoPCA->setCheckState(Qt::Checked); + + ui->cbxAutoPCA->addItem(tr("Anonymous")); //匿名 + ui->cbxAutoPCA->addItem(tr("Authenticated")); //已认证 + ui->cbxAutoPCA->addItem(tr("Both")); //两者兼用 + ui->cbxAutoPCA->setCurrentIndex(0); + + ui->lePCAfile->setText(tr("None")); //(无) + + ui->cbxInnerAuth->addItem("GTC"); + ui->cbxInnerAuth->addItem("MSCHAPv2"); + ui->cbxInnerAuth->setCurrentIndex(0); + + ui->btnConnect->setEnabled(false); + + this->setFixedSize(432,673); + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 + **/ + ui->cbxConn->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxConn->view()->setParent(this); + ui->cbxConn->view()->hide(); + ui->cbxConn->installEventFilter(this); + + ui->cbxSecurity->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxSecurity->view()->setParent(this); + ui->cbxSecurity->view()->hide(); + ui->cbxSecurity->installEventFilter(this); + + connect(ui->cbxConn->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + Q_EMIT ui->cbxConn->setCurrentIndex(index.row()); + ui->cbxConn->view()->hide(); + }); + + connect(ui->cbxSecurity->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + ui->cbxSecurity->view()->hide(); + Q_EMIT ui->cbxSecurity->setCurrentIndex(index.row()); + }); + + ui->cbxConn->view()->setGeometry(QRect(ui->cbxConn->geometry().left(), ui->cbxConn->geometry().bottom(), ui->cbxConn->view()->width(), ui->cbxConn->view()->height())); + ui->cbxSecurity->view()->setGeometry(QRect(ui->cbxSecurity->geometry().left(), ui->cbxSecurity->geometry().bottom(), ui->cbxSecurity->view()->width(), ui->cbxSecurity->view()->height())); + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- + ** 手动绑定下拉框视图和下拉框 + **/ +} + +DlgConnHidWifiSecFast::~DlgConnHidWifiSecFast() +{ + delete ui; +} + +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- +** 手动绑定下拉框视图和下拉框 +**/ +bool DlgConnHidWifiSecFast::eventFilter(QObject *obj, QEvent *ev) +{ + if(ev->type() == QEvent::MouseButtonPress) + { + if(obj == ui->cbxConn) + { + ui->cbxConn->view()->setVisible(!ui->cbxConn->view()->isVisible()); + if(ui->cbxConn->view()->isVisible()) + ui->cbxConn->view()->setFocus(); + } else if (obj == ui->cbxSecurity) + { + ui->cbxSecurity->view()->setVisible(!ui->cbxSecurity->view()->isVisible()); + if(ui->cbxSecurity->view()->isVisible()) + ui->cbxSecurity->view()->setFocus(); + } + } + return false; +} +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- +** 手动绑定下拉框视图和下拉框 +**/ + +void DlgConnHidWifiSecFast::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiSecFast::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiSecFast::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +void DlgConnHidWifiSecFast::changeDialogSecu() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, 0, this->parentWidget()); + connHidWifi->show(); + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, 0, this->parentWidget()); + connHidWifiWpa->show(); + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { + if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(5); + WepOrWpa = 0; + } + } else { + if (WepOrWpa == 0){ + ui->cbxSecurity->setCurrentIndex(6); + WepOrWpa = 1; + } + } +} + +void DlgConnHidWifiSecFast::changeDialogAuth() +{ + if(ui->cbxAuth->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(WepOrWpa, this->parentWidget()); + connHidWifiSecTls->show(); + } else if(ui->cbxAuth->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecLeap *connHidWifiSecLeap = new DlgConnHidWifiSecLeap(WepOrWpa, this->parentWidget()); + connHidWifiSecLeap->show(); + } else if(ui->cbxAuth->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPwd *connHidWifiSecPwd = new DlgConnHidWifiSecPwd(WepOrWpa, this->parentWidget()); + connHidWifiSecPwd->show(); + } else if(ui->cbxAuth->currentIndex()==3) { + qDebug()<<"it's not need to change dialog"; + } else if(ui->cbxAuth->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTunnelTLS *connHidWifiSecTuTls = new DlgConnHidWifiSecTunnelTLS(WepOrWpa, this->parentWidget()); + connHidWifiSecTuTls->show(); + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPeap *connHidWifiSecPeap = new DlgConnHidWifiSecPeap(WepOrWpa); + connHidWifiSecPeap->show(); + } +} + +void DlgConnHidWifiSecFast::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecFast::on_btnConnect_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecFast::on_checkBoxAutoPCA_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->cbxAutoPCA->setEnabled(false); + } else { + ui->cbxAutoPCA->setEnabled(true); + } +} + +void DlgConnHidWifiSecFast::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword ->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecFast::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if(ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecFast::on_leAnonyId_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if(ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecFast::on_leUserName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if(ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecFast::on_lePassword_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if(ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecFast::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifisecfast.h b/KylinNM/wireless-security/dlgconnhidwifisecfast.h new file mode 100644 index 0000000..7a1491a --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecfast.h @@ -0,0 +1,81 @@ +/* + * 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 +#include + +namespace Ui { +class DlgConnHidWifiSecFast; +} + +class DlgConnHidWifiSecFast : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiSecFast(int type, QWidget *parent = 0); + ~DlgConnHidWifiSecFast(); + +protected: + void paintEvent(QPaintEvent *event); + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 过滤点击事件 + **/ + bool eventFilter(QObject *obj, QEvent *ev) override; + +public slots: + void changeDialogSecu(); + void changeDialogAuth(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_checkBoxAutoPCA_stateChanged(int arg1); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_leAnonyId_textEdited(const QString &arg1); + + void on_leUserName_textEdited(const QString &arg1); + + void on_lePassword_textEdited(const QString &arg1); + +private: + Ui::DlgConnHidWifiSecFast *ui; + int WepOrWpa = 0;//0 WEP;1WPA + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFISECFAST_H diff --git a/KylinNM/wireless-security/dlgconnhidwifisecfast.ui b/KylinNM/wireless-security/dlgconnhidwifisecfast.ui new file mode 100644 index 0000000..8b91563 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecfast.ui @@ -0,0 +1,505 @@ + + + DlgConnHidWifiSecFast + + + + 0 + 0 + 432 + 673 + + + + Connect to Hidden Wi-Fi Network + + + + + 332 + 542 + 18 + 9 + + + + + 11 + + + + + + + + + + 76 + 176 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 170 + 182 + 30 + + + + + 10 + + + + + + + 76 + 80 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 260 + 182 + 30 + + + + + 10 + + + + + + + + + + 180 + 530 + 182 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 180 + 485 + 182 + 30 + + + + + 10 + + + + + + + 76 + 491 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 215 + 182 + 30 + + + + + 10 + + + + + + + + + + 76 + 536 + 90 + 20 + + + + + 10 + + + + + + + + + + 315 + 620 + 90 + 30 + + + + + 10 + + + + + + + + + + 180 + 75 + 182 + 32 + + + + + 10 + + + + + + + + + + 76 + 266 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 221 + 90 + 20 + + + + + 10 + + + + + + + + + + 215 + 620 + 90 + 30 + + + + + 10 + + + + + + + + + + 76 + 311 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 305 + 182 + 32 + + + + + 10 + + + + + + + 76 + 356 + 100 + 25 + + + + + 10 + + + + + + + + + + 180 + 350 + 182 + 32 + + + + + 10 + + + + + + + + + + 76 + 401 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 395 + 182 + 32 + + + + + 10 + + + + + + + 76 + 446 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 440 + 182 + 32 + + + + + 10 + + + + + + + + + + 30 + 30 + 140 + 22 + + + + + 9 + + + + + + + + + + 0 + 0 + 432 + 673 + + + + + + + + + + 10 + 140 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 590 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + lbNetName + leNetName + lbConn + cbxAuth + lePassword + leUserName + lbUserName + cbxSecurity + lbPassword + btnConnect + cbxConn + lbAuth + lbSecurity + btnCancel + lbAnonyId + leAnonyId + checkBoxAutoPCA + cbxAutoPCA + lbPCAfile + lePCAfile + lbInnerAuth + cbxInnerAuth + checkBoxPwd + lbLeftupTitle + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifisecleap.cpp b/KylinNM/wireless-security/dlgconnhidwifisecleap.cpp new file mode 100644 index 0000000..a9d9e41 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecleap.cpp @@ -0,0 +1,343 @@ +/* + * 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 + +DlgConnHidWifiSecLeap::DlgConnHidWifiSecLeap(int type, QWidget *parent) : + WepOrWpa(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifiSecLeap) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbAuth->setStyleSheet(objQss.labelQss); + ui->lbUserName->setStyleSheet(objQss.labelQss); + ui->lbPassword->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->cbxAuth->setStyleSheet(objQss.cbxQss); + ui->cbxAuth->setView(new QListView()); + ui->leUserName->setStyleSheet(objQss.leQss); + ui->lePassword->setStyleSheet(objQss.leQss); + ui->checkBox->setStyleSheet(objQss.checkBoxQss); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + + ui->lbLeftupTitle->setText(tr("Add hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi安全性: + ui->lbAuth->setText(tr("Authentication")); //认证: + ui->lbUserName->setText(tr("Username")); //用户名: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + int status = system("nmcli connection show>/tmp/kylin-nm-connshow"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiSecLeap' failed");} + QFile file("/tmp/kylin-nm-connshow"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if(line.indexOf("wifi") != -1){ + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + ui->cbxSecurity->addItem("LEAP"); + ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + if (WepOrWpa == 0) { + ui->cbxSecurity->setCurrentIndex(5); + } else if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(6); + } + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogSecu())); + + ui->cbxAuth->addItem("TLS"); + ui->cbxAuth->addItem("LEAP"); + ui->cbxAuth->addItem("PWD"); + ui->cbxAuth->addItem("FAST"); + ui->cbxAuth->addItem(tr("Tunneled TLS"));//隧道 TLS + ui->cbxAuth->addItem(tr("Protected EAP (PEAP)")); //受保护的 EAP + ui->cbxAuth->setCurrentIndex(1); + connect(ui->cbxAuth,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogAuth())); + + ui->btnConnect->setEnabled(false); + + this->setFixedSize(432,487); + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 + **/ + ui->cbxConn->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxConn->view()->setParent(this); + ui->cbxConn->view()->hide(); + ui->cbxConn->installEventFilter(this); + + ui->cbxSecurity->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxSecurity->view()->setParent(this); + ui->cbxSecurity->view()->hide(); + ui->cbxSecurity->installEventFilter(this); + + connect(ui->cbxConn->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + Q_EMIT ui->cbxConn->setCurrentIndex(index.row()); + ui->cbxConn->view()->hide(); + }); + + connect(ui->cbxSecurity->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + ui->cbxSecurity->view()->hide(); + Q_EMIT ui->cbxSecurity->setCurrentIndex(index.row()); + }); + + ui->cbxConn->view()->setGeometry(QRect(ui->cbxConn->geometry().left(), ui->cbxConn->geometry().bottom(), ui->cbxConn->view()->width(), ui->cbxConn->view()->height())); + ui->cbxSecurity->view()->setGeometry(QRect(ui->cbxSecurity->geometry().left(), ui->cbxSecurity->geometry().bottom(), ui->cbxSecurity->view()->width(), ui->cbxSecurity->view()->height())); + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- + ** 手动绑定下拉框视图和下拉框 + **/ +} + +DlgConnHidWifiSecLeap::~DlgConnHidWifiSecLeap() +{ + delete ui; +} + +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- +** 手动绑定下拉框视图和下拉框 +**/ +bool DlgConnHidWifiSecLeap::eventFilter(QObject *obj, QEvent *ev) +{ + if(ev->type() == QEvent::MouseButtonPress) + { + if(obj == ui->cbxConn) + { + ui->cbxConn->view()->setVisible(!ui->cbxConn->view()->isVisible()); + if(ui->cbxConn->view()->isVisible()) + ui->cbxConn->view()->setFocus(); + } else if (obj == ui->cbxSecurity) + { + ui->cbxSecurity->view()->setVisible(!ui->cbxSecurity->view()->isVisible()); + if(ui->cbxSecurity->view()->isVisible()) + ui->cbxSecurity->view()->setFocus(); + } + } + return false; +} +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- +** 手动绑定下拉框视图和下拉框 +**/ + +void DlgConnHidWifiSecLeap::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiSecLeap::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiSecLeap::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +void DlgConnHidWifiSecLeap::changeDialogSecu() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, 0, this->parentWidget()); + connHidWifi->show(); + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, 0, this->parentWidget()); + connHidWifiWpa->show(); + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { + if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(5); + WepOrWpa = 0; + } + } else { + if (WepOrWpa == 0){ + ui->cbxSecurity->setCurrentIndex(6); + WepOrWpa = 1; + } + } +} + +void DlgConnHidWifiSecLeap::changeDialogAuth() +{ + if(ui->cbxAuth->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(WepOrWpa, this->parentWidget()); + connHidWifiSecTls->show(); + } else if(ui->cbxAuth->currentIndex()==1) { + qDebug()<<"it's not need to change dialog"; + } else if(ui->cbxAuth->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPwd *connHidWifiSecPwd = new DlgConnHidWifiSecPwd(WepOrWpa, this->parentWidget()); + connHidWifiSecPwd->show(); + } else if(ui->cbxAuth->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecFast *connHidWifiSecFast = new DlgConnHidWifiSecFast(WepOrWpa, this->parentWidget()); + connHidWifiSecFast->show(); + } else if(ui->cbxAuth->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTunnelTLS *connHidWifiSecTuTls = new DlgConnHidWifiSecTunnelTLS(WepOrWpa, this->parentWidget()); + connHidWifiSecTuTls->show(); + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPeap *connHidWifiSecPeap = new DlgConnHidWifiSecPeap(WepOrWpa, this->parentWidget()); + connHidWifiSecPeap->show(); + } +} + +void DlgConnHidWifiSecLeap::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecLeap::on_btnConnect_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecLeap::on_checkBox_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword ->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecLeap::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecLeap::on_leUserName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecLeap::on_lePassword_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecLeap::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifisecleap.h b/KylinNM/wireless-security/dlgconnhidwifisecleap.h new file mode 100644 index 0000000..4336b65 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecleap.h @@ -0,0 +1,77 @@ +/* + * 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 +#include + +namespace Ui { +class DlgConnHidWifiSecLeap; +} + +class DlgConnHidWifiSecLeap : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiSecLeap(int type, QWidget *parent = 0); + ~DlgConnHidWifiSecLeap(); + +protected: + void paintEvent(QPaintEvent *event); + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 过滤点击事件 + **/ + bool eventFilter(QObject *obj, QEvent *ev) override; + +public slots: + void changeDialogSecu(); + void changeDialogAuth(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_checkBox_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_leUserName_textEdited(const QString &arg1); + + void on_lePassword_textEdited(const QString &arg1); + +private: + Ui::DlgConnHidWifiSecLeap *ui; + int WepOrWpa = 0;//0 WEP;1WPA + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss, checkBoxCAQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFISECLEAP_H diff --git a/KylinNM/wireless-security/dlgconnhidwifisecleap.ui b/KylinNM/wireless-security/dlgconnhidwifisecleap.ui new file mode 100644 index 0000000..9664fd8 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecleap.ui @@ -0,0 +1,354 @@ + + + DlgConnHidWifiSecLeap + + + + 0 + 0 + 432 + 487 + + + + Connect to Hidden Wi-Fi Network + + + + + 175 + 215 + 182 + 32 + + + + + 10 + + + + + + + + + + 175 + 350 + 182 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 332 + 362 + 18 + 9 + + + + + 10 + + + + + + + + + + 76 + 176 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 221 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 305 + 182 + 32 + + + + + 10 + + + + + + + 315 + 440 + 90 + 30 + + + + + 10 + + + + + + + + + + 175 + 75 + 182 + 32 + + + + + 10 + + + + + + + + + + 76 + 311 + 90 + 20 + + + + + 10 + + + + + + + + + + 215 + 440 + 90 + 30 + + + + + 10 + + + + + + + + + + 175 + 260 + 182 + 32 + + + + + 10 + + + + + + + + + + 76 + 266 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 170 + 182 + 32 + + + + + 10 + + + + + + + 76 + 356 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 80 + 90 + 20 + + + + + 10 + + + + + + + + + + 30 + 30 + 140 + 22 + + + + + + + + + + 0 + 0 + 432 + 487 + + + + + + + + + + 10 + 140 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 410 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + cbxSecurity + lePassword + checkBox + lbNetName + lbSecurity + leUserName + btnConnect + cbxConn + lbUserName + btnCancel + cbxAuth + lbAuth + leNetName + lbPassword + lbConn + lbLeftupTitle + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifisecpeap.cpp b/KylinNM/wireless-security/dlgconnhidwifisecpeap.cpp new file mode 100644 index 0000000..50a0c9f --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecpeap.cpp @@ -0,0 +1,461 @@ +/* + * 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 + +DlgConnHidWifiSecPeap::DlgConnHidWifiSecPeap(int type, QWidget *parent) : + WepOrWpa(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifiSecPeap) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbAuth->setStyleSheet(objQss.labelQss); + ui->lbAnonyId->setStyleSheet(objQss.labelQss); + ui->lbDomain->setStyleSheet(objQss.labelQss); + ui->lbCA->setStyleSheet(objQss.labelQss); + ui->lbCaPwd->setStyleSheet(objQss.labelQss); + ui->lbPEAPver->setStyleSheet(objQss.labelQss); + ui->lbInnerAuth->setStyleSheet(objQss.labelQss); + ui->lbUserName->setStyleSheet(objQss.labelQss); + ui->lbPassword->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->cbxAuth->setStyleSheet(objQss.cbxQss); + ui->cbxAuth->setView(new QListView()); + ui->leAnonyId->setStyleSheet(objQss.leQss); + ui->leDomain->setStyleSheet(objQss.leQss); + ui->cbxCA->setStyleSheet(objQss.cbxQss); + ui->cbxCA->setView(new QListView()); + ui->leCaPwd->setStyleSheet(objQss.leQss); + ui->checkBoxPwd->setStyleSheet(objQss.checkBoxQss); + ui->checkBoxCA->setStyleSheet(objQss.checkBoxCAQss); + ui->cbxPEAPver->setStyleSheet(objQss.cbxQss); + ui->cbxPEAPver->setView(new QListView()); + ui->cbxInnerAuth->setStyleSheet(objQss.cbxQss); + ui->cbxInnerAuth->setView(new QListView()); + ui->leUserName->setStyleSheet(objQss.leQss); + ui->lePassword->setStyleSheet(objQss.leQss); + ui->checkBoxPwdSec->setStyleSheet(objQss.checkBoxQss); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + + + ui->lbLeftupTitle->setText(tr("Add hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi安全性: + ui->lbAuth->setText(tr("Authentication")); //认证: + ui->lbAnonyId->setText(tr("Anonymous identity")); //匿名身份: + ui->lbDomain->setText(tr("Domain")); //域名: + ui->lbCA->setText(tr("CA certificate")); //CA 证书: + ui->lbCaPwd->setText(tr("CA certificate password")); //CA 证书密码: + ui->checkBoxCA->setText(tr("No CA certificate is required")); //不需要CA证书 + ui->lbPEAPver->setText(tr("PEAP version")); //PEAP版本: + ui->lbInnerAuth->setText(tr("Inner authentication")); //内部认证: + ui->lbUserName->setText(tr("Username")); //用户名: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem("新建..."); + int status = system("nmcli connection show>/tmp/kylin-nm-connshow"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiSecPeap' failed");} + QFile file("/tmp/kylin-nm-connshow"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if(line.indexOf("wifi") != -1){ + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + ui->cbxSecurity->addItem("LEAP"); + ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + if (WepOrWpa == 0) { + ui->cbxSecurity->setCurrentIndex(5); + } else if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(6); + } + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogSecu())); + + ui->cbxAuth->addItem("TLS"); + ui->cbxAuth->addItem("LEAP"); + ui->cbxAuth->addItem("PWD"); + ui->cbxAuth->addItem("FAST"); + ui->cbxAuth->addItem(tr("Tunneled TLS"));//隧道 TLS + ui->cbxAuth->addItem(tr("Protected EAP (PEAP)")); //受保护的 EAP + ui->cbxAuth->setCurrentIndex(5); + connect(ui->cbxAuth,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogAuth())); + + ui->cbxCA->addItem(tr("None")); //无 + ui->cbxCA->addItem(tr("Choose from file")); //从文件选择... + ui->cbxCA->setCurrentIndex(0); + + ui->cbxPEAPver->addItem(tr("Automatic")); //自动 + ui->cbxPEAPver->addItem(tr("Version 0")); //版本 0 + ui->cbxPEAPver->addItem(tr("Version 1")); //版本 1 + ui->cbxPEAPver->setCurrentIndex(0); + + ui->cbxInnerAuth->addItem("MSCHAPv2"); + ui->cbxInnerAuth->addItem("MDS"); + ui->cbxInnerAuth->addItem("GTC"); + ui->cbxInnerAuth->setCurrentIndex(0); + + ui->btnConnect->setEnabled(false); + + this->setFixedSize(432,700); + +} + +DlgConnHidWifiSecPeap::~DlgConnHidWifiSecPeap() +{ + delete ui; +} + +void DlgConnHidWifiSecPeap::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiSecPeap::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiSecPeap::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +void DlgConnHidWifiSecPeap::changeDialogSecu() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, 0,this->parentWidget()); + connHidWifi->show(); + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, 0, this->parentWidget()); + connHidWifiWpa->show(); + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { + if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(5); + WepOrWpa = 0; + } + } else { + if (WepOrWpa == 0){ + ui->cbxSecurity->setCurrentIndex(6); + WepOrWpa = 1; + } + } +} + +void DlgConnHidWifiSecPeap::changeDialogAuth() +{ + if(ui->cbxAuth->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(WepOrWpa, this->parentWidget()); + connHidWifiSecTls->show(); + } else if(ui->cbxAuth->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecLeap *connHidWifiSecLeap = new DlgConnHidWifiSecLeap(WepOrWpa, this->parentWidget()); + connHidWifiSecLeap->show(); + } else if(ui->cbxAuth->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPwd *connHidWifiSecPwd = new DlgConnHidWifiSecPwd(WepOrWpa); + connHidWifiSecPwd->show(); + } else if(ui->cbxAuth->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecFast *connHidWifiSecFast = new DlgConnHidWifiSecFast(WepOrWpa); + connHidWifiSecFast->show(); + } else if(ui->cbxAuth->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTunnelTLS *connHidWifiSecTuTls = new DlgConnHidWifiSecTunnelTLS(WepOrWpa); + connHidWifiSecTuTls->show(); + } else { + qDebug()<<"it's not need to change dialog"; + } +} + +void DlgConnHidWifiSecPeap::on_cbxCA_currentIndexChanged(const QString &arg1) +{ + if (ui->cbxCA->currentIndex() == 0){ + ui->leCaPwd->setText(""); + ui->lbCaPwd->setEnabled(false); + ui->leCaPwd->setEnabled(false); + } else { + ui->leCaPwd->setText(""); + ui->lbCaPwd->setEnabled(true); + ui->leCaPwd->setEnabled(true); + } +} + +void DlgConnHidWifiSecPeap::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecPeap::on_btnConnect_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecPeap::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->leCaPwd->setEchoMode(QLineEdit::Password); + } else { + ui->leCaPwd->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecPeap::on_checkBoxCA_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->cbxCA->setCurrentIndex(0); + ui->leCaPwd->setText(""); + ui->lbCA->setEnabled(true); + ui->cbxCA->setEnabled(true); + } else { + ui->cbxCA->setCurrentIndex(0); + ui->leCaPwd->setText(""); + ui->lbCA->setEnabled(false); + ui->cbxCA->setEnabled(false); + } +} + +void DlgConnHidWifiSecPeap::on_checkBoxPwdSec_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecPeap::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecPeap::on_leAnonyId_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecPeap::on_leDomain_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecPeap::on_leCaPwd_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecPeap::on_leUserName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecPeap::on_lePassword_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecPeap::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifisecpeap.h b/KylinNM/wireless-security/dlgconnhidwifisecpeap.h new file mode 100644 index 0000000..d0361df --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecpeap.h @@ -0,0 +1,84 @@ +/* + * 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 +#include + +namespace Ui { +class DlgConnHidWifiSecPeap; +} + +class DlgConnHidWifiSecPeap : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiSecPeap(int type, QWidget *parent = 0); + ~DlgConnHidWifiSecPeap(); + +protected: + void paintEvent(QPaintEvent *event); + +public slots: + void changeDialogSecu(); + void changeDialogAuth(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_cbxCA_currentIndexChanged(const QString &arg1); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_checkBoxCA_stateChanged(int arg1); + + void on_checkBoxPwdSec_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_leAnonyId_textEdited(const QString &arg1); + + void on_leDomain_textEdited(const QString &arg1); + + void on_leCaPwd_textEdited(const QString &arg1); + + void on_leUserName_textEdited(const QString &arg1); + + void on_lePassword_textEdited(const QString &arg1); + +private: + Ui::DlgConnHidWifiSecPeap *ui; + int WepOrWpa = 0;//0 WEP;1WPA + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss, checkBoxCAQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFISECPEAP_H diff --git a/KylinNM/wireless-security/dlgconnhidwifisecpeap.ui b/KylinNM/wireless-security/dlgconnhidwifisecpeap.ui new file mode 100644 index 0000000..82bc354 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecpeap.ui @@ -0,0 +1,614 @@ + + + DlgConnHidWifiSecPeap + + + + 0 + 0 + 432 + 700 + + + + Connect to Hidden Wi-Fi Network + + + + + 180 + 141 + 200 + 32 + + + + + 10 + + + + + + + 180 + 341 + 200 + 32 + + + + + 10 + + + + + + + + + + 76 + 76 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 301 + 200 + 32 + + + + + 10 + + + + + + + 180 + 71 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 381 + 200 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 315 + 650 + 90 + 30 + + + + + 10 + + + + + + + + + + 180 + 181 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 261 + 200 + 32 + + + + + 10 + + + + + + + 183 + 421 + 200 + 25 + + + + + 10 + + + + + + + + + + 76 + 146 + 90 + 20 + + + + + 10 + + + + + + + + + + 215 + 650 + 90 + 30 + + + + + 10 + + + + + + + + + + 76 + 306 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 386 + 90 + 20 + + + + + 10 + + + + + + + + + + 357 + 593 + 18 + 9 + + + + + 10 + + + + + + + + + + 357 + 393 + 18 + 9 + + + + + 10 + + + + + + + + + + 76 + 186 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 461 + 200 + 32 + + + + + 10 + + + + + + + + + + 76 + 226 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 466 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 221 + 200 + 32 + + + + + 10 + + + + + + + + + + 76 + 346 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 266 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 586 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 541 + 200 + 32 + + + + + 10 + + + + + + + 180 + 501 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 581 + 200 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 76 + 506 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 546 + 90 + 20 + + + + + 10 + + + + + + + + + + 0 + 0 + 432 + 700 + + + + + + + + + + 30 + 28 + 140 + 22 + + + + + + + + + + 10 + 121 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 631 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + leNetName + cbxCA + lbConn + leDomain + cbxConn + leCaPwd + btnConnect + cbxSecurity + leAnonyId + checkBoxCA + lbNetName + btnCancel + lbDomain + lbCaPwd + checkBoxPwd + lbSecurity + cbxPEAPver + lbAuth + lbPEAPver + cbxAuth + lbCA + lbAnonyId + lbPassword + leUserName + cbxInnerAuth + lePassword + lbInnerAuth + lbUserName + checkBoxPwdSec + lbLeftupTitle + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifisecpwd.cpp b/KylinNM/wireless-security/dlgconnhidwifisecpwd.cpp new file mode 100644 index 0000000..94b90d7 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecpwd.cpp @@ -0,0 +1,291 @@ +/* + * 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 + +DlgConnHidWifiSecPwd::DlgConnHidWifiSecPwd(int type, QWidget *parent) : + WepOrWpa(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifiSecPwd) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbAuth->setStyleSheet(objQss.labelQss); + ui->lbUserName->setStyleSheet(objQss.labelQss); + ui->lbPassword->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->cbxAuth->setStyleSheet(objQss.cbxQss); + ui->cbxAuth->setView(new QListView()); + ui->leUserName->setStyleSheet(objQss.leQss); + ui->lePassword->setStyleSheet(objQss.leQss); + ui->checkBox->setStyleSheet(objQss.checkBoxQss); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + + + ui->lbLeftupTitle->setText(tr("Add hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi安全性: + ui->lbAuth->setText(tr("Authentication")); //认证: + ui->lbUserName->setText(tr("Username")); //用户名: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + int status = system("nmcli connection show>/tmp/kylin-nm-connshow"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiSecPwd' failed");} + QFile file("/tmp/kylin-nm-connshow"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if(line.indexOf("wifi") != -1){ + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + ui->cbxSecurity->addItem("LEAP"); + ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + if (WepOrWpa == 0) { + ui->cbxSecurity->setCurrentIndex(5); + } else if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(6); + } + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogSecu())); + + ui->cbxAuth->addItem("TLS"); + ui->cbxAuth->addItem("LEAP"); + ui->cbxAuth->addItem("PWD"); + ui->cbxAuth->addItem("FAST"); + ui->cbxAuth->addItem(tr("Tunneled TLS"));//隧道 TLS + ui->cbxAuth->addItem(tr("Protected EAP (PEAP)")); //受保护的 EAP + ui->cbxAuth->setCurrentIndex(2); + connect(ui->cbxAuth,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogAuth())); + + ui->btnConnect->setEnabled(false); + + this->setFixedSize(432,487); + +} + +DlgConnHidWifiSecPwd::~DlgConnHidWifiSecPwd() +{ + delete ui; +} + +void DlgConnHidWifiSecPwd::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiSecPwd::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiSecPwd::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +void DlgConnHidWifiSecPwd::changeDialogSecu() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, 0, this->parentWidget()); + connHidWifi->show(); + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, 0, this->parentWidget()); + connHidWifiWpa->show(); + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { + if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(5); + WepOrWpa = 0; + } + } else { + if (WepOrWpa == 0){ + ui->cbxSecurity->setCurrentIndex(6); + WepOrWpa = 1; + } + } +} + +void DlgConnHidWifiSecPwd::changeDialogAuth() +{ + if(ui->cbxAuth->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(WepOrWpa, this->parentWidget()); + connHidWifiSecTls->show(); + } else if(ui->cbxAuth->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecLeap *connHidWifiSecLeap = new DlgConnHidWifiSecLeap(WepOrWpa, this->parentWidget()); + connHidWifiSecLeap->show(); + } else if(ui->cbxAuth->currentIndex()==2) { + qDebug()<<"it's not need to change dialog"; + } else if(ui->cbxAuth->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecFast *connHidWifiSecFast = new DlgConnHidWifiSecFast(WepOrWpa); + connHidWifiSecFast->show(); + } else if(ui->cbxAuth->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTunnelTLS *connHidWifiSecTuTls = new DlgConnHidWifiSecTunnelTLS(WepOrWpa); + connHidWifiSecTuTls->show(); + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPeap *connHidWifiSecPeap = new DlgConnHidWifiSecPeap(WepOrWpa); + connHidWifiSecPeap->show(); + } +} + +void DlgConnHidWifiSecPwd::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecPwd::on_btnConnect_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecPwd::on_checkBox_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword ->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecPwd::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecPwd::on_leUserName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecPwd::on_lePassword_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecPwd::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifisecpwd.h b/KylinNM/wireless-security/dlgconnhidwifisecpwd.h new file mode 100644 index 0000000..d44250d --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecpwd.h @@ -0,0 +1,72 @@ +/* + * 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 +#include + +namespace Ui { +class DlgConnHidWifiSecPwd; +} + +class DlgConnHidWifiSecPwd : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiSecPwd(int type, QWidget *parent = 0); + ~DlgConnHidWifiSecPwd(); + +protected: + void paintEvent(QPaintEvent *event); + +public slots: + void changeDialogSecu(); + void changeDialogAuth(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_checkBox_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_leUserName_textEdited(const QString &arg1); + + void on_lePassword_textEdited(const QString &arg1); + +private: + Ui::DlgConnHidWifiSecPwd *ui; + int WepOrWpa = 0;//0 WEP;1WPA + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss, checkBoxCAQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFISECPWD_H diff --git a/KylinNM/wireless-security/dlgconnhidwifisecpwd.ui b/KylinNM/wireless-security/dlgconnhidwifisecpwd.ui new file mode 100644 index 0000000..7dc8cba --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisecpwd.ui @@ -0,0 +1,354 @@ + + + DlgConnHidWifiSecPwd + + + + 0 + 0 + 432 + 487 + + + + Connect to Hidden Wi-Fi Network + + + + + 333 + 363 + 18 + 9 + + + + + 10 + + + + + + + + + + 215 + 440 + 90 + 30 + + + + + 10 + + + + + + + + + + 0 + 0 + 432 + 487 + + + + + + + + + + 30 + 30 + 140 + 22 + + + + + + + + + + 175 + 170 + 182 + 32 + + + + + 10 + + + + + + + 76 + 266 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 311 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 80 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 75 + 182 + 32 + + + + + 10 + + + + + + + + + + 315 + 440 + 90 + 30 + + + + + 10 + + + + + + + + + + 175 + 215 + 182 + 32 + + + + + 10 + + + + + + + + + + 175 + 305 + 182 + 32 + + + + + 10 + + + + + + + 175 + 350 + 182 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 76 + 176 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 221 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 356 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 260 + 182 + 32 + + + + + 10 + + + + + + + + + + 10 + 140 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 410 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + btnCancel + leNetName + lbAuth + lbUserName + lbConn + cbxConn + btnConnect + cbxSecurity + leUserName + lePassword + lbNetName + lbSecurity + lbPassword + cbxAuth + lbLeftupTitle + lineUp + lineDown + checkBox + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifisectls.cpp b/KylinNM/wireless-security/dlgconnhidwifisectls.cpp new file mode 100644 index 0000000..5a61d76 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisectls.cpp @@ -0,0 +1,628 @@ +/* + * 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 + +DlgConnHidWifiSecTls::DlgConnHidWifiSecTls(int type, QWidget *parent) : + WepOrWpa(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifiSecTls) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbAuth->setStyleSheet(objQss.labelQss); + ui->lbIdentity->setStyleSheet(objQss.labelQss); + ui->lbDomain->setStyleSheet(objQss.labelQss); + ui->lbCA->setStyleSheet(objQss.labelQss); + ui->lbCaPwd->setStyleSheet(objQss.labelQss); + ui->lbUserCertify->setStyleSheet(objQss.labelQss); + ui->lbUserCertifyPwd->setStyleSheet(objQss.labelQss); + ui->lbUserPriKey->setStyleSheet(objQss.labelQss); + ui->lbUserKeyPwd->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->cbxAuth->setStyleSheet(objQss.cbxQss); + ui->cbxAuth->setView(new QListView()); + ui->leIdentity->setStyleSheet(objQss.leQss); + ui->leDomain->setStyleSheet(objQss.leQss); + ui->cbxCA->setStyleSheet(objQss.cbxQss); + ui->cbxCA->setView(new QListView()); + ui->leCaPwd->setStyleSheet(objQss.leQss); + ui->checkBoxPwd->setStyleSheet(objQss.checkBoxQss); + ui->checkBoxCA->setStyleSheet(objQss.checkBoxCAQss); + ui->cbxUserCertify->setStyleSheet(objQss.cbxQss); + ui->cbxUserCertify->setView(new QListView()); + ui->leUserCertifyPwd->setStyleSheet(objQss.leQss); + ui->cbxUserPriKey->setStyleSheet(objQss.cbxQss); + ui->cbxUserPriKey->setView(new QListView()); + ui->leUserKeyPwd->setStyleSheet(objQss.leQss); + ui->checkBoxPwdSec->setStyleSheet(objQss.checkBoxQss); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnCancelQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + ui->checkBoxCA->setFocusPolicy(Qt::NoFocus); + + ui->lbLeftupTitle->setText(tr("Add hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi安全性: + ui->lbAuth->setText(tr("Authentication")); //认证: + ui->lbIdentity->setText(tr("Identity")); //身份: + ui->lbDomain->setText(tr("Domain")); //域名: + ui->lbCA->setText(tr("CA certificate")); //CA 证书: + ui->lbCaPwd->setText(tr("CA certificate password")); //CA 证书密码: + ui->checkBoxCA->setText(tr("No CA certificate is required")); //不需要CA证书 + ui->lbUserCertify->setText(tr("User certificate")); //用户证书: + ui->lbUserCertifyPwd->setText(tr("User certificate password")); //用户证书密码: + ui->lbUserPriKey->setText(tr("User private key")); //用户私钥: + ui->lbUserKeyPwd->setText(tr("User key password")); //用户密钥密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + int status = system("nmcli connection show>/tmp/kylin-nm-connshow"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiSecTls' failed");} + QFile file("/tmp/kylin-nm-connshow"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if(line.indexOf("wifi") != -1){ + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + ui->cbxSecurity->addItem("LEAP"); + ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + if (WepOrWpa == 0) { + ui->cbxSecurity->setCurrentIndex(5); + } else if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(6); + } + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogSecu())); + + ui->cbxAuth->addItem("TLS"); + ui->cbxAuth->addItem("LEAP"); + ui->cbxAuth->addItem("PWD"); + ui->cbxAuth->addItem("FAST"); + ui->cbxAuth->addItem(tr("Tunneled TLS"));//隧道 TLS + ui->cbxAuth->addItem(tr("Protected EAP (PEAP)")); //受保护的 EAP + ui->cbxAuth->setCurrentIndex(0); + connect(ui->cbxAuth,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogAuth())); + + ui->cbxCA->addItem(tr("None")); //无 + ui->cbxCA->addItem(tr("Choose from file")); //从文件选择... + ui->cbxCA->setCurrentIndex(0); + + ui->cbxUserCertify->addItem(tr("None")); //无 + ui->cbxUserCertify->addItem(tr("Choose from file")); //从文件选择... + ui->cbxUserCertify->setCurrentIndex(0); + + ui->cbxUserPriKey->addItem(tr("None")); //无 + ui->cbxUserPriKey->addItem(tr("Choose from file")); //从文件选择... + ui->cbxUserPriKey->setCurrentIndex(0); + + ui->btnConnect->setEnabled(false); + + ui->lbCaPwd->setEnabled(false); + ui->leCaPwd->setEnabled(false); + + ui->lbUserCertifyPwd->setEnabled(false); + ui->leUserCertifyPwd->setEnabled(false); + + ui->lbUserPriKey->setEnabled(false); + ui->cbxUserPriKey->setEnabled(false); + + ui->lbUserKeyPwd->setEnabled(false); + ui->leUserKeyPwd->setEnabled(false); + + this->setFixedSize(432,705); + +} + +DlgConnHidWifiSecTls::~DlgConnHidWifiSecTls() +{ + delete ui; +} + +void DlgConnHidWifiSecTls::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiSecTls::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiSecTls::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +void DlgConnHidWifiSecTls::changeDialogSecu() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, 0, this->parentWidget()); + connHidWifi->show(); + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, 0, this->parentWidget()); + connHidWifiWpa->show(); + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { + if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(5); + WepOrWpa = 0; + } + } else { + if (WepOrWpa == 0){ + ui->cbxSecurity->setCurrentIndex(6); + WepOrWpa = 1; + } + } +} + +void DlgConnHidWifiSecTls::changeDialogAuth() +{ + if(ui->cbxAuth->currentIndex()==0){ + qDebug()<<"it's not need to change dialog"; + } else if(ui->cbxAuth->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecLeap *connHidWifiSecLeap = new DlgConnHidWifiSecLeap(WepOrWpa); + connHidWifiSecLeap->show(); + } else if(ui->cbxAuth->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPwd *connHidWifiSecPwd = new DlgConnHidWifiSecPwd(WepOrWpa); + connHidWifiSecPwd->show(); + } else if(ui->cbxAuth->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecFast *connHidWifiSecFast = new DlgConnHidWifiSecFast(WepOrWpa); + connHidWifiSecFast->show(); + } else if(ui->cbxAuth->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTunnelTLS *connHidWifiSecTuTls = new DlgConnHidWifiSecTunnelTLS(WepOrWpa); + connHidWifiSecTuTls->show(); + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPeap *connHidWifiSecPeap = new DlgConnHidWifiSecPeap(WepOrWpa); + connHidWifiSecPeap->show(); + } +} + +void DlgConnHidWifiSecTls::on_cbxCA_currentIndexChanged(const QString &arg1) +{ + if (ui->cbxCA->currentIndex() == 0){ + ui->leCaPwd->setText(""); + ui->lbCaPwd->setEnabled(false); + ui->leCaPwd->setEnabled(false); + }else{ + ui->leCaPwd->setText(""); + ui->lbCaPwd->setEnabled(true); + ui->leCaPwd->setEnabled(true); + } +} + +void DlgConnHidWifiSecTls::on_cbxUserCertify_currentIndexChanged(const QString &arg1) +{ + if (ui->cbxUserCertify->currentIndex() == 0){ + ui->leUserCertifyPwd->setText(""); + ui->lbUserCertifyPwd->setEnabled(false); + ui->leUserCertifyPwd->setEnabled(false); + + ui->lbUserPriKey->setEnabled(false); + ui->cbxUserPriKey->setEnabled(false); + ui->cbxUserPriKey->setCurrentIndex(0); + + ui->leUserKeyPwd->setText(""); + ui->lbUserKeyPwd->setEnabled(false); + ui->leUserKeyPwd->setEnabled(false); + }else{ + ui->leUserCertifyPwd->setText(""); + ui->lbUserCertifyPwd->setEnabled(true); + ui->leUserCertifyPwd->setEnabled(true); + + ui->lbUserPriKey->setEnabled(true); + ui->cbxUserPriKey->setEnabled(true); + ui->cbxUserPriKey->setCurrentIndex(0); + + ui->leUserKeyPwd->setText(""); + ui->lbUserKeyPwd->setEnabled(false); + ui->leUserKeyPwd->setEnabled(false); + } +} + +void DlgConnHidWifiSecTls::on_cbxUserPriKey_currentIndexChanged(const QString &arg1) +{ + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->leUserKeyPwd->setText(""); + ui->lbUserKeyPwd->setEnabled(false); + ui->leUserKeyPwd->setEnabled(false); + }else{ + ui->leUserKeyPwd->setText(""); + ui->lbUserKeyPwd->setEnabled(true); + ui->leUserKeyPwd->setEnabled(true); + } +} + +void DlgConnHidWifiSecTls::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecTls::on_btnConnect_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecTls::on_checkBoxCA_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->cbxCA->setCurrentIndex(0); + ui->lbCA->setEnabled(true); + ui->cbxCA->setEnabled(true); + } else { + ui->cbxCA->setCurrentIndex(0); + ui->lbCA->setEnabled(false); + ui->cbxCA->setEnabled(false); + } +} + +void DlgConnHidWifiSecTls::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->leCaPwd->setEchoMode(QLineEdit::Password); + } else { + ui->leCaPwd->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecTls::on_checkBoxPwdSec_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->leUserCertifyPwd->setEchoMode(QLineEdit::Password); + ui->leUserKeyPwd->setEchoMode(QLineEdit::Password); + } else { + ui->leUserCertifyPwd->setEchoMode(QLineEdit::Normal); + ui->leUserKeyPwd->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecTls::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leIdentity->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxCA->currentIndex() == 0){ + if (ui->cbxUserCertify->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else { + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } else { + if (ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserCertify->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else { + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } + } + } +} + +void DlgConnHidWifiSecTls::on_leIdentity_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leIdentity->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxCA->currentIndex() == 0){ + if (ui->cbxUserCertify->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else { + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } else { + if (ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserCertify->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else { + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } + } + } +} + +void DlgConnHidWifiSecTls::on_leDomain_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leIdentity->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxCA->currentIndex() == 0){ + if (ui->cbxUserCertify->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else { + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } else { + if (ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserCertify->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else { + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } + } + } +} + +void DlgConnHidWifiSecTls::on_leCaPwd_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leIdentity->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserCertify->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else { + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } +} + +void DlgConnHidWifiSecTls::on_leUserCertifyPwd_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leIdentity->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxCA->currentIndex() == 0){ + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } else { + if (ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxUserPriKey->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } + } +} + +void DlgConnHidWifiSecTls::on_leUserKeyPwd_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leIdentity->text() == ""){ + ui->btnConnect->setEnabled(false); + } else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + if (ui->cbxCA->currentIndex() == 0){ + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } else { + if (ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->leUserCertifyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserKeyPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + } else{ + ui->btnConnect->setEnabled(true); + } + } + } + } +} + +void DlgConnHidWifiSecTls::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifisectls.h b/KylinNM/wireless-security/dlgconnhidwifisectls.h new file mode 100644 index 0000000..c133807 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisectls.h @@ -0,0 +1,88 @@ +/* + * 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 +#include + +namespace Ui { +class DlgConnHidWifiSecTls; +} + +class DlgConnHidWifiSecTls : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiSecTls(int type, QWidget *parent = 0); + ~DlgConnHidWifiSecTls(); + +protected: + void paintEvent(QPaintEvent *event); + +public slots: + void changeDialogSecu(); + void changeDialogAuth(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_checkBoxCA_stateChanged(int arg1); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_checkBoxPwdSec_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_leIdentity_textEdited(const QString &arg1); + + void on_leDomain_textEdited(const QString &arg1); + + void on_leCaPwd_textEdited(const QString &arg1); + + void on_leUserCertifyPwd_textEdited(const QString &arg1); + + void on_leUserKeyPwd_textEdited(const QString &arg1); + + void on_cbxCA_currentIndexChanged(const QString &arg1); + + void on_cbxUserCertify_currentIndexChanged(const QString &arg1); + + void on_cbxUserPriKey_currentIndexChanged(const QString &arg1); + +private: + Ui::DlgConnHidWifiSecTls *ui; + int WepOrWpa = 0;//0 WEP;1WPA + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss, checkBoxCAQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFISECTLS_H diff --git a/KylinNM/wireless-security/dlgconnhidwifisectls.ui b/KylinNM/wireless-security/dlgconnhidwifisectls.ui new file mode 100644 index 0000000..969ab4f --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisectls.ui @@ -0,0 +1,617 @@ + + + DlgConnHidWifiSecTls + + + + 0 + 0 + 432 + 705 + + + + Connect to Hidden Wi-Fi Network + + + + + 180 + 185 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 145 + 200 + 32 + + + + + 10 + + + + + + + 180 + 505 + 200 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 180 + 385 + 200 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 357 + 397 + 18 + 9 + + + + + 10 + + + + + + + + + + 76 + 80 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 150 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 310 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 350 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 465 + 200 + 32 + + + + + 10 + + + + + + + + + + 76 + 270 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 510 + 90 + 20 + + + + + 10 + + + + + + + + + + 215 + 660 + 90 + 30 + + + + + 10 + + + + + + + + + + 76 + 590 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 345 + 200 + 32 + + + + + 10 + + + + + + + + + + 76 + 550 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 390 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 305 + 200 + 32 + + + + + 10 + + + + + + + 357 + 597 + 18 + 9 + + + + + 10 + + + + + + + + + + 180 + 265 + 200 + 32 + + + + + 10 + + + + + + + 180 + 585 + 200 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 76 + 470 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 230 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 225 + 200 + 32 + + + + + 10 + + + + + + + + + + 315 + 660 + 90 + 30 + + + + + 10 + + + + + + + + + + 180 + 425 + 200 + 25 + + + + + 10 + + + + + + + + + + 180 + 75 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 545 + 200 + 32 + + + + + 10 + + + + + + + + + + 76 + 190 + 90 + 20 + + + + + 10 + + + + + + + + + + 0 + 0 + 432 + 705 + + + + + + + + + + 30 + 30 + 140 + 22 + + + + + + + + + + 10 + 125 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 640 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + cbxSecurity + leNetName + leUserCertifyPwd + leCaPwd + checkBoxPwd + lbConn + lbNetName + lbDomain + lbCA + cbxUserCertify + lbIdentity + lbUserCertifyPwd + btnCancel + lbUserKeyPwd + cbxCA + lbUserPriKey + lbCaPwd + leDomain + leIdentity + leUserKeyPwd + lbUserCertify + lbAuth + cbxAuth + btnConnect + checkBoxCA + cbxConn + cbxUserPriKey + lbSecurity + lbLeftupTitle + checkBoxPwdSec + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifisectunneltls.cpp b/KylinNM/wireless-security/dlgconnhidwifisectunneltls.cpp new file mode 100644 index 0000000..fb02a60 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisectunneltls.cpp @@ -0,0 +1,457 @@ +/* + * 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 + +DlgConnHidWifiSecTunnelTLS::DlgConnHidWifiSecTunnelTLS(int type, QWidget *parent) : + WepOrWpa(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifiSecTunnelTLS) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbAuth->setStyleSheet(objQss.labelQss); + ui->lbAnonyId->setStyleSheet(objQss.labelQss); + ui->lbDomain->setStyleSheet(objQss.labelQss); + ui->lbCA->setStyleSheet(objQss.labelQss); + ui->lbCaPwd->setStyleSheet(objQss.labelQss); + ui->lbInnerAuth->setStyleSheet(objQss.labelQss); + ui->lbUserName->setStyleSheet(objQss.labelQss); + ui->lbPassword->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->cbxAuth->setStyleSheet(objQss.cbxQss); + ui->cbxAuth->setView(new QListView()); + ui->leAnonyId->setStyleSheet(objQss.leQss); + ui->leDomain->setStyleSheet(objQss.leQss); + ui->cbxCA->setStyleSheet(objQss.cbxQss); + ui->cbxCA->setView(new QListView()); + ui->leCaPwd->setStyleSheet(objQss.leQss); + ui->checkBoxPwd->setStyleSheet(objQss.checkBoxQss); + ui->checkBoxCA->setStyleSheet(objQss.checkBoxCAQss); + ui->cbxInnerAuth->setStyleSheet(objQss.cbxQss); + ui->cbxInnerAuth->setView(new QListView()); + ui->leUserName->setStyleSheet(objQss.leQss); + ui->lePassword->setStyleSheet(objQss.leQss); + ui->checkBoxPwdSec->setStyleSheet(objQss.checkBoxQss); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + ui->checkBoxCA->setFocusPolicy(Qt::NoFocus); + + + ui->lbLeftupTitle->setText(tr("Add hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi安全性: + ui->lbAuth->setText(tr("Authentication")); //认证: + ui->lbAnonyId->setText(tr("Anonymous identity")); //匿名身份: + ui->lbDomain->setText(tr("Domain")); //域名: + ui->lbCA->setText(tr("CA certificate")); //CA 证书: + ui->lbCaPwd->setText(tr("CA certificate password")); //CA 证书密码: + ui->checkBoxCA->setText(tr("No CA certificate is required")); //不需要CA证书 + ui->lbInnerAuth->setText(tr("Inner authentication")); //内部认证: + ui->lbUserName->setText(tr("Username")); //用户名: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + int status = system("nmcli connection show>/tmp/kylin-nm-connshow"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiSecTunnelTLS' failed");} + QFile file("/tmp/kylin-nm-connshow"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if(line.indexOf("wifi") != -1){ + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + ui->cbxSecurity->addItem("LEAP"); + ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + if (WepOrWpa == 0) { + ui->cbxSecurity->setCurrentIndex(5); + } else if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(6); + } + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogSecu())); + + ui->cbxAuth->addItem("TLS"); + ui->cbxAuth->addItem("LEAP"); + ui->cbxAuth->addItem("PWD"); + ui->cbxAuth->addItem("FAST"); + ui->cbxAuth->addItem(tr("Tunneled TLS"));//隧道 TLS + ui->cbxAuth->addItem(tr("Protected EAP (PEAP)")); //受保护的 EAP + ui->cbxAuth->setCurrentIndex(4); + connect(ui->cbxAuth,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialogAuth())); + + ui->cbxCA->addItem(tr("None")); //无 + ui->cbxCA->addItem(tr("Choose from file")); //从文件选择... + ui->cbxCA->setCurrentIndex(0); + + ui->cbxInnerAuth->addItem("PAP"); + ui->cbxInnerAuth->addItem("MSCHAP"); + ui->cbxInnerAuth->addItem("MSCHAPv2"); + ui->cbxInnerAuth->addItem("MSCHAPv2(no EAP)"); + ui->cbxInnerAuth->addItem("CHAP"); + ui->cbxInnerAuth->addItem("MDS"); + ui->cbxInnerAuth->addItem("GTC"); + ui->cbxInnerAuth->setCurrentIndex(0); + + ui->btnConnect->setEnabled(false); + + this->setFixedSize(432,665); + +} + +DlgConnHidWifiSecTunnelTLS::~DlgConnHidWifiSecTunnelTLS() +{ + delete ui; +} + +void DlgConnHidWifiSecTunnelTLS::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiSecTunnelTLS::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiSecTunnelTLS::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +void DlgConnHidWifiSecTunnelTLS::changeDialogSecu() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, 0, this->parentWidget()); + connHidWifi->show(); + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, 0, this->parentWidget()); + connHidWifiWpa->show(); + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { + if (WepOrWpa == 1) { + ui->cbxSecurity->setCurrentIndex(5); + WepOrWpa = 0; + } + } else { + if (WepOrWpa == 0){ + ui->cbxSecurity->setCurrentIndex(6); + WepOrWpa = 1; + } + } +} + +void DlgConnHidWifiSecTunnelTLS::changeDialogAuth() +{ + if(ui->cbxAuth->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(WepOrWpa, this->parentWidget()); + connHidWifiSecTls->show(); + } else if(ui->cbxAuth->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecLeap *connHidWifiSecLeap = new DlgConnHidWifiSecLeap(WepOrWpa, this->parentWidget()); + connHidWifiSecLeap->show(); + } else if(ui->cbxAuth->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPwd *connHidWifiSecPwd = new DlgConnHidWifiSecPwd(WepOrWpa, this->parentWidget()); + connHidWifiSecPwd->show(); + } else if(ui->cbxAuth->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecFast *connHidWifiSecFast = new DlgConnHidWifiSecFast(WepOrWpa, this->parentWidget()); + connHidWifiSecFast->show(); + } else if(ui->cbxAuth->currentIndex()==4) { + qDebug()<<"it's not need to change dialog"; + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecPeap *connHidWifiSecPeap = new DlgConnHidWifiSecPeap(WepOrWpa, this->parentWidget()); + connHidWifiSecPeap->show(); + } +} + +void DlgConnHidWifiSecTunnelTLS::on_cbxCA_currentIndexChanged(const QString &arg1) +{ + if (ui->cbxCA->currentIndex() == 0){ + ui->leCaPwd->setText(""); + ui->lbCaPwd->setEnabled(false); + ui->leCaPwd->setEnabled(false); + } else { + ui->leCaPwd->setText(""); + ui->lbCaPwd->setEnabled(true); + ui->leCaPwd->setEnabled(true); + } +} + +void DlgConnHidWifiSecTunnelTLS::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecTunnelTLS::on_btnConnect_clicked() +{ + this->close(); +} + +void DlgConnHidWifiSecTunnelTLS::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->leCaPwd->setEchoMode(QLineEdit::Password); + } else { + ui->leCaPwd->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecTunnelTLS::on_checkBoxCA_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->cbxCA->setCurrentIndex(0); + ui->leCaPwd->setText(""); + ui->lbCA->setEnabled(true); + ui->cbxCA->setEnabled(true); + } else { + ui->cbxCA->setCurrentIndex(0); + ui->leCaPwd->setText(""); + ui->lbCA->setEnabled(false); + ui->cbxCA->setEnabled(false); + } +} + +void DlgConnHidWifiSecTunnelTLS::on_checkBoxPwdSec_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiSecTunnelTLS::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecTunnelTLS::on_leAnonyId_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecTunnelTLS::on_leDomain_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecTunnelTLS::on_leCaPwd_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiSecTunnelTLS::on_leUserName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecTunnelTLS::on_lePwd_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leAnonyId->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leDomain->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->leUserName->text() == ""){ + ui->btnConnect->setEnabled(false); + }else if (ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + if (ui->cbxCA->currentIndex() == 0){ + ui->btnConnect->setEnabled(true); + }else if(ui->leCaPwd->text() == ""){ + ui->btnConnect->setEnabled(false); + }else{ + ui->btnConnect->setEnabled(true); + } + } +} + +void DlgConnHidWifiSecTunnelTLS::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifisectunneltls.h b/KylinNM/wireless-security/dlgconnhidwifisectunneltls.h new file mode 100644 index 0000000..bbd881a --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisectunneltls.h @@ -0,0 +1,84 @@ +/* + * 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 +#include + +namespace Ui { +class DlgConnHidWifiSecTunnelTLS; +} + +class DlgConnHidWifiSecTunnelTLS : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiSecTunnelTLS(int type, QWidget *parent = 0); + ~DlgConnHidWifiSecTunnelTLS(); + +protected: + void paintEvent(QPaintEvent *event); + +public slots: + void changeDialogSecu(); + void changeDialogAuth(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_cbxCA_currentIndexChanged(const QString &arg1); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_checkBoxCA_stateChanged(int arg1); + + void on_checkBoxPwdSec_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_leAnonyId_textEdited(const QString &arg1); + + void on_leDomain_textEdited(const QString &arg1); + + void on_leCaPwd_textEdited(const QString &arg1); + + void on_leUserName_textEdited(const QString &arg1); + + void on_lePwd_textEdited(const QString &arg1); + +private: + Ui::DlgConnHidWifiSecTunnelTLS *ui; + int WepOrWpa = 0;//0 WEP;1WPA + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss, checkBoxCAQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFISECTUNNELTLS_H diff --git a/KylinNM/wireless-security/dlgconnhidwifisectunneltls.ui b/KylinNM/wireless-security/dlgconnhidwifisectunneltls.ui new file mode 100644 index 0000000..c625c2f --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifisectunneltls.ui @@ -0,0 +1,579 @@ + + + DlgConnHidWifiSecTunnelTLS + + + + 0 + 0 + 432 + 665 + + + + Connect to Hidden Wi-Fi Network + + + + + 180 + 75 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 385 + 200 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 180 + 145 + 200 + 32 + + + + + 10 + + + + + + + 315 + 620 + 90 + 30 + + + + + 10 + + + + + + + + + + 180 + 545 + 200 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 215 + 620 + 90 + 30 + + + + + 10 + + + + + + + + + + 76 + 310 + 90 + 20 + + + + + 10 + + + + + + + + + + 357 + 557 + 18 + 9 + + + + + 10 + + + + + + + + + + 76 + 510 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 190 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 185 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 345 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 465 + 200 + 32 + + + + + 10 + + + + + + + + + + 180 + 505 + 200 + 32 + + + + + 10 + + + + QLineEdit::Normal + + + + + + 76 + 350 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 225 + 200 + 32 + + + + + 10 + + + + + + + + + + 76 + 270 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 150 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 425 + 200 + 25 + + + + + 10 + + + + + + + + + + 76 + 470 + 90 + 20 + + + + + 10 + + + + + + + + + + 180 + 305 + 200 + 32 + + + + + 10 + + + + + + + 76 + 230 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 80 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 390 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 550 + 90 + 20 + + + + + 10 + + + + + + + + + + 357 + 397 + 18 + 9 + + + + + 10 + + + + + + + + + + 180 + 265 + 200 + 32 + + + + + 10 + + + + + + + 0 + 0 + 432 + 665 + + + + + + + + + + 30 + 30 + 140 + 22 + + + + + + + + + + 10 + 125 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 600 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + cbxConn + leCaPwd + leNetName + btnConnect + lePassword + btnCancel + lbDomain + checkBoxPwdSec + lbUserName + lbSecurity + cbxSecurity + cbxCA + cbxInnerAuth + leUserName + lbCA + cbxAuth + lbAnonyId + lbNetName + checkBoxCA + lbInnerAuth + leDomain + lbAuth + lbConn + lbCaPwd + lbPassword + checkBoxPwd + leAnonyId + lbLeftupTitle + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifiwep.cpp b/KylinNM/wireless-security/dlgconnhidwifiwep.cpp new file mode 100644 index 0000000..72fa078 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifiwep.cpp @@ -0,0 +1,239 @@ +/* + * 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 + +DlgConnHidWifiWep::DlgConnHidWifiWep(int type, QWidget *parent) : + WepPwdOrCode(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifiWep) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbKey->setStyleSheet(objQss.labelQss); + ui->lbWEPindex->setStyleSheet(objQss.labelQss); + ui->lbAuth->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->leKey->setStyleSheet(objQss.leQss); + ui->checkBoxPwd->setStyleSheet(objQss.checkBoxQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->cbxWEPindex->setStyleSheet(objQss.cbxQss); + ui->cbxWEPindex->setView(new QListView()); + ui->cbxAuth->setStyleSheet(objQss.cbxQss); + ui->cbxAuth->setView(new QListView()); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + + ui->lbLeftupTitle->setText(tr("Add hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Network name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi 安全性: + ui->lbKey->setText(tr("Key")); //密钥: + ui->lbWEPindex->setText(tr("WEP index")); //WEP 检索: + ui->lbAuth->setText(tr("Authentication")); //认证: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + int status = system("nmcli connection show>/tmp/kylin-nm-connshow"); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiWep' failed");} + QFile file("/tmp/kylin-nm-connshow"); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if(line.indexOf("wifi") != -1){ + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + ui->cbxSecurity->addItem("LEAP"); + ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + if (WepPwdOrCode == 0) { + ui->cbxSecurity->setCurrentIndex(2); + } else if (WepPwdOrCode == 1) { + ui->cbxSecurity->setCurrentIndex(3); + } + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialog())); + + ui->cbxWEPindex->addItem(tr("1(default)")); //1(默认) + ui->cbxWEPindex->addItem("2"); + ui->cbxWEPindex->addItem("3"); + ui->cbxWEPindex->addItem("4"); + ui->cbxWEPindex->setCurrentIndex(0); + + ui->cbxAuth->addItem(tr("Open System")); //开放式系统 + ui->cbxAuth->addItem(tr("Shared Key")); //共享密钥 + ui->cbxAuth->setCurrentIndex(0); + + ui->btnConnect->setEnabled(false); + + this->setFixedSize(432,493); + +} + +DlgConnHidWifiWep::~DlgConnHidWifiWep() +{ + delete ui; +} + +void DlgConnHidWifiWep::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiWep::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiWep::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +//切换到其他Wi-Fi安全类型 +void DlgConnHidWifiWep::changeDialog() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, 0, this->parentWidget()); + connHidWifi->show(); + } else if(ui->cbxSecurity->currentIndex()==1) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWpa *connHidWifiWpa = new DlgConnHidWifiWpa(0, 0, this->parentWidget()); + connHidWifiWpa->show(); + } else if(ui->cbxSecurity->currentIndex()==2) { + if (WepPwdOrCode == 1) { + ui->cbxSecurity->setCurrentIndex(2); + WepPwdOrCode = 0; + } + } else if(ui->cbxSecurity->currentIndex()==3) { + if (WepPwdOrCode == 0) { + ui->cbxSecurity->setCurrentIndex(3); + WepPwdOrCode = 1; + } + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(0, this->parentWidget()); + connHidWifiSecTls->show(); + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(1, this->parentWidget()); + connHidWifiSecTls->show(); + } +} + +void DlgConnHidWifiWep::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiWep::on_btnConnect_clicked() +{ + this->close(); +} + +void DlgConnHidWifiWep::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->leKey->setEchoMode(QLineEdit::Password); + } else { + ui->leKey->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiWep::on_leKey_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == "" || ui->leKey->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiWep::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == "" || ui->leKey->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiWep::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifiwep.h b/KylinNM/wireless-security/dlgconnhidwifiwep.h new file mode 100644 index 0000000..bd071ac --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifiwep.h @@ -0,0 +1,69 @@ +/* + * 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 +#include + +namespace Ui { +class DlgConnHidWifiWep; +} + +class DlgConnHidWifiWep : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiWep(int type, QWidget *parent = 0); + ~DlgConnHidWifiWep(); + +protected: + void paintEvent(QPaintEvent *event); + +public slots: + void changeDialog(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_leKey_textEdited(const QString &arg1); + + void on_leNetName_textEdited(const QString &arg1); + +private: + Ui::DlgConnHidWifiWep *ui; + int WepPwdOrCode = 0; //0 WEP password;1 WEP Code Sentence + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFIWEP_H diff --git a/KylinNM/wireless-security/dlgconnhidwifiwep.ui b/KylinNM/wireless-security/dlgconnhidwifiwep.ui new file mode 100644 index 0000000..baac5c8 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifiwep.ui @@ -0,0 +1,360 @@ + + + DlgConnHidWifiWep + + + + 0 + 0 + 432 + 493 + + + + Connect to Hidden Wi-Fi Network + + + + + 76 + 266 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 311 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 356 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 215 + 182 + 32 + + + + + 10 + + + + + + + + + + 315 + 440 + 90 + 30 + + + + + 10 + + + + + + + + + + 175 + 350 + 182 + 32 + + + + + 10 + + + + + + + + + + 76 + 80 + 90 + 20 + + + + + 10 + + + + Qt::LeftToRight + + + + + + + + + 175 + 305 + 182 + 32 + + + + + 10 + + + + + + + + + + 215 + 440 + 90 + 30 + + + + + 10 + + + + + + + + + + 332 + 272 + 18 + 9 + + + + + 10 + + + + + + + + + + 76 + 176 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 260 + 182 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 175 + 170 + 182 + 32 + + + + + 10 + + + + + + + 76 + 221 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 75 + 182 + 32 + + + + + 10 + + + + + + + + + + 0 + 0 + 432 + 493 + + + + + + + + + + 30 + 30 + 140 + 22 + + + + + + + + + + 10 + 140 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 410 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + leKey + lbKey + lbWEPindex + lbAuth + cbxSecurity + btnConnect + cbxAuth + lbConn + cbxWEPindex + btnCancel + checkBoxPwd + lbNetName + leNetName + lbSecurity + cbxConn + lbLeftupTitle + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/dlgconnhidwifiwpa.cpp b/KylinNM/wireless-security/dlgconnhidwifiwpa.cpp new file mode 100644 index 0000000..c1a9fdc --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifiwpa.cpp @@ -0,0 +1,411 @@ +/* + * 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 +#include + +#include + +DlgConnHidWifiWpa::DlgConnHidWifiWpa(int type, KylinNM *mainWindow, QWidget *parent) : + isUsed(type), + QDialog(parent), + ui(new Ui::DlgConnHidWifiWpa) +{ + ui->setupUi(this); + + this->setWindowFlags(Qt::FramelessWindowHint); + this->setAttribute(Qt::WA_TranslucentBackground); + //需要添加 void paintEvent(QPaintEvent *event) 函数 + + QPainterPath path; + auto rect = this->rect(); + rect.adjust(1, 1, -1, -1); + path.addRoundedRect(rect, 6, 6); + setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon())); + + KylinDBus mkylindbus; + double trans = mkylindbus.getTransparentData(); + QString strTrans; + strTrans = QString::number(trans, 10, 2); + QString sty = "QWidget{border-radius:6px;background-color:rgba(255,255,255,1);border:1px solid rgba(255, 255, 255, 0.05);}"; + this->setStyleSheet(sty); + //this->setStyleSheet("QWidget{border-radius:6px;background-color:rgba(19,19,20,0.7);border:1px solid rgba(255, 255, 255, 0.05);}"); + + MyQss objQss; + + ui->lbBoder->setStyleSheet("QLabel{border-radius:6px;background-color:rgba(19,19,20,0.95);border:1px solid rgba(255, 255, 255, 0.05);}"); + ui->lbBoder->hide(); + ui->lbLeftupTitle->setStyleSheet("QLabel{border:0px;font-size:20px;color:rgba(255,255,255,0.97);background-color:transparent;}"); + ui->lbConn->setStyleSheet(objQss.labelQss); + ui->lbNetName->setStyleSheet(objQss.labelQss); + ui->lbSecurity->setStyleSheet(objQss.labelQss); + ui->lbPassword->setStyleSheet(objQss.labelQss); + + ui->cbxConn->setStyleSheet(objQss.cbxQss); + ui->cbxConn->setView(new QListView()); + ui->leNetName->setStyleSheet(objQss.leQss); + ui->lePassword->setStyleSheet(objQss.leQss); + ui->cbxSecurity->setStyleSheet(objQss.cbxQss); + ui->cbxSecurity->setView(new QListView()); + ui->checkBoxPwd->setStyleSheet(objQss.checkBoxQss); + + ui->btnCancel->setStyleSheet(objQss.btnCancelQss); + ui->btnConnect->setStyleSheet(objQss.btnConnQss); + ui->lineUp->setStyleSheet(objQss.lineQss); + ui->lineDown->setStyleSheet(objQss.lineQss); + ui->btnCancel->setFocusPolicy(Qt::NoFocus); + ui->checkBoxPwd->setFocusPolicy(Qt::NoFocus); + + + ui->lbLeftupTitle->setText(tr("Add Hidden Wi-Fi")); //加入隐藏Wi-Fi + ui->lbConn->setText(tr("Connection")); //连接设置: + ui->lbNetName->setText(tr("Wi-Fi name")); //网络名称: + ui->lbSecurity->setText(tr("Wi-Fi security")); //Wi-Fi 安全性: + ui->lbPassword->setText(tr("Password")); //密码: + ui->btnCancel->setText(tr("Cancel")); //取消 + ui->btnConnect->setText(tr("Connect")); //连接 + + ui->cbxConn->addItem(tr("C_reate…")); //新建... + QString tmpPath = "/tmp/kylin-nm-connshow-" + QDir::home().dirName(); + QString cmd = "nmcli connection show > " + tmpPath; + int status = system(cmd.toUtf8().data()); + if (status != 0) { + syslog(LOG_ERR, "execute 'nmcli connection show' in function 'DlgConnHidWifiWpa' failed"); + } + QFile file(tmpPath); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + QStringList txtLine = txt.split("\n"); + file.close(); + foreach (QString line, txtLine) { + if (line.indexOf("wifi") != -1 || line.indexOf("802-11-wireless") != -1) { + QStringList subLine = line.split(" "); + ui->cbxConn->addItem(subLine[0]); + } + } + ui->cbxConn->setCurrentIndex(0); + connect(ui->cbxConn,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeWindow())); + + ui->cbxSecurity->addItem(tr("None")); //无 + ui->cbxSecurity->addItem(tr("WPA & WPA2 Personal")); //WPA 及 WPA2 个人 + //ui->cbxSecurity->addItem(tr("WEP 40/128-bit Key (Hex or ASCII)")); //WEP 40/128 位密钥(十六进制或ASCII) + //ui->cbxSecurity->addItem(tr("WEP 128-bit Passphrase")); //WEP 128 位密码句 + //ui->cbxSecurity->addItem("LEAP"); + //ui->cbxSecurity->addItem(tr("Dynamic WEP (802.1X)")); //动态 WEP (802.1x) + //ui->cbxSecurity->addItem(tr("WPA & WPA2 Enterprise")); //WPA 及 WPA2 企业 + ui->cbxSecurity->setCurrentIndex(1); + connect(ui->cbxSecurity,SIGNAL(currentIndexChanged(QString)),this,SLOT(changeDialog())); + + if (isUsed == 0){ + ui->btnConnect->setEnabled(false); + } else { + ui->cbxConn->setCurrentIndex(isUsed); + ui->leNetName->setText(ui->cbxConn->currentText()); + ui->leNetName->setEnabled(false); + ui->lbNetName->setEnabled(false); + ui->lbSecurity->setEnabled(false); + ui->cbxSecurity->setEnabled(false); + ui->lbPassword->setEnabled(false); + ui->lePassword->setText(""); + ui->lePassword->setEnabled(false); + ui->btnConnect->setEnabled(true); + ui->checkBoxPwd->setEnabled(false); + } + + this->setFixedSize(432,397); + + this->mw = mainWindow; + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 + **/ + ui->cbxConn->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxConn->view()->setParent(this); + ui->cbxConn->view()->hide(); + ui->cbxConn->installEventFilter(this); + + ui->cbxSecurity->view()->setWindowFlags(Qt::Popup | Qt::X11BypassWindowManagerHint); + ui->cbxSecurity->view()->setParent(this); + ui->cbxSecurity->view()->hide(); + ui->cbxSecurity->installEventFilter(this); + + connect(ui->cbxConn->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + Q_EMIT ui->cbxConn->setCurrentIndex(index.row()); + ui->cbxConn->view()->hide(); + }); + + connect(ui->cbxSecurity->view(), &QAbstractItemView::pressed, this, [=](QModelIndex index){ + ui->cbxSecurity->view()->hide(); + Q_EMIT ui->cbxSecurity->setCurrentIndex(index.row()); + }); + + ui->cbxConn->view()->setGeometry(QRect(ui->cbxConn->geometry().left(), ui->cbxConn->geometry().bottom(), ui->cbxConn->view()->width(), ui->cbxConn->view()->height())); + ui->cbxSecurity->view()->setGeometry(QRect(ui->cbxSecurity->geometry().left(), ui->cbxSecurity->geometry().bottom(), ui->cbxSecurity->view()->width(), ui->cbxSecurity->view()->height())); + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- + ** 手动绑定下拉框视图和下拉框 + **/ +} + +DlgConnHidWifiWpa::~DlgConnHidWifiWpa() +{ + delete ui; +} + +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- +** 手动绑定下拉框视图和下拉框 +**/ +bool DlgConnHidWifiWpa::eventFilter(QObject *obj, QEvent *ev) +{ + if(ev->type() == QEvent::MouseButtonPress) + { + if(obj == ui->cbxConn) + { + ui->cbxConn->view()->setVisible(!ui->cbxConn->view()->isVisible()); + if(ui->cbxConn->view()->isVisible()) + ui->cbxConn->view()->setFocus(); + } else if (obj == ui->cbxSecurity) + { + ui->cbxSecurity->view()->setVisible(!ui->cbxSecurity->view()->isVisible()); + if(ui->cbxSecurity->view()->isVisible()) + ui->cbxSecurity->view()->setFocus(); + } + } + return false; +} +/**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---END---- +** 手动绑定下拉框视图和下拉框 +**/ + +void DlgConnHidWifiWpa::mousePressEvent(QMouseEvent *event){ + if(event->button() == Qt::LeftButton){ + this->isPress = true; + this->winPos = this->pos(); + this->dragPos = event->globalPos(); + event->accept(); + } +} +void DlgConnHidWifiWpa::mouseReleaseEvent(QMouseEvent *event){ + this->isPress = false; +} +void DlgConnHidWifiWpa::mouseMoveEvent(QMouseEvent *event){ + if(this->isPress){ + this->move(this->winPos - (this->dragPos - event->globalPos())); + event->accept(); + } +} + +//切换到其他Wi-Fi安全类型 +void DlgConnHidWifiWpa::changeDialog() +{ + if(ui->cbxSecurity->currentIndex()==0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0,mw, this->parentWidget()); + connHidWifi->show(); + connect(connHidWifi, SIGNAL(reSetWifiList() ), mw, SLOT(on_btnWifiList_clicked()) ); + } else if(ui->cbxSecurity->currentIndex()==1) { + qDebug()<<"it's not need to change dialog"; + } else if(ui->cbxSecurity->currentIndex()==2) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(0, this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==3) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiWep *connHidWifiWep = new DlgConnHidWifiWep(1,this->parentWidget()); + connHidWifiWep->show(); + } else if(ui->cbxSecurity->currentIndex()==4) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiLeap *connHidWifiLeap = new DlgConnHidWifiLeap(this->parentWidget()); + connHidWifiLeap->show(); + } else if(ui->cbxSecurity->currentIndex()==5) { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(0, this->parentWidget()); + connHidWifiSecTls->show(); + } else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifiSecTls *connHidWifiSecTls = new DlgConnHidWifiSecTls(1, this->parentWidget()); + connHidWifiSecTls->show(); + } +} + +//同一 Wi-Fi安全类型的窗口变换 +void DlgConnHidWifiWpa::changeWindow() +{ + if (ui->cbxConn->currentIndex() == 0){ +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(0, mw, this->parentWidget()); + connHidWifi->show(); + connect(connHidWifi, SIGNAL(reSetWifiList() ), mw, SLOT(on_btnWifiList_clicked()) ); + }else if (ui->cbxConn->currentIndex() >= 1){ + QString tmpPath = "/tmp/kylin-nm-connshow-" + QDir::home().dirName(); + QString name = ui->cbxConn->currentText(); + QString currStr = "nmcli connection show \"" + name.replace("\"","\\\"") + "\" > " + tmpPath; + + int status = system(currStr.toUtf8().data()); + if(status != 0){ + syslog(LOG_ERR, "execute 'nmcli connection show' in function 'changeWindow' failed"); + } + QFile file(tmpPath); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ + qDebug()<<"Can't open the file!"; + } + QString txt = file.readAll(); + file.close(); + if (txt.indexOf("802-11-wireless-security.key-mgmt:") != -1){ + isUsed = ui->cbxConn->currentIndex(); + ui->lbNetName->setEnabled(false); + ui->leNetName->setText(ui->cbxConn->currentText()); + ui->leNetName->setEnabled(false); + ui->lbSecurity->setEnabled(false); + ui->cbxSecurity->setEnabled(false); + ui->lePassword->setText(""); + ui->lbPassword->setEnabled(false); + ui->lePassword->setEnabled(false); + ui->btnConnect->setEnabled(true); + }else { +// QApplication::setQuitOnLastWindowClosed(false); + this->hide(); + DlgConnHidWifi *connHidWifi = new DlgConnHidWifi(ui->cbxConn->currentIndex(), mw); + connHidWifi->show(); + connect(connHidWifi, SIGNAL(reSetWifiList() ), mw, SLOT(on_btnWifiList_clicked()) ); + } + } +} + +void DlgConnHidWifiWpa::on_btnCancel_clicked() +{ + this->close(); +} + +void DlgConnHidWifiWpa::on_btnConnect_clicked() +{ + QThread *t = new QThread(); + connect(t, SIGNAL(finished()), t, SLOT(deleteLater())); + connect(t, SIGNAL(started()), this, SLOT(slotStartLoading())); + connect(this, SIGNAL(stopSignal()), t, SLOT(quit())); + t->start(); + + QString wifiName = ui->leNetName->text(); + QString wifiPassword = ui->lePassword->text(); + BackThread *bt = new BackThread(); + strWifiname = wifiName; + strWifiPassword = wifiPassword; + if (isUsed == 0){ + int x = 0; + do{ + sleep(1); + QString tmpPath = "/tmp/kylin-nm-btoutput-" + QDir::home().dirName(); + QString cmd = "nmcli device wifi connect \"" + wifiName.replace("\"","\\\"") + "\" password \"" + wifiPassword.replace("\"","\\\"") + "\" hidden yes > " + tmpPath; + + int status = system(cmd.toUtf8().data()); + if (status != 0) { + syslog(LOG_ERR, "execute 'nmcli device wifi connect' in function 'on_btnConnect_clicked' failed"); + } + + QFile file(tmpPath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug()<<"Can't open the file!"<execConnWifi(wifiName); + connect(this, SIGNAL(sendMessage()), this,SLOT(emitSignal() )); + QTimer::singleShot(4*1000, this, SLOT(emitSignal() )); + } + this->close(); +} + +void DlgConnHidWifiWpa::on_checkBoxPwd_stateChanged(int arg1) +{ + if (arg1 == 0) { + ui->lePassword ->setEchoMode(QLineEdit::Password); + } else { + ui->lePassword->setEchoMode(QLineEdit::Normal); + } +} + +void DlgConnHidWifiWpa::on_leNetName_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == "" || ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiWpa::on_lePassword_textEdited(const QString &arg1) +{ + if (ui->leNetName->text() == "" || ui->lePassword->text() == ""){ + ui->btnConnect->setEnabled(false); + } else { + ui->btnConnect->setEnabled(true); + } +} + +void DlgConnHidWifiWpa::slotStartLoading() +{ + mw->startLoading(); +} + +void DlgConnHidWifiWpa::on_execSecConn() +{ + QString name = strWifiname; + QString pwd = strWifiPassword; + QString str = "nmcli device wifi connect \"" + name.replace("\"","\\\"") + "\" password\"" + pwd.replace("\"","\\\"") + "\""; + int status = system(str.toUtf8().data()); + if (status != 0){ syslog(LOG_ERR, "execute 'nmcli device wifi connect' in function 'on_execSecConn' failed");} + connect(this, SIGNAL(sendMessage()), this,SLOT(emitSignal() )); + QTimer::singleShot(3*1000, this, SLOT(emitSignal() )); +} + +void DlgConnHidWifiWpa::emitSignal() +{ + emit reSetWifiList(); + mw->stopLoading(); + emit this->stopSignal(); +} + +void DlgConnHidWifiWpa::paintEvent(QPaintEvent *event) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + QWidget::paintEvent(event); +} diff --git a/KylinNM/wireless-security/dlgconnhidwifiwpa.h b/KylinNM/wireless-security/dlgconnhidwifiwpa.h new file mode 100644 index 0000000..3b73126 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifiwpa.h @@ -0,0 +1,90 @@ +/* + * 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 +#include +#include + +class KylinNM; + +namespace Ui { +class DlgConnHidWifiWpa; +} + +class DlgConnHidWifiWpa : public QDialog +{ + Q_OBJECT + +public: + explicit DlgConnHidWifiWpa(int type, KylinNM *mw = 0, QWidget *parent = 0); + ~DlgConnHidWifiWpa(); + +protected: + void paintEvent(QPaintEvent *event); + + /**解决锁屏设置 X11BypassWindowManagerHint 属性导致QCombox弹框异常的问题---START---- + ** 手动绑定下拉框视图和下拉框 过滤点击事件 + **/ + bool eventFilter(QObject *obj, QEvent *ev) override; + +public slots: + void changeDialog(); + void changeWindow(); + void emitSignal(); + void on_execSecConn(); + void slotStartLoading(); + +private slots: + void on_btnCancel_clicked(); + + void on_btnConnect_clicked(); + + void on_checkBoxPwd_stateChanged(int arg1); + + void on_leNetName_textEdited(const QString &arg1); + + void on_lePassword_textEdited(const QString &arg1); + +signals: + void reSetWifiList(); + void sendMessage(); + void execSecConn(); + void stopSignal(); + +private: + Ui::DlgConnHidWifiWpa *ui; + int isUsed;//=0 current wifi not used before; >=1 used + KylinNM *mw; + QString strWifiname; + QString strWifiPassword; + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +// QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss; + + bool isPress; + QPoint winPos; + QPoint dragPos; +}; + +#endif // DLGCONNHIDWIFIWPA_H diff --git a/KylinNM/wireless-security/dlgconnhidwifiwpa.ui b/KylinNM/wireless-security/dlgconnhidwifiwpa.ui new file mode 100644 index 0000000..093ab22 --- /dev/null +++ b/KylinNM/wireless-security/dlgconnhidwifiwpa.ui @@ -0,0 +1,284 @@ + + + DlgConnHidWifiWpa + + + + 0 + 0 + 432 + 397 + + + + Connect to Hidden Wi-Fi Network + + + + + 76 + 221 + 90 + 20 + + + + + 10 + + + + + + + + + + 76 + 176 + 90 + 20 + + + + + 10 + + + + + + + + + + 215 + 350 + 90 + 30 + + + + + 10 + + + + + + + + + + 175 + 75 + 182 + 32 + + + + + 10 + + + + + + + + + + 332 + 272 + 18 + 9 + + + + + 10 + + + + + + + + + + 76 + 266 + 90 + 20 + + + + + 10 + + + + + + + + + + 175 + 170 + 182 + 32 + + + + + 10 + + + + + + + + + + 175 + 261 + 182 + 32 + + + + + 10 + + + + QLineEdit::Password + + + + + + 315 + 350 + 90 + 30 + + + + + 10 + + + + + + + + + + 76 + 80 + 90 + 20 + + + + + 10 + + + + Qt::LeftToRight + + + + + + + + + 175 + 215 + 182 + 32 + + + + + 10 + + + + + + + 0 + 0 + 432 + 397 + + + + + + + + + + 30 + 30 + 240 + 22 + + + + + + + + + + 10 + 140 + 412 + 1 + + + + Qt::Horizontal + + + + + + 10 + 320 + 412 + 1 + + + + Qt::Horizontal + + + lbBoder + lePassword + lbNetName + lbSecurity + btnCancel + cbxConn + checkBoxPwd + lbPassword + cbxSecurity + btnConnect + lbConn + leNetName + lbLeftupTitle + lineUp + lineDown + + + + diff --git a/KylinNM/wireless-security/kylinheadfile.cpp b/KylinNM/wireless-security/kylinheadfile.cpp new file mode 100644 index 0000000..e8b92dc --- /dev/null +++ b/KylinNM/wireless-security/kylinheadfile.cpp @@ -0,0 +1,44 @@ +/* + * 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 +#include +#include +#include +#include +#include + +class MyQss +{ +public: + MyQss(); + + QString labelQss, cbxQss, leQss, btnConnQss, btnCancelQss, lineQss, checkBoxQss, checkBoxCAQss; + +}; + +#endif // KYLINHEADFILE_H diff --git a/README.md b/README.md new file mode 100644 index 0000000..8f8048e --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +## ukui-screensaver + +![build](https://github.com/ukui/ukui-screensaver/tree/master) + +ukui-screensaver是UKUI桌面环境的锁屏及屏保 + +### 依赖 + +------ + +### 编译依赖 + +- KF5 + - libkf5windowsystem-dev + +- cmake (>=2.6) +- qtbase5-dev +- libqt5x11extras5-dev +- libpam0g-dev +- qttools5-dev +- qttools5-dev-tools +- libglib2.0-dev +- libopencv-dev +- libx11-dev +- libxtst-dev +- libqt5svg5-dev +- libgsettings-qt-dev +- libmatemixer-dev +- libukui-log4qt-dev + +### 运行依赖 + +- ukui-session-manager +- ethtool +- mate-desktop-common + +### 编译 + +------ + +```shell +$ cd ukui-screensaver +$ mkdir build +$ cd build +$ cmake .. +$ make +``` + +### 安装 + +------ + +```shell +$ sudo make install +``` + +### 主体框架 + - **InProgress** + - [x] 界面绘制 + - [x] 功能实现 + - [x] 界面美化 + - **TROUBLE** + - 无 + - **TODO** + - 功能插件 + - 应用窗口置顶 diff --git a/VirtualKeyboard/CMakeLists.txt b/VirtualKeyboard/CMakeLists.txt new file mode 100644 index 0000000..f9d52c7 --- /dev/null +++ b/VirtualKeyboard/CMakeLists.txt @@ -0,0 +1,24 @@ +find_package(Qt5 COMPONENTS Core Widgets REQUIRED) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTORCC ON) + +qt5_add_resources(VirtualKeyboard_SRC + src/keyboard.qrc) + +set(VirtualKeyboard_SRC + ${VirtualKeyboard_SRC} + src/cursormonitor.cpp + src/keyboardwidget.cpp + src/virtualkeyboard.cpp + src/x11keyboard.cpp + src/keyboard.qrc) + +include_directories( + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ) + +add_library(VirtualKeyboard STATIC ${VirtualKeyboard_SRC}) +target_link_libraries(VirtualKeyboard Qt5::Core Qt5::Widgets) diff --git a/VirtualKeyboard/README.md b/VirtualKeyboard/README.md new file mode 100644 index 0000000..c067665 --- /dev/null +++ b/VirtualKeyboard/README.md @@ -0,0 +1 @@ +A simple virtual keyboard in X11 diff --git a/VirtualKeyboard/VirtualKeyboard.pri b/VirtualKeyboard/VirtualKeyboard.pri new file mode 100644 index 0000000..e8029dc --- /dev/null +++ b/VirtualKeyboard/VirtualKeyboard.pri @@ -0,0 +1,19 @@ +SOURCES += \ + $$PWD/src/keyboardwidget.cpp \ + $$PWD/src/x11keyboard.cpp \ + $$PWD/src/cursormonitor.cpp \ + $$PWD/src/virtualkeyboard.cpp + + +HEADERS += \ + $$PWD/src/keyboardwidget.h \ + $$PWD/src/x11keyboard.h \ + $$PWD/src/cursormonitor.h \ + $$PWD/src/virtualkeyboard.h + +FORMS += \ + $$PWD/src/keyboardwidget.ui + + +RESOURCES += \ + $$PWD/src/keyboard.qrc diff --git a/VirtualKeyboard/VirtualKeyboard.pro b/VirtualKeyboard/VirtualKeyboard.pro new file mode 100644 index 0000000..0e979d8 --- /dev/null +++ b/VirtualKeyboard/VirtualKeyboard.pro @@ -0,0 +1,32 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-10-12T16:43:42 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = VirtualKeyboard +TEMPLATE = app + +# 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 + +CONFIG += link_pkgconfig debug + +PKGCONFIG += xtst x11 + +include(VirtualKeyboard.pri) + +SOURCES += \ + $$PWD/src/main.cpp diff --git a/VirtualKeyboard/src/cursormonitor.cpp b/VirtualKeyboard/src/cursormonitor.cpp new file mode 100644 index 0000000..2c76123 --- /dev/null +++ b/VirtualKeyboard/src/cursormonitor.cpp @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2018 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, 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 "cursormonitor.h" +#include +#include +#include +CursorMonitor::CursorMonitor(QObject *parent) : QThread(parent) +{ + +} + +void CursorMonitor::run() +{ + Display *display; + XEvent xevent; + Window window; + + display = XOpenDisplay(NULL); + if (display == 0) { + syslog(LOG_ERR, "CursorMonitor unable to open display"); + return; + } + + + window = DefaultRootWindow(display); + XAllowEvents(display, AsyncBoth, CurrentTime); + + XGrabPointer(display, + window, + 1, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask , + GrabModeAsync, + GrabModeAsync, + None, + None, + CurrentTime); + + while(1) { + XNextEvent(display, &xevent); + + switch (xevent.type) { + case MotionNotify: + //printf("Mouse move : [%d, %d]\n", xevent.xmotion.x_root, xevent.xmotion.y_root); + Q_EMIT cursorPosChanged(QPoint(xevent.xmotion.x_root, xevent.xmotion.y_root)); + break; + case ButtonPress: +// printf("Button pressed : %s\n", key_name[xevent.xbutton.button - 1]); + break; + case ButtonRelease: +// printf("Button released : %s\n", key_name[xevent.xbutton.button - 1]); + break; + } + } +} diff --git a/VirtualKeyboard/src/cursormonitor.h b/VirtualKeyboard/src/cursormonitor.h new file mode 100644 index 0000000..7722453 --- /dev/null +++ b/VirtualKeyboard/src/cursormonitor.h @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2018 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, 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 CURSORMONITOR_H +#define CURSORMONITOR_H + +#include +#include + +class CursorMonitor : public QThread +{ + Q_OBJECT +public: + explicit CursorMonitor(QObject *parent = nullptr); + void run(); + +Q_SIGNALS: + void cursorPosChanged(const QPoint& pos); +}; + +#endif // CURSORMONITOR_H diff --git a/VirtualKeyboard/src/images/backspace.svg b/VirtualKeyboard/src/images/backspace.svg new file mode 100644 index 0000000..092d72d --- /dev/null +++ b/VirtualKeyboard/src/images/backspace.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/VirtualKeyboard/src/images/backspace_click.svg b/VirtualKeyboard/src/images/backspace_click.svg new file mode 100644 index 0000000..4a9d7fa --- /dev/null +++ b/VirtualKeyboard/src/images/backspace_click.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/VirtualKeyboard/src/images/capslock.svg b/VirtualKeyboard/src/images/capslock.svg new file mode 100644 index 0000000..a5a367c --- /dev/null +++ b/VirtualKeyboard/src/images/capslock.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/VirtualKeyboard/src/images/capslock_click.svg b/VirtualKeyboard/src/images/capslock_click.svg new file mode 100644 index 0000000..36ae8f8 --- /dev/null +++ b/VirtualKeyboard/src/images/capslock_click.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/VirtualKeyboard/src/images/capslock_hl.svg b/VirtualKeyboard/src/images/capslock_hl.svg new file mode 100644 index 0000000..4f8870a --- /dev/null +++ b/VirtualKeyboard/src/images/capslock_hl.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/VirtualKeyboard/src/images/capslock_hl_click.svg b/VirtualKeyboard/src/images/capslock_hl_click.svg new file mode 100644 index 0000000..65b0a21 --- /dev/null +++ b/VirtualKeyboard/src/images/capslock_hl_click.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/VirtualKeyboard/src/images/close.svg b/VirtualKeyboard/src/images/close.svg new file mode 100644 index 0000000..c509415 --- /dev/null +++ b/VirtualKeyboard/src/images/close.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/VirtualKeyboard/src/images/close_click.svg b/VirtualKeyboard/src/images/close_click.svg new file mode 100644 index 0000000..d143065 --- /dev/null +++ b/VirtualKeyboard/src/images/close_click.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/VirtualKeyboard/src/images/down.svg b/VirtualKeyboard/src/images/down.svg new file mode 100644 index 0000000..73361dd --- /dev/null +++ b/VirtualKeyboard/src/images/down.svg @@ -0,0 +1,9 @@ + + + +画板 15 + + + + diff --git a/VirtualKeyboard/src/images/down_click.svg b/VirtualKeyboard/src/images/down_click.svg new file mode 100644 index 0000000..9140b38 --- /dev/null +++ b/VirtualKeyboard/src/images/down_click.svg @@ -0,0 +1,6 @@ + + + + + diff --git a/VirtualKeyboard/src/images/enter.svg b/VirtualKeyboard/src/images/enter.svg new file mode 100644 index 0000000..5cbc51d --- /dev/null +++ b/VirtualKeyboard/src/images/enter.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/VirtualKeyboard/src/images/enter_click.svg b/VirtualKeyboard/src/images/enter_click.svg new file mode 100644 index 0000000..106cc7b --- /dev/null +++ b/VirtualKeyboard/src/images/enter_click.svg @@ -0,0 +1,9 @@ + + + + + + diff --git a/VirtualKeyboard/src/images/left.svg b/VirtualKeyboard/src/images/left.svg new file mode 100644 index 0000000..6ac0fa8 --- /dev/null +++ b/VirtualKeyboard/src/images/left.svg @@ -0,0 +1,7 @@ + + + +画板 19 + + diff --git a/VirtualKeyboard/src/images/left_click.svg b/VirtualKeyboard/src/images/left_click.svg new file mode 100644 index 0000000..edfd291 --- /dev/null +++ b/VirtualKeyboard/src/images/left_click.svg @@ -0,0 +1,7 @@ + + + +画板 20 + + diff --git a/VirtualKeyboard/src/images/right.svg b/VirtualKeyboard/src/images/right.svg new file mode 100644 index 0000000..62c301c --- /dev/null +++ b/VirtualKeyboard/src/images/right.svg @@ -0,0 +1,6 @@ + + + + + diff --git a/VirtualKeyboard/src/images/right_click.svg b/VirtualKeyboard/src/images/right_click.svg new file mode 100644 index 0000000..5ba0ec6 --- /dev/null +++ b/VirtualKeyboard/src/images/right_click.svg @@ -0,0 +1,6 @@ + + + + + diff --git a/VirtualKeyboard/src/images/super.svg b/VirtualKeyboard/src/images/super.svg new file mode 100644 index 0000000..c847e44 --- /dev/null +++ b/VirtualKeyboard/src/images/super.svg @@ -0,0 +1 @@ +画板 11 \ No newline at end of file diff --git a/VirtualKeyboard/src/images/super_click.svg b/VirtualKeyboard/src/images/super_click.svg new file mode 100644 index 0000000..7fcc495 --- /dev/null +++ b/VirtualKeyboard/src/images/super_click.svg @@ -0,0 +1 @@ +画板 12 \ No newline at end of file diff --git a/VirtualKeyboard/src/images/up.svg b/VirtualKeyboard/src/images/up.svg new file mode 100644 index 0000000..d5613b2 --- /dev/null +++ b/VirtualKeyboard/src/images/up.svg @@ -0,0 +1,9 @@ + + + +画板 13 + + + + diff --git a/VirtualKeyboard/src/images/up_click.svg b/VirtualKeyboard/src/images/up_click.svg new file mode 100644 index 0000000..225e401 --- /dev/null +++ b/VirtualKeyboard/src/images/up_click.svg @@ -0,0 +1,6 @@ + + + + + diff --git a/VirtualKeyboard/src/keyboard.qrc b/VirtualKeyboard/src/keyboard.qrc new file mode 100644 index 0000000..4e38067 --- /dev/null +++ b/VirtualKeyboard/src/keyboard.qrc @@ -0,0 +1,27 @@ + + + keyboard.qss + + + images/backspace_click.svg + images/backspace.svg + images/capslock_click.svg + images/capslock_hl.svg + images/capslock.svg + images/down_click.svg + images/down.svg + images/enter_click.svg + images/enter.svg + images/left_click.svg + images/left.svg + images/right_click.svg + images/right.svg + images/super_click.svg + images/super.svg + images/up.svg + images/close_click.svg + images/close.svg + images/capslock_hl_click.svg + images/up_click.svg + + diff --git a/VirtualKeyboard/src/keyboard.qss b/VirtualKeyboard/src/keyboard.qss new file mode 100644 index 0000000..e91e23c --- /dev/null +++ b/VirtualKeyboard/src/keyboard.qss @@ -0,0 +1,37 @@ +QPushButton +{ + border: none; + font: 24px; + color: white; + background: #35322f; + border-radius: 5px; +} + +QPushButton::pressed +{ + color: gray; + background: #2a2826; +} + +#btn_backspace, #btn_enter, #btn_shift_l, +#btn_shift_r, #btn_ctrl_l, #btn_ctrl_r, +#btn_alt_l, #btn_alt_r, #btn_super +{ + font: 16px; + background: #1e1b18 +} + +#btn_backspace::pressed, #btn_enter::pressed, #btn_shift_l::pressed, +#btn_shift_r::pressed, #btn_ctrl_l::pressed, #btn_ctrl_r::pressed, +#btn_alt_l::pressed, #btn_alt_r::pressed, #btn_super::pressed +{ + background: #181613; + color: gray; +} + +#btn_letter, #btn_symbol, #btn_number, +#btn_insert, #btn_delete, #btn_home, +#btn_end, #btn_pgup, #btn_pgdn, #btn_close +{ + font: 16px; +} diff --git a/VirtualKeyboard/src/keyboardwidget.cpp b/VirtualKeyboard/src/keyboardwidget.cpp new file mode 100644 index 0000000..e97a710 --- /dev/null +++ b/VirtualKeyboard/src/keyboardwidget.cpp @@ -0,0 +1,459 @@ +/** + * Copyright (C) 2018 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, 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 "keyboardwidget.h" +#include "ui_keyboardwidget.h" +#include +#include +#include + +#define SYMBOL_KEY_COUNT 29 +#define SYMBOL_PAGE_COUNT 2 + +#define BUTTON_BG "QPushButton{background:#1E1B18}" +#define BUTTON_BG_PRESSED "QPushButton{background: #181613;}" +#define BUTTON_BG_HL "QPushButton{background:#80c342}" +#define BUTTON_BG_HL_PRESSED "QPushButton{background:#486E25}" + + +QChar symbols[SYMBOL_PAGE_COUNT][SYMBOL_KEY_COUNT] = + { {'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', + 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', + 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/'}, + {'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', + '`', '-', '=', '[', ']', '\\', '|', '{', '}', + '~','<', '>', ':', ';', '\'', '"', '_', '+', '?'}}; + + +KeyboardWidget::KeyboardWidget(QWidget *parent) : + QWidget(parent), + ui(new Ui::KeyboardWidget), + capsLock(false), + isShift(false), + page(0) +{ + vKeyboard = new X11Keyboard(this); + connect(this, SIGNAL(keyPressed(QChar)), + vKeyboard, SLOT(onKeyPressed(QChar))); + connect(this, SIGNAL(keyPressed(FuncKey::FUNCKEY)), + vKeyboard, SLOT(onKeyPressed(FuncKey::FUNCKEY))); + + ui->setupUi(this); + bindSingal(); + setDefaultIcon(); +} + +KeyboardWidget::~KeyboardWidget() +{ + delete ui; +} + +void KeyboardWidget::resizeEvent(QResizeEvent */*event*/) +{ + int w = width(); + int h = height(); + int mainLeftMargin = ui->hl_main->contentsMargins().left(); + int mainRightMargin = ui->hl_main->contentsMargins().right(); + int mainTopMargin = ui->hl_main->contentsMargins().left(); + int mainBottomMargin = ui->hl_main->contentsMargins().right(); + int mainSpacing = ui->hl_main->spacing(); + int itemSpacing = ui->hl_1->spacing(); + + int btnWidthCount = w - 11 * itemSpacing - mainSpacing- mainLeftMargin - mainRightMargin; + int btnHeightCount = h - 3 * itemSpacing - mainTopMargin - mainBottomMargin; + double btnWidth = btnWidthCount / 12; + double btnHeight = btnHeightCount / 4; + for(int i = 0; i <= 28; i++) { + QString btnObjName = "btn_" + QString::number(i); + QPushButton *btn = ui->page_letter->findChild(btnObjName); + btn->setFixedSize(btnWidth, btnHeight); + } + ui->btn_ctrl_l->setFixedSize(btnWidth * 1.3, btnHeight); + ui->btn_ctrl_r->setFixedSize(btnWidth * 1.3, btnHeight); + ui->btn_alt_l->setFixedSize(btnWidth, btnHeight); + ui->btn_alt_r->setFixedSize(btnWidth, btnHeight); + ui->btn_super->setFixedSize(btnWidth, btnHeight); + ui->btn_shift_l->setFixedSize(btnWidth, btnHeight); + ui->btn_shift_r->setFixedHeight(btnHeight); + ui->spacer_2->changeSize(btnWidth / 2, 20); + + + for(int i = 1; i <= 9; i++) { + QString btnObjName = "btn_num_" + QString::number(i); + QPushButton *btn = ui->page_number->findChild(btnObjName); + btn->setFixedWidth(btnWidth); + } + ui->btn_backspace_num->setFixedSize(btnWidth,btnHeight); + ui->btn_insert->setFixedWidth(btnWidth); + ui->btn_delete->setFixedWidth(btnWidth); + ui->btn_home->setFixedWidth(btnWidth); + ui->btn_end->setFixedWidth(btnWidth); + ui->btn_pgup->setFixedWidth(btnWidth); + ui->btn_pgdn->setFixedWidth(btnWidth); + ui->btn_up->setFixedSize(btnWidth,btnHeight); + ui->btn_down->setFixedSize(btnWidth,btnHeight); + ui->btn_left->setFixedSize(btnWidth,btnHeight); + ui->btn_right->setFixedSize(btnWidth,btnHeight); + + ui->btn_close->setFixedHeight(btnHeight); + ui->btn_letter->setFixedHeight(btnHeight); + ui->btn_symbol->setFixedHeight(btnHeight); + ui->btn_number->setFixedHeight(btnHeight); + + setIconSize(); +} + +float hScale = 0.6; +float wScale = hScale; +#define SET_ICON_SIZE_SCALE(btn) \ + ui->btn_##btn->setIconSize(QSize(ui->btn_##btn->width() * hScale, ui->btn_##btn->height() * wScale)); + +#define SET_ICON_SIZE(btn) \ + ui->btn_##btn->setIconSize(QSize(ui->btn_##btn->width(), ui->btn_##btn->height())); + +#define SET_SHIFT_ICON_SIZE_SCALE(btn) \ + ui->btn_##btn->setIconSize(QSize(ui->btn_##btn->height() * 0.4, ui->btn_##btn->height() * 0.4)); + +#define SET_ENTER_ICON_SIZE_SCALE(btn) \ + ui->btn_##btn->setIconSize(QSize(ui->btn_##btn->width() * 0.4, ui->btn_##btn->height() * 0.4)); + +void KeyboardWidget::setIconSize() +{ + SET_ICON_SIZE_SCALE(backspace); + SET_ICON_SIZE_SCALE(backspace_num); + SET_ENTER_ICON_SIZE_SCALE(enter); + SET_ICON_SIZE_SCALE(enter_num); + SET_ICON_SIZE_SCALE(close); + SET_ICON_SIZE_SCALE(super); + + SET_SHIFT_ICON_SIZE_SCALE(shift_l); + SET_SHIFT_ICON_SIZE_SCALE(shift_r); + SET_ICON_SIZE(up); + SET_ICON_SIZE(down); + SET_ICON_SIZE(left); + SET_ICON_SIZE(right); +} + +void KeyboardWidget::bindSingal() +{ + for(auto obj : ui->page_letter->children()) { + if(obj->metaObject()->className() == QString("QPushButton")) { + QPushButton *btn = static_cast(obj); + btn->setFocusPolicy(Qt::NoFocus); + connect(btn, &QPushButton::clicked, this, &KeyboardWidget::onButtonClicked); + connect(btn, &QPushButton::pressed, this, &KeyboardWidget::onButtonPressed); + connect(btn, &QPushButton::released, this, &KeyboardWidget::onButtonReleased); + } + } + for(auto obj : ui->page_number->children()) { + if(obj->metaObject()->className() == QString("QPushButton")) { + QPushButton *btn = static_cast(obj); + btn->setFocusPolicy(Qt::NoFocus); + connect(btn, &QPushButton::clicked, this, &KeyboardWidget::onButtonClicked); + connect(btn, &QPushButton::pressed, this, &KeyboardWidget::onButtonPressed); + connect(btn, &QPushButton::released, this, &KeyboardWidget::onButtonReleased); + } + } + ui->btn_close->setFocusPolicy(Qt::NoFocus); + ui->btn_letter->setFocusPolicy(Qt::NoFocus); + ui->btn_symbol->setFocusPolicy(Qt::NoFocus); + ui->btn_number->setFocusPolicy(Qt::NoFocus); + + connect(ui->btn_letter, &QPushButton::clicked, this, [&] { + ui->stackedWidget->setCurrentWidget(ui->page_letter); + page = 0; + switchPage(); + }); + connect(ui->btn_symbol, &QPushButton::clicked, this, [&] { + ui->stackedWidget->setCurrentWidget(ui->page_letter); + page = 1; + switchPage(); + }); + connect(ui->btn_number, &QPushButton::clicked, this, [&] { + ui->stackedWidget->setCurrentWidget(ui->page_number); + }); + connect(ui->btn_close, &QPushButton::clicked, + this, &KeyboardWidget::aboutToClose); + + connect(ui->btn_close, &QPushButton::pressed, + this, &KeyboardWidget::onButtonPressed); + connect(ui->btn_close, &QPushButton::released, + this, &KeyboardWidget::onButtonReleased); +} + +void KeyboardWidget::setDefaultIcon() +{ + ui->btn_backspace->setIcon(QIcon(":/images/images/backspace.svg")); + ui->btn_backspace_num->setIcon(QIcon(":/images/images/backspace.svg")); + ui->btn_enter->setIcon(QIcon(":/images/images/enter.svg")); + ui->btn_enter_num->setIcon(QIcon(":/images/images/enter.svg")); + ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); + ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); + ui->btn_close->setIcon(QIcon(":/images/images/close.svg")); + //ui->btn_super->setIcon(QIcon(":/images/images/super.svg")); + ui->btn_super->setText("Super"); + ui->btn_up->setIcon(QIcon(":/images/images/up.svg")); + ui->btn_down->setIcon(QIcon(":/images/images/down.svg")); + ui->btn_left->setIcon(QIcon(":/images/images/left.svg")); + ui->btn_right->setIcon(QIcon(":/images/images/right.svg")); +} + +QString KeyboardWidget::getKeyName(QPushButton *btn) +{ + QString objName = btn->objectName(); + int lastUnderline = objName.lastIndexOf('_'); + int start = strlen("btn_"); + int keyLength = lastUnderline - start; + QString keyName = objName.mid(start, keyLength); + return keyName; +} + +void KeyboardWidget::changeFuncKeyStyle(QPushButton *btn, bool isPressed) +{ + QString modName = getKeyName(btn); + Modifier::MOD mod = Modifier::getModifier(modName); + + if(vKeyboard->hasModifier(mod)) { + if(isPressed) + btn->setStyleSheet(BUTTON_BG_HL_PRESSED); + else + btn->setStyleSheet(BUTTON_BG_HL); + } else { + if(isPressed) + btn->setStyleSheet(BUTTON_BG_PRESSED); + else + btn->setStyleSheet(BUTTON_BG); + } +} + +void KeyboardWidget::changeShitKeyStyle(QPushButton *btn, bool isPressed) +{ + if(page == 0){ + if(isShift) { + if(capsLock){ + if(isPressed) { + btn->setStyleSheet(BUTTON_BG_HL_PRESSED); + btn->setIcon(QIcon(":/images/images/capslock_click.svg")); + } else { + btn->setStyleSheet(BUTTON_BG_HL); + btn->setIcon(QIcon(":/images/images/capslock.svg")); + } + } + else { + if(isPressed) + btn->setIcon(QIcon(":/images/images/capslock_hl_click.svg")); + else + btn->setIcon(QIcon(":/images/images/capslock_hl.svg")); + } + } else { + if(isPressed) + btn->setIcon(QIcon(":/images/images/capslock_click.svg")); + else + btn->setIcon(QIcon(":/images/images/capslock.svg")); + } + } +} + + +void KeyboardWidget::changeDirectKeyStyle(QPushButton *btn, bool isPressed) +{ + QString keyName = getKeyName(btn); + FuncKey::FUNCKEY key = FuncKey::getKey(keyName); + if(key == FuncKey::UNKNOWN) + return; + + QString iconName = QString(":/images/images/%1.svg").arg(keyName); + QString iconNamePressed = QString(":/images/images/%1_click.svg").arg(keyName); + + if(isPressed) + btn->setIcon(QIcon(iconNamePressed)); + else + btn->setIcon(QIcon(iconName)); +} + +/** + * @brief 修改按键样式 + * @param obj 按键 + * @param isPressed 按下或者松开 + */ +void KeyboardWidget::changeKeyStyle(QPushButton *btn, bool isPressed) +{ + if(btn == ui->btn_ctrl_l || btn == ui->btn_ctrl_r || + btn == ui->btn_alt_l || btn == ui->btn_alt_r || + btn == ui->btn_super) { + changeFuncKeyStyle(btn, isPressed); + } + + if(btn == ui->btn_shift_l) + changeShitKeyStyle(ui->btn_shift_l, isPressed); + if(btn == ui->btn_shift_r) + changeShitKeyStyle(ui->btn_shift_r, isPressed); + + changeDirectKeyStyle(btn, isPressed); +} + +void KeyboardWidget::onButtonPressed() +{ + QPushButton *btn = static_cast(sender()); + changeKeyStyle(btn, true); +} + +void KeyboardWidget::onButtonReleased() +{ + QPushButton *btn = static_cast(sender()); + changeKeyStyle(btn, false); +} + +void KeyboardWidget::onButtonClicked() +{ + QObject *obj = sender(); + if(obj->metaObject()->className() != QString("QPushButton")) + return; + + QPushButton *btn = static_cast(obj); + QString keyName = getKeyName(btn); + qDebug() << "keyName: " << keyName; + + Modifier::MOD mod = Modifier::getModifier(keyName); + FuncKey::FUNCKEY funcKey = FuncKey::getKey(keyName); + + if(keyName == "shift") { + if(page == 0) { + isShift = !isShift; + if(isShift) { //第一次被按下 + capsLock = false; + shiftLastClicked = QTime::currentTime(); + ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock_hl.svg")); + ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock_hl.svg")); + } + else { + int doubleClickInterval = QApplication::doubleClickInterval(); + if(shiftLastClicked.msecsTo(QTime::currentTime()) <= doubleClickInterval) { + //shift键双击,锁定大写 + capsLock = true; + isShift = true; + ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); + ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); + ui->btn_shift_l->setStyleSheet("QPushButton{background:#80c342}"); + ui->btn_shift_r->setStyleSheet("QPushButton{background:#80c342}"); + } else { + ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); + ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); + ui->btn_shift_l->setStyleSheet("QPushButton{background:#1e1b18}"); + ui->btn_shift_r->setStyleSheet("QPushButton{background:#1e1b18}"); + } + } + toggleCase(); + } else { + page = page % (SYMBOL_PAGE_COUNT - 1) + 1; + switchPage(); + } + } else if(mod != Modifier::UNKNOWN) { + if(vKeyboard->hasModifier(mod)) { + vKeyboard->removeModifier(mod); + btn->setStyleSheet(BUTTON_BG); + btn->setStyleSheet(BUTTON_BG); + } else { + vKeyboard->addModifier(mod); + btn->setStyleSheet(BUTTON_BG_HL); + btn->setStyleSheet(BUTTON_BG_HL); + } + } else if(funcKey != FuncKey::UNKNOWN) { + Q_EMIT keyPressed(funcKey); + } else { //字符键 + QChar c; + QString text = btn->text(); + qDebug() << "clicked button text: " << text; + if(text == "&&") + c = '&'; + else if(text.length() == 1) + c = text.at(0); + + Q_EMIT keyPressed(c); + + //如果shift键被单击,按一个键后就恢复为小写 + if(isShift && !capsLock) { + isShift = false; + toggleCase(); + changeShitKeyStyle(ui->btn_shift_l, false); + changeShitKeyStyle(ui->btn_shift_r, false); + } + clearModifier(); + } +} + +void KeyboardWidget::clearModifier() +{ + for(auto mod : vKeyboard->getAllModifier()) { + QString modName = Modifier::getModifierName(mod); + if(mod == Modifier::SUPER) { + QString objName = QString("btn_%1").arg(modName); + QPushButton *btn = ui->page_letter->findChild(objName); + btn->setStyleSheet(BUTTON_BG); + } else { + QString objName = QString("btn_%1_l").arg(modName); + QPushButton *btn = ui->page_letter->findChild(objName); + btn->setStyleSheet(BUTTON_BG); + objName = QString("btn_%1_r").arg(modName); + btn = ui->page_letter->findChild(objName); + btn->setStyleSheet(BUTTON_BG); + } + } + vKeyboard->clearModifier(); +} + +void KeyboardWidget::toggleCase() +{ + for(int i = 0; i < 26; i++) { + QString objName = "btn_" + QString::number(i); + QPushButton *btn = findChild(objName); + QChar ch; + if(isShift) { //切换到大写 + ch = symbols[0][i].toUpper(); + } else { + ch = symbols[0][i]; + } + btn->setText(ch); + } +} + +void KeyboardWidget::switchPage() +{ + if(page == 0) { + ui->btn_shift_l->setText(""); + ui->btn_shift_r->setText(""); + ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); + ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); + } else { + ui->btn_shift_l->setText(""); + ui->btn_shift_r->setText(""); + ui->btn_shift_l->setIcon(QIcon(":/images/images/capslock.svg")); + ui->btn_shift_r->setIcon(QIcon(":/images/images/capslock.svg")); + } + + for(int i = 0; i < SYMBOL_KEY_COUNT; i++) { + QString btnObjName = "btn_" + QString::number(i); + QPushButton *btn = ui->page_letter->findChild(btnObjName); + QChar c = symbols[page][i]; + if(c == '&') + btn->setText("&&"); + else + btn->setText(c); + } +} + diff --git a/VirtualKeyboard/src/keyboardwidget.h b/VirtualKeyboard/src/keyboardwidget.h new file mode 100644 index 0000000..25591ae --- /dev/null +++ b/VirtualKeyboard/src/keyboardwidget.h @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2018 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, 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 KEYBOARDWIDGET_H +#define KEYBOARDWIDGET_H + +#include +#include +#include +#include "x11keyboard.h" + +namespace Ui { +class KeyboardWidget; +} + +class QPushButton; + +class KeyboardWidget : public QWidget +{ + Q_OBJECT + +public: + explicit KeyboardWidget(QWidget *parent = 0); + ~KeyboardWidget(); + +protected: + void resizeEvent(QResizeEvent *event); + +private: + void bindSingal(); + void toggleCase(); + void switchPage(); + void setDefaultIcon(); + void setIconSize(); + void changeKeyStyle(QPushButton *btn, bool isPressed); + void changeFuncKeyStyle(QPushButton *btn, bool isPressed); + void changeShitKeyStyle(QPushButton *btn, bool isPressed); + void changeDirectKeyStyle(QPushButton *btn, bool isPressed); + void clearModifier(); + QString getKeyName(QPushButton *btn); + + +private Q_SLOTS: + void onButtonClicked(); + void onButtonPressed(); + void onButtonReleased(); + +Q_SIGNALS: + void aboutToClose(); + void keyPressed(QChar c); + void keyPressed(FuncKey::FUNCKEY key); + +private: + Ui::KeyboardWidget *ui; + bool capsLock; //是否大写锁定 + bool isShift; + QTime shiftLastClicked; //shift键上次被点击的时间 + int page; //当前是第几页的键盘 + X11Keyboard *vKeyboard; +}; + +#endif // KEYBOARDWIDGET_H diff --git a/VirtualKeyboard/src/keyboardwidget.ui b/VirtualKeyboard/src/keyboardwidget.ui new file mode 100644 index 0000000..ac55eff --- /dev/null +++ b/VirtualKeyboard/src/keyboardwidget.ui @@ -0,0 +1,1203 @@ + + + KeyboardWidget + + + Qt::NonModal + + + + 0 + 0 + 1132 + 293 + + + + + 0 + 0 + + + + + 0 + 0 + + + + KeyboardWidget + + + + 0 + + + QLayout::SetMinAndMaxSize + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 20 + + + QLayout::SetNoConstraint + + + 10 + + + 10 + + + 10 + + + 10 + + + + + 1 + + + + + 0 + + + QLayout::SetNoConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 5 + + + QLayout::SetNoConstraint + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 10 + + + QLayout::SetNoConstraint + + + + + + 0 + 0 + + + + q + + + + + + + + 0 + 0 + + + + w + + + + + + + + 0 + 0 + + + + e + + + + + + + + 0 + 0 + + + + r + + + + + + + + 0 + 0 + + + + t + + + + + + + + 0 + 0 + + + + y + + + + + + + + 0 + 0 + + + + u + + + + + + + + 0 + 0 + + + + i + + + + + + + + 0 + 0 + + + + o + + + + + + + + 0 + 0 + + + + p + + + + + + + + 0 + 0 + + + + + + + + + + + + + 10 + + + QLayout::SetNoConstraint + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + a + + + + + + + + 0 + 0 + + + + s + + + + + + + + 0 + 0 + + + + d + + + + + + + + 0 + 0 + + + + f + + + + + + + + 0 + 0 + + + + g + + + + + + + + 0 + 0 + + + + h + + + + + + + + 0 + 0 + + + + j + + + + + + + + 0 + 0 + + + + k + + + + + + + + 0 + 0 + + + + l + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + 10 + + + QLayout::SetNoConstraint + + + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + 0 + + + + z + + + + + + + + 0 + 0 + + + + x + + + + + + + + 0 + 0 + + + + c + + + + + + + + 0 + 0 + + + + v + + + + + + + + 0 + 0 + + + + b + + + + + + + + 0 + 0 + + + + n + + + + + + + + 0 + 0 + + + + m + + + + + + + + 0 + 0 + + + + , + + + + + + + + 0 + 0 + + + + . + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + 10 + + + QLayout::SetNoConstraint + + + + + + 0 + 0 + + + + + + + Ctrl + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + Alt + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + Alt + + + + + + + + 0 + 0 + + + + / + + + + + + + + 0 + 0 + + + + Ctrl + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + QLayout::SetNoConstraint + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 10 + + + QLayout::SetNoConstraint + + + + + QLayout::SetNoConstraint + + + 10 + + + + + + 0 + 0 + + + + 9 + + + + + + + + 0 + 0 + + + + 5 + + + + + + + + 0 + 0 + + + + 8 + + + + + + + + 0 + 0 + + + + 4 + + + + + + + + 0 + 0 + + + + 2 + + + + + + + + 0 + 0 + + + + 7 + + + + + + + + 0 + 0 + + + + 1 + + + + + + + + 0 + 0 + + + + 6 + + + + + + + + 0 + 0 + + + + 3 + + + + + + + + 0 + 0 + + + + 0 + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QLayout::SetNoConstraint + + + 10 + + + + + + 0 + 0 + + + + Delete + + + + + + + + 0 + 0 + + + + End + + + + + + + + 0 + 0 + + + + Insert + + + + + + + + 0 + 0 + + + + PgUp + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + Home + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + PgDn + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 5 + + + QLayout::SetNoConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Abc + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + @ + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + 123 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + diff --git a/VirtualKeyboard/src/main.cpp b/VirtualKeyboard/src/main.cpp new file mode 100644 index 0000000..99fc2f0 --- /dev/null +++ b/VirtualKeyboard/src/main.cpp @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2018 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, 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 "virtualkeyboard.h" +#include + +int main(int argc, char *argv[]) +{ +// qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard")); + QApplication a(argc, argv); + VirtualKeyboard *keyboard = new VirtualKeyboard; + QObject::connect(keyboard, &VirtualKeyboard::aboutToClose, &a, &QApplication::quit); + keyboard->resize(400,300); + keyboard->show(); + + return a.exec(); +} diff --git a/VirtualKeyboard/src/virtualkeyboard.cpp b/VirtualKeyboard/src/virtualkeyboard.cpp new file mode 100644 index 0000000..ea46695 --- /dev/null +++ b/VirtualKeyboard/src/virtualkeyboard.cpp @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2018 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, 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 "virtualkeyboard.h" +#include +#include +#include +#include + +VirtualKeyboard::VirtualKeyboard(QWidget *parent) + : QWidget(parent) +{ + Q_INIT_RESOURCE(keyboard); + + setAutoFillBackground(true); + QPalette plt; + plt.setBrush(QPalette::Background, Qt::black); + setPalette(plt); + + setWindowFlags(Qt::FramelessWindowHint | + Qt::WindowStaysOnTopHint | + Qt::WindowDoesNotAcceptFocus); + + + keyboardWidget = new KeyboardWidget(this); + QHBoxLayout *hl_keyboard = new QHBoxLayout(this); + QSpacerItem *spacer = new QSpacerItem(40, 20); + hl_keyboard->addSpacerItem(spacer); + hl_keyboard->addWidget(keyboardWidget); + QSpacerItem *spacer2 = new QSpacerItem(40, 20); + hl_keyboard->addSpacerItem(spacer2); + + QFile qssFile(":/qss/keyboard.qss"); + qssFile.open(QIODevice::ReadOnly); + setStyleSheet(qssFile.readAll()); + qssFile.close(); + + QDesktopWidget *desktop = QApplication::desktop(); + cursorMonitor = new CursorMonitor(this); + + //在多显示器情况下,监视鼠标指针的位置和主显示器变化信号 + connect(cursorMonitor, &CursorMonitor::cursorPosChanged, + this, [&](const QPoint &pos){ + adjustGeometry(desktop->screenNumber(pos)); + }); + + connect(desktop, &QDesktopWidget::primaryScreenChanged, + this, [&]{ + adjustGeometry(desktop->primaryScreen()); + }); + + connect(keyboardWidget, &KeyboardWidget::aboutToClose, + this, &VirtualKeyboard::aboutToClose); + + adjustGeometry(desktop->primaryScreen()); +} + +void VirtualKeyboard::adjustGeometry(int screen) +{ + QDesktopWidget *desktop = QApplication::desktop(); + QWidget *activateScreen = desktop->screen(screen); + setGeometry(0, activateScreen->height() - activateScreen->height() / 3, + activateScreen->width(), activateScreen->height() / 3); +} diff --git a/VirtualKeyboard/src/virtualkeyboard.h b/VirtualKeyboard/src/virtualkeyboard.h new file mode 100644 index 0000000..44b628a --- /dev/null +++ b/VirtualKeyboard/src/virtualkeyboard.h @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2018 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, 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 VIRTUALKEYBOARD_H +#define VIRTUALKEYBOARD_H + +#include +#include + +#include "keyboardwidget.h" +#include "cursormonitor.h" + +class VirtualKeyboard : public QWidget +{ + Q_OBJECT +public: + explicit VirtualKeyboard(QWidget *parent = 0); + +private: + void adjustGeometry(int screen); + +Q_SIGNALS: + void aboutToClose(); + +private: + KeyboardWidget *keyboardWidget; + CursorMonitor *cursorMonitor; + bool isApplication; +}; + + +#endif // VIRTUALKEYBOARD_H diff --git a/VirtualKeyboard/src/x11keyboard.cpp b/VirtualKeyboard/src/x11keyboard.cpp new file mode 100644 index 0000000..5e160ed --- /dev/null +++ b/VirtualKeyboard/src/x11keyboard.cpp @@ -0,0 +1,208 @@ +/** + * Copyright (C) 2018 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, 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 "x11keyboard.h" +#include +#include +#include +#include + + + +struct CharMap { + QChar name; + KeySym code; +}; + +struct CharMap XSpecialSymbolMap[] { + {' ', XK_space}, + {',', XK_comma}, + {'.', XK_period}, + {'\'', XK_quoteright}, + {'@', XK_at}, + {'#', XK_numbersign}, + {'$', XK_dollar}, + {'%', XK_percent}, + {'&', XK_ampersand}, + {'*', XK_asterisk}, + {'(', XK_parenleft}, + {')', XK_parenright}, + {'-', XK_minus}, + {'+', XK_plus}, + {'!', XK_exclam}, + {'"', XK_quotedbl}, + {'<', XK_less}, + {'>', XK_greater}, + {':', XK_colon}, + {';', XK_semicolon}, + {'/', XK_slash}, + {'?', XK_question}, + {'=', XK_equal}, + {'.', XK_kana_middledot}, + {'~', XK_asciitilde}, + {'`', XK_grave}, + {'|', XK_bar}, + {'^', XK_asciicircum}, + {'{', XK_braceleft}, + {'}', XK_braceright}, + {'[', XK_bracketleft}, + {']', XK_bracketright}, + {'_', XK_underscore}, + {'\\', XK_backslash}, +}; + +QMap funckeyMap = { + {FuncKey::SPACE, XK_space}, + {FuncKey::BACKSPACE, XK_BackSpace}, + {FuncKey::ENTER, XK_Return}, + {FuncKey::HOME, XK_Home}, + {FuncKey::END, XK_End}, + {FuncKey::PGUP, XK_Page_Up}, + {FuncKey::PGDN, XK_Page_Down}, + {FuncKey::INSERT, XK_Insert}, + {FuncKey::DELETE, XK_Delete}, + {FuncKey::UP, XK_Up}, + {FuncKey::DOWN, XK_Down}, + {FuncKey::LEFT, XK_Left}, + {FuncKey::RIGHT, XK_Right} +}; + +QMap modifierMap = { + {Modifier::CTRL, XK_Control_L}, + {Modifier::ALT, XK_Alt_L}, + {Modifier::SUPER, XK_Super_L}, + {Modifier::SHIFT, XK_Shift_L} +}; + +QVector shiftKeyVec = {'~', '!', '@', '#', '$', '%', '^', '&', '*', + '(', ')', '_', '+', '{', '}', '|', ':', '"', + '>', '?'}; + +static Display *display = XOpenDisplay(0); +bool isShift = false; +bool isLetter = false; +unsigned int keyCodeOfChar(QChar c) +{ + QString text(c); + + KeySym keysym = XStringToKeysym(text.toLocal8Bit().data()); + + if(keysym == NoSymbol) { + int symbolCount = sizeof(XSpecialSymbolMap) / sizeof(struct CharMap); + for(int i = 0; i < symbolCount; i++) { + if(XSpecialSymbolMap[i].name == c) { + keysym = XSpecialSymbolMap[i].code; + break; + } + } + } + qDebug() << "keysym: " << keysym; + + isShift = shiftKeyVec.contains(c) || (c >= 'A' && c <= 'Z'); + + isLetter = c.isLetter(); + + KeyCode code = XKeysymToKeycode(display, keysym); + + return code; +} + +X11Keyboard::X11Keyboard(QObject *parent) + : QObject(parent) +{ + +} + +X11Keyboard::~X11Keyboard() +{ + XCloseDisplay(display); +} + +void X11Keyboard::addModifier(Modifier::MOD mod) +{ + modList.push_back(mod); +} + +void X11Keyboard::removeModifier(Modifier::MOD mod) +{ + modList.removeOne(mod); +} + +bool X11Keyboard::hasModifier(Modifier::MOD mod) +{ + return modList.contains(mod); +} + +QList X11Keyboard::getAllModifier() +{ + return modList; +} + +void X11Keyboard::clearModifier() +{ + modList.clear(); +} + + +void X11Keyboard::onKeyPressed(QChar c) +{ + unsigned int keyCode = keyCodeOfChar(c); + sendKey(keyCode); +} + +void X11Keyboard::onKeyPressed(FuncKey::FUNCKEY key) +{ + KeyCode keyCode; + KeySym keysym = funckeyMap[key]; + + if(keysym != NoSymbol) + keyCode = XKeysymToKeycode(display, keysym); + + sendKey(keyCode); +} + +void X11Keyboard::sendKey(unsigned int keyCode) +{ + Window focusWindow; + int revert; + XGetInputFocus(display, &focusWindow, &revert); + + for(auto mod : modList){ + KeyCode keyCode = XKeysymToKeycode(display, modifierMap[mod]); + XTestFakeKeyEvent(display, keyCode, True, 2); + } + + //如果使用了修饰键(如ctrl、alt)且字符键是字母,则不起用shift键,否则快捷键不起作用 + if(!modList.isEmpty() && isLetter) + isShift = false; + + if(isShift) + XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Shift_L), True, 2); + + XTestFakeKeyEvent(display, keyCode, True, CurrentTime); + XTestFakeKeyEvent(display, keyCode, False, CurrentTime); + + if(isShift) + XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_Shift_L), False, 2); + for(auto mod : modList){ + KeyCode keyCode = XKeysymToKeycode(display, modifierMap[mod]); + XTestFakeKeyEvent(display, keyCode, False, 2); + } + + XFlush(display); +} diff --git a/VirtualKeyboard/src/x11keyboard.h b/VirtualKeyboard/src/x11keyboard.h new file mode 100644 index 0000000..42fd997 --- /dev/null +++ b/VirtualKeyboard/src/x11keyboard.h @@ -0,0 +1,116 @@ +/** + * Copyright (C) 2018 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, 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 X11KEYBOARD_H +#define X11KEYBOARD_H + +#include +#include + +class Modifier : public QObject +{ + Q_OBJECT +public: + Modifier(){} + + enum MOD{ + UNKNOWN = -1, + CTRL, + SHIFT, + ALT, + SUPER + }; + Q_ENUM(MOD) + + static QString getModifierName(int mod) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + const char* modName = metaEnum.valueToKey(mod); + QString result = QString(modName).toLower(); + return result; + } + static MOD getModifier(const QString &modName) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + MOD mod = (MOD)metaEnum.keyToValue(modName.toUpper().toLocal8Bit().data()); + return mod; + } +}; + +class FuncKey : public QObject +{ + Q_OBJECT +public: + FuncKey(){} + + enum FUNCKEY { + UNKNOWN = -1, + SPACE = 0, + BACKSPACE, + ENTER, + HOME, + END, + PGUP, + PGDN, + INSERT, + DELETE, + UP, + DOWN, + LEFT, + RIGHT + }; + Q_ENUM(FUNCKEY) + static QString getKeyName(int key) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + const char* keyName = metaEnum.valueToKey(key); + QString result = QString(keyName).toLower(); + return result; + } + static FUNCKEY getKey(const QString &keyName) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + FUNCKEY key = (FUNCKEY)metaEnum.keyToValue(keyName.toUpper().toLocal8Bit().data()); + return key; + } +}; + +class X11Keyboard : public QObject +{ + Q_OBJECT +public: + explicit X11Keyboard(QObject *parent = nullptr); + ~X11Keyboard(); + void addModifier(Modifier::MOD mod); + void removeModifier(Modifier::MOD mod); + bool hasModifier(Modifier::MOD mod); + QList getAllModifier(); + void clearModifier(); + +public Q_SLOTS: + void onKeyPressed(QChar c); + void onKeyPressed(FuncKey::FUNCKEY key); + +private: + void sendKey(unsigned int keyCode); + +private: + QList modList; +}; + +#endif // X11KEYBOARD_H diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..a66e4e2 --- /dev/null +++ b/config.h.in @@ -0,0 +1,9 @@ +#cmakedefine USE_INTEL + +// == 下面是测试用的 +#cmakedefine01 TEST_ON +#cmakedefine01 TEST_OF + +#ifndef __${VAR}___@VAR@ + +#endif diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt new file mode 100644 index 0000000..ac9b470 --- /dev/null +++ b/data/CMakeLists.txt @@ -0,0 +1,6 @@ +install(FILES org.ukui.screensaver.gschema.xml DESTINATION /usr/share/glib-2.0/schemas) +install(FILES ukui-screensaver.desktop DESTINATION /etc/xdg/autostart) +install(FILES ukui-screensaver.directory DESTINATION /usr/share/desktop-directories) +install(FILES ukui-screensavers.menu DESTINATION /etc/xdg/menus) +install(FILES ukui-screensaver-qt DESTINATION /etc/pam.d) +install(FILES screensaver-startup.sh DESTINATION /usr/bin) diff --git a/data/org.ukui.screensaver.gschema.xml b/data/org.ukui.screensaver.gschema.xml new file mode 100644 index 0000000..b9d8aeb --- /dev/null +++ b/data/org.ukui.screensaver.gschema.xml @@ -0,0 +1,169 @@ + + + + + + + + + + + + + + + + false + Automatic switching background + Set this to TRUE to activate the automatic switching background. + + + true + show rest time on custom screensaver + Set this to TRUE to show rest time on custom screensaver. + + + true + show rest time on ukui screensaver + Set this to TRUE to show rest time on ukui screensaver. + + + + "" + set user text on screensaver. + set user text on screensaver. + + + "/usr/share/backgrounds" + set background path on screensaver. + set background path on screensaver. + + + true + set text postion + Set this to TRUE to show text on screensaver center. + + + 300 + Time to update background on ukui-screensavaer-default + The number of seconds to change screensaver background. + + + + + true + Activate when idle + Set this to TRUE to activate the screensaver when the session is idle. + + + true + Activation when lock + Set this to TRUE to lock the screen when the the session is idle. + + + true + Lock on activation + Set this to TRUE to lock the screen when the screensaver goes active. + + + 5 + idle delay to lock + Wait idle delay to lock + + + 5 + idle lock to lock + Display the lock screen + + + true + Lock when sleep + Set this to TRUE to lock the screen when the system goes sleep. + + + 'default-ukui' + Screensaver theme selection mode + The selection mode used by screensaver. May be "blank-only" to enable the screensaver without using any theme on activation, "single" to enable screensaver using only one theme on activation (specified in "themes" key), and "random" to enable the screensaver using a random theme on activation. + + + 'fade-in-out' + Effect for images transition + The selection effect used by screensaer which play images. May be "none" to play images without any transition effect. It's ignored when "mode" is not "image". + + + 60 + Time interval of switching images + The number of seconds of time interval of switching images + + + [] + Screensaver themes + This key specifies the list of themes to be used by the screensaver. It's ignored when "mode" key is "blank-only", should provide the theme name when "mode" is "single", and should provide a list of themes when "mode" is "random". + + + 30 + Time before power management baseline + The number of seconds of inactivity before signalling to power management. This key is set and maintained by the session power management agent. + + + 10 + Time before theme change + The number of minutes to run before changing the screensaver theme. + + + 0 + Time before locking + The number of minutes after screensaver activation before locking the screen. + + + false + Allow embedding a keyboard into the window + Set this to TRUE to allow embedding a keyboard into the window when trying to unlock. The "keyboard_command" key must be set with the appropriate command. + + + '' + Embedded keyboard command + The command that will be run, if the "embedded_keyboard_enabled" key is set to TRUE, to embed a keyboard widget into the window. This command should implement an XEMBED plug interface and output a window XID on the standard output. + + + false + Allow logout + Set this to TRUE to offer an option in the unlock dialog to allow logging out after a delay. The delay is specified in the "logout_delay" key. + + + 120 + Time before logout option + The number of minutes after the screensaver activation before a logout option will appear in the unlock dialog. This key has effect only if the "logout_enable" key is set to TRUE. + + + '' + Logout command + The command to invoke when the logout button is clicked. This command should simply log the user out without any interaction. This key has effect only if the "logout_enable" key is set to TRUE. + + + true + Allow user switching + Set this to TRUE to offer an option in the unlock dialog to switch to a different user account. + + + true + Allow the session status message to be displayed + Allow the session status message to be displayed when the screen is locked. + + + '/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg' + the background iamge of lockscreen + Allow the user to set the background iamge of lockscreen. + + + 0 + Number of side-bar notify messages + The number of sider notify messages + + + true + Allow to show messages + Set this to TRUE to if u want to see how many masseges not read + + + diff --git a/data/screensaver-startup.sh b/data/screensaver-startup.sh new file mode 100755 index 0000000..fa8710d --- /dev/null +++ b/data/screensaver-startup.sh @@ -0,0 +1,5 @@ +#!/bin/bash +/usr/lib/ukui-screensaver/set4kScale >/dev/null 2>&1 +ukui-screensaver-dialog --lock-startup & >/dev/null 2>&1 +/usr/lib/ukui-screensaver/screensaver-focus-helper & >/dev/null 2>&1 + diff --git a/data/ukui-screensaver-qt b/data/ukui-screensaver-qt new file mode 100644 index 0000000..8ac0d54 --- /dev/null +++ b/data/ukui-screensaver-qt @@ -0,0 +1,14 @@ +auth requisite pam_nologin.so +auth sufficient pam_succeed_if.so user ingroup nopasswdlogin + +@include common-auth +auth optional pam_gnome_keyring.so + + +#If you are using Arch,comment out the +#above and use the following. + +#auth include system-auth +#account include system-auth +#password include system-auth +#session include system-auth diff --git a/data/ukui-screensaver.desktop b/data/ukui-screensaver.desktop new file mode 100644 index 0000000..ce57723 --- /dev/null +++ b/data/ukui-screensaver.desktop @@ -0,0 +1,19 @@ +[Desktop Entry] +Type=Application +Name=Screensaver +Name[tr]=Ekran Koruyucu +Name[zh_CN]=屏幕保护程序 +Name[zh_HK]=螢幕保護程式 +Name[zh_TW]=螢幕保護程式 +Comment[tr]=Ekran koruyucuyu çalıştır ve programı kilitler +Comment[zh_CN]=运行屏幕保护及锁定程序 +Comment[zh_TW]=啟動螢幕保護程式以及鎖定程式 +Exec=ukui-screensaver-backend +NoDisplay=true +X-UKUI-Autostart-Phase=Application +X-UKUI-Autostart-Notify=true +X-UKUI-Bugzilla-Bugzilla=UKUI +X-UKUI-Bugzilla-Product=ukui-screensaver +X-UKUI-Bugzilla-Component=general +X-UKUI-Bugzilla-Version=1.0.0 +OnlyShowIn=UKUI diff --git a/data/ukui-screensaver.directory b/data/ukui-screensaver.directory new file mode 100644 index 0000000..2fd2ff2 --- /dev/null +++ b/data/ukui-screensaver.directory @@ -0,0 +1,180 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Screensavers +Name[am]=የመመልከቻው ማዳኛዎች +Name[ar]=حافظات الشاشة +Name[as]=স্ক্ৰীনছেভাৰ +Name[ast]=Curiapantalles +Name[be]=Ахоўнікі экрану +Name[be@latin]=Źbierahalniki ekranu +Name[bg]=Предпазители на екрана +Name[bn]=স্ক্রীন সেভার +Name[bn_IN]=স্ক্রীনসেভার +Name[br]=Damanterioù skramm +Name[ca]=Estalvis de pantalla +Name[ca@valencia]=Estalvis de pantalla +Name[cmn]=螢幕保護程式 +Name[crh]=Ekran qoruyıcıları +Name[cs]=Šetřiče obrazovky +Name[cy]=Arbedwyr Sgrin +Name[da]=Pauseskærme +Name[de]=Bildschirmschoner +Name[dz]=གསལ་གཞི་ཉེན་སྲུང་ཚུ། +Name[el]=Θέματα +Name[en_AU]=Screensavers +Name[en_CA]=Screensavers +Name[en_GB]=Screensavers +Name[es]=Salvapantallas +Name[es_AR]=Protectores de pantalla +Name[et]=Ekraanisäästjad +Name[eu]=Pantaila-babeslea +Name[fa]=محافظ‌های صفحهٔ نمایش +Name[fi]=Näytönsäästäjät +Name[fr]=Économiseurs d'écran +Name[ga]=Spárálaithe Scáileáin +Name[gl]=Protectores de pantalla +Name[gu]=સ્ક્રીનસેવરો +Name[he]=שומרי מסך +Name[hi]=स्क्रीनसेवरs +Name[hr]=Zaslonski čuvari +Name[hu]=Képernyővédők +Name[id]=Screensaver +Name[is]=Skjáhvílur +Name[it]=Salvaschermo +Name[ja]=いろいろなスクリーンセーバーを格納するフォルダ +Name[ka]=ეკრანმზოგები +Name[kn]=ಸ್ಕ್ರೀನ್‌ಸೇವರುಗಳು +Name[ko]=화면 보호기 +Name[ku]=Parêzvanên ekranê +Name[ky]=Экран сактагычтар +Name[lt]=Ekrano užsklandos +Name[lv]=Ekrānsaudzētāji +Name[mai]=स्क्रीनसेवर +Name[mg]=Sary mitsitsy +Name[mk]=Чувари на екранот +Name[ml]=സ്ക്രീന്‍സേവറുകള്‍ +Name[mn]=_Дэлгэц гамнагчүүд +Name[mr]=स्क्रीनसेवर +Name[ms]=Penyelamat skrin +Name[nb]=Skjermsparere +Name[nds]=Billschirmschoners +Name[ne]=स्क्रिनसेभर +Name[nl]=Screensavers +Name[nn]=Skjermsparare +Name[oc]=Estalviaires d'ecran +Name[or]=ପରଦା ସଂରକ୍ଷକ +Name[pa]=ਸਕਰੀਨ-ਸੇਵਰ +Name[pl]=Wygaszacze ekranu +Name[ps]=پرده ساتونکي +Name[pt]=Protetores de Ecrã +Name[pt_BR]=Proteções de tela +Name[ro]=Economizoare de ecran +Name[ru]=Хранители экрана +Name[si]=තිරආවරක +Name[sk]=Šetriče obrazovky +Name[sl]=Ohranjevalniki zaslona +Name[sq]=Ruajtës ekrani +Name[sr]=Чувари екрана +Name[sr@latin]=Čuvari ekrana +Name[sv]=Skärmsläckare +Name[ta]=திரைசேமிப்பிகள் +Name[te]=తెరకాపరులు +Name[th]=โปรแกรมรักษาหน้าจอ +Name[tr]=Ekran koruyucular +Name[uk]=Заставки екрану +Name[ur]=سکرین سیور +Name[vi]=Ảnh bảo vệ màn hình +Name[zh_CN]=屏幕保护程序 +Name[zh_HK]=螢幕保護程式 +Name[zh_TW]=螢幕保護程式 +Comment=Screensaver themes +Comment[am]=የመመልከቻው ማዳኛ ገጽታዎች +Comment[ar]=سِمات حافظة الشاشة +Comment[as]=স্ক্ৰীনছেভাৰ থিম +Comment[ast]=Temes del Curiapantalles +Comment[be]=Тэмы ахоўніка экрану +Comment[be@latin]=Matyvy źbierahalnika ekranu +Comment[bg]=Теми за предпазителя +Comment[bn]=স্ক্রীনসেভার থীম +Comment[bn_IN]=স্ক্রীনসেভার থিম +Comment[br]=Neuzioù an damanter skramm +Comment[ca]=Temes de l'estalvi de pantalla +Comment[ca@valencia]=Temes de l'estalvi de pantalla +Comment[cmn]=螢幕保護程式布景主題 +Comment[crh]=Ekran qoruyıcısı temaları +Comment[cs]=Motivy šetřiče obrazovky +Comment[cy]=Themâu arbedwr sgrin +Comment[da]=Pauseskærm temaer +Comment[de]=Bildschirmschonerthemen +Comment[dz]=གསལ་གཞི་ཉེན་སྲུང་བརྗོད་དོན་ཚུ། +Comment[el]=Θέματα προστασίας οθόνης +Comment[en@shaw]=𐑕𐑒𐑮𐑰𐑯𐑕𐑱𐑝𐑼 𐑔𐑰𐑥𐑟 +Comment[en_AU]=Screensaver themes +Comment[en_CA]=Screensaver themes +Comment[en_GB]=Screensaver themes +Comment[es]=Temas del salvapantallas +Comment[es_AR]=Temas de protector de pantalla +Comment[et]=Ekraanisäästja teemad +Comment[eu]=Pantaila-babeslearen gaiak +Comment[fa]=تم‌های محافظ صفحهٔ نمایش +Comment[fi]=Näytönsäästäjän teemat +Comment[fr]=Thèmes de l'économiseur d'écran +Comment[ga]=Téamaí spárálaí scáileáin +Comment[gl]=Temas do protector de pantalla +Comment[gu]=સ્ક્રીનસેવર થીમો +Comment[he]=ערכות נושא לשומר המסך +Comment[hi]=स्क्रीनसेवर थीम +Comment[hr]=Teme zaslonskog čuvara +Comment[hu]=Képernyővédő-témák +Comment[id]=Tema screensaver +Comment[is]=Ásýnd skjáhvílu +Comment[it]=Temi del salvaschermo +Comment[ja]=スクリーンセーバーのテーマ +Comment[ka]=ეკრანმზოგის გაფორმების თემები +Comment[kn]=ಸ್ಕ್ರೀನ್‌ಸೇವರ್ ಥೀಮ್‌ಗಳು +Comment[ko]=화면 보호기 테마 +Comment[ku]=Dirbên dîmenderparêzê +Comment[ky]=Экран сактагыч темалары +Comment[lt]=Ekrano užsklandos temos +Comment[lv]=Ekrānsaudzētāja tēmas +Comment[mai]=स्क्रीनसेवर थीम +Comment[mg]=Endri-tsary mitsitsy +Comment[mk]=Теми за чуварот на екранот +Comment[ml]=സ്ക്രീന്‍സേവറിന്റെ പ്രമേയങ്ങള്‍ +Comment[mn]=_Дэлгэц гамнагчийн загварууд +Comment[mr]=स्क्रीनसेवर सुत्रयोजना +Comment[ms]=Tema penyelamat skrin +Comment[nb]=Tema for skjermsparer +Comment[nds]=Billschirmschonerthemen +Comment[ne]=स्क्रिनसेभर विषयवस्तु +Comment[nl]=Screensavers +Comment[nn]=Tema for skjermsparar +Comment[oc]=Tèmas d'estalviaire d'ecran +Comment[or]=ପରଦା ସଂରକ୍ଷକ ପ୍ରସଙ୍ଗ +Comment[pa]=ਸਕਰੀਨ-ਸੇਵਰ ਥੀਮ +Comment[pl]=Motywy wygaszacza ekranu +Comment[ps]=د پرده ساتونکي کوندې +Comment[pt]=Temas do Protetor de Ecrã +Comment[pt_BR]=Temas de proteção de tela +Comment[ro]=Teme pentru economizor +Comment[ru]=Темы хранителя экрана +Comment[si]=තිරආවරකයේ තේමා +Comment[sk]=Témy šetriča obrazovky +Comment[sl]=Teme ohranjevalnika zaslona +Comment[sq]=Temat e ruajtësit të ekranit +Comment[sr]=Теме чувара екрана +Comment[sr@latin]=Teme čuvara ekrana +Comment[sv]=Skärmsläckarteman +Comment[ta]=திரைசேமிப்பி சூழல்கள் +Comment[te]=తెరకాపరి వైవిద్యాంశాలు +Comment[th]=ชุดโปรแกรมรักษาหน้าจอ +Comment[tr]=Ekran koruyucu temaları +Comment[uk]=Теми збереження екрану +Comment[ur]=سکرین سیور کی تھیم +Comment[vi]=Sắc thái của ảnh bảo vệ màn hình +Comment[zh_CN]=屏幕保护程序主题 +Comment[zh_HK]=螢幕保護程式佈景主題 +Comment[zh_TW]=螢幕保護程式布景主題 +Icon=screensaver +Type=Directory +NoDisplay=false diff --git a/data/ukui-screensavers.menu b/data/ukui-screensavers.menu new file mode 100644 index 0000000..f3dc43d --- /dev/null +++ b/data/ukui-screensavers.menu @@ -0,0 +1,20 @@ + + + + + Screensavers + ukui-screensaver.directory + + + + + + + + + + Screensaver + + + diff --git a/i18n_ts/CMakeLists.txt b/i18n_ts/CMakeLists.txt new file mode 100644 index 0000000..f4b0cef --- /dev/null +++ b/i18n_ts/CMakeLists.txt @@ -0,0 +1,12 @@ +find_package(Qt5LinguistTools) + +file(GLOB ts_files *.ts) +qt5_create_translation(qm_files ${ts_files}) +add_custom_target(i18n + DEPENDS ${qm_files} + SOURCES ${ts_files} + ) +# 让主目标依赖翻译文件,这样才会执行i18n +add_dependencies(ukui-screensaver-dialog i18n) + +install(FILES ${qm_files} DESTINATION /usr/share/ukui-screensaver/i18n_qm/) diff --git a/i18n_ts/bo.ts b/i18n_ts/bo.ts new file mode 100644 index 0000000..1f66585 --- /dev/null +++ b/i18n_ts/bo.ts @@ -0,0 +1,2088 @@ + + + + + AuthDialog + + + Authentication failure, Please try again + + + + + + + + Please try again in %1 minutes. + + + + + + + + Please try again in %1 seconds. + + + + + + + + Account locked permanently. + + + + + Verify face recognition or enter password to unlock + + + + + Press fingerprint or enter password to unlock + + + + + Verify voiceprint or enter password to unlock + + + + + Verify finger vein or enter password to unlock + + + + + Verify iris or enter password to unlock + + + + + Use the bound wechat scanning code or enter the password to unlock + + + + + + Password cannot be empty + + + + + Password + + + + + Input Password + + + + + Login + + + + + Retry + + + + + Failed to verify %1, please enter password to unlock + + + + + Unable to verify %1, please enter password to unlock + + + + + Failed to verify %1, you still have %2 verification opportunities + + + + + NET Exception + + + + + BiometricAuthWidget + + + Current device: + + + + + Identify failed, Please retry. + + + + + BiometricDevicesWidget + + + Please select the biometric device + + + + + Device type: + + + + + Device name: + + + + + OK + + + + + ConfForm + + + edit network + + + + + LAN name: + + + + + Method: + + + + + Address: + + + + + Netmask: + + + + + Gateway: + + + + + DNS 1: + + + + + DNS 2: + + + + + Edit Conn + + + + + + Auto(DHCP) + + + + + + Manual + + + + + Cancel + + + + + Save + + + + + Ok + + + + + Can not create new wired network for without wired card + + + + + New network already created + + + + + New network settings already finished + + + + + New settings already effective + + + + + Edit Network + + + + + Add Wired Network + + + + + DeviceType + + + FingerPrint + + + + + FingerVein + + + + + Iris + + + + + Face + + + + + VoicePrint + + + + + QRCode + + + + + DigitalAuthDialog + + + + LoginByUEdu + + + + + ResetPWD? + + + + + + SetNewUEduPWD + + + + + clear + + + + + ConfirmNewUEduPWD + + + + + The two password entries are inconsistent, please reset + + + + + Password entered incorrectly, please try again + + + + + DlgConnHidWifi + + + + Connect to Hidden Wi-Fi Network + + + + + Add Hidden Wi-Fi + + + + + Connection + + + + + Wi-Fi name + + + + + Wi-Fi security + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + DlgConnHidWifiLeap + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Username + + + + + Password + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + DlgConnHidWifiSecFast + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Anonymous identity + + + + + Allow automatic PAC pro_visioning + + + + + PAC file + + + + + Inner authentication + + + + + Username + + + + + Password + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + Anonymous + + + + + Authenticated + + + + + Both + + + + + DlgConnHidWifiSecLeap + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Username + + + + + Password + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecPeap + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Anonymous identity + + + + + Domain + + + + + CA certificate + + + + + CA certificate password + + + + + No CA certificate is required + + + + + PEAP version + + + + + Inner authentication + + + + + Username + + + + + Password + + + + + Cancel + + + + + Connect + + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + Choose from file + + + + + Automatic + + + + + Version 0 + + + + + Version 1 + + + + + DlgConnHidWifiSecPwd + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Username + + + + + Password + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecTls + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Identity + + + + + Domain + + + + + CA certificate + + + + + CA certificate password + + + + + No CA certificate is required + + + + + User certificate + + + + + User certificate password + + + + + User private key + + + + + User key password + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + + + Choose from file + + + + + DlgConnHidWifiSecTunnelTLS + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Anonymous identity + + + + + Domain + + + + + CA certificate + + + + + CA certificate password + + + + + No CA certificate is required + + + + + Inner authentication + + + + + Username + + + + + Password + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + Choose from file + + + + + DlgConnHidWifiWep + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Key + + + + + WEP index + + + + + Authentication + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + 1(default) + + + + + Open System + + + + + Shared Key + + + + + DlgConnHidWifiWpa + + + + Connect to Hidden Wi-Fi Network + + + + + Add Hidden Wi-Fi + + + + + Connection + + + + + Wi-Fi name + + + + + Wi-Fi security + + + + + Password + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + DlgHotspotCreate + + + + Dialog + + + + + Create Hotspot + + + + + Network name + + + + + Wi-Fi security + + + + + Password + + + + + Cancel + + + + + Ok + + + + + None + + + + + WPA & WPA2 Personal + + + + + InputInfos + + + + Get code + + + + + Recapture(60s) + + + + + Recapture(%1s) + + + + + Service exception... + + + + + Invaild parameters... + + + + + Unknown fault:%1 + + + + + KeyboardWidget + + + + KeyboardWidget + + + + + KylinNM + + + + kylin-nm + + + + + No usable network in the list + + + + + Inactivated LAN + + + + + Other WLAN + + + + + + LAN + + + + + + WLAN + + + + + HotSpot + + + + + FlyMode + + + + + + Advanced + + + + + Show KylinNM + + + + + No wireless card detected + + + + + Activated LAN + + + + + Activated WLAN + + + + + + + + + Not connected + + + + + + + + + + + + + Disconnected + + + + + + NetOn, + + + + + No Other Wired Network Scheme + + + + + No Other Wireless Network Scheme + + + + + Wired net is disconnected + + + + + Conn Ethernet Success + + + + + Conn Ethernet Fail + + + + + Conn Wifi Success + + + + + Confirm your Wi-Fi password or usable of wireless card + + + + + LockWidget + + + + Form + + + + + + Date + + + + + + Time + + + + + LoginOptionsWidget + + + Login Options + + + + + Identify device removed! + + + + + MyLineEdit + + + + + Verification code + + + + + OneConnForm + + + + Form + + + + + + + + Connect + + + + + Disconnect + + + + + Input Password... + + + + + Automatically join the network + + + + + Connect to Hidden Wi-Fi Network + + + + + None + + + + + WiFi Security: + + + + + Signal: + + + + + MAC: + + + + + Conn Wifi Failed + + + + + OneLancForm + + + + Form + + + + + + Connect + + + + + Disconnect + + + + + + No Configuration + + + + + IPv4: + + + + + IPv6: + + + + + BandWidth: + + + + + MAC: + + + + + PhoneAuthWidget + + + + Verification by phoneNum + + + + + 「 Use bound Phone number to verification 」 + + + + + + commit + + + + + 「 Use SMS to verification 」 + + + + + + Network not connected~ + + + + + Verification Code invalid! + + + + + Verification Code incorrect.Please retry! + + + + + Failed time over limit!Retry after 1 hour! + + + + + verifaction failed! + + + + + Network unavailable~ + + + + + PowerManager + + + Log Out + + + + + lock + + + + + + Restart + + + + + + Power Off + + + + + Suspend + + + + + Sleep + + + + + QObject + + + The screensaver is active. + + + + + The screensaver is inactive. + + + + + Screensaver + + + Picture does not exist + + + + + View + + + + + You have new notification + + + + + SleepTime + + + You have rested: + + + + + SwitchButtonGroup + + + uEduPWD + + + + + Wechat + + + + + TabletLockWidget + + + + + + + + Cancel + + + + + + Back + + + + + Skip + + + + + New password is the same as old + + + + + Reset password error:%1 + + + + + Please scan by correct WeChat + + + + + Utils + + + kylin network applet desktop message + + + + + VerificationWidget + + + Please scan by bound WeChat + + + + + VerticalVerificationWidget + + + Please scan by bound WeChat + + + + + WeChatAuthDialog + + + + Login by wechat + + + + + + 「 Use registered WeChat account to login 」 + + + + + + Verification by wechat + + + + + + 「 Use bound WeChat account to verification 」 + + + + + + Network not connected~ + + + + + Scan code successfully + + + + + Timeout!Try again! + + + + + main + + + Screensaver for ukui-screensaver + + + + + show on root window + + + + + show on window. + + + + + window id + + + + + Start command for the ukui ScreenSaver. + + + + + + + lock the screen immediately + + + + + query the status of the screen saver + + + + + unlock the screen saver + + + + + show the screensaver + + + + + Dialog for the ukui ScreenSaver. + + + + + activated by session idle signal + + + + + + lock the screen and show screensaver immediately + + + + + show screensaver immediately + + + + diff --git a/i18n_ts/bo_CN.ts b/i18n_ts/bo_CN.ts new file mode 100644 index 0000000..4135111 --- /dev/null +++ b/i18n_ts/bo_CN.ts @@ -0,0 +1,1679 @@ + + + + + AuthDialog + + Retry + ཡང་བསྐྱར་ཚོད་ལེན། + + + Please enter your password or enroll your fingerprint + གསང་ཨང་མནོན་པའམ་མཛུབ་རིམ་མནོན་རོགས། + + + Too many unsuccessful attempts,please enter password. + མཛུབ་རིས་ར་སྤྲོད་ཕམ་ཉེས་ཚད་ཆེས་ཆེ་ལས་བརྒལ་བ། ཁྱོས་གསང་ཨང་བཀོལ་ནས་ཟྭ་འབྱེད་རོགས། + + + Fingerprint authentication failed, you still have %1 verification opportunities + མཛུབ་རིས་ར་སྤྲོད་ཕམ་ཉེས་བྱུང་། ཁྱོད་ལ་ད་དུང་གོ་སྐབས་གཅིག་ཡོད། + + + Password: + གསང་ཨང་། + + + Biometric Authentication + སྐྱེ་དངོས་ངོས་འཛིན་ཀྱི་དཔང་ལེན། + + + Other Devices + སྒྲིག་ཆས་གཞན་དག + + + Password Authentication + གསང་ཨང་ར་སྤྲོད་གྲོས་ཆིངས། + + + Authentication failure, Please try again + དཔང་ལེན་བྱ་མ་ཐུབ། ཡང་བསྐྱར་ཚོད་ལྟ་བྱོས། + + + Please try again in %1 minutes. + + + + Please try again in %1 seconds. + + + + Account locked permanently. + + + + Verify face recognition or enter password to unlock + + + + Press fingerprint or enter password to unlock + + + + Verify voiceprint or enter password to unlock + + + + Verify finger vein or enter password to unlock + + + + Verify iris or enter password to unlock + + + + Password cannot be empty + + + + Password + + + + Login + + + + NET Exception + + + + Failed to verify %1, you still have %2 verification opportunities + + + + Use the bound wechat scanning code or enter the password to unlock + + + + Failed to verify %1, please enter password to unlock + + + + Unable to verify %1, please enter password to unlock + + + + Input Password + + + + + BiometricAuthWidget + + Identify failed, Please retry. + ངོས་འཛིན་མ་ཐུབ། ཡང་བསྐྱར་ཚོད་ལྟ་བྱོས། + + + Current device: + མིག་སྔའི་སྒྲིག་ཆས་རེའུ་མིག: + + + + BiometricDevicesWidget + + OK + གཏན་འཁེལ་བྱེད་པ། + + + Please select the biometric device + ཉིད་ཀྱིས་སྐྱེ་དངོས་སྒྲིག་ཆས་འདེམ་རོགས། + + + Device type: + སྒྲིག་ཆས་ཀྱི་རིགས། + + + Device name: + སྒྲིག་ཆས་ཀྱི་མིང་། + + + + ConfForm + + edit network + + + + LAN name: + + + + Method: + + + + Address: + + + + Netmask: + + + + Gateway: + + + + DNS 1: + + + + DNS 2: + + + + Edit Conn + + + + Auto(DHCP) + + + + Manual + + + + Cancel + + + + Save + + + + Ok + + + + Can not create new wired network for without wired card + + + + New network already created + + + + New network settings already finished + + + + New settings already effective + + + + Edit Network + + + + Add Wired Network + + + + + DeviceType + + Face + མིའི་གདོང་། + + + Iris + འཇའ་སྐྱི། + + + VoicePrint + སྒྲ་རིས། + + + FingerPrint + མཛུབ་རིས། + + + FingerVein + མཛུབ་མོའི་སྡོད་རྩ། + + + QRCode + + + + + DigitalAuthDialog + + LoginByUEdu + + + + ResetPWD? + + + + SetNewUEduPWD + + + + clear + + + + ConfirmNewUEduPWD + + + + The two password entries are inconsistent, please reset + + + + Password entered incorrectly, please try again + + + + + DlgConnHidWifi + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgConnHidWifiLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Username + + + + Password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + + DlgConnHidWifiSecFast + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Allow automatic PAC pro_visioning + + + + PAC file + + + + Inner authentication + + + + Username + + + + Password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Anonymous + + + + Authenticated + + + + Both + + + + + DlgConnHidWifiSecLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecPeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + PEAP version + + + + Inner authentication + + + + Username + + + + Password + + + + Cancel + + + + Connect + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + Automatic + + + + Version 0 + + + + Version 1 + + + + + DlgConnHidWifiSecPwd + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecTls + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + User certificate + + + + User certificate password + + + + User private key + + + + User key password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiSecTunnelTLS + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + Inner authentication + + + + Username + + + + Password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiWep + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Key + + + + WEP index + + + + Authentication + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + 1(default) + + + + Open System + + + + Shared Key + + + + + DlgConnHidWifiWpa + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgHotspotCreate + + Dialog + + + + Create Hotspot + + + + Network name + + + + Wi-Fi security + + + + Password + + + + Cancel + + + + Ok + + + + None + + + + WPA & WPA2 Personal + + + + + InputInfos + + Get code + + + + Recapture(60s) + + + + Recapture(%1s) + + + + Service exception... + + + + Invaild parameters... + + + + Unknown fault:%1 + + + + + KeyboardWidget + + KeyboardWidget + + + + + KylinNM + + kylin-nm + + + + No usable network in the list + + + + HotSpot + + + + FlyMode + + + + Advanced + + + + Show KylinNM + + + + No wireless card detected + + + + Not connected + + + + Disconnected + + + + NetOn, + + + + No Other Wired Network Scheme + + + + No Other Wireless Network Scheme + + + + Wired net is disconnected + + + + Conn Ethernet Success + + + + Conn Ethernet Fail + + + + Conn Wifi Success + + + + Confirm your Wi-Fi password or usable of wireless card + + + + Inactivated LAN + + + + LAN + + + + WLAN + + + + Activated LAN + + + + Activated WLAN + + + + Other WLAN + + + + + LockWidget + + Date + དུས་ཚོད། + + + Form + ནས་འོང་བ། + + + Time + དུས་ཚོད། + + + Guest + མགྲོན་པོ། + + + SwitchUser + བཀོལ་མི་བརྗེ་བ། + + + + LoginOptionsWidget + + Login Options + + + + Identify device removed! + + + + + MyLineEdit + + Verification code + + + + + OneConnForm + + Form + ནས་འོང་བ། + + + Connect + + + + Disconnect + + + + Input Password... + + + + Automatically join the network + + + + Connect to Hidden Wi-Fi Network + + + + None + + + + WiFi Security: + + + + Signal: + + + + MAC: + + + + Conn Wifi Failed + + + + + OneLancForm + + Form + ནས་འོང་བ། + + + Connect + + + + Disconnect + + + + No Configuration + + + + IPv4: + + + + IPv6: + + + + BandWidth: + + + + MAC: + + + + + PhoneAuthWidget + + Verification by phoneNum + + + + 「 Use bound Phone number to verification 」 + + + + commit + + + + 「 Use SMS to verification 」 + + + + Network not connected~ + + + + Verification Code invalid! + + + + Verification Code incorrect.Please retry! + + + + Failed time over limit!Retry after 1 hour! + + + + verifaction failed! + + + + Network unavailable~ + + + + + PowerManager + + Sleep + མལ་གསོ། + + + Log Out + རྩིས་ཐེམ་ནས་བསུབ་པ། + + + Lock Screen + བརྙན་ཡོལ་ཟྭ་རྒྱག།(_L) + + + Restart + བསྐྱར་སློང་། + + + Switch User + སྤྱོད་མཁན་བརྗེ་རེས། + + + Suspend + འགེལ་འཇོག + + + Power Off + འཁོར་ཁ་རྒྱག་པ། + + + lock + + + + + QObject + + The screensaver is inactive. + འཆར་ངོས་སྲུང་སྐྱོབ་བྱ་རིམ་སད་མི་འདུག + + + The screensaver is active. + འཆར་ངོས་སྲུང་སྐྱོབ་བྱ་རིམ་སད་འདུག + + + + Screensaver + + Automatic switching + རང་འགུལ་བརྗེ་སྤོར། + + + Picture does not exist + པར་རིས་མི་འདུག + + + Set as desktop wallpaper + ཅོག་ངོས་ཀྱི་གདོང་ཤོག་ཏུ་འཇོག་པ། + + + View + + + + You have new notification + + + + + SleepTime + + You have rested: + ཁྱེད་ཀྱིས་ ལ་ངལ་གསོས་ཟིན། + + + + SwitchButtonGroup + + uEduPWD + + + + Wechat + + + + + TabletLockWidget + + Cancel + + + + Back + + + + Skip + + + + New password is the same as old + + + + Reset password error:%1 + + + + Please scan by correct WeChat + + + + + Utils + + kylin network applet desktop message + + + + + VerificationWidget + + Please scan by bound WeChat + + + + + VerticalVerificationWidget + + Please scan by bound WeChat + + + + + WeChatAuthDialog + + Login by wechat + + + + 「 Use registered WeChat account to login 」 + + + + Verification by wechat + + + + 「 Use bound WeChat account to verification 」 + + + + Network not connected~ + + + + Scan code successfully + + + + Timeout!Try again! + + + + + main + + Start command for the ukui ScreenSaver. + ཡོལ་སྒོའི་ཁ་འབྱེད་བཀའ་བརྡ། + + + lock the screen immediately + མྱུར་དུ་འཆར་ངོས་ཀྱི་ཟྭ་རྒྱག་པ། + + + query the status of the screen saver + འཆར་ངོས་ལ་ཟྭ་བརྒྱབ་པའི་གནས་ཚུལ་ལེན་པ། + + + unlock the screen saver + འཆར་ངོས་ཀྱི་ཟྭ་ཕྱེ་བ། + + + Screensaver for ukui-screensaver + + + + show on root window + + + + show on window. + + + + window id + + + + show the screensaver + + + + Dialog for the ukui ScreenSaver. + + + + activated by session idle signal + + + + lock the screen and show screensaver immediately + + + + show screensaver immediately + + + + diff --git a/i18n_ts/es.ts b/i18n_ts/es.ts new file mode 100644 index 0000000..21c1487 --- /dev/null +++ b/i18n_ts/es.ts @@ -0,0 +1,1736 @@ + + + + + AuthDialog + + Form + Formar + + + More Devices + Más dispositivos + + + Biometric + Biometrico + + + Password + Contraseña + + + Retry + Procesar de nuevo + + + UnLock + Desbloquear + + + LoggedIn + Conectado + + + Password Incorrect, Please try again + Contraseña incorrecta, por favor intente de nuevo + + + Authentication failure, Please try again + + + + Please try again in %1 minutes. + + + + Please try again in %1 seconds. + + + + Account locked permanently. + + + + Password cannot be empty + + + + Login + + + + Password + + + + Verify face recognition or enter password to unlock + + + + Press fingerprint or enter password to unlock + + + + Verify voiceprint or enter password to unlock + + + + Verify finger vein or enter password to unlock + + + + Verify iris or enter password to unlock + + + + NET Exception + + + + Failed to verify %1, you still have %2 verification opportunities + + + + Use the bound wechat scanning code or enter the password to unlock + + + + Failed to verify %1, please enter password to unlock + + + + Unable to verify %1, please enter password to unlock + + + + Input Password + + + + + BioAuthWidget + + Form + Formar + + + TextLabel + TextLabel + + + More + Más + + + Retry + Procesar de nuevo + + + Password + Contraseña + + + + BioDevices + + FingerPrint + Huella dactilar + + + FingerVein + FingerVein + + + Iris + Iris + + + Face + Cara + + + VoicePrint + Impresión de voz + + + + BioDevicesWidget + + Form + Formar + + + Please select other biometric devices + Por favor seleccione otros dispositivos biométricos + + + Device Type: + Tipo de dispositivo: + + + Device Name: + Nombre del dispositivo: + + + + BiometricAuthWidget + + Current device: + + + + Identify failed, Please retry. + + + + + BiometricDevicesWidget + + Please select the biometric device + + + + Device type: + + + + Device name: + + + + OK + + + + + ConfForm + + edit network + + + + LAN name: + + + + Method: + + + + Address: + + + + Netmask: + + + + Gateway: + + + + DNS 1: + + + + DNS 2: + + + + Edit Conn + + + + Auto(DHCP) + + + + Manual + + + + Cancel + + + + Save + + + + Ok + + + + Can not create new wired network for without wired card + + + + New network already created + + + + New network settings already finished + + + + New settings already effective + + + + Edit Network + + + + Add Wired Network + + + + + DeviceType + + FingerPrint + Huella dactilar + + + FingerVein + FingerVein + + + Iris + Iris + + + Face + Cara + + + VoicePrint + Impresión de voz + + + QRCode + + + + + DigitalAuthDialog + + LoginByUEdu + + + + ResetPWD? + + + + SetNewUEduPWD + + + + clear + + + + ConfirmNewUEduPWD + + + + The two password entries are inconsistent, please reset + + + + Password entered incorrectly, please try again + + + + + DlgConnHidWifi + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgConnHidWifiLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Username + + + + Password + Contraseña + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + + DlgConnHidWifiSecFast + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Allow automatic PAC pro_visioning + + + + PAC file + + + + Inner authentication + + + + Username + + + + Password + Contraseña + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Anonymous + + + + Authenticated + + + + Both + + + + + DlgConnHidWifiSecLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + Contraseña + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecPeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + PEAP version + + + + Inner authentication + + + + Username + + + + Password + Contraseña + + + Cancel + + + + Connect + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + Automatic + + + + Version 0 + + + + Version 1 + + + + + DlgConnHidWifiSecPwd + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + Contraseña + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecTls + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + User certificate + + + + User certificate password + + + + User private key + + + + User key password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiSecTunnelTLS + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + Inner authentication + + + + Username + + + + Password + Contraseña + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiWep + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Key + + + + WEP index + + + + Authentication + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + 1(default) + + + + Open System + + + + Shared Key + + + + + DlgConnHidWifiWpa + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Password + Contraseña + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgHotspotCreate + + Dialog + + + + Create Hotspot + + + + Network name + + + + Wi-Fi security + + + + Password + Contraseña + + + Cancel + + + + Ok + + + + None + + + + WPA & WPA2 Personal + + + + + InputInfos + + Get code + + + + Recapture(60s) + + + + Recapture(%1s) + + + + Service exception... + + + + Invaild parameters... + + + + Unknown fault:%1 + + + + + KeyboardWidget + + KeyboardWidget + TecladoWidget + + + + KylinNM + + kylin-nm + + + + No usable network in the list + + + + HotSpot + + + + FlyMode + + + + Advanced + + + + Show KylinNM + + + + No wireless card detected + + + + Not connected + + + + Disconnected + + + + NetOn, + + + + No Other Wired Network Scheme + + + + No Other Wireless Network Scheme + + + + Wired net is disconnected + + + + Conn Ethernet Success + + + + Conn Ethernet Fail + + + + Conn Wifi Success + + + + Confirm your Wi-Fi password or usable of wireless card + + + + Inactivated LAN + + + + LAN + + + + WLAN + + + + Activated LAN + + + + Activated WLAN + + + + Other WLAN + + + + + LockWidget + + Form + Formar + + + Date + Fecha + + + Time + Hora + + + Guest + Huésped + + + SwitchUser + Cambiar de usuario + + + + LoginOptionsWidget + + Login Options + + + + Password + Contraseña + + + Identify device removed! + + + + + MyLineEdit + + Verification code + + + + + OneConnForm + + Form + Formar + + + Connect + + + + Disconnect + + + + Input Password... + + + + Automatically join the network + + + + Connect to Hidden Wi-Fi Network + + + + None + + + + WiFi Security: + + + + Signal: + + + + MAC: + + + + Conn Wifi Failed + + + + + OneLancForm + + Form + Formar + + + Connect + + + + Disconnect + + + + No Configuration + + + + IPv4: + + + + IPv6: + + + + BandWidth: + + + + MAC: + + + + + PhoneAuthWidget + + Verification by phoneNum + + + + 「 Use bound Phone number to verification 」 + + + + commit + + + + 「 Use SMS to verification 」 + + + + Network not connected~ + + + + Verification Code invalid! + + + + Verification Code incorrect.Please retry! + + + + Failed time over limit!Retry after 1 hour! + + + + verifaction failed! + + + + Network unavailable~ + + + + + PowerManager + + SwitchUser + Cambiar de usuario + + + Log Out + + + + Restart + + + + Power Off + + + + Suspend + + + + Sleep + + + + lock + + + + + QObject + + The screensaver is active. + + + + The screensaver is inactive. + + + + + Screensaver + + Picture does not exist + + + + View + + + + You have new notification + + + + + SleepTime + + You have rested: + + + + + SwitchButtonGroup + + uEduPWD + + + + Wechat + + + + + TabletLockWidget + + Cancel + + + + Back + + + + Skip + + + + New password is the same as old + + + + Reset password error:%1 + + + + Please scan by correct WeChat + + + + + Utils + + kylin network applet desktop message + + + + + VerificationWidget + + Please scan by bound WeChat + + + + + VerticalVerificationWidget + + Please scan by bound WeChat + + + + + WeChatAuthDialog + + Login by wechat + + + + 「 Use registered WeChat account to login 」 + + + + Verification by wechat + + + + 「 Use bound WeChat account to verification 」 + + + + Network not connected~ + + + + Scan code successfully + + + + Timeout!Try again! + + + + + main + + Start command for the ukui ScreenSaver. + Comando de inicio para el protector de pantalla de ukui. + + + lock the screen immediately + bloquea la pantalla inmediatamente + + + Dialog for the ukui ScreenSaver. + Diálogo para el protector de pantalla de ukui. + + + activated by session idle signal + activado por la señal de inactividad de la sesión + + + Screensaver for ukui-screensaver + + + + show on root window + + + + show on window. + + + + window id + + + + query the status of the screen saver + + + + lock the screen and show screensaver immediately + + + + unlock the screen saver + + + + show the screensaver + + + + show screensaver immediately + + + + diff --git a/i18n_ts/fr.ts b/i18n_ts/fr.ts new file mode 100644 index 0000000..c4588df --- /dev/null +++ b/i18n_ts/fr.ts @@ -0,0 +1,1736 @@ + + + + + AuthDialog + + Form + Forme + + + More Devices + Plus d'appareils + + + Biometric + Biométrique + + + Password + Mot de passe + + + Retry + Réessayez + + + UnLock + Ouvrir + + + LoggedIn + Connecté + + + Password Incorrect, Please try again + Mot de passe incorrect, veuillez réessayer + + + Authentication failure, Please try again + + + + Please try again in %1 minutes. + + + + Please try again in %1 seconds. + + + + Account locked permanently. + + + + Password cannot be empty + + + + Login + + + + Password + + + + Verify face recognition or enter password to unlock + + + + Press fingerprint or enter password to unlock + + + + Verify voiceprint or enter password to unlock + + + + Verify finger vein or enter password to unlock + + + + Verify iris or enter password to unlock + + + + NET Exception + + + + Failed to verify %1, you still have %2 verification opportunities + + + + Use the bound wechat scanning code or enter the password to unlock + + + + Failed to verify %1, please enter password to unlock + + + + Unable to verify %1, please enter password to unlock + + + + Input Password + + + + + BioAuthWidget + + Form + Forme + + + TextLabel + TextLabel + + + More + Plus + + + Retry + Réessayez + + + Password + Mot de passe + + + + BioDevices + + FingerPrint + Empreinte digitale + + + FingerVein + FingerVein + + + Iris + Iris + + + Face + Visage + + + VoicePrint + VoicePrint + + + + BioDevicesWidget + + Form + Forme + + + Please select other biometric devices + Veuillez sélectionner d'autres appareils biométriques + + + Device Type: + Type d'appareil: + + + Device Name: + Nom de l'appareil: + + + + BiometricAuthWidget + + Current device: + + + + Identify failed, Please retry. + + + + + BiometricDevicesWidget + + Please select the biometric device + + + + Device type: + + + + Device name: + + + + OK + + + + + ConfForm + + edit network + + + + LAN name: + + + + Method: + + + + Address: + + + + Netmask: + + + + Gateway: + + + + DNS 1: + + + + DNS 2: + + + + Edit Conn + + + + Auto(DHCP) + + + + Manual + + + + Cancel + + + + Save + + + + Ok + + + + Can not create new wired network for without wired card + + + + New network already created + + + + New network settings already finished + + + + New settings already effective + + + + Edit Network + + + + Add Wired Network + + + + + DeviceType + + FingerPrint + Empreinte digitale + + + FingerVein + FingerVein + + + Iris + Iris + + + Face + Visage + + + VoicePrint + VoicePrint + + + QRCode + + + + + DigitalAuthDialog + + LoginByUEdu + + + + ResetPWD? + + + + SetNewUEduPWD + + + + clear + + + + ConfirmNewUEduPWD + + + + The two password entries are inconsistent, please reset + + + + Password entered incorrectly, please try again + + + + + DlgConnHidWifi + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgConnHidWifiLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Username + + + + Password + Mot de passe + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + + DlgConnHidWifiSecFast + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Allow automatic PAC pro_visioning + + + + PAC file + + + + Inner authentication + + + + Username + + + + Password + Mot de passe + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Anonymous + + + + Authenticated + + + + Both + + + + + DlgConnHidWifiSecLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + Mot de passe + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecPeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + PEAP version + + + + Inner authentication + + + + Username + + + + Password + Mot de passe + + + Cancel + + + + Connect + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + Automatic + + + + Version 0 + + + + Version 1 + + + + + DlgConnHidWifiSecPwd + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + Mot de passe + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecTls + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + User certificate + + + + User certificate password + + + + User private key + + + + User key password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiSecTunnelTLS + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + Inner authentication + + + + Username + + + + Password + Mot de passe + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiWep + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Key + + + + WEP index + + + + Authentication + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + 1(default) + + + + Open System + + + + Shared Key + + + + + DlgConnHidWifiWpa + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Password + Mot de passe + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgHotspotCreate + + Dialog + + + + Create Hotspot + + + + Network name + + + + Wi-Fi security + + + + Password + Mot de passe + + + Cancel + + + + Ok + + + + None + + + + WPA & WPA2 Personal + + + + + InputInfos + + Get code + + + + Recapture(60s) + + + + Recapture(%1s) + + + + Service exception... + + + + Invaild parameters... + + + + Unknown fault:%1 + + + + + KeyboardWidget + + KeyboardWidget + KeyboardWidget + + + + KylinNM + + kylin-nm + + + + No usable network in the list + + + + HotSpot + + + + FlyMode + + + + Advanced + + + + Show KylinNM + + + + No wireless card detected + + + + Not connected + + + + Disconnected + + + + NetOn, + + + + No Other Wired Network Scheme + + + + No Other Wireless Network Scheme + + + + Wired net is disconnected + + + + Conn Ethernet Success + + + + Conn Ethernet Fail + + + + Conn Wifi Success + + + + Confirm your Wi-Fi password or usable of wireless card + + + + Inactivated LAN + + + + LAN + + + + WLAN + + + + Activated LAN + + + + Activated WLAN + + + + Other WLAN + + + + + LockWidget + + Form + Forme + + + Date + Rendez-vous amoureux + + + Time + Temps + + + Guest + Client + + + SwitchUser + Changer d'utilisateur + + + + LoginOptionsWidget + + Login Options + + + + Password + Mot de passe + + + Identify device removed! + + + + + MyLineEdit + + Verification code + + + + + OneConnForm + + Form + Forme + + + Connect + + + + Disconnect + + + + Input Password... + + + + Automatically join the network + + + + Connect to Hidden Wi-Fi Network + + + + None + + + + WiFi Security: + + + + Signal: + + + + MAC: + + + + Conn Wifi Failed + + + + + OneLancForm + + Form + Forme + + + Connect + + + + Disconnect + + + + No Configuration + + + + IPv4: + + + + IPv6: + + + + BandWidth: + + + + MAC: + + + + + PhoneAuthWidget + + Verification by phoneNum + + + + 「 Use bound Phone number to verification 」 + + + + commit + + + + 「 Use SMS to verification 」 + + + + Network not connected~ + + + + Verification Code invalid! + + + + Verification Code incorrect.Please retry! + + + + Failed time over limit!Retry after 1 hour! + + + + verifaction failed! + + + + Network unavailable~ + + + + + PowerManager + + SwitchUser + Changer d'utilisateur + + + Log Out + + + + Restart + + + + Power Off + + + + Suspend + + + + Sleep + + + + lock + + + + + QObject + + The screensaver is active. + + + + The screensaver is inactive. + + + + + Screensaver + + Picture does not exist + + + + View + + + + You have new notification + + + + + SleepTime + + You have rested: + + + + + SwitchButtonGroup + + uEduPWD + + + + Wechat + + + + + TabletLockWidget + + Cancel + + + + Back + + + + Skip + + + + New password is the same as old + + + + Reset password error:%1 + + + + Please scan by correct WeChat + + + + + Utils + + kylin network applet desktop message + + + + + VerificationWidget + + Please scan by bound WeChat + + + + + VerticalVerificationWidget + + Please scan by bound WeChat + + + + + WeChatAuthDialog + + Login by wechat + + + + 「 Use registered WeChat account to login 」 + + + + Verification by wechat + + + + 「 Use bound WeChat account to verification 」 + + + + Network not connected~ + + + + Scan code successfully + + + + Timeout!Try again! + + + + + main + + Start command for the ukui ScreenSaver. + Commande de démarrage pour l'ukui ScreenSaver. + + + lock the screen immediately + verrouiller l'écran immédiatement + + + Dialog for the ukui ScreenSaver. + Boîte de dialogue pour l'écran de veille ukui. + + + activated by session idle signal + activé par le signal d'inactivité de la session + + + Screensaver for ukui-screensaver + + + + show on root window + + + + show on window. + + + + window id + + + + query the status of the screen saver + + + + lock the screen and show screensaver immediately + + + + unlock the screen saver + + + + show the screensaver + + + + show screensaver immediately + + + + diff --git a/i18n_ts/pt.ts b/i18n_ts/pt.ts new file mode 100644 index 0000000..2de6ea7 --- /dev/null +++ b/i18n_ts/pt.ts @@ -0,0 +1,1736 @@ + + + + + AuthDialog + + Form + Formato + + + More Devices + Mais dispositivos + + + Biometric + Biométrico + + + Password + Senha + + + Retry + Tente novamente + + + UnLock + Desbloquear + + + LoggedIn + Logado + + + Password Incorrect, Please try again + Senha incorreta, por favor tente novamente + + + Authentication failure, Please try again + + + + Please try again in %1 minutes. + + + + Please try again in %1 seconds. + + + + Account locked permanently. + + + + Password cannot be empty + + + + Login + + + + Password + + + + Verify face recognition or enter password to unlock + + + + Press fingerprint or enter password to unlock + + + + Verify voiceprint or enter password to unlock + + + + Verify finger vein or enter password to unlock + + + + Verify iris or enter password to unlock + + + + NET Exception + + + + Failed to verify %1, you still have %2 verification opportunities + + + + Use the bound wechat scanning code or enter the password to unlock + + + + Failed to verify %1, please enter password to unlock + + + + Unable to verify %1, please enter password to unlock + + + + Input Password + + + + + BioAuthWidget + + Form + Formato + + + TextLabel + TextLabel + + + More + Mais + + + Retry + Tente novamente + + + Password + Senha + + + + BioDevices + + FingerPrint + Impressão digital + + + FingerVein + FingerVein + + + Iris + Íris + + + Face + Face + + + VoicePrint + VoicePrint + + + + BioDevicesWidget + + Form + Formato + + + Please select other biometric devices + Por favor, selecione outros dispositivos biométricos + + + Device Type: + Tipo de dispositivo: + + + Device Name: + Nome do dispositivo: + + + + BiometricAuthWidget + + Current device: + + + + Identify failed, Please retry. + + + + + BiometricDevicesWidget + + Please select the biometric device + + + + Device type: + + + + Device name: + + + + OK + + + + + ConfForm + + edit network + + + + LAN name: + + + + Method: + + + + Address: + + + + Netmask: + + + + Gateway: + + + + DNS 1: + + + + DNS 2: + + + + Edit Conn + + + + Auto(DHCP) + + + + Manual + + + + Cancel + + + + Save + + + + Ok + + + + Can not create new wired network for without wired card + + + + New network already created + + + + New network settings already finished + + + + New settings already effective + + + + Edit Network + + + + Add Wired Network + + + + + DeviceType + + FingerPrint + Impressão digital + + + FingerVein + FingerVein + + + Iris + Íris + + + Face + Face + + + VoicePrint + VoicePrint + + + QRCode + + + + + DigitalAuthDialog + + LoginByUEdu + + + + ResetPWD? + + + + SetNewUEduPWD + + + + clear + + + + ConfirmNewUEduPWD + + + + The two password entries are inconsistent, please reset + + + + Password entered incorrectly, please try again + + + + + DlgConnHidWifi + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgConnHidWifiLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Username + + + + Password + Senha + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + + DlgConnHidWifiSecFast + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Allow automatic PAC pro_visioning + + + + PAC file + + + + Inner authentication + + + + Username + + + + Password + Senha + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Anonymous + + + + Authenticated + + + + Both + + + + + DlgConnHidWifiSecLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + Senha + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecPeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + PEAP version + + + + Inner authentication + + + + Username + + + + Password + Senha + + + Cancel + + + + Connect + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + Automatic + + + + Version 0 + + + + Version 1 + + + + + DlgConnHidWifiSecPwd + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + Senha + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecTls + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + User certificate + + + + User certificate password + + + + User private key + + + + User key password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiSecTunnelTLS + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + Inner authentication + + + + Username + + + + Password + Senha + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiWep + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Key + + + + WEP index + + + + Authentication + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + 1(default) + + + + Open System + + + + Shared Key + + + + + DlgConnHidWifiWpa + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Password + Senha + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgHotspotCreate + + Dialog + + + + Create Hotspot + + + + Network name + + + + Wi-Fi security + + + + Password + Senha + + + Cancel + + + + Ok + + + + None + + + + WPA & WPA2 Personal + + + + + InputInfos + + Get code + + + + Recapture(60s) + + + + Recapture(%1s) + + + + Service exception... + + + + Invaild parameters... + + + + Unknown fault:%1 + + + + + KeyboardWidget + + KeyboardWidget + KeyboardWidget + + + + KylinNM + + kylin-nm + + + + No usable network in the list + + + + HotSpot + + + + FlyMode + + + + Advanced + + + + Show KylinNM + + + + No wireless card detected + + + + Not connected + + + + Disconnected + + + + NetOn, + + + + No Other Wired Network Scheme + + + + No Other Wireless Network Scheme + + + + Wired net is disconnected + + + + Conn Ethernet Success + + + + Conn Ethernet Fail + + + + Conn Wifi Success + + + + Confirm your Wi-Fi password or usable of wireless card + + + + Inactivated LAN + + + + LAN + + + + WLAN + + + + Activated LAN + + + + Activated WLAN + + + + Other WLAN + + + + + LockWidget + + Form + Formato + + + Date + Encontro + + + Time + Tempo + + + Guest + Convidado + + + SwitchUser + Mudar de utilizador + + + + LoginOptionsWidget + + Login Options + + + + Password + Senha + + + Identify device removed! + + + + + MyLineEdit + + Verification code + + + + + OneConnForm + + Form + Formato + + + Connect + + + + Disconnect + + + + Input Password... + + + + Automatically join the network + + + + Connect to Hidden Wi-Fi Network + + + + None + + + + WiFi Security: + + + + Signal: + + + + MAC: + + + + Conn Wifi Failed + + + + + OneLancForm + + Form + Formato + + + Connect + + + + Disconnect + + + + No Configuration + + + + IPv4: + + + + IPv6: + + + + BandWidth: + + + + MAC: + + + + + PhoneAuthWidget + + Verification by phoneNum + + + + 「 Use bound Phone number to verification 」 + + + + commit + + + + 「 Use SMS to verification 」 + + + + Network not connected~ + + + + Verification Code invalid! + + + + Verification Code incorrect.Please retry! + + + + Failed time over limit!Retry after 1 hour! + + + + verifaction failed! + + + + Network unavailable~ + + + + + PowerManager + + SwitchUser + Mudar de utilizador + + + Log Out + + + + Restart + + + + Power Off + + + + Suspend + + + + Sleep + + + + lock + + + + + QObject + + The screensaver is active. + + + + The screensaver is inactive. + + + + + Screensaver + + Picture does not exist + + + + View + + + + You have new notification + + + + + SleepTime + + You have rested: + + + + + SwitchButtonGroup + + uEduPWD + + + + Wechat + + + + + TabletLockWidget + + Cancel + + + + Back + + + + Skip + + + + New password is the same as old + + + + Reset password error:%1 + + + + Please scan by correct WeChat + + + + + Utils + + kylin network applet desktop message + + + + + VerificationWidget + + Please scan by bound WeChat + + + + + VerticalVerificationWidget + + Please scan by bound WeChat + + + + + WeChatAuthDialog + + Login by wechat + + + + 「 Use registered WeChat account to login 」 + + + + Verification by wechat + + + + 「 Use bound WeChat account to verification 」 + + + + Network not connected~ + + + + Scan code successfully + + + + Timeout!Try again! + + + + + main + + Start command for the ukui ScreenSaver. + Inicie o comando para o ScreenSaver do ukui. + + + lock the screen immediately + bloquear a tela imediatamente + + + Dialog for the ukui ScreenSaver. + Diálogo para o ScreenSaver ukui. + + + activated by session idle signal + ativado por sinal ocioso de sessão + + + Screensaver for ukui-screensaver + + + + show on root window + + + + show on window. + + + + window id + + + + query the status of the screen saver + + + + lock the screen and show screensaver immediately + + + + unlock the screen saver + + + + show the screensaver + + + + show screensaver immediately + + + + diff --git a/i18n_ts/ru.ts b/i18n_ts/ru.ts new file mode 100644 index 0000000..f3ab806 --- /dev/null +++ b/i18n_ts/ru.ts @@ -0,0 +1,1736 @@ + + + + + AuthDialog + + Form + форма + + + More Devices + Дополнительные устройства + + + Biometric + Биометрические + + + Password + пароль + + + Retry + Retry + + + UnLock + отпереть + + + LoggedIn + LoggedIn + + + Password Incorrect, Please try again + Пароль неверен, повторите попытку + + + Authentication failure, Please try again + + + + Please try again in %1 minutes. + + + + Please try again in %1 seconds. + + + + Account locked permanently. + + + + Password cannot be empty + + + + Login + + + + Password + + + + Verify face recognition or enter password to unlock + + + + Press fingerprint or enter password to unlock + + + + Verify voiceprint or enter password to unlock + + + + Verify finger vein or enter password to unlock + + + + Verify iris or enter password to unlock + + + + NET Exception + + + + Failed to verify %1, you still have %2 verification opportunities + + + + Use the bound wechat scanning code or enter the password to unlock + + + + Failed to verify %1, please enter password to unlock + + + + Unable to verify %1, please enter password to unlock + + + + Input Password + + + + + BioAuthWidget + + Form + форма + + + TextLabel + TextLabel + + + More + Больше + + + Retry + Retry + + + Password + пароль + + + + BioDevices + + FingerPrint + FingerPrint + + + FingerVein + FingerVein + + + Iris + Ирис + + + Face + Лицо + + + VoicePrint + Voiceprint + + + + BioDevicesWidget + + Form + форма + + + Please select other biometric devices + Выберите другие биометрические устройства + + + Device Type: + Тип устройства: + + + Device Name: + Имя устройства: + + + + BiometricAuthWidget + + Current device: + + + + Identify failed, Please retry. + + + + + BiometricDevicesWidget + + Please select the biometric device + + + + Device type: + + + + Device name: + + + + OK + + + + + ConfForm + + edit network + + + + LAN name: + + + + Method: + + + + Address: + + + + Netmask: + + + + Gateway: + + + + DNS 1: + + + + DNS 2: + + + + Edit Conn + + + + Auto(DHCP) + + + + Manual + + + + Cancel + + + + Save + + + + Ok + + + + Can not create new wired network for without wired card + + + + New network already created + + + + New network settings already finished + + + + New settings already effective + + + + Edit Network + + + + Add Wired Network + + + + + DeviceType + + FingerPrint + FingerPrint + + + FingerVein + FingerVein + + + Iris + Ирис + + + Face + Лицо + + + VoicePrint + Voiceprint + + + QRCode + + + + + DigitalAuthDialog + + LoginByUEdu + + + + ResetPWD? + + + + SetNewUEduPWD + + + + clear + + + + ConfirmNewUEduPWD + + + + The two password entries are inconsistent, please reset + + + + Password entered incorrectly, please try again + + + + + DlgConnHidWifi + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgConnHidWifiLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Username + + + + Password + пароль + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + + DlgConnHidWifiSecFast + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Allow automatic PAC pro_visioning + + + + PAC file + + + + Inner authentication + + + + Username + + + + Password + пароль + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Anonymous + + + + Authenticated + + + + Both + + + + + DlgConnHidWifiSecLeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + пароль + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecPeap + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + PEAP version + + + + Inner authentication + + + + Username + + + + Password + пароль + + + Cancel + + + + Connect + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + Automatic + + + + Version 0 + + + + Version 1 + + + + + DlgConnHidWifiSecPwd + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Username + + + + Password + пароль + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecTls + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + User certificate + + + + User certificate password + + + + User private key + + + + User key password + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiSecTunnelTLS + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Authentication + + + + Anonymous identity + + + + Domain + + + + CA certificate + + + + CA certificate password + + + + No CA certificate is required + + + + Inner authentication + + + + Username + + + + Password + пароль + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + Tunneled TLS + + + + Protected EAP (PEAP) + + + + Choose from file + + + + + DlgConnHidWifiWep + + Connect to Hidden Wi-Fi Network + + + + Add hidden Wi-Fi + + + + Connection + + + + Network name + + + + Wi-Fi security + + + + Key + + + + WEP index + + + + Authentication + + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + WEP 128-bit Passphrase + + + + Dynamic WEP (802.1X) + + + + WPA & WPA2 Enterprise + + + + 1(default) + + + + Open System + + + + Shared Key + + + + + DlgConnHidWifiWpa + + Connect to Hidden Wi-Fi Network + + + + Add Hidden Wi-Fi + + + + Connection + + + + Wi-Fi name + + + + Wi-Fi security + + + + Password + пароль + + + Cancel + + + + Connect + + + + C_reate… + + + + None + + + + WPA & WPA2 Personal + + + + + DlgHotspotCreate + + Dialog + + + + Create Hotspot + + + + Network name + + + + Wi-Fi security + + + + Password + пароль + + + Cancel + + + + Ok + + + + None + + + + WPA & WPA2 Personal + + + + + InputInfos + + Get code + + + + Recapture(60s) + + + + Recapture(%1s) + + + + Service exception... + + + + Invaild parameters... + + + + Unknown fault:%1 + + + + + KeyboardWidget + + KeyboardWidget + KeyboardWidget + + + + KylinNM + + kylin-nm + + + + No usable network in the list + + + + HotSpot + + + + FlyMode + + + + Advanced + + + + Show KylinNM + + + + No wireless card detected + + + + Not connected + + + + Disconnected + + + + NetOn, + + + + No Other Wired Network Scheme + + + + No Other Wireless Network Scheme + + + + Wired net is disconnected + + + + Conn Ethernet Success + + + + Conn Ethernet Fail + + + + Conn Wifi Success + + + + Confirm your Wi-Fi password or usable of wireless card + + + + Inactivated LAN + + + + LAN + + + + WLAN + + + + Activated LAN + + + + Activated WLAN + + + + Other WLAN + + + + + LockWidget + + Form + форма + + + Date + Дата + + + Time + Время + + + Guest + гость + + + SwitchUser + Сменить пользователя + + + + LoginOptionsWidget + + Login Options + + + + Password + пароль + + + Identify device removed! + + + + + MyLineEdit + + Verification code + + + + + OneConnForm + + Form + форма + + + Connect + + + + Disconnect + + + + Input Password... + + + + Automatically join the network + + + + Connect to Hidden Wi-Fi Network + + + + None + + + + WiFi Security: + + + + Signal: + + + + MAC: + + + + Conn Wifi Failed + + + + + OneLancForm + + Form + форма + + + Connect + + + + Disconnect + + + + No Configuration + + + + IPv4: + + + + IPv6: + + + + BandWidth: + + + + MAC: + + + + + PhoneAuthWidget + + Verification by phoneNum + + + + 「 Use bound Phone number to verification 」 + + + + commit + + + + 「 Use SMS to verification 」 + + + + Network not connected~ + + + + Verification Code invalid! + + + + Verification Code incorrect.Please retry! + + + + Failed time over limit!Retry after 1 hour! + + + + verifaction failed! + + + + Network unavailable~ + + + + + PowerManager + + SwitchUser + Сменить пользователя + + + Log Out + + + + Restart + + + + Power Off + + + + Suspend + + + + Sleep + + + + lock + + + + + QObject + + The screensaver is active. + + + + The screensaver is inactive. + + + + + Screensaver + + Picture does not exist + + + + View + + + + You have new notification + + + + + SleepTime + + You have rested: + + + + + SwitchButtonGroup + + uEduPWD + + + + Wechat + + + + + TabletLockWidget + + Cancel + + + + Back + + + + Skip + + + + New password is the same as old + + + + Reset password error:%1 + + + + Please scan by correct WeChat + + + + + Utils + + kylin network applet desktop message + + + + + VerificationWidget + + Please scan by bound WeChat + + + + + VerticalVerificationWidget + + Please scan by bound WeChat + + + + + WeChatAuthDialog + + Login by wechat + + + + 「 Use registered WeChat account to login 」 + + + + Verification by wechat + + + + 「 Use bound WeChat account to verification 」 + + + + Network not connected~ + + + + Scan code successfully + + + + Timeout!Try again! + + + + + main + + Start command for the ukui ScreenSaver. + Начните команду для ukui ScreenSaver. + + + lock the screen immediately + немедленно заблокируйте экран + + + Dialog for the ukui ScreenSaver. + Диалог для экранного экрана ukui. + + + activated by session idle signal + активируется сигналом холостого хода + + + Screensaver for ukui-screensaver + + + + show on root window + + + + show on window. + + + + window id + + + + query the status of the screen saver + + + + lock the screen and show screensaver immediately + + + + unlock the screen saver + + + + show the screensaver + + + + show screensaver immediately + + + + diff --git a/i18n_ts/tr.ts b/i18n_ts/tr.ts new file mode 100644 index 0000000..1d46147 --- /dev/null +++ b/i18n_ts/tr.ts @@ -0,0 +1,2222 @@ + + + + + AuthDialog + + More Devices + Diğer Cihazlar + + + Biometric + Biometrik + + + Password + Parola + + + + Retry + Yeniden Dene + + + UnLock + Kilidi Aç + + + Password: + Parola + + + Account locked %1 minutes due to %2 fail attempts + %2 başarısız denemeden dolayı hesap %1 dakika kilitlendi + + + Password Incorrect, Please try again + Parola yanlış, Lütfen tekrar deneyin + + + Authentication failure,there are still %1 remaining opportunities + Kimlik doğrulama hatası, hala %1 kalan denemen var + + + + Authentication failure, Please try again + + + + + + + + Please try again in %1 minutes. + + + + + + + + Please try again in %1 seconds. + + + + + + + + Account locked permanently. + + + + + Verify face recognition or enter password to unlock + + + + + Press fingerprint or enter password to unlock + + + + + Verify voiceprint or enter password to unlock + + + + + Verify finger vein or enter password to unlock + + + + + Verify iris or enter password to unlock + + + + + Use the bound wechat scanning code or enter the password to unlock + + + + + + Password cannot be empty + + + + + Password + + + + + Input Password + + + + + Login + + + + + Failed to verify %1, please enter password to unlock + + + + + Unable to verify %1, please enter password to unlock + + + + + Failed to verify %1, you still have %2 verification opportunities + + + + + NET Exception + + + + Biometric Authentication + Biyometrik Kimlik Doğrulama + + + Password Authentication + Parola Doğrulama + + + Other Devices + Diğer Ayıtlar + + + + BioDevices + + FingerPrint + Parmak İzi + + + FingerVein + Damar İzi + + + Iris + Göz + + + Face + Yüz + + + VoicePrint + Ses İzi + + + + BioDevicesWidget + + Please select other biometric devices + Lütfen diğer biyometrik cihazları seçin + + + Device Type: + Aygıt Türü: + + + Device Name: + Aygıt Adı: + + + + BiometricAuthWidget + + + Current device: + Şuanki aygıt: + + + + Identify failed, Please retry. + Tanımlama başarısız, Lütfen tekrar deneyin. + + + + BiometricDevicesWidget + + + Please select the biometric device + Lütfen biyometrik aygıtı seçin + + + + Device type: + Aygıt türü: + + + + Device name: + Aygıt adı: + + + + OK + Tamam + + + + ConfForm + + + edit network + + + + + LAN name: + + + + + Method: + + + + + Address: + + + + + Netmask: + + + + + Gateway: + + + + + DNS 1: + + + + + DNS 2: + + + + + Edit Conn + + + + + + Auto(DHCP) + + + + + + Manual + + + + + Cancel + + + + + Save + + + + + Ok + + + + + Can not create new wired network for without wired card + + + + + New network already created + + + + + New network settings already finished + + + + + New settings already effective + + + + + Edit Network + + + + + Add Wired Network + + + + + DeviceType + + + FingerPrint + Parmak İzi + + + + FingerVein + Parmak Damarı + + + + Iris + Göz + + + + Face + Yüz + + + + VoicePrint + Ses İzi + + + + QRCode + + + + + DigitalAuthDialog + + + + LoginByUEdu + + + + + ResetPWD? + + + + + + SetNewUEduPWD + + + + + clear + + + + + ConfirmNewUEduPWD + + + + + The two password entries are inconsistent, please reset + + + + + Password entered incorrectly, please try again + + + + + DlgConnHidWifi + + + + Connect to Hidden Wi-Fi Network + + + + + Add Hidden Wi-Fi + + + + + Connection + + + + + Wi-Fi name + + + + + Wi-Fi security + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + DlgConnHidWifiLeap + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Username + + + + + Password + Parola + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + DlgConnHidWifiSecFast + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Anonymous identity + + + + + Allow automatic PAC pro_visioning + + + + + PAC file + + + + + Inner authentication + + + + + Username + + + + + Password + Parola + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + Anonymous + + + + + Authenticated + + + + + Both + + + + + DlgConnHidWifiSecLeap + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Username + + + + + Password + Parola + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecPeap + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Anonymous identity + + + + + Domain + + + + + CA certificate + + + + + CA certificate password + + + + + No CA certificate is required + + + + + PEAP version + + + + + Inner authentication + + + + + Username + + + + + Password + Parola + + + + Cancel + + + + + Connect + + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + Choose from file + + + + + Automatic + + + + + Version 0 + + + + + Version 1 + + + + + DlgConnHidWifiSecPwd + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Username + + + + + Password + Parola + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + DlgConnHidWifiSecTls + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Identity + + + + + Domain + + + + + CA certificate + + + + + CA certificate password + + + + + No CA certificate is required + + + + + User certificate + + + + + User certificate password + + + + + User private key + + + + + User key password + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + + + Choose from file + + + + + DlgConnHidWifiSecTunnelTLS + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Authentication + + + + + Anonymous identity + + + + + Domain + + + + + CA certificate + + + + + CA certificate password + + + + + No CA certificate is required + + + + + Inner authentication + + + + + Username + + + + + Password + Parola + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + Tunneled TLS + + + + + Protected EAP (PEAP) + + + + + Choose from file + + + + + DlgConnHidWifiWep + + + + Connect to Hidden Wi-Fi Network + + + + + Add hidden Wi-Fi + + + + + Connection + + + + + Network name + + + + + Wi-Fi security + + + + + Key + + + + + WEP index + + + + + Authentication + + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + WEP 40/128-bit Key (Hex or ASCII) + + + + + WEP 128-bit Passphrase + + + + + Dynamic WEP (802.1X) + + + + + WPA & WPA2 Enterprise + + + + + 1(default) + + + + + Open System + + + + + Shared Key + + + + + DlgConnHidWifiWpa + + + + Connect to Hidden Wi-Fi Network + + + + + Add Hidden Wi-Fi + + + + + Connection + + + + + Wi-Fi name + + + + + Wi-Fi security + + + + + Password + Parola + + + + Cancel + + + + + Connect + + + + + C_reate… + + + + + None + + + + + WPA & WPA2 Personal + + + + + DlgHotspotCreate + + + + Dialog + + + + + Create Hotspot + + + + + Network name + + + + + Wi-Fi security + + + + + Password + Parola + + + + Cancel + + + + + Ok + + + + + None + + + + + WPA & WPA2 Personal + + + + + InputInfos + + + + Get code + + + + + Recapture(60s) + + + + + Recapture(%1s) + + + + + Service exception... + + + + + Invaild parameters... + + + + + Unknown fault:%1 + + + + + KeyboardWidget + + + + KeyboardWidget + + + + + KylinNM + + + + kylin-nm + + + + + No usable network in the list + + + + + Inactivated LAN + + + + + Other WLAN + + + + + + LAN + + + + + + WLAN + + + + + HotSpot + + + + + FlyMode + + + + + + Advanced + + + + + Show KylinNM + + + + + No wireless card detected + + + + + Activated LAN + + + + + Activated WLAN + + + + + + + + + Not connected + + + + + + + + + + + + + Disconnected + + + + + + NetOn, + + + + + No Other Wired Network Scheme + + + + + No Other Wireless Network Scheme + + + + + Wired net is disconnected + + + + + Conn Ethernet Success + + + + + Conn Ethernet Fail + + + + + Conn Wifi Success + + + + + Confirm your Wi-Fi password or usable of wireless card + + + + + LockWidget + + + + Form + + + + + + Date + Tarih + + + + + Time + Zaman + + + Guest + Misafir + + + SwitchUser + Kullanıcı Değiştir + + + + LoginOptionsWidget + + + Login Options + + + + Password + Parola + + + + Identify device removed! + + + + + MyLineEdit + + + + + Verification code + + + + + OneConnForm + + + + Form + + + + + + + + Connect + + + + + Disconnect + + + + + Input Password... + + + + + Automatically join the network + + + + + Connect to Hidden Wi-Fi Network + + + + + None + + + + + WiFi Security: + + + + + Signal: + + + + + MAC: + + + + + Conn Wifi Failed + + + + + OneLancForm + + + + Form + + + + + + Connect + + + + + Disconnect + + + + + + No Configuration + + + + + IPv4: + + + + + IPv6: + + + + + BandWidth: + + + + + MAC: + + + + + PhoneAuthWidget + + + + Verification by phoneNum + + + + + 「 Use bound Phone number to verification 」 + + + + + + commit + + + + + 「 Use SMS to verification 」 + + + + + + Network not connected~ + + + + + Verification Code invalid! + + + + + Verification Code incorrect.Please retry! + + + + + Failed time over limit!Retry after 1 hour! + + + + + verifaction failed! + + + + + Network unavailable~ + + + + + PowerManager + + + lock + kilit + + + SwitchUser + Kullanıcı Değiştir + + + logout + Çıkış + + + reboot + yeniden başlat + + + shutdown + kapat + + + Lock Screen + Ekranı Kilitle + + + Switch User + Kullanıcı Değiştir + + + + Log Out + Çıkış + + + + + Restart + Yeniden Başlat + + + + + Power Off + Bilgisayarı Kapat + + + + Suspend + + + + + Sleep + + + + + QObject + + + The screensaver is active. + + + + + The screensaver is inactive. + + + + + Screensaver + + exit(Esc) + çıkış(Esc) + + + exit + çıkış + + + + Picture does not exist + + + + + View + + + + + You have new notification + + + + Set as desktop wallpaper + Masaüstü arkaplanı olarak ayarla + + + Automatic switching + Otomatik değiştir + + + + SleepTime + + + You have rested: + + + + + SwitchButtonGroup + + + uEduPWD + + + + + Wechat + + + + + TabletLockWidget + + + + + + + + Cancel + + + + + + Back + + + + + Skip + + + + + New password is the same as old + + + + + Reset password error:%1 + + + + + Please scan by correct WeChat + + + + + Utils + + + kylin network applet desktop message + + + + + VerificationWidget + + + Please scan by bound WeChat + + + + + VerticalVerificationWidget + + + Please scan by bound WeChat + + + + + WeChatAuthDialog + + + + Login by wechat + + + + + + 「 Use registered WeChat account to login 」 + + + + + + Verification by wechat + + + + + + 「 Use bound WeChat account to verification 」 + + + + + + Network not connected~ + + + + + Scan code successfully + + + + + Timeout!Try again! + + + + + main + + + Start command for the ukui ScreenSaver. + Ukui Ekran Koruyucu için başlatma komutu. + + + + + + lock the screen immediately + Ekranı hemen kilitle + + + + query the status of the screen saver + + + + + unlock the screen saver + + + + + show the screensaver + + + + + Dialog for the ukui ScreenSaver. + + + + + activated by session idle signal + + + + + + lock the screen and show screensaver immediately + + + + + show screensaver immediately + + + + + Screensaver for ukui-screensaver + + + + + show on root window + + + + + show on window. + + + + + window id + + + + diff --git a/i18n_ts/zh_CN.ts b/i18n_ts/zh_CN.ts new file mode 100644 index 0000000..c76dc77 --- /dev/null +++ b/i18n_ts/zh_CN.ts @@ -0,0 +1,2506 @@ + + + + + AuthDialog + + More Devices + 选择其他设备 + + + Biometric + 使用生物识别认证 + + + Password + 使用密码认证 + + + + Retry + 重试 + + + UnLock + 解锁 + + + Slide to unlock + 向上滑动解锁 + + + You have %1 unread message + 您有%1条未读消息 + + + LoggedIn + 已登录 + + + Password: + 密码: + + + Account locked %1 minutes due to %2 fail attempts + 账户锁定%1分钟由于%2次错误尝试 + + + + + + + Please try again in %1 minutes. + 请%1分钟后再试 + + + + + + + Please try again in %1 seconds. + 请%1秒后再试 + + + + + + + Account locked permanently. + 账号已被永久锁定 + + + + Verify face recognition or enter password to unlock + 验证人脸识别或输入密码解锁 + + + + Press fingerprint or enter password to unlock + 按压指纹或输入密码解锁 + + + + Verify voiceprint or enter password to unlock + 验证声纹或输入密码解锁 + + + + Verify finger vein or enter password to unlock + 验证指静脉或输入密码解锁 + + + + Verify iris or enter password to unlock + 验证虹膜或输入密码解锁 + + + + Input Password + 输入密码 + + + + Failed to verify %1, please enter password to unlock + 验证%1失败,请输入密码解锁 + + + + Unable to verify %1, please enter password to unlock + 无法验证%1,请输入密码解锁 + + + Use the bound wechat scanning code or enter the password to log in + 使用绑定的微信扫码或输入密码登录 + + + + + Password cannot be empty + 密码不能为空 + + + Failed to verify %1, please enter password. + 验证%1失败,请输入密码. + + + Unable to verify %1, please enter password. + 无法验证%1,请输入密码. + + + + Failed to verify %1, you still have %2 verification opportunities + 验证%1失败,您还有%2次尝试机会 + + + Biometric/code scan authentication failed too many times, please enter the password. + 生物/扫码验证失败达最大次数,请使用密码解锁 + + + Bioauth/code scan authentication failed, you still have %1 verification opportunities + 生物/扫码验证失败,您还有%1次尝试机会 + + + + NET Exception + 网络异常 + + + Password Incorrect, Please try again + 密码错误,请重试 + + + Authentication failure,there are still %1 remaining opportunities + 认证失败,还剩%1次尝试机会 + + + Please enter your password or enroll your fingerprint + 请输入密码或者录入指纹 + + + + Authentication failure, Please try again + 认证失败,请重试 + + + + Use the bound wechat scanning code or enter the password to unlock + 使用绑定的微信扫码或输入密码解锁 + + + + Password + 密码 + + + + Login + 登录 + + + Biometric Authentication + 生物识别认证 + + + Password Authentication + 密码认证 + + + Other Devices + 其他设备 + + + Too many unsuccessful attempts,please enter password. + 指纹验证失败达最大次数,请使用密码登录 + + + Fingerprint authentication failed, you still have %1 verification opportunities + 指纹验证失败,您还有%1次尝试机会 + + + + BioDevices + + FingerPrint + 指纹 + + + FingerVein + 指静脉 + + + Iris + 虹膜 + + + Face + 人脸 + + + VoicePrint + 声纹 + + + + BioDevicesWidget + + Please select other biometric devices + 请选择其他生物识别设备 + + + Device Type: + 设备类型: + + + Device Name: + 设备名称: + + + + BiometricAuthWidget + + + Current device: + 当前设备: + + + + Identify failed, Please retry. + 识别失败,请重试 + + + + BiometricDevicesWidget + + + Please select the biometric device + 请选择生物设备 + + + + Device type: + 设备类型: + + + + Device name: + 设备型号: + + + + OK + 确定 + + + + ConfForm + + + edit network + 网络属性 + + + + LAN name: + 网络名称: + + + + Method: + 编辑IP设置: + + + + Address: + IP地址: + + + + Netmask: + 子网掩码: + + + + Gateway: + 默认网关: + + + + DNS 1: + 首选DNS: + + + + DNS 2: + 备选DNS: + + + + Edit Conn + 网络设置 + + + + + Auto(DHCP) + 自动(DHCP) + + + + + Manual + 手动 + + + + Cancel + 返回 + + + + Save + 确定 + + + + Ok + 确定 + + + + Can not create new wired network for without wired card + 缺少有线网卡 无法新建网络 + + + + New network already created + 已创建新的有线网络 + + + + New network settings already finished + 新的网络配置已经完成 + + + + Edit Network + 网络属性 + + + + Add Wired Network + 新建有线网络 + + + create wired network successfully + 已创建新的有线网络 + + + change configuration of wired network successfully + 新的设置已经生效 + + + + New settings already effective + 新的设置已经生效 + + + There is a same named LAN exsits. + 已有同名连接存在 + + + + DeviceType + + + FingerPrint + 指纹 + + + + FingerVein + 指静脉 + + + + Iris + 虹膜 + + + + Face + 人脸识别 + + + + VoicePrint + 声纹 + + + + QRCode + 二维码 + + + + DigitalAuthDialog + + + + LoginByUEdu + 请输入锁屏密码 + + + now is authing, wait a moment + 认证中,请稍后 + + + Password Incorrect, Please try again + 密码错误,请重试 + + + + ResetPWD? + 忘记密码? + + + + + SetNewUEduPWD + 设置新锁屏密码 + + + + ConfirmNewUEduPWD + 确认新锁屏密码 + + + + The two password entries are inconsistent, please reset + 两次密码输入不一致,请重设 + + + + Password entered incorrectly, please try again + 密码输入错误,请重试 + + + + clear + 清空 + + + + DlgConnHidWifi + + + Add Hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Wi-Fi name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Cancel + 返回 + + + + Connect + 确定 + + + + C_reate… + 新建... + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + DlgConnHidWifiLeap + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Username + 用户名: + + + + Password + 密码: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + C_reate… + 新建... + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + DlgConnHidWifiSecFast + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Authentication + 认证: + + + + Anonymous identity + 匿名身份: + + + + Allow automatic PAC pro_visioning + 自动PAC配置: + + + + PAC file + PAC文件: + + + + Inner authentication + 内部认证: + + + + Username + 用户名: + + + + Password + 密码: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + C_reate… + 新建... + + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + Tunneled TLS + 隧道 TLS + + + + Protected EAP (PEAP) + 受保护的 EAP + + + + Anonymous + 匿名 + + + + Authenticated + 已认证 + + + + Both + 两者兼用 + + + + DlgConnHidWifiSecLeap + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Authentication + 认证: + + + + Username + 用户名: + + + + Password + 密码: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + C_reate… + 新建... + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + Tunneled TLS + 隧道 TLS + + + + Protected EAP (PEAP) + 受保护的 EAP + + + + DlgConnHidWifiSecPeap + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Authentication + 认证: + + + + Anonymous identity + 匿名身份: + + + + Domain + 域名: + + + + CA certificate + CA 证书: + + + + CA certificate password + CA 证书密码: + + + + No CA certificate is required + 不需要CA证书 + + + + PEAP version + PEAP版本: + + + + Inner authentication + 内部认证: + + + + Username + 用户名: + + + + Password + 密码: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + Tunneled TLS + 隧道 TLS + + + + Protected EAP (PEAP) + 受保护的 EAP + + + + Choose from file + 从文件选择... + + + + Automatic + 自动 + + + + Version 0 + 版本 0 + + + + Version 1 + 版本 1 + + + + DlgConnHidWifiSecPwd + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Authentication + 认证: + + + + Username + 用户名: + + + + Password + 密码: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + C_reate… + 新建... + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + Tunneled TLS + 隧道 TLS + + + + Protected EAP (PEAP) + 受保护的 EAP + + + + DlgConnHidWifiSecTls + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Authentication + 认证: + + + + Identity + 身份: + + + + Domain + 域名: + + + + CA certificate + CA 证书: + + + + CA certificate password + CA 证书密码: + + + + No CA certificate is required + 不需要CA证书 + + + + User certificate + 用户证书: + + + + User certificate password + 用户证书密码: + + + + User private key + 用户私钥: + + + + User key password + 用户密钥密码: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + C_reate… + 新建... + + + + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + Tunneled TLS + 隧道 TLS + + + + Protected EAP (PEAP) + 受保护的 EAP + + + + + + Choose from file + 从文件选择... + + + + DlgConnHidWifiSecTunnelTLS + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Authentication + 认证: + + + + Anonymous identity + 匿名身份: + + + + Domain + 域名: + + + + CA certificate + CA 证书: + + + + CA certificate password + CA 证书密码: + + + + No CA certificate is required + 不需要CA证书 + + + + Inner authentication + 内部认证: + + + + Username + 用户名: + + + + Password + 密码: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + C_reate… + 新建... + + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + Tunneled TLS + 隧道 TLS + + + + Protected EAP (PEAP) + 受保护的 EAP + + + + Choose from file + 从文件选择... + + + + DlgConnHidWifiWep + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Key + 密钥 + + + + WEP index + WEP 检索 + + + + Authentication + 认证: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + C_reate… + 新建... + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + 1(default) + 1(默认) + + + + Open System + 开放式系统 + + + + Shared Key + 共享密钥 + + + + DlgConnHidWifiWpa + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Add Hidden Wi-Fi + 加入无线网络 + + + + Connection + 连接设置: + + + + Wi-Fi name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Password + 密码: + + + + Cancel + 返回 + + + + Connect + 连接 + + + + C_reate… + 新建... + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + WEP 40/128-bit Key (Hex or ASCII) + WEP 40/128 位密钥(十六进制或ASCII) + + + WEP 128-bit Passphrase + WEP 128 位密码句 + + + Dynamic WEP (802.1X) + 动态 WEP (802.1x) + + + WPA & WPA2 Enterprise + WPA 及 WPA2 企业 + + + + DlgHotspotCreate + + + Dialog + + + + + Create Hotspot + 创建个人热点 + + + + Network name + 网络名称: + + + + Wi-Fi security + Wi-Fi 安全性: + + + + Password + 密码: + + + + Cancel + 返回 + + + + Ok + 确定 + + + + None + + + + + WPA & WPA2 Personal + WPA 及 WPA2 个人 + + + + InputInfos + + + Service exception... + 服务异常,重试中... + + + + Invaild parameters... + 参数异常,重试中... + + + + Unknown fault:%1 + 未知错误:%1 + + + + Recapture(60s) + 重新获取(60s) + + + + Recapture(%1s) + 重新获取(%1s) + + + + + Get code + 获取验证码 + + + + KeyboardWidget + + + KeyboardWidget + + + + + KylinDBus + + kylin network applet desktop message + 麒麟网络工具信息提示 + + + + KylinNM + + + kylin-nm + 网络工具 + + + + + LAN + 有线网络 + + + Enabel LAN List + 其他有线网络 + + + WiFi + 无线网络 + + + Enabel WiFi List + 其他无线网络 + + + New WiFi + 加入其他网络 + + + Network + 网络 + + + + + Advanced + 设置网络 + + + Ethernet + 有线网络 + + + Connect Hide Network + 加入网络 + + + Wifi + 无线网络 + + + Enabled + 已开启 + + + Disabled + 已关闭 + + + + HotSpot + 个人热点 + + + + FlyMode + 飞行模式 + + + Show MainWindow + 显示网络连接界面 + + + + Inactivated LAN + 未激活 + + + Inactivated WLAN + 未激活 + + + + Other WLAN + 其他 + + + + + WLAN + 无线局域网 + + + + Show KylinNM + + + + + No wireless card detected + 未检测到无线网卡 + + + + Activated LAN + 已激活 + + + + Activated WLAN + 已激活 + + + + + + + + Not connected + 未连接任何网络 + + + + + + + + + + + + Disconnected + 未连接 + + + + No Other Wired Network Scheme + 列表中无其他有线网络 + + + Edit + 编辑 + + + Done + 完成 + + + No wifi connected. + 未连接任何网络 + + + + No Other Wireless Network Scheme + 未检测到其他无线网络 + + + + Wired net is disconnected + 断开有线网络 + + + Wi-Fi is disconnected + 断开无线网络 + + + + Confirm your Wi-Fi password or usable of wireless card + 请确认Wi-Fi密码或无线设备 + + + Ethernet Networks + 其他有线网络 + + + New LAN + 新建有线网络 + + + Hide WiFi + 加入网络 + + + + No usable network in the list + 列表暂无可连接网络 + + + + + NetOn, + 已连接, + + + Wifi Networks + 其他无线网络 + + + None + + + + keep wired network switch is on before turning on wireless switch + 打开无线网开关前保持有线网开关打开 + + + please insert the wireless network adapter + 请先插入无线网卡 + + + Abnormal connection exist, program will delete it + 正在断开异常连接的网络 + + + update Wi-Fi list now, click again + 正在更新 Wi-Fi列表 请再次点击 + + + update Wi-Fi list now + 正在更新 Wi-Fi列表 + + + + Conn Ethernet Success + 连接有线网络成功 + + + + Conn Ethernet Fail + 连接有线网络失败 + + + + Conn Wifi Success + 连接无线网络成功 + + + + LockWidget + + + Form + + + + + Date + 日期 + + + + Time + 时间 + + + Guest + 游客 + + + SwitchUser + 切换用户 + + + + LoginOptionsWidget + + + Login Options + 登录选项 + + + Password + 密码 + + + Wechat + 微信 + + + + Identify device removed! + 校验设备已移除! + + + + MyLineEdit + + + + + Verification code + 短信验证码 + + + + OneConnForm + + + Form + -- + + + + Automatically join the network + 自动加入该网络 + + + Input password + 输入密码 + + + Config + 设置 + + + + + + + Connect + 连接 + + + + Disconnect + 断开连接 + + + + Input Password... + 输入密码... + + + + Connect to Hidden Wi-Fi Network + 连接到隐藏 Wi-Fi 网络 + + + + Signal: + 信号强度: + + + Public + 开放 + + + Safe + 安全 + + + Rate + 速率 + + + + None + + + + + WiFi Security: + WiFi安全性: + + + + MAC: + 物理地址: + + + + Conn Wifi Failed + 连接无线网络失败 + + + + OneLancForm + + + Form + -- + + + Config + 设置 + + + + + Connect + 连接 + + + + Disconnect + 断开连接 + + + + + No Configuration + 未配置 + + + + IPv4: + IPv4地址: + + + + IPv6: + IPv6地址: + + + + BandWidth: + 带宽: + + + + MAC: + 物理地址: + + + Auto + 自动 + + + + PhoneAuthWidget + + + + Verification by phoneNum + 手机号验证 + + + + 「 Use bound Phone number to verification 」 + + + + + 「 Use SMS to verification 」 + 「 请使用绑定该账户手机号验证 」 + + + + + commit + 提交 + + + + + Network not connected~ + 系统未联网,请检查网络连接~ + + + + Network unavailable~ + 网络状态差,请检查网络连接~ + + + + Verification Code invalid! + 验证码失效 + + + + Verification Code incorrect.Please retry! + 验证码错误!请填写正确的验证码! + + + + Failed time over limit!Retry after 1 hour! + 验证码错误次数超过10次,1小时后再试 + + + + verifaction failed! + 手机验证失败 + + + + PowerManager + + + lock + 锁定 + + + SwitchUser + 切换用户 + + + logout + 注销 + + + reboot + 重启 + + + shutdown + 关机 + + + Lock Screen + 锁屏 + + + Switch User + 切换用户 + + + + Log Out + 注销 + + + + + Restart + 重启 + + + + Power Off + 关机 + + + + Shut Down + 关机 + + + + Hibernate + 休眠 + + + + Suspend + 睡眠 + + + Sleep + 休眠 + + + + QObject + + + The screensaver is active. + 屏幕保护程序已激活 + + + + The screensaver is inactive. + 屏幕保护程序未激活 + + + + Screensaver + + exit(Esc) + 退出(Esc) + + + exit + 退出 + + + + Picture does not exist + 图片不存在 + + + Set as desktop wallpaper + 设置为桌面壁纸 + + + Automatic switching + 自动切换 + + + You have %1 unread message + 您有%1条未读消息 + + + + You have new notification + 您有新的消息 + + + + View + 预览 + + + + SleepTime + + + You have rested: + 您已休息: + + + + SureWindow + + + Form + -- + + + + TextLabel + + + + + Cancel + 取消 + + + + Confirm + 确认 + + + + Multiple users are logged in at the same time.Are you sure you want to reboot this system? + 同时有多个用户登录系统,您确定要退出系统吗? + + + + SwitchButton + + login by password + 密码登录 + + + login by qr code + 微信登录 + + + + SwitchButtonGroup + + + uEduPWD + 密码登录 + + + + Wechat + 微信登录 + + + + TabletLockWidget + + You have %1 unread message + 您有%1条未读消息 + + + Slide to unlock + 向上滑动解锁 + + + + New password is the same as old + 新密码与原密码相同 + + + + Reset password error:%1 + 重置密码失败:%1 + + + + Please scan by correct WeChat + 请使用正确的微信扫码 + + + + + + + + + Cancel + 取消 + + + + + Back + 返回 + + + + Skip + 跳过 + + + + Utils + + + kylin network applet desktop message + 麒麟网络工具信息提示 + + + + VerificationWidget + + + Please scan by bound WeChat + 请使用已绑定的微信扫码 + + + + VerticalVerificationWidget + + + Please scan by bound WeChat + 请使用已绑定的微信扫码 + + + + WeChatAuthDialog + + + + Login by wechat + 微信登录 + + + + + Verification by wechat + 微信验证 + + + + + 「 Use registered WeChat account to login 」 + 「 使用已注册的微信号登录 」 + + + + + 「 Use bound WeChat account to verification 」 + 「 请使用绑定该账号的微信验证 」 + + + + + Network not connected~ + 系统未联网,请检查网络连接~ + + + + Scan code successfully + 扫码成功 + + + + Timeout!Try again! + 超时!请重新扫码! + + + Login failed + 登录失败 + + + + main + + + Start command for the ukui ScreenSaver. + 启动锁屏到命令 + + + + + + lock the screen immediately + 马上锁定屏幕 + + + + query the status of the screen saver + 获取锁屏状态 + + + + unlock the screen saver + 解锁屏幕 + + + + show the screensaver + + + + + Dialog for the ukui ScreenSaver. + + + + + activated by session idle signal + + + + + + lock the screen and show screensaver immediately + + + + + show screensaver immediately + + + + + Screensaver for ukui-screensaver + + + + + show on root window + + + + + show on window. + + + + + window id + + + + diff --git a/man/ukui-screensaver-backend.1 b/man/ukui-screensaver-backend.1 new file mode 100644 index 0000000..d39bf68 --- /dev/null +++ b/man/ukui-screensaver-backend.1 @@ -0,0 +1,62 @@ +.\" ukui-screensaver manual page +.\" +.\" This is free software; you may 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, +.\" or (at your option) any later version. +.\" +.\" This 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. +.\" +.TH UKUI-SCREENSAVER 1 "03 May 2018" "UKUI Desktop Environment" +.\" Please adjust this date whenever revising the manpage. +.\" +.SH "NAME" +ukui-screensaver \- The UKUI Desktop Screensaver and Locker +.SH "SYNOPSIS" +.B ukui-screensaver [OPTIONS] +.SH "DESCRIPTION" +UKUI Screensaver is the default screen saver and locker for the UKUI Desktop. It is designed with simplicity and security in mind. \fBukui-screensaver\fP integrates well with the UKUI desktop, and it supports User Switching and the ability to lock down configuration settings. +.SH "OPTIONS" +.TP +\fB\-\-display=DISPLAY\fR +X display to use. +.TP +\fB\-\-no\-daemon\fR +Don't start as a daemon +.TP +\fB\-\-debug\fR +Enable debugging messages for \fBukui-screensaver\fP +.TP +\fB\-\-version\fR +Output version information and exit. +.TP +\fB\-h, \-\-help\fR +Print standard command line options. +.TP +\fB\-\-help\-all\fR +Print all command line options. +.P +This program also accepts the standard GTK options. +.SH "BUGS" +.SS Should you encounter any bugs, they may be reported at: +http://github.com/ukui-desktop/ukui-screensaver/issues +.SH "AUTHORS" +.SS ukui-screensaver is maintained by: +.nf +Hao Lee +.fi +.SS This Man Page has been updated for the UKUI Desktop Environment by: +Hao Lee (2018) +.SH "SEE ALSO" +.SS Further information may also be available at: http://wiki.ukui-desktop.org/docs +.P +.BR ukui-screensaver-command (1), +.BR ukui-screensaver-preferences (1), +.BR gtk-options (7) diff --git a/man/ukui-screensaver-command.1 b/man/ukui-screensaver-command.1 new file mode 100644 index 0000000..6e808e2 --- /dev/null +++ b/man/ukui-screensaver-command.1 @@ -0,0 +1,60 @@ +.\" ukui-screensaver manual page +.\" +.\" This is free software; you may 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, +.\" or (at your option) any later version. +.\" +.\" This 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. +.\" +.TH UKUI-SCREENSAVER 1 "03 May 2018" "UKUI Desktop Environment" +.\" Please adjust this date whenever revising the manpage. +.\" +.SH "NAME" +ukui-screensaver \- The UKUI Desktop Screensaver and Locker +.SH "SYNOPSIS" +.B ukui-screensaver [OPTIONS] +.SH "DESCRIPTION" +UKUI Screensaver is the default screen saver and locker for the UKUI Desktop. It is designed with simplicity and security in mind. \fBukui-screensaver\fP integrates well with the UKUI desktop, and it supports User Switching and the ability to lock down configuration settings. +.SH "OPTIONS" +.TP +\fB\-\-display=DISPLAY\fR +X display to use. +.TP +\fB\-\-no\-daemon\fR +Don't start as a daemon +.TP +\fB \-\-debug\fR +Enable debugging messages for \fBukui-screensaver\fP +.TP +\fB\-\-version\fR +Output version information and exit. +.TP +\fB\-h, \-\-help\fR +Print standard command line options. +.TP +\fB\-\-help\-all\fR +Print all command line options. +.P +This program also accepts the standard GTK options. +.SH "BUGS" +.SS Should you encounter any bugs, they may be reported at: +http://github.com/ukui-desktop/ukui-screensaver/issues +.SH "AUTHORS" +.SS ukui-screensaver is maintained by: +.nf +Hao Lee +.fi +.SS This Man Page has been updated/re-written for the UKUI Desktop Environment by: +Hao Lee (2018) +.SH "SEE ALSO" +.SS Further information may also be available at: http://wiki.ukui-desktop.org/docs +.P +.BR ukui-screensaver-command (1), diff --git a/man/ukui-screensaver-dialog.1 b/man/ukui-screensaver-dialog.1 new file mode 100644 index 0000000..d39bf68 --- /dev/null +++ b/man/ukui-screensaver-dialog.1 @@ -0,0 +1,62 @@ +.\" ukui-screensaver manual page +.\" +.\" This is free software; you may 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, +.\" or (at your option) any later version. +.\" +.\" This 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. +.\" +.TH UKUI-SCREENSAVER 1 "03 May 2018" "UKUI Desktop Environment" +.\" Please adjust this date whenever revising the manpage. +.\" +.SH "NAME" +ukui-screensaver \- The UKUI Desktop Screensaver and Locker +.SH "SYNOPSIS" +.B ukui-screensaver [OPTIONS] +.SH "DESCRIPTION" +UKUI Screensaver is the default screen saver and locker for the UKUI Desktop. It is designed with simplicity and security in mind. \fBukui-screensaver\fP integrates well with the UKUI desktop, and it supports User Switching and the ability to lock down configuration settings. +.SH "OPTIONS" +.TP +\fB\-\-display=DISPLAY\fR +X display to use. +.TP +\fB\-\-no\-daemon\fR +Don't start as a daemon +.TP +\fB\-\-debug\fR +Enable debugging messages for \fBukui-screensaver\fP +.TP +\fB\-\-version\fR +Output version information and exit. +.TP +\fB\-h, \-\-help\fR +Print standard command line options. +.TP +\fB\-\-help\-all\fR +Print all command line options. +.P +This program also accepts the standard GTK options. +.SH "BUGS" +.SS Should you encounter any bugs, they may be reported at: +http://github.com/ukui-desktop/ukui-screensaver/issues +.SH "AUTHORS" +.SS ukui-screensaver is maintained by: +.nf +Hao Lee +.fi +.SS This Man Page has been updated for the UKUI Desktop Environment by: +Hao Lee (2018) +.SH "SEE ALSO" +.SS Further information may also be available at: http://wiki.ukui-desktop.org/docs +.P +.BR ukui-screensaver-command (1), +.BR ukui-screensaver-preferences (1), +.BR gtk-options (7) diff --git a/screensaver-focus-helper/CMakeLists.txt b/screensaver-focus-helper/CMakeLists.txt new file mode 100644 index 0000000..2a8374d --- /dev/null +++ b/screensaver-focus-helper/CMakeLists.txt @@ -0,0 +1,27 @@ +project(screensaver-capslock-helper) + +pkg_check_modules(X11 REQUIRED x11) +pkg_check_modules(XCB REQUIRED xcb) + +include_directories( + ${X11_INCLUDE_DIRS} + ${XCB_INCLUDE_DIRS} + ) + +set(CMAKE_AUTOMOC ON) + +qt5_wrap_cpp(bin_SRCS + blackwindow.h + ) +set(bin_SRCS + ${bin_SRCS} + main.cpp + blackwindow.cpp + ) + +add_executable(screensaver-focus-helper ${bin_SRCS}) +target_link_libraries(screensaver-focus-helper Qt5::Core Qt5::Widgets Qt5::X11Extras ${X11_LIBRARIES} ${XCB_LIBRARIES}) + +install(TARGETS + screensaver-focus-helper + DESTINATION lib/ukui-screensaver) diff --git a/screensaver-focus-helper/blackwindow.cpp b/screensaver-focus-helper/blackwindow.cpp new file mode 100644 index 0000000..52f270e --- /dev/null +++ b/screensaver-focus-helper/blackwindow.cpp @@ -0,0 +1,93 @@ +#include "blackwindow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BlackWindow::BlackWindow(QWidget *parent) : QWidget(parent) +{ + setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint + | Qt::X11BypassWindowManagerHint); + + setAttribute(Qt::WA_TranslucentBackground); + + setCursor(Qt::BlankCursor); + //qApp->installNativeEventFilter(this); + //installEventFilter(this); +} + +void BlackWindow::paintEvent(QPaintEvent *event) +{ + for(auto screen : QGuiApplication::screens()) + { + QPainter painter(this); + QColor cor = "#000000"; + painter.setBrush(cor); + painter.drawRect(screen->geometry()); + + } + return QWidget::paintEvent(event); +} + +void BlackWindow::laterActivate() +{ + raise(); +} + +bool BlackWindow::eventFilter(QObject *obj, QEvent *event) +{ + if(event->type() == QEvent::WindowDeactivate){ + QTimer::singleShot(50,this,SLOT(laterActivate())); + } + + return false; +} + +bool BlackWindow::nativeEventFilter(const QByteArray &eventType, void *message, long *result) +{ + if (qstrcmp(eventType, "xcb_generic_event_t") != 0 || screensaverIsShow) { + return false; + } + xcb_generic_event_t *event = reinterpret_cast(message); + const uint8_t responseType = event->response_type & ~0x80; + if (responseType == XCB_CONFIGURE_NOTIFY) { + xcb_configure_notify_event_t *xc = reinterpret_cast(event); + if(xc->window == winId()) + return false; + XWindowAttributes window_attributes; + XGetWindowAttributes (QX11Info::display(), xc->window,&window_attributes); + XClassHint ch; + ch.res_name = NULL; + ch.res_class = NULL; + XGetClassHint (QX11Info::display(), xc->window, &ch); + if(QString(ch.res_name) == "ukui-screensaver-dialog"){ + // screensaverIsShow = true; + return false; + } + + laterActivate(); + }else if(responseType == XCB_MAP_NOTIFY){ + xcb_map_notify_event_t *xm = reinterpret_cast(event); + if(xm->window == winId()) + return false; + XWindowAttributes window_attributes; + XGetWindowAttributes (QX11Info::display(), xm->window,&window_attributes); + XClassHint ch; + ch.res_name = NULL; + ch.res_class = NULL; + XGetClassHint (QX11Info::display(), xm->window, &ch); + if(QString(ch.res_name) == "ukui-screensaver-dialog"){ + // screensaverIsShow = true; + return false; + } + laterActivate(); + } + return false; +} diff --git a/screensaver-focus-helper/blackwindow.h b/screensaver-focus-helper/blackwindow.h new file mode 100644 index 0000000..9f30d24 --- /dev/null +++ b/screensaver-focus-helper/blackwindow.h @@ -0,0 +1,25 @@ +#ifndef BLACKWINDOW_H +#define BLACKWINDOW_H + +#include +#include + +class BlackWindow : public QWidget, public QAbstractNativeEventFilter +{ + Q_OBJECT +public: + explicit BlackWindow(QWidget *parent = nullptr); + + virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override; + bool eventFilter(QObject *obj, QEvent *event); +signals: + +private Q_SLOTS: + void laterActivate(); + +protected: + void paintEvent(QPaintEvent *event); + bool screensaverIsShow = false; +}; + +#endif // BLACKWINDOW_H diff --git a/screensaver-focus-helper/main.cpp b/screensaver-focus-helper/main.cpp new file mode 100644 index 0000000..35a93f6 --- /dev/null +++ b/screensaver-focus-helper/main.cpp @@ -0,0 +1,20 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "blackwindow.h" +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + BlackWindow w; + w.setGeometry(QApplication::desktop()->geometry()); + //w.activateWindow(); + w.show(); + a.exec(); + return 0; +} diff --git a/screensaver/CMakeLists.txt b/screensaver/CMakeLists.txt new file mode 100644 index 0000000..7bce0d7 --- /dev/null +++ b/screensaver/CMakeLists.txt @@ -0,0 +1,58 @@ +pkg_check_modules(X11 REQUIRED x11) +pkg_check_modules(XTST REQUIRED xtst) +pkg_check_modules(QGS REQUIRED gsettings-qt) + +include_directories(${PROJECT_BINARY_DIR}) +include_directories(${PROJECT_SOURCE_DIR}/Common) + +include_directories( + ${X11_INCLUDE_DIRS} + ${XTST_INCLUDE_DIRS} + ${QGS_INCLUDE_DIRS} + ) + +set(EXTRA_LIBS + ${EXTRA_LIBS} + ${X11_LIBRARIES} + ${XTST_LIBRARIES} + ${QGS_LIBRARIES} + Common + ) +qt5_add_resources(screensaver_SRC + default.qrc + ) + +qt5_wrap_cpp(screensaver_SRC + chinesedate.h + screensaver.h + mbackground.h + cyclelabel.h + scconfiguration.h + sleeptime.h + weathermanager.h + ../src/networkwatcher.h + ) +set(screensaver_SRC + ${screensaver_SRC} + main.cpp + chinesedate.cpp + mbackground.cpp + screensaver.cpp + cyclelabel.cpp + scconfiguration.cpp + sleeptime.cpp + weathermanager.cpp + ../src/networkwatcher.cpp + ) +add_executable(ukui-screensaver-default ${screensaver_SRC}) +target_link_libraries(ukui-screensaver-default Qt5::Core Qt5::Widgets Qt5::X11Extras Qt5::Xml Qt5::Network ${EXTRA_LIBS}) + +install(TARGETS + ukui-screensaver-default + DESTINATION lib/ukui-screensaver) + +install(FILES + language/screensaver-zh_CN.ini + language/screensaver-en_US.ini + language/screensaver-jd.ini + DESTINATION share/ukui-screensaver/language) diff --git a/screensaver/assets/default-intel.qss b/screensaver/assets/default-intel.qss new file mode 100644 index 0000000..ca19d3c --- /dev/null +++ b/screensaver/assets/default-intel.qss @@ -0,0 +1,86 @@ +QLabel#m_weatherArea { + font-size:26px; + color: #ffffff; +} +QLabel#dateOfWeek { + font-size:40px; + color: #ffffff; + text-align:left; +} +QLabel#dateOfLocaltime { + font-size:96px; + color: #ffffff; + text-align:left; +} +QLabel#dateOfDay { + font-size:32px; + color: #ffffff; + text-align:left; +} +QLabel#dateOfLunar { + font-size:18px; + color: #ffffff; +} +QLabel#clockTime { + background:rgba(255,255,255,0.15); + border-radius: 6px; + font-size:20px; + color: #ffffff; +} +QLabel#colon { + font-size:20px; + color: #ffffff; +} +QLabel#restTime { + font-size:20px; + color: #ffffff; + opacity:0.6; +} +QLabel#centerLabel { + font-size:18px; + color: #ffffff; +} +QLabel#authorLabel { + font-size:18px; + color: #ffffff; +} +QPushButton{ + background:rgba(255,255,255,0.12); +} +#escButton,#prevButton,#nextButton,#settingsButton{ + background: rgba(255, 255, 255, 12%); + border-radius:24px; + border-size:0px; + color:white; + icon-size:24px; +} +#escButton::hover,#prevButton::hover,#nextButton::hover,#settingsButton::hover +{ + background: rgba(255, 255, 255, 30%); +} +#escButton::pressed,#prevButton::pressed,#nextButton::pressed,#settingsButton::pressed +{ + background: rgba(255, 255, 255, 8%); +} +#vboxFrame{ + background: rgba(255, 255, 255, 12%); + border: 0px; + border-radius:4px; +} +#WallpaperButton{ + background: rgba(255, 255, 255, 0%); + border-radius:4px; + color:white; + icon-size:24px; +} +#WallpaperButton::hover{ + background: rgba(61, 107, 229, 255); +} +#autoSwitchLabel{ + font-size:14px; + color: #ffffff; +} +#autoSwitch{ + background: rgba(255, 255, 255, 0%); + border-radius:4px; +} diff --git a/screensaver/assets/default.qss b/screensaver/assets/default.qss new file mode 100644 index 0000000..2abe225 --- /dev/null +++ b/screensaver/assets/default.qss @@ -0,0 +1,90 @@ +QLabel#dateOfWeek { + font-size:16px; + color: #ffffff; +} +QLabel#dateOfLocaltime { + font-size:50px; + color: #ffffff; +} +QLabel#dateOfDay { + font-size:16px; + color: #ffffff; +} +QLabel#dateOfLunar { + font-size:16px; + color: #ffffff; +} +QLabel#clockTime { + background:rgba(255,255,255,0.15); + border-radius: 6px; + font-size:20px; + color: #ffffff; +} +QLabel#colon { + font-size:20px; + color: #ffffff; +} +QLabel#restTime { + font-size:20px; + color: #ffffff; + opacity:0.6; +} +QLabel#centerLabel { + font-size:36px; + color: #ffffff; +} +QLabel#authorLabel { + font-size:28px; + color: #ffffff; +} +QLabel#myText{ + font-size:18px; + border-radius: 6px; + background: rgba(255, 255, 255, 82%); + padding: 24px 48px 24px 48px; + color: #000000; +} +QPushButton{ + background:rgba(255,255,255,0.12); +} +#escButton,#prevButton,#nextButton,#settingsButton{ + background: rgba(255, 255, 255, 12%); + border-radius:24px; + border-size:0px; + color:white; + icon-size:24px; +} +#escButton::hover,#prevButton::hover,#nextButton::hover,#settingsButton::hover +{ + background: rgba(255, 255, 255, 30%); +} +#escButton::pressed,#prevButton::pressed,#nextButton::pressed,#settingsButton::pressed +{ + background: rgba(255, 255, 255, 8%); +} +#vboxFrame{ + background: rgba(255, 255, 255, 12%); + border: 0px; + border-radius:4px; +} +#WallpaperButton{ + background: rgba(255, 255, 255, 0%); + border-radius:4px; + color:white; + icon-size:24px; +} +#WallpaperButton::hover{ + background: rgba(61, 107, 229, 255); +} +#autoSwitchLabel{ + font-size:14px; + color: #ffffff; +} +#screenLabel{ + font-size:14px; + color: #ffffff; +} +#autoSwitch{ + background: rgba(255, 255, 255, 0%); + border-radius:4px; +} diff --git a/screensaver/assets/download.svg b/screensaver/assets/download.svg new file mode 100644 index 0000000..c335266 --- /dev/null +++ b/screensaver/assets/download.svg @@ -0,0 +1 @@ +下载 \ No newline at end of file diff --git a/screensaver/assets/logo-kylin.svg b/screensaver/assets/logo-kylin.svg new file mode 100644 index 0000000..d76a963 --- /dev/null +++ b/screensaver/assets/logo-kylin.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/screensaver/assets/logo.svg b/screensaver/assets/logo.svg new file mode 100644 index 0000000..c7d90aa --- /dev/null +++ b/screensaver/assets/logo.svg @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/screensaver/assets/message.png b/screensaver/assets/message.png new file mode 100644 index 0000000..cfe54a4 Binary files /dev/null and b/screensaver/assets/message.png differ diff --git a/screensaver/assets/next.svg b/screensaver/assets/next.svg new file mode 100644 index 0000000..25b93b3 --- /dev/null +++ b/screensaver/assets/next.svg @@ -0,0 +1 @@ +下一张 \ No newline at end of file diff --git a/screensaver/assets/prev.svg b/screensaver/assets/prev.svg new file mode 100644 index 0000000..597f035 --- /dev/null +++ b/screensaver/assets/prev.svg @@ -0,0 +1 @@ +上一张 \ No newline at end of file diff --git a/screensaver/assets/setBackground.svg b/screensaver/assets/setBackground.svg new file mode 100644 index 0000000..2662a40 --- /dev/null +++ b/screensaver/assets/setBackground.svg @@ -0,0 +1 @@ +设为壁纸 \ No newline at end of file diff --git a/screensaver/assets/settings.svg b/screensaver/assets/settings.svg new file mode 100644 index 0000000..860b704 --- /dev/null +++ b/screensaver/assets/settings.svg @@ -0,0 +1 @@ +设置 \ No newline at end of file diff --git a/screensaver/assets/wallpaper.svg b/screensaver/assets/wallpaper.svg new file mode 100644 index 0000000..2662a40 --- /dev/null +++ b/screensaver/assets/wallpaper.svg @@ -0,0 +1 @@ +设为壁纸 \ No newline at end of file diff --git a/screensaver/assets/weather-icon/.DS_Store b/screensaver/assets/weather-icon/.DS_Store new file mode 100644 index 0000000..dbb415d Binary files /dev/null and b/screensaver/assets/weather-icon/.DS_Store differ diff --git a/screensaver/assets/weather-icon/._.DS_Store b/screensaver/assets/weather-icon/._.DS_Store new file mode 100644 index 0000000..9ad849c Binary files /dev/null and b/screensaver/assets/weather-icon/._.DS_Store differ diff --git a/screensaver/assets/weather-icon/._511-中度霾-Moderate haze.svg b/screensaver/assets/weather-icon/._511-中度霾-Moderate haze.svg new file mode 100644 index 0000000..58f2119 Binary files /dev/null and b/screensaver/assets/weather-icon/._511-中度霾-Moderate haze.svg differ diff --git a/screensaver/assets/weather-icon/100.svg b/screensaver/assets/weather-icon/100.svg new file mode 100644 index 0000000..26f3a2a --- /dev/null +++ b/screensaver/assets/weather-icon/100.svg @@ -0,0 +1 @@ +100-晴-SunnyClear \ No newline at end of file diff --git a/screensaver/assets/weather-icon/101.svg b/screensaver/assets/weather-icon/101.svg new file mode 100644 index 0000000..7fa3796 --- /dev/null +++ b/screensaver/assets/weather-icon/101.svg @@ -0,0 +1 @@ +101-多云-Cloudy \ No newline at end of file diff --git a/screensaver/assets/weather-icon/102.svg b/screensaver/assets/weather-icon/102.svg new file mode 100644 index 0000000..0bd2141 --- /dev/null +++ b/screensaver/assets/weather-icon/102.svg @@ -0,0 +1 @@ +102-少云-Few Clouds \ No newline at end of file diff --git a/screensaver/assets/weather-icon/103.svg b/screensaver/assets/weather-icon/103.svg new file mode 100644 index 0000000..ebd0846 --- /dev/null +++ b/screensaver/assets/weather-icon/103.svg @@ -0,0 +1 @@ +103-晴间多云-Partly Cloudy \ No newline at end of file diff --git a/screensaver/assets/weather-icon/104.svg b/screensaver/assets/weather-icon/104.svg new file mode 100644 index 0000000..1fafb80 --- /dev/null +++ b/screensaver/assets/weather-icon/104.svg @@ -0,0 +1 @@ +104-阴-Overcast \ No newline at end of file diff --git a/screensaver/assets/weather-icon/200.svg b/screensaver/assets/weather-icon/200.svg new file mode 100644 index 0000000..1c5af38 --- /dev/null +++ b/screensaver/assets/weather-icon/200.svg @@ -0,0 +1 @@ +200-有风-Windy \ No newline at end of file diff --git a/screensaver/assets/weather-icon/201.svg b/screensaver/assets/weather-icon/201.svg new file mode 100644 index 0000000..61a0d38 --- /dev/null +++ b/screensaver/assets/weather-icon/201.svg @@ -0,0 +1 @@ +201-平静-Calm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/202.svg b/screensaver/assets/weather-icon/202.svg new file mode 100644 index 0000000..f6299d0 --- /dev/null +++ b/screensaver/assets/weather-icon/202.svg @@ -0,0 +1 @@ +202-微风-Light Breeze \ No newline at end of file diff --git a/screensaver/assets/weather-icon/203.svg b/screensaver/assets/weather-icon/203.svg new file mode 100644 index 0000000..0d759fc --- /dev/null +++ b/screensaver/assets/weather-icon/203.svg @@ -0,0 +1 @@ +203-和风-Moderate Gentle Breeze \ No newline at end of file diff --git a/screensaver/assets/weather-icon/204.svg b/screensaver/assets/weather-icon/204.svg new file mode 100644 index 0000000..f7b5410 --- /dev/null +++ b/screensaver/assets/weather-icon/204.svg @@ -0,0 +1 @@ +204-清风-Fresh Breeze \ No newline at end of file diff --git a/screensaver/assets/weather-icon/205.svg b/screensaver/assets/weather-icon/205.svg new file mode 100644 index 0000000..e84f495 --- /dev/null +++ b/screensaver/assets/weather-icon/205.svg @@ -0,0 +1 @@ +205-强风劲风-Strong Breeze \ No newline at end of file diff --git a/screensaver/assets/weather-icon/206.svg b/screensaver/assets/weather-icon/206.svg new file mode 100644 index 0000000..0e1a298 --- /dev/null +++ b/screensaver/assets/weather-icon/206.svg @@ -0,0 +1 @@ +206-疾风-High Wind, Near Gale \ No newline at end of file diff --git a/screensaver/assets/weather-icon/207.svg b/screensaver/assets/weather-icon/207.svg new file mode 100644 index 0000000..d9337d4 --- /dev/null +++ b/screensaver/assets/weather-icon/207.svg @@ -0,0 +1 @@ +207-大风-Gale \ No newline at end of file diff --git a/screensaver/assets/weather-icon/208.svg b/screensaver/assets/weather-icon/208.svg new file mode 100644 index 0000000..f98d914 --- /dev/null +++ b/screensaver/assets/weather-icon/208.svg @@ -0,0 +1 @@ +208-烈风Strong Gale \ No newline at end of file diff --git a/screensaver/assets/weather-icon/209.svg b/screensaver/assets/weather-icon/209.svg new file mode 100644 index 0000000..fe17ad5 --- /dev/null +++ b/screensaver/assets/weather-icon/209.svg @@ -0,0 +1 @@ +209-风暴-Storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/210.svg b/screensaver/assets/weather-icon/210.svg new file mode 100644 index 0000000..decfa5d --- /dev/null +++ b/screensaver/assets/weather-icon/210.svg @@ -0,0 +1 @@ +210-狂爆风-Violent Storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/211.svg b/screensaver/assets/weather-icon/211.svg new file mode 100644 index 0000000..99103df --- /dev/null +++ b/screensaver/assets/weather-icon/211.svg @@ -0,0 +1 @@ +211-飓风-Hurricane \ No newline at end of file diff --git a/screensaver/assets/weather-icon/212.svg b/screensaver/assets/weather-icon/212.svg new file mode 100644 index 0000000..9bbbc3a --- /dev/null +++ b/screensaver/assets/weather-icon/212.svg @@ -0,0 +1 @@ +212-龙卷风-Tornado \ No newline at end of file diff --git a/screensaver/assets/weather-icon/213.svg b/screensaver/assets/weather-icon/213.svg new file mode 100644 index 0000000..6c5b028 --- /dev/null +++ b/screensaver/assets/weather-icon/213.svg @@ -0,0 +1 @@ +213-热带风暴Tropical Storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/300.svg b/screensaver/assets/weather-icon/300.svg new file mode 100644 index 0000000..94af903 --- /dev/null +++ b/screensaver/assets/weather-icon/300.svg @@ -0,0 +1 @@ +300-阵雨-Shower Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/301.svg b/screensaver/assets/weather-icon/301.svg new file mode 100644 index 0000000..3e68269 --- /dev/null +++ b/screensaver/assets/weather-icon/301.svg @@ -0,0 +1 @@ +301-强阵雨-Heavy Shower Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/302.svg b/screensaver/assets/weather-icon/302.svg new file mode 100644 index 0000000..7a8679d --- /dev/null +++ b/screensaver/assets/weather-icon/302.svg @@ -0,0 +1 @@ +302-雷阵雨-Thundershower \ No newline at end of file diff --git a/screensaver/assets/weather-icon/303.svg b/screensaver/assets/weather-icon/303.svg new file mode 100644 index 0000000..9f0910a --- /dev/null +++ b/screensaver/assets/weather-icon/303.svg @@ -0,0 +1 @@ +303-强雷阵雨-Heavy Thunderstorm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/304.svg b/screensaver/assets/weather-icon/304.svg new file mode 100644 index 0000000..afbac16 --- /dev/null +++ b/screensaver/assets/weather-icon/304.svg @@ -0,0 +1 @@ +304-雷阵雨伴有冰雹-hailThundershower with hail \ No newline at end of file diff --git a/screensaver/assets/weather-icon/305.svg b/screensaver/assets/weather-icon/305.svg new file mode 100644 index 0000000..e3a8649 --- /dev/null +++ b/screensaver/assets/weather-icon/305.svg @@ -0,0 +1 @@ +305-小雨-Light Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/306.svg b/screensaver/assets/weather-icon/306.svg new file mode 100644 index 0000000..d106107 --- /dev/null +++ b/screensaver/assets/weather-icon/306.svg @@ -0,0 +1 @@ +306-中雨-Moderate Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/307.svg b/screensaver/assets/weather-icon/307.svg new file mode 100644 index 0000000..fed2a07 --- /dev/null +++ b/screensaver/assets/weather-icon/307.svg @@ -0,0 +1 @@ +307-大雨-Heavy Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/308.svg b/screensaver/assets/weather-icon/308.svg new file mode 100644 index 0000000..5659581 --- /dev/null +++ b/screensaver/assets/weather-icon/308.svg @@ -0,0 +1 @@ +308-极端降雨-Extreme Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/309.svg b/screensaver/assets/weather-icon/309.svg new file mode 100644 index 0000000..a140288 --- /dev/null +++ b/screensaver/assets/weather-icon/309.svg @@ -0,0 +1 @@ +309-毛毛雨细雨-Drizzle Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/310.svg b/screensaver/assets/weather-icon/310.svg new file mode 100644 index 0000000..95f74da --- /dev/null +++ b/screensaver/assets/weather-icon/310.svg @@ -0,0 +1 @@ +310-暴雨-Storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/311.svg b/screensaver/assets/weather-icon/311.svg new file mode 100644 index 0000000..312cd20 --- /dev/null +++ b/screensaver/assets/weather-icon/311.svg @@ -0,0 +1 @@ +311-大暴雨-Heavy Storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/312.svg b/screensaver/assets/weather-icon/312.svg new file mode 100644 index 0000000..189f4a8 --- /dev/null +++ b/screensaver/assets/weather-icon/312.svg @@ -0,0 +1 @@ +312-特大暴雨-Severe Storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/313.svg b/screensaver/assets/weather-icon/313.svg new file mode 100644 index 0000000..1994d7b --- /dev/null +++ b/screensaver/assets/weather-icon/313.svg @@ -0,0 +1 @@ +313-冻雨-Freezing Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/314.svg b/screensaver/assets/weather-icon/314.svg new file mode 100644 index 0000000..4fae886 --- /dev/null +++ b/screensaver/assets/weather-icon/314.svg @@ -0,0 +1 @@ +314-小到中雨-Light to moderate rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/315.svg b/screensaver/assets/weather-icon/315.svg new file mode 100644 index 0000000..735772e --- /dev/null +++ b/screensaver/assets/weather-icon/315.svg @@ -0,0 +1 @@ +315-中到大雨-Moderate to heavy rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/316.svg b/screensaver/assets/weather-icon/316.svg new file mode 100644 index 0000000..57da6bc --- /dev/null +++ b/screensaver/assets/weather-icon/316.svg @@ -0,0 +1 @@ +316-大到暴雨-Heavy rain to storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/317.svg b/screensaver/assets/weather-icon/317.svg new file mode 100644 index 0000000..c9790eb --- /dev/null +++ b/screensaver/assets/weather-icon/317.svg @@ -0,0 +1 @@ +317-暴雨到大暴雨-Storm to heavy storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/318.svg b/screensaver/assets/weather-icon/318.svg new file mode 100644 index 0000000..7f39b9d --- /dev/null +++ b/screensaver/assets/weather-icon/318.svg @@ -0,0 +1 @@ +318-大暴雨到特大暴雨-Heavy to severe storm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/399.svg b/screensaver/assets/weather-icon/399.svg new file mode 100644 index 0000000..69ddae1 --- /dev/null +++ b/screensaver/assets/weather-icon/399.svg @@ -0,0 +1 @@ +399-雨-Rain \ No newline at end of file diff --git a/screensaver/assets/weather-icon/400.svg b/screensaver/assets/weather-icon/400.svg new file mode 100644 index 0000000..7b56e19 --- /dev/null +++ b/screensaver/assets/weather-icon/400.svg @@ -0,0 +1 @@ +400-小雪-Light Snow \ No newline at end of file diff --git a/screensaver/assets/weather-icon/401.svg b/screensaver/assets/weather-icon/401.svg new file mode 100644 index 0000000..0c88512 --- /dev/null +++ b/screensaver/assets/weather-icon/401.svg @@ -0,0 +1 @@ +401-中雪-Moderate Snow \ No newline at end of file diff --git a/screensaver/assets/weather-icon/402.svg b/screensaver/assets/weather-icon/402.svg new file mode 100644 index 0000000..aeb88cd --- /dev/null +++ b/screensaver/assets/weather-icon/402.svg @@ -0,0 +1 @@ +402-大雪-Heavy Snow \ No newline at end of file diff --git a/screensaver/assets/weather-icon/403.svg b/screensaver/assets/weather-icon/403.svg new file mode 100644 index 0000000..925b7f6 --- /dev/null +++ b/screensaver/assets/weather-icon/403.svg @@ -0,0 +1 @@ +403-暴雪-Snowstorm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/404.svg b/screensaver/assets/weather-icon/404.svg new file mode 100644 index 0000000..a4c1177 --- /dev/null +++ b/screensaver/assets/weather-icon/404.svg @@ -0,0 +1 @@ +404-雨夹雪-Sleet \ No newline at end of file diff --git a/screensaver/assets/weather-icon/405.svg b/screensaver/assets/weather-icon/405.svg new file mode 100644 index 0000000..f9769f9 --- /dev/null +++ b/screensaver/assets/weather-icon/405.svg @@ -0,0 +1 @@ +405-雨雪天气-Rain And Snow \ No newline at end of file diff --git a/screensaver/assets/weather-icon/406.svg b/screensaver/assets/weather-icon/406.svg new file mode 100644 index 0000000..5c0dfa2 --- /dev/null +++ b/screensaver/assets/weather-icon/406.svg @@ -0,0 +1 @@ +406-阵雨夹雪-Shower Snow \ No newline at end of file diff --git a/screensaver/assets/weather-icon/407.svg b/screensaver/assets/weather-icon/407.svg new file mode 100644 index 0000000..7851fed --- /dev/null +++ b/screensaver/assets/weather-icon/407.svg @@ -0,0 +1 @@ +407-阵雪-Snow Flurry \ No newline at end of file diff --git a/screensaver/assets/weather-icon/408.svg b/screensaver/assets/weather-icon/408.svg new file mode 100644 index 0000000..a5a6ea3 --- /dev/null +++ b/screensaver/assets/weather-icon/408.svg @@ -0,0 +1 @@ +408-小到中雪-Light to moderate snow \ No newline at end of file diff --git a/screensaver/assets/weather-icon/409.svg b/screensaver/assets/weather-icon/409.svg new file mode 100644 index 0000000..d9011e1 --- /dev/null +++ b/screensaver/assets/weather-icon/409.svg @@ -0,0 +1 @@ +409-中到大雪-Moderate to heavy snow \ No newline at end of file diff --git a/screensaver/assets/weather-icon/410.svg b/screensaver/assets/weather-icon/410.svg new file mode 100644 index 0000000..32d3cc8 --- /dev/null +++ b/screensaver/assets/weather-icon/410.svg @@ -0,0 +1 @@ +410-大到暴雪-Heavy snow to snowstorm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/499.svg b/screensaver/assets/weather-icon/499.svg new file mode 100644 index 0000000..a1b390d --- /dev/null +++ b/screensaver/assets/weather-icon/499.svg @@ -0,0 +1 @@ +499-雪-snow \ No newline at end of file diff --git a/screensaver/assets/weather-icon/500.svg b/screensaver/assets/weather-icon/500.svg new file mode 100644 index 0000000..447377b --- /dev/null +++ b/screensaver/assets/weather-icon/500.svg @@ -0,0 +1 @@ +500-薄雾-Mist \ No newline at end of file diff --git a/screensaver/assets/weather-icon/501.svg b/screensaver/assets/weather-icon/501.svg new file mode 100644 index 0000000..69f35ef --- /dev/null +++ b/screensaver/assets/weather-icon/501.svg @@ -0,0 +1 @@ +501-雾-Foggy \ No newline at end of file diff --git a/screensaver/assets/weather-icon/502.svg b/screensaver/assets/weather-icon/502.svg new file mode 100644 index 0000000..965a144 --- /dev/null +++ b/screensaver/assets/weather-icon/502.svg @@ -0,0 +1 @@ +502-霾-Haze \ No newline at end of file diff --git a/screensaver/assets/weather-icon/503.svg b/screensaver/assets/weather-icon/503.svg new file mode 100644 index 0000000..f13b1ca --- /dev/null +++ b/screensaver/assets/weather-icon/503.svg @@ -0,0 +1 @@ +503-扬沙-Sand \ No newline at end of file diff --git a/screensaver/assets/weather-icon/504.svg b/screensaver/assets/weather-icon/504.svg new file mode 100644 index 0000000..2f03641 --- /dev/null +++ b/screensaver/assets/weather-icon/504.svg @@ -0,0 +1 @@ +504-浮尘-Dust \ No newline at end of file diff --git a/screensaver/assets/weather-icon/507.svg b/screensaver/assets/weather-icon/507.svg new file mode 100644 index 0000000..e420e64 --- /dev/null +++ b/screensaver/assets/weather-icon/507.svg @@ -0,0 +1 @@ +507-沙尘暴-Duststorm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/508.svg b/screensaver/assets/weather-icon/508.svg new file mode 100644 index 0000000..299f3ba --- /dev/null +++ b/screensaver/assets/weather-icon/508.svg @@ -0,0 +1 @@ +508-强沙尘暴-Sandstorm \ No newline at end of file diff --git a/screensaver/assets/weather-icon/509.svg b/screensaver/assets/weather-icon/509.svg new file mode 100644 index 0000000..6c44bfd --- /dev/null +++ b/screensaver/assets/weather-icon/509.svg @@ -0,0 +1 @@ +509-浓雾-Dense fog \ No newline at end of file diff --git a/screensaver/assets/weather-icon/510.svg b/screensaver/assets/weather-icon/510.svg new file mode 100644 index 0000000..b1b02d5 --- /dev/null +++ b/screensaver/assets/weather-icon/510.svg @@ -0,0 +1 @@ +510-强浓雾-Strong fog \ No newline at end of file diff --git a/screensaver/assets/weather-icon/511.svg b/screensaver/assets/weather-icon/511.svg new file mode 100644 index 0000000..475d564 --- /dev/null +++ b/screensaver/assets/weather-icon/511.svg @@ -0,0 +1 @@ +511-中度霾-Moderate haze \ No newline at end of file diff --git a/screensaver/assets/weather-icon/512.svg b/screensaver/assets/weather-icon/512.svg new file mode 100644 index 0000000..c72f806 --- /dev/null +++ b/screensaver/assets/weather-icon/512.svg @@ -0,0 +1 @@ +512-重度霾-Heavy haze \ No newline at end of file diff --git a/screensaver/assets/weather-icon/513.svg b/screensaver/assets/weather-icon/513.svg new file mode 100644 index 0000000..c788e77 --- /dev/null +++ b/screensaver/assets/weather-icon/513.svg @@ -0,0 +1 @@ +513-严重霾-Severe haze \ No newline at end of file diff --git a/screensaver/assets/weather-icon/514.svg b/screensaver/assets/weather-icon/514.svg new file mode 100644 index 0000000..c2a618c --- /dev/null +++ b/screensaver/assets/weather-icon/514.svg @@ -0,0 +1 @@ +514-大雾-Heavy fog \ No newline at end of file diff --git a/screensaver/assets/weather-icon/515.svg b/screensaver/assets/weather-icon/515.svg new file mode 100644 index 0000000..30513e7 --- /dev/null +++ b/screensaver/assets/weather-icon/515.svg @@ -0,0 +1 @@ +515-特强浓雾-Extra heavy fog \ No newline at end of file diff --git a/screensaver/assets/weather-icon/900.svg b/screensaver/assets/weather-icon/900.svg new file mode 100644 index 0000000..2208903 --- /dev/null +++ b/screensaver/assets/weather-icon/900.svg @@ -0,0 +1 @@ +900-热-Hot \ No newline at end of file diff --git a/screensaver/assets/weather-icon/901.svg b/screensaver/assets/weather-icon/901.svg new file mode 100644 index 0000000..ad9fd2c --- /dev/null +++ b/screensaver/assets/weather-icon/901.svg @@ -0,0 +1 @@ +901-冷-Cold \ No newline at end of file diff --git a/screensaver/assets/weather-icon/999.svg b/screensaver/assets/weather-icon/999.svg new file mode 100644 index 0000000..0e8ce03 --- /dev/null +++ b/screensaver/assets/weather-icon/999.svg @@ -0,0 +1,16 @@ + + + 天气 + + + + + + + + + + + + + \ No newline at end of file diff --git a/screensaver/chinesedate.cpp b/screensaver/chinesedate.cpp new file mode 100644 index 0000000..811e504 --- /dev/null +++ b/screensaver/chinesedate.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#include "chinesedate.h" +#include +#include +#include +unsigned int chineseDays[201]={0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909 + 0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919 + 0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929 + 0x06566,0x0d4a0,0x0ea50,0x16a95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939 + 0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949 + 0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959 + 0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969 + 0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979 + 0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989 + 0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x05ac0,0x0ab60,0x096d5,0x092e0,//1990-1999 + 0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009 + 0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019 + 0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029 + 0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039 + 0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049 + /**Add By JJonline@JJonline.Cn**/ + 0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059 + 0x092e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069 + 0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079 + 0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089 + 0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099 + 0x0d520}; + +int Month[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; +ChineseDate::ChineseDate() +{ + ChineseMonth<<""<<"正"<<"二"<<"三"<<"四"<<"五"<<"六"<<"七"<<"八"<<"九"<<"十"<<"冬"<<"腊"; + ChineseDay<<""<<"一"<<"二"<<"三"<<"四"<<"五"<<"六"<<"七"<<"八"<<"九"; + ChineseDays<<"初"<<"十"<<"廿"<<"三十"; + +} + +int ChineseDate::getYearDays(int year) +{ + int sum = 12 * 29; + for (unsigned int i = 0x8000; i > 0x8; i = i >> 1) { + sum += chineseDays[year - 1900] & i ? 1 : 0; + } + sum += getLeapMonthDays(year); + return sum; +} + +bool ChineseDate::isLeapMonth(int year) +{ + return chineseDays[year - 1900] & 0xf ? true : false; +} + +int ChineseDate::getLeapMonthDays(int year) +{ + if(isLeapMonth(year)) + return chineseDays[year-1900]& 0x10000 ? 30 : 29; + return 0; +} + +int ChineseDate::getLeapMonth(int year) +{ + if(isLeapMonth(year)) + return chineseDays[year-1900] & 0xf; + return 0; +} + +int ChineseDate::getYearMonthDays(int year,int month) +{ + return chineseDays[year-1900] & (0x10000 >> month) ? 30 : 29; +} + +QString ChineseDate::getChineseDays(int month, int day, bool isleap) +{ + QString res = ""; + if(isleap) + res = res + "闰"; + + res = res + ChineseMonth.at(month) + "月"; + if(day == 10) + res = res + "初十"; + else if(day == 20) + res = res + "二十"; + else if(day == 30) + res = res + "三十"; + else + res = res + ChineseDays.at(day/10) + ChineseDay.at(day%10); + return res; +} + +QString ChineseDate::getDateLunar() +{ + int leapyear,leapmonth,leapday; + QDateTime currentTime = QDateTime::currentDateTime(); + QDate oldTile(1900, 1, 31); + //获取当前日期到1900年1月31日的天数 + int offset = oldTile.daysTo(currentTime.date()); + + //获取农历年 + int i,yearlength; + for (i = 1900; i < 2101 && offset > 0; i++) { + yearlength = getYearDays(i); + offset -= yearlength; + } + if (offset < 0) { + offset += yearlength; + i--; + } + leapyear = i; + + //获取农历月 + bool isLeap = false; + int temp; + int leapMonth = getLeapMonth(leapyear); + for (i = 1; i < 13 && offset >= 0; i++) { + temp = getYearMonthDays(leapyear,i); + offset -= temp; + isLeap = false; + if (i == leapMonth) { + if (offset < 0) { + i--; + isLeap = true; + } else { + temp = getLeapMonthDays(leapyear); + offset -= temp; + } + } + } + if (offset < 0) { + if (i == leapMonth && isLeap) { + offset += temp; + isLeap = false; + } else if (i == (leapMonth + 1)) { + offset += temp; + isLeap = true; + i--; + } else { + offset += temp; + i--; + } + } + leapmonth = i; + leapday = offset + 1; + + return getChineseDays(leapmonth,leapday,isLeap); +} diff --git a/screensaver/chinesedate.h b/screensaver/chinesedate.h new file mode 100644 index 0000000..8f580fc --- /dev/null +++ b/screensaver/chinesedate.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#ifndef CHINESEDATE_H +#define CHINESEDATE_H +#include +#include + +class ChineseDate +{ +public: + ChineseDate(); + QString getDateLunar(); +private: + /** + * @brief 根据农历年份获取该年天数 + * @param year 农历年份 + * @return + */ + int getYearDays(int year); + /** + * @brief 根据农历年份判断该年是否有闰月 + * @param year 农历年份 + * @return + */ + bool isLeapMonth(int year); + /** + * @brief 根据农历年份获取闰月的天数,如果存在闰月的话 + * @param year 农历年份 + * @return + */ + int getLeapMonthDays(int year); + /** + * @brief 根据农历年份获取闰月的月份 + * @param year 农历年份 + * @return + */ + int getLeapMonth(int year); + /** + * @brief 根据农历年份和月份获取当月的天数 + * @param year 农历年份 + * @param month 农历月份 + * @return + */ + int getYearMonthDays(int year,int month); + /** + * @brief 获取农历日期 + * @return + */ + QString getChineseDays(int month,int day,bool isleap); + + QStringList ChineseMonth; + QStringList ChineseDay; + QStringList ChineseDays; + +}; + +#endif // CHINESEDATE_H diff --git a/screensaver/cyclelabel.cpp b/screensaver/cyclelabel.cpp new file mode 100644 index 0000000..a97f42f --- /dev/null +++ b/screensaver/cyclelabel.cpp @@ -0,0 +1,98 @@ +/* -*- 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 "cyclelabel.h" + +CycleLabel::CycleLabel(QWidget *parent) + :QFrame(parent), + m_width(20), + m_height(20) +{ + this->setFixedSize(QSize(m_width, m_height)); + setWindowFlags(Qt::FramelessWindowHint); + setAttribute(Qt::WA_TranslucentBackground, true); +} + +void CycleLabel::paintEvent(QPaintEvent *){ + //启用反锯齿 + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + + drawBg(&painter); + drawSlider(&painter); +} + +void CycleLabel::setSize(QSize size) +{ + m_width = size.width(); + m_height = size.height(); + setFixedSize(size); + repaint(); +} + +void CycleLabel::drawBg(QPainter *painter) +{ + painter->save(); + + if (!checked){ + painter->setPen(QColor(0,0,0,66)); + painter->setBrush(QColor(0,0,0,66)); + } + else{ + painter->setPen(Qt::NoPen); + painter->setBrush(bgColorOn); + } + + //circle in + QRect rect(0, 0, width(), height()); + //半径为高度的一半 + int radius = rect.height() / 2; + //圆的宽度为高度 + int circleWidth = rect.height(); + + QPainterPath path; + path.moveTo(radius, rect.left()); + path.arcTo(QRectF(rect.left(), rect.top(), circleWidth, circleWidth), 90, 180); + path.lineTo(rect.width() - radius, rect.height()); + path.arcTo(QRectF(rect.width() - rect.height(), rect.top(), circleWidth, circleWidth), 270, 180); + path.lineTo(radius, rect.top()); + + painter->drawPath(path); + + painter->restore(); + +} + +void CycleLabel::drawSlider(QPainter *painter){ + painter->save(); + painter->setPen(Qt::NoPen); + + painter->setBrush(QColor("#ffffff")); + + //circle in + QRect rect(0, 0, m_width, m_height); + int sliderWidth = m_width/2; + QRect sliderRect(sliderWidth/2, sliderWidth/2, sliderWidth, sliderWidth); + painter->drawEllipse(sliderRect); + + painter->restore(); +} + + diff --git a/screensaver/cyclelabel.h b/screensaver/cyclelabel.h new file mode 100644 index 0000000..9967836 --- /dev/null +++ b/screensaver/cyclelabel.h @@ -0,0 +1,64 @@ +/* -*- 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 CYCLELABEL_H +#define CYCLELABEL_H +#include +#include +#include +#include +#include +#include + +class CycleLabel : public QFrame +{ + Q_OBJECT +public: + CycleLabel(QWidget *parent = 0); + void setSize(QSize size); + +protected: + + void paintEvent(QPaintEvent *); + +private: + bool checked; + + QColor borderColorOff; + QColor bgColorOff; + QColor bgColorOn; + QColor sliderColorOff; + QColor sliderColorOn; + int space; //滑块离背景间隔 + int rectRadius; //圆角角度 + int step; //移动步长 + int startX; + int endX; + QTimer * timer; + + void drawBg(QPainter *painter); + void drawSlider(QPainter *painter); + int m_width; + int m_height; + + +}; + +#endif // CHECKBUTTON_H diff --git a/screensaver/default.qrc b/screensaver/default.qrc new file mode 100644 index 0000000..2bdb7f2 --- /dev/null +++ b/screensaver/default.qrc @@ -0,0 +1,87 @@ + + + assets/default.qss + assets/default-intel.qss + + + assets/logo.svg + assets/download.svg + assets/prev.svg + assets/next.svg + assets/setBackground.svg + assets/settings.svg + assets/wallpaper.svg + assets/logo-kylin.svg + assets/message.png + + + assets/weather-icon/100.svg + assets/weather-icon/101.svg + assets/weather-icon/102.svg + assets/weather-icon/103.svg + assets/weather-icon/104.svg + assets/weather-icon/200.svg + assets/weather-icon/201.svg + assets/weather-icon/202.svg + assets/weather-icon/203.svg + assets/weather-icon/204.svg + assets/weather-icon/205.svg + assets/weather-icon/206.svg + assets/weather-icon/207.svg + assets/weather-icon/208.svg + assets/weather-icon/209.svg + assets/weather-icon/210.svg + assets/weather-icon/211.svg + assets/weather-icon/212.svg + assets/weather-icon/213.svg + assets/weather-icon/300.svg + assets/weather-icon/301.svg + assets/weather-icon/302.svg + assets/weather-icon/303.svg + assets/weather-icon/304.svg + assets/weather-icon/305.svg + assets/weather-icon/306.svg + assets/weather-icon/307.svg + assets/weather-icon/308.svg + assets/weather-icon/309.svg + assets/weather-icon/310.svg + assets/weather-icon/311.svg + assets/weather-icon/312.svg + assets/weather-icon/313.svg + assets/weather-icon/314.svg + assets/weather-icon/315.svg + assets/weather-icon/316.svg + assets/weather-icon/317.svg + assets/weather-icon/318.svg + assets/weather-icon/399.svg + assets/weather-icon/400.svg + assets/weather-icon/401.svg + assets/weather-icon/402.svg + assets/weather-icon/403.svg + assets/weather-icon/404.svg + assets/weather-icon/405.svg + assets/weather-icon/406.svg + assets/weather-icon/407.svg + assets/weather-icon/408.svg + assets/weather-icon/409.svg + assets/weather-icon/410.svg + assets/weather-icon/499.svg + assets/weather-icon/500.svg + assets/weather-icon/501.svg + assets/weather-icon/502.svg + assets/weather-icon/503.svg + assets/weather-icon/504.svg + assets/weather-icon/507.svg + assets/weather-icon/508.svg + assets/weather-icon/509.svg + assets/weather-icon/510.svg + assets/weather-icon/511.svg + assets/weather-icon/512.svg + assets/weather-icon/513.svg + assets/weather-icon/514.svg + assets/weather-icon/515.svg + assets/weather-icon/900.svg + assets/weather-icon/901.svg + assets/weather-icon/999.svg + + diff --git a/screensaver/language/screensaver-en_US.ini b/screensaver/language/screensaver-en_US.ini new file mode 100644 index 0000000..11c66b9 --- /dev/null +++ b/screensaver/language/screensaver-en_US.ini @@ -0,0 +1,130 @@ +[1] +FL="May there be enough clouds in your life " +SL="to make a beautiful sunset." +author= +[2] +OL="And forever has no end." +author= +[3] +FL="Just because someone doesn't love you the way you want them to," +SL="doesn't mean they don't love you with all they have." +author= +[4] +OL="Happiness is good health and a bad memory." +author= +[5] +FL="The best and most beautiful things in the world can not be" +SL="seen or even touched,they must be felt with heart." +author= +[6] +FL="I am not afraid of tomorrow for I have seen" +SL="yesterday and love today." +author= +[7] +OL="Enjoy when you can,and endure when you must." +author= +[8] +FL="A friend is one of the nicest things you can have," +SL="and one of the best things you can be." +author= +[9] +OL="Only you can control your future." +author= +[10] +OL="Don't let what you cannot do interfere with what you can do." +author= +[11] +OL="Seeing is believing.But is it a truth?" +author= +[12] +FL="You don't have to see the whole staircase," +SL="just take the first step." +author= +[13] +FL="Start where you are.Use what you have." +SL="Do what you can." +author= +[14] +FL="If I had eight hours to chop down a tree," +SL="I'd spend six hours sharpening my ax." +author= +[15] +OL="Actions is the foundational key to all success." +author= +[16] +OL="Refrain from excess." +author= +[17] +FL="The longest way must have its close;" +SL="the gloomiest night will wear on to a morning." +author= +[18] +OL="Sometimes ever,sometimes never." +author= +[19] +OL="My angel,flung out of space." +author= +[20] +FL="Three thousand,see light is a cloud;" +SL="Troubles are many,would like to open is a sunny day." +author= +[21] +OL="Everything comes full circle." +author= +[22] +FL="In delay there lies no plenty,Then come kiss me," +SL="sweet and twenty,Youth's a stuff that will not endure." +author= +[23] +OL="There is always a better way." +author= +[24] +OL="No act of kindness,no matter how small,is ever wasted." +author= +[25] +FL="Laugh loudly,laugh often,and most important," +SL="laugh at yourself." +author= +[26] +FL="When you want something,at the universe conspires" +SL="in helping you to achieve it." +author= +[27] +FL="It's the possibility of having a dream come true" +SL="that makes life interesting." +author= +[28] +FL="Some people don't belong to you," +SL="but it's good to meet them." +author= +[29] +OL="Miracles happen every day." +author= +[30] +OL="You can't change the past." +author= +[31] +OL="To make each day count." +author= +[32] +FL="If you reveal your secrets to the wind you should not" +SL="blame the wind revealing them to the trees." +author= +[33] +FL="I love three things in the world:the sun,the moon and you." +SL="The sun for day,the moon for night and you forever." +author= +[34] +OL="In me the tiger sniffs the rose." +author= +[35] +OL="The longest day has an end." +author= +[36] +FL="Sometimes accompanied,sometimes alone," +SL="stay awesome all the time." +author= +[37] +FL="There are no easy answers," +SL="there's only living through the questions." +author= diff --git a/screensaver/language/screensaver-jd.ini b/screensaver/language/screensaver-jd.ini new file mode 100644 index 0000000..113d502 --- /dev/null +++ b/screensaver/language/screensaver-jd.ini @@ -0,0 +1,161 @@ +[1] +OL=没有共产党,就没有新中国! +author= +[2] +OL=解放思想,实事求是! +author= +[3] +OL=中国产生了共产党,这是开天辟地的大事变! +author= +[4] +FL=一百年来,中国共产党团结带领中国人民 +SL=书写了中华民族几千年历史上最恢宏的史诗! +author= +[5] +FL=一百年来,中国共产党团结带领中国人民进行的一切奋斗、一切牺牲、 +SL=一切创造,归结起来就是一个主题:实现中华民族伟大复兴! +author= +[6] +OL=初心易得,始终难守! +author= +[7] +FL=我们要用历史映照现实,远观未来。看清楚过去为什么能够成功, +SL=弄明白未来怎样才能继续成功! +author= +[8] +FL=中国共产党领导是党和国家的根本所在,命脉所在; +SL=是全国各族人民的利益所系、命运所系! +author= +[9] +OL=中国共产党根基在人民,血脉在人民、力量在人民! +author= +[10] +FL=中国共产党始终代表最广大人民根本利益, +SL=没有任何自己特殊的利益! +author= +[11] +FL=用马克思主义观察时代、把握时代、引领时代, +SL=继续发展当代中国马克思主义、21世纪马克思主义! +author= +[12] +FL=走自己的路是党的全部理论和实践立足点, +SL=更是党百年奋斗得出的历史结论! +author= +[13] +OL=强国必须强军,军强才能国安! +author= +[14] +OL=敢于斗争,敢于胜利,是中国共产党不可战胜的强大精神力量! +author= +[15] +FL=新时代的中国青年,要以实现中华民族伟大复兴为己任, +SL=增强做中国人的志气、骨气、底气! +author= +[16] +FL=伟大、光荣、正确的中国共产党万岁! +SL=伟大、光荣、英雄的中国人民万岁! +author= +[17] +OL=发展才是硬道理! +author= +[18] +OL=聚精会神搞建设,一心一意谋发展! +author= +[19] +OL=看准了,就大胆地试,大胆地闯! +author= +[20] +OL=人固有一死,或重于泰山,或轻于鸿毛! +SL= +author= +[21] +FL=理论联系实际,是马克思主义“活的灵魂”, +SL=是共产党人从斗争中创造新局面的思想路线! +author= +[22] +OL=用中国理论阐释中国实践,用中国实践升华中国理论! +author= +[23] +FL=理论联系实际、和人民群众紧密联系在一起、 +SL=批评与自我批评,是中国共产党的三大优良作风! +author= +[24] +FL=坚持中国特色社会主义道路自信、 +SL=理论自信、制度自信、文化自信! +author= +[25] +OL=让初心薪火相传,把使命永担在肩! +author= +[26] +OL=心有所信,方能行远! +author= +[27] +FL=面向未来,走好新时代的长征路, +SL=我们更需要坚定理想信念、矢志拼搏奋斗! +author= +[28] +FL=牢记初心使命,坚定必胜信念, +SL=发扬斗争精神,增强斗争本领! +author= +[29] +OL=发扬优良传统,承担历史使命! +author= +[30] +FL=实事求是、坚持真理,科学应变、主动求变,咬定目标、 +SL=勇往直前,走好新时代的长征路! +author= +[31] +FL=缅怀革命先烈,赓续共产党人精神血脉, +SL=坚定理想信念,砥砺革命意志! +author= +[32] +FL=革命理想高于天,理想信念之火 +SL=一经点燃就会产生巨大的精神力量! +author= +[33] +OL=信仰、信念、信心是最好的防腐剂! +author= +[34] +OL=学史明理、学史增信、学史崇德、学史力行! +author= +[35] +OL=时代是思想之母,实践是理论之源! +author= +[36] +FL=实践发展永无止境,我们认识真理、 +SL=进行理论创新就永无止境! +author= +[37] +OL=理想因其远大而为理想,信念因其执着而为信念! +author= +[38] +FL=在胜利和顺境时不骄傲不急躁, +SL=在困难和逆境时不消沉不动摇! +author= +[39] +OL=从群众中来、到群众中去! +author= +[40] +FL=中国特色社会主义道路是实现社会主义现代化的必由之路, +SL=是创造人民美好生活的必由之路! +author= +[41] +FL=人民立场是中国共产党的根本政治立场, +SL=是马克思主义政党区别于其他政党的显著标志! +author= +[42] +OL=方向决定道路,道路决定命运! +author= +[43] +OL=全党要坚定道路自信、理论自信、制度自信、文化自信! +author= +[44] +OL=得众则得国,失众则失国! +author= +[45] +OL=自信人生二百年,会当水击三千里! +author= +[46] +FL=发展是党执政兴国的第一要务, +SL=是解决中国所有问题的关键! +author= diff --git a/screensaver/language/screensaver-zh_CN.ini b/screensaver/language/screensaver-zh_CN.ini new file mode 100644 index 0000000..f8befd1 --- /dev/null +++ b/screensaver/language/screensaver-zh_CN.ini @@ -0,0 +1,161 @@ +[1] +FL=因为有悔,所以披星戴月 +SL=因为有梦,所以奋不顾身 +author= +[2] +OL=大直若屈,大巧若拙,大辩若讷。 +author=《老子》 +[3] +OL=博学之,审问之,慎思之,明辨之,笃行之。 +author=《礼记》 +[4] +OL=兼听则明,偏听则暗。 +author=《资治通鉴》 +[5] +FL=一花一世界,一叶一追寻。 +SL=一曲一场叹,一生为一人。 +author=威廉·布莱克《天真的预言》 +[6] +FL=月光下,你带着笑地向我步来, +SL=月色与雪色之间,你是第三种绝色。 +author=余光中 +[7] +OL=不要问我心里有没有你,我余光中都是你。 +author=余光中 +[8] +FL=你要是愿意,我就永远爱你, +SL=你要是不愿意,我就永远相思。 +author=王小波 +[9] +FL=草在结它的种子,风在摇它的叶子。 +SL=我们站着,不说话,就十分美好。 +author=顾城 +[10] +OL=见到你,我觉得多少适应了这个世界。 +author=村上春树 +[11] +OL=不须耳鬓常厮伴,一笑低头意已倾。 +author=朱生豪 +[12] +FL=君臣一梦,今古空名。 +SL=但远山长,云山乱,晓山青。 +author=苏轼 +[13] +FL=心如规矩,志如尺衡, +SL=平静如水,正直如绳。 +author=严遵 +[14] +OL=近水知鱼性,近山识鸟音。 +author=周希陶 +[15] +OL=此处果有可乐,我即别无所思。 +author=林语堂 +[16] +FL=心之所向,素履以往, +SL=生如逆旅,一苇以航。 +author=七堇年《尘曲》 +[17] +FL=你说,我们就山居于此吧, +SL=胭脂用尽时,桃花就开了。 +author=与谢野晶子 +[18] +OL=世间所有的相遇,都是久别重逢。 +author=白落梅 +[19] +OL=浮云一别后,流水十年间。 +author=韦应物《淮上喜会梁川故人》 +[20] +OL=最是人间留不住,朱颜辞镜花辞树。 +author=王国维《蝶恋花》 +[21] +OL=行到水穷处,坐看云起时。 +author=王维 +[22] +OL=我有一瓢酒,可以慰风尘。 +author=韦应物 +[23] +OL=墙头马上遥相顾,一见知君即断肠。 +author=白居易 +[24] +OL=人生到处知何似,应似飞鸿踏雪泥。 +author=《和子由渑池怀旧》 +[25] +OL=粗缯大布裹生涯,腹有诗书气自华。 +author=《和董传留别》 +[26] +OL=清风徐来,水波不兴。 +author=《前赤壁赋》 +[27] +OL=我有斗酒,藏之久矣,以待子不时之须。 +author=《后赤壁赋》 +[28] +FL=若是有缘,千山暮雪,万里层云,终会重逢。 +SL=若是无缘,自此一去,天涯海角,再难相会。 +author=白落梅《你若安好便是晴天》 +[29] +FL=愿你一生努力,一生被爱。 +SL=想要的都拥有,得不到的都释怀。 +author=八月长安 +[30] +OL=凌晨四点醒来,发现海棠花未眠。 +author=川端康成 +[31] +OL=无路可走的时候,就不断回到原点。 +author=东野圭吾 +[32] +OL=你要批评指点四周的风景,你首先要爬上屋顶。 +author=歌德 +[33] +OL=只有流过血的手指,才能弹出世间的绝唱。 +author=泰戈尔 +[34] +FL=幸亏时光不会倒流, +SL=否则万物一定会朝旧岁月里疾步奔跑。 +author=《迷楼》 +[35] +FL=我看到那些岁月如何奔驰, +SL=挨过了冬季,便迎来了春天。 +author=《瓦尔登湖》 +[36] +FL=整个世界展现在我们面前, +SL=期待着我们去创造,而不是去重复。 +author=毕加索 +[37] +FL=不必太纠结于当下,也不必太忧虑未来, +SL=当你经历过一些事情的时候,眼前的风景已经和从前不一样了。 +author=村上春树 +[38] +OL=三更梦醒,你是檐上落下的星。 +author=佚名 +[39] +OL=我将永远忠于自己,披星戴月的奔向理想与自由。 +author=佚名 +[40] +OL=有一天,我看了43次日落! +author=《小王子》 +[41] +OL=当太阳升到最高点的时候,影子就不见了。 +author=佚名 +[42] +OL=拯救地球好累,虽然有些疲惫但我还是会。 +author=《超人不会飞》 +[43] +OL=陌上花开,可缓缓归矣 +author=佚名 +[44] +OL=别慌,月亮也正在大海某处迷茫 +author=佚名 +[45] +OL=夏天到了,春天的不甘该统统放下了 +author=佚名 +[46] +OL=保持热爱,奔赴山海 +author=佚名 +[47] +FL=你好,是故事的开始, +SL=你要好好的,是故事的结局。 +author=佚名 +[48] +OL=工欲善其事,必先利其器。 +author=《孔子》 + diff --git a/screensaver/main.cpp b/screensaver/main.cpp new file mode 100644 index 0000000..eb40b19 --- /dev/null +++ b/screensaver/main.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#include "screensaver.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#define WORKING_DIRECTORY "/usr/share/ukui-screensaver" +bool bControlFlg = false;//是否控制面板窗口 + +int main(int argc, char *argv[]) +{ +#if(QT_VERSION>=QT_VERSION_CHECK(5,6,0)) + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); +#endif + QApplication a(argc, argv); + prctl(PR_SET_PDEATHSIG, SIGHUP); + //加载翻译文件 + QString locale = QLocale::system().name(); + QTranslator translator; + QString qmFile = QString(WORKING_DIRECTORY"/i18n_qm/%1.qm").arg(locale); + translator.load(qmFile); + a.installTranslator(&translator); + qDebug() << "load translation file " << qmFile; + + + QCommandLineParser parser; + QString windowId; + Screensaver s; + XWindowAttributes xwa; + + parser.setApplicationDescription("Test helper"); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("source", QCoreApplication::translate("main", "Screensaver for ukui-screensaver")); + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.addOptions({ + {{"r", "root"}, + QCoreApplication::translate("main", "show on root window")}, + {{"w", "window-id"}, + QCoreApplication::translate("main", "show on window."), + QCoreApplication::translate("main", "window id")}, + }); + parser.process(a); + + bool onWindow = parser.isSet("window-id"); + bool onRoot = parser.isSet("root"); + + double scale = 1; + QScreen *screen = QApplication::primaryScreen(); + scale = screen->devicePixelRatio(); + + if(onWindow){ + windowId = parser.value("window-id"); + WId wid = windowId.toULong(); + QWindow* window = QWindow::fromWinId(wid); + window->setProperty("_q_embedded_native_parent_handle",QVariant(wid)); + s.winId(); + s.windowHandle()->setParent(window); + XGetWindowAttributes (QX11Info::display(), wid, &xwa); + +#ifndef USE_INTEL + XClassHint ch; + ch.res_name = NULL; + ch.res_class = NULL; + XGetClassHint (QX11Info::display(), wid, &ch); + if(ch.res_name && strcmp(ch.res_name,"ukui-control-center")==0){ + bControlFlg = true; + s.addClickedEvent(); + } +#endif + + //获取屏保所在屏幕对应的缩放比例。 + for(auto screen : QGuiApplication::screens()) + { + QPoint pos(xwa.x,xwa.y); + if(screen->geometry().contains(pos)){ + scale = screen->devicePixelRatio(); + } + } + + s.resize(xwa.width/scale + 1,xwa.height/scale + 1); + s.move(0,0); + s.show(); + } + else if(onRoot){ + bControlFlg = false; + WId wid = QX11Info::appRootWindow(); + QWindow* window = QWindow::fromWinId(wid); + window->setProperty("_q_embedded_native_parent_handle",QVariant(wid)); + s.winId(); + s.windowHandle()->setParent(window); + XGetWindowAttributes (QX11Info::display(), wid, &xwa); + qDebug()<<"xwa.width = "<. + * +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "mbackground.h" + +#include "commonfunc.h" + +MBackground::MBackground(): + currentIndex(0) +{ + getAllPixmap(); +} + +QString MBackground::getCurrent() +{ + if(list.count()<0) + return ""; + + if(currentIndex>=0 && currentIndex=list.count() ||currentIndex<0) + return ""; + + if(currentIndex == list.count() - 1) + currentIndex = 0; + else + currentIndex++; + + return list.at(currentIndex); +} + +QString MBackground::getPrev() +{ + if(list.count() == 1) + return list.at(0); + + if(list.count()<=0 || currentIndex>=list.count() || currentIndex<0) + return ""; + + if(currentIndex == 0) + currentIndex = list.count() - 1; + else + currentIndex--; + + return list.at(currentIndex); +} + +QString MBackground::getRand() +{ + if(list.count() <= 0) + return ""; + qsrand(time(NULL)); + currentIndex = qrand() % list.count(); + + return list.at(currentIndex); +} + +void MBackground::getAllPixmap() +{ + QDomDocument doc; + QFile *file; + file = new QFile("/usr/share/ukui-background-properties/focal-ubuntukylin-wallpapers.xml"); + if (!file->open(QIODevice::ReadOnly)) + { + qDebug()<fileName()<<" open failed"; + return ; + } + + if (!doc.setContent(file)) + { + file->close(); + return ; + } + file->close(); + file->deleteLater(); + QDomElement root = doc.documentElement();//读取根节点 + QDomNode node = root.firstChild();//读取第一个子节点 QDomNode 节点 + while (!node.isNull()) + { + QDomElement node1 = node.firstChildElement("filename"); + QString fileName = node1.text(); + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile(fileName); + if(mime.name().startsWith("image/")){ + list.append(fileName); + } + + node = node.nextSibling();//读取下一个兄弟节点 + } +} diff --git a/screensaver/mbackground.h b/screensaver/mbackground.h new file mode 100644 index 0000000..747cf1d --- /dev/null +++ b/screensaver/mbackground.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#ifndef MBACKGROUND_H +#define MBACKGROUND_H + +#include +#include +#include +#include +#include +#include "scconfiguration.h" + +class MBackground +{ +public: + MBackground(); + QString getCurrent(); + QString getNext(); + QString getPrev(); + QString getRand(); + +private: + void getAllPixmap(); + + QStringList list; + int currentIndex; +}; + +#endif // MBACKGROUND_H diff --git a/screensaver/scconfiguration.cpp b/screensaver/scconfiguration.cpp new file mode 100644 index 0000000..a348df4 --- /dev/null +++ b/screensaver/scconfiguration.cpp @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "scconfiguration.h" +#include "commonfunc.h" +#include +#include +#include +#include + +#define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" +#define GSETTINGS_SCHEMA_MATE_BACKGROUND "org.mate.background" +#define GSETTINGS_SCHEMA_SCREENSAVER_DEFAULT "org.ukui.screensaver-default" +#define TIME_TYPE_SCHEMA "org.ukui.control-center.panel.plugins" +#define GSETTINGS_SCHEMA_STYLE "org.ukui.style" + +SCConfiguration* SCConfiguration::instance_ = nullptr; + +SCConfiguration::SCConfiguration(QObject *parent) : + QObject(parent), + mgsettings(nullptr), + ukgsettings(nullptr), + udgsettings(nullptr), + timegsettings(nullptr), + stygsettings(nullptr) +{ + initGsettings(); +} + +SCConfiguration* SCConfiguration::instance(QObject *parent) +{ + if(instance_ == nullptr) + instance_ = new SCConfiguration(parent); + return instance_; +} + +void SCConfiguration::initGsettings() +{ + if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_MATE_BACKGROUND)) + mgsettings = new QGSettings(GSETTINGS_SCHEMA_MATE_BACKGROUND, "", this); + + if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_SCREENSAVER)) + ukgsettings = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); + + if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_SCREENSAVER_DEFAULT)) + udgsettings = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER_DEFAULT,"",this); + + if(QGSettings::isSchemaInstalled(TIME_TYPE_SCHEMA)) + timegsettings = new QGSettings(TIME_TYPE_SCHEMA,"",this); + + if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_STYLE)) + stygsettings = new QGSettings(GSETTINGS_SCHEMA_STYLE, "", this); + + connect(udgsettings, &QGSettings::changed, + this, &SCConfiguration::onConfigurationChanged); + connect(ukgsettings, &QGSettings::changed, + this, &SCConfiguration::onConfigurationChanged); + connect(timegsettings, &QGSettings::changed, + this, &SCConfiguration::onConfigurationChanged); + connect(stygsettings, &QGSettings::changed, + this, &SCConfiguration::onConfigurationChanged); +} + +void SCConfiguration::initDefaultSettings() +{ + + +} + +void SCConfiguration::onConfigurationChanged(QString key) +{ + if(key == "cycleTime"){ + int cycleTime = getCycleTime(); + Q_EMIT cycleTimeChanged(cycleTime); + }else if(key == "automaticSwitchingEnabled"){ + bool changed = getAutoSwitch(); + Q_EMIT autoSwitchChanged(changed); + }else if(key == "backgroundPath"){ + QString path = getBackgroundPath(); + Q_EMIT backgroundPathChanged(path); + }else if(key == "mytext"){ + QString text = getMyText(); + Q_EMIT myTextChanged(text); + }else if(key == "showCustomRestTime"){ + bool ret = getCShowRestTime(); + Q_EMIT showCRestTimeChanged(ret); + }else if(key == "showUkuiRestTime"){ + bool ret = getUShowRestTime(); + Q_EMIT showURestTimeChanged(ret); + }else if(key == "textIsCenter"){ + bool ret = getTextIsCenter(); + Q_EMIT textIsCenterChanged(ret); + }else if(key == "showMessageEnabled"){ + bool ret = getMessageShowEnable(); + Q_EMIT messageShowEnableChanged(ret); + }else if(key == "messageNumber"){ + int num = getMessageNumber(); + Q_EMIT messageNumberChanged(num); + }else if(key == "hoursystem"){ + int timeType = timegsettings->get("hoursystem").toInt(); + Q_EMIT timeTypeChanged(timeType); + }else if(key == "type"){ + QString dateType = timegsettings->get("date").toString(); + Q_EMIT dateTypeChanged(dateType); + }else if(key == "menuTransparency"){ + int blur_Num = stygsettings->get("menuTransparency").toInt(); + Q_EMIT blurChanged(blur_Num); + }else if(key == "styleName"){ + QString m_curStyle = stygsettings->get("styleName").toString(); + Q_EMIT styleChanged(m_curStyle); + } +} + +QString SCConfiguration::getDefaultBackground() +{ + QString backgroundFile = ""; + if(ukgsettings){ + backgroundFile = ukgsettings->get("background").toString(); + } + + if(ispicture(backgroundFile)) + return backgroundFile; + else + return "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg"; +} + +int SCConfiguration::getTimeType() +{ + int timeType = 24; + if(timegsettings){ + QStringList keys = timegsettings->keys(); + if (keys.contains("hoursystem")) { + timeType = timegsettings->get("hoursystem").toInt(); + } + } + return timeType; +} + +QString SCConfiguration::getDateType() +{ + QString dateType = "cn"; + if(timegsettings){ + QStringList keys = timegsettings->keys(); + if (keys.contains("date")) { + dateType = timegsettings->get("date").toString(); + } + } + return dateType; +} + +bool SCConfiguration::getAutoSwitch() +{ + bool ret = false; + if(udgsettings){ + ret = udgsettings->get("automatic-switching-enabled").toBool(); + } + + return ret; +} + +bool SCConfiguration::getIsCustom() +{ + bool ret = false; + if(ukgsettings){ + ret = (ukgsettings->get("mode").toString() == "default-ukui-custom"); + } + + return ret; +} + +bool SCConfiguration::getMessageShowEnable() +{ + bool ret = false; + if(ukgsettings){ + ret = ukgsettings->get("show-message-enabled").toBool(); + } + + return ret; +} + +int SCConfiguration::getMessageNumber() +{ + bool ret = false; + if(ukgsettings){ + ret = (ukgsettings->get("mode").toString() == "default-ukui-custom"); + } + + return ret; +} + +bool SCConfiguration::getCShowRestTime() +{ + bool ret = true; + if(udgsettings){ + QStringList keys = udgsettings->keys(); + ret = udgsettings->get("show-custom-rest-time").toBool(); + } + return ret; +} + +bool SCConfiguration::getUShowRestTime() +{ + bool ret = true; + if(udgsettings){ + QStringList keys = udgsettings->keys(); + ret = udgsettings->get("show-ukui-rest-time").toBool(); + } + return ret; +} + +int SCConfiguration::getCycleTime() +{ + int cycleTime = 300; + if(udgsettings){ + cycleTime = udgsettings->get("cycle-time").toInt(); + } + return cycleTime; +} + +QString SCConfiguration::getBackgroundPath() +{ + QString backgroundPath = "/usr/share/backgrounds"; + if(udgsettings){ + backgroundPath = udgsettings->get("background-path").toString(); + } + return backgroundPath; +} + +bool SCConfiguration::getTextIsCenter() +{ + bool ret = true; + if(udgsettings){ + ret = udgsettings->get("text-is-center").toBool(); + } + return ret; +} + +QString SCConfiguration::getMyText() +{ + QString myText = ""; + if(udgsettings){ + myText = udgsettings->get("mytext").toString(); + } + return myText; +} + +int SCConfiguration::getBlurNumber() +{ + int blurNum = 50; + if(stygsettings){ + blurNum = stygsettings->get("menu-transparency").toInt(); + qDebug()<<"????nm"<get("style-name").toString(); + } + return curStyle; +} diff --git a/screensaver/scconfiguration.h b/screensaver/scconfiguration.h new file mode 100644 index 0000000..e41ba78 --- /dev/null +++ b/screensaver/scconfiguration.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef SCCONFIGURATION_H +#define SCCONFIGURATION_H + +#ifndef QT_NO_KEYWORDS +#define QT_NO_KEYWORDS +#endif + + +#include +#include + +class QGSettings; + +class SCConfiguration : public QObject +{ + Q_OBJECT +public: + explicit SCConfiguration(QObject *parent = nullptr); + static SCConfiguration *instance(QObject *parent = nullptr); + + QString getDefaultBackground(); //获取屏保默认背景 + int getTimeType(); //获取显示时间格式 + QString getDateType(); //获取日期格式 + bool getAutoSwitch(); //获取是否自动切换 + bool getCShowRestTime(); //自定义是否显示休息时间 + bool getUShowRestTime(); //UKUI是否显示休息时间 + bool getIsCustom(); //屏保是否自定义 + int getCycleTime(); //背景图片切换间隔时间 + QString getBackgroundPath(); //背景图片来源 + bool getTextIsCenter(); //文字是否居中 + QString getMyText(); //获取文字 + bool getMessageShowEnable(); //获取是否显示消息 + int getMessageNumber(); //获取消息数量 + int getBlurNumber(); + QString getcurStyle(); +public: + +public Q_SLOTS: + void onConfigurationChanged(QString key); + +Q_SIGNALS: + void cycleTimeChanged(int cycleTime); + bool autoSwitchChanged(bool changed); + QString backgroundPathChanged(QString path); + QString myTextChanged(QString text); + bool showCRestTimeChanged(bool isShow); + bool showURestTimeChanged(bool isShow); + bool textIsCenterChanged(bool isCenter); + int messageNumberChanged(int number); + bool messageShowEnableChanged(bool enabled); + int timeTypeChanged(int time); + QString dateTypeChanged(QString type); + int blurChanged(int num); + QString styleChanged(QString type); + +private: + void initGsettings(); + void initDefaultSettings(); +private: + QGSettings *mgsettings; + QGSettings *ukgsettings; + QGSettings *udgsettings; + QGSettings *timegsettings; + QGSettings *stygsettings; + + static SCConfiguration *instance_; +}; + +#endif // CONFIGURATION_H diff --git a/screensaver/screensaver.cpp b/screensaver/screensaver.cpp new file mode 100644 index 0000000..e481abe --- /dev/null +++ b/screensaver/screensaver.cpp @@ -0,0 +1,1406 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "screensaver.h" +#include +#include +#include +#include + +#include "commonfunc.h" +#include "config.h" + +#define TIME_TYPE_SCHEMA "org.ukui.control-center.panel.plugins" +#define THEME_TYPE_SCHENA "org.ukui.style" + +#define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" +#define KEY_MESSAGE_NUMBER "message-number" +#define KEY_MESSAGE_SHOW_ENABLED "show-message-enabled" +#define KEY_HOURSYSTEM "hoursystem" +#define KEY_DATE_FORMAT "date" + +QTime Screensaver::m_currentTime = QTime::currentTime(); +extern bool bControlFlg; + +Screensaver::Screensaver(QWidget *parent): + QWidget(parent), + switchTimer(nullptr), + backgroundPath(""), + cycleTime(300), + isCustom(false), + isCShowRestTime(true), + isUShowRestTime(true), + myTextLabel(nullptr), + myPreviewLabel(nullptr),//预览label标签 + configuration(SCConfiguration::instance()), + myTextWidget(nullptr), + centerWidget(nullptr), + sleepTime(nullptr), + timer(nullptr), + background(""), + autoSwitch(nullptr), + vboxFrame(nullptr), + isAutoSwitch(false), + flag(0), + hasChanged(false), + process(nullptr), + screenLabel(nullptr), + respondClick(false), + m_weatherManager(new WeatherManager(this)) +{ + installEventFilter(this); + // setWindowFlags(Qt::X11BypassWindowManagerHint); + setUpdateCenterWidget(); + setMouseTracking(true); + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + + isCustom = configuration->getIsCustom(); + if(isCustom){ + cycleTime = configuration->getCycleTime(); + isAutoSwitch = configuration->getAutoSwitch(); + backgroundPath = configuration->getBackgroundPath(); + isCShowRestTime = configuration->getCShowRestTime(); + textIsCenter = configuration->getTextIsCenter(); + myText = configuration->getMyText(); + }else + isUShowRestTime = configuration->getUShowRestTime(); + + initUI(); + m_background = new MBackground(); + + QString backgroundFile = configuration->getDefaultBackground(); + background = QPixmap(backgroundFile); + + QList labelList = this->findChildren(); + for(int i = 0;isetAlignment(Qt::AlignCenter); + } +#ifndef USE_INTEL + updateBackgroundPath(); + startSwitchImages(); + + connectSingles(); +#endif + QGSettings *themeSettings; + if(QGSettings::isSchemaInstalled(TIME_TYPE_SCHEMA)) + themeSettings = new QGSettings(TIME_TYPE_SCHEMA,"",this); + + connect(themeSettings, &QGSettings::changed, + this, &Screensaver::themeChanged); + + screenLabel = new QLabel(this); + screenLabel->setObjectName("screenLabel"); + screenLabel->setText(tr("Picture does not exist")); + screenLabel->adjustSize(); + screenLabel->hide(); + +} + +Screensaver::~Screensaver() +{ + +} + +void Screensaver::themeChanged() +{ + if(myTextLabel){ + QColor highLightColor = palette().color(QPalette::Base); + QString stringColor = QString("rgba(%1,%2,%3,82%)") + .arg(highLightColor.red()) + .arg(highLightColor.green()) + .arg(highLightColor.blue()); + QColor textColor = palette().color(QPalette::Text); + QString textString = QString("rgb(%1,%2,%3)") + .arg(textColor.red()) + .arg(textColor.green()) + .arg(textColor.blue()); + QColor borderColor = palette().color(QPalette::BrightText); + QString borderString = QString("rgba(%1,%2,%3,85%)") + .arg(borderColor.red()) + .arg(borderColor.green()) + .arg(borderColor.blue()); + + if(width() < 600 || height()<400) + myTextLabel->setStyleSheet(QString("font-size:5px;border-radius: 2px;background: %1;color: %2;padding: 4px 8px 4px 8px;border-width: 1px;border-style: solid;border-color:%3;") \ + .arg(stringColor).arg(textString).arg(borderString)); + else + myTextLabel->setStyleSheet(QString("font-size:18px;border-radius: 6px;background: %1;color: %2;padding: 24px 48px 24px 48px;border-width: 1px;border-style: solid;border-color:%3;") \ + .arg(stringColor).arg(textString).arg(borderString)); + } +} + +void Screensaver::connectSingles() +{ + connect(configuration, &SCConfiguration::autoSwitchChanged, + this, &Screensaver::autoSwitchChanged); + connect(configuration, &SCConfiguration::backgroundPathChanged, + this, &Screensaver::backgroundPathChanged); + connect(configuration, &SCConfiguration::cycleTimeChanged, + this, &Screensaver::cycleTimeChanged); + connect(configuration, &SCConfiguration::myTextChanged, + this, &Screensaver::myTextChanged); + connect(configuration, &SCConfiguration::showCRestTimeChanged, + this, &Screensaver::showCRestTimeChanged); + connect(configuration, &SCConfiguration::showURestTimeChanged, + this, &Screensaver::showURestTimeChanged); + connect(configuration, &SCConfiguration::textIsCenterChanged, + this, &Screensaver::textIsCenterChanged); + connect(configuration, &SCConfiguration::messageNumberChanged, + this, &Screensaver::onMessageNumberChanged); + connect(configuration, &SCConfiguration::messageShowEnableChanged, + this, &Screensaver::onMessageShowEnabledChanged); + connect(configuration, &SCConfiguration::timeTypeChanged, + this, &Screensaver::onTimeFormatChanged); + connect(configuration, &SCConfiguration::dateTypeChanged, + this, &Screensaver::onDateFormatChanged); + connect(configuration, &SCConfiguration::blurChanged, + this, &Screensaver::onBlurNumChanged); + connect(configuration, &SCConfiguration::styleChanged, + this, &Screensaver::onStyleChanged); +} + +void Screensaver::onBlurNumChanged(int num) +{ + blur_Num = num; + if(curStyle == "ukui-dark" || curStyle == "ukui-black"){ + myTextLabel->setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:16px}").arg(blur_Num * 0.01)); + cycleLabel->setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:8px}").arg(blur_Num * 0.01)); + } else{ + myTextLabel->setStyleSheet(QString("QLabel{background: rgba(255, 255, 255, %1); border-radius:16px}").arg(blur_Num * 0.01)); + cycleLabel->setStyleSheet(QString("QLabel{background: rgba(255, 255, 255, %1); border-radius:8px}").arg(blur_Num * 0.01)); + } +} + +void Screensaver::onStyleChanged(QString style) +{ + curStyle = style; + if(curStyle == "ukui-dark" || curStyle == "ukui-black"){ + myTextLabel->setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:16px}").arg(blur_Num * 0.01)); + cycleLabel->setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:8px}").arg(blur_Num * 0.01)); + } else{ + myTextLabel->setStyleSheet(QString("QLabel{background: rgba(255, 255, 255, %1); border-radius:16px}").arg(blur_Num * 0.01)); + cycleLabel->setStyleSheet(QString("QLabel{background: rgba(255, 255, 255, %1); border-radius:8px}").arg(blur_Num * 0.01)); + } +} + +void Screensaver::onTimeFormatChanged(int type){ + timeType = type; +} + +void Screensaver::onDateFormatChanged(QString type){ + dateType = type; +} + +void Screensaver::onMessageNumberChanged(int num) +{ + int number = configuration->getMessageNumber(); + (configuration->getMessageShowEnable() && number > 0) ? showNotice() : hideNotice(); +} + +void Screensaver::onMessageShowEnabledChanged(bool enabled) +{ + int number = configuration->getMessageNumber(); + (configuration->getMessageShowEnable() && number > 0) ? showNotice() : hideNotice(); +} + +void Screensaver::autoSwitchChanged(bool isSwitch) +{ + if(!isCustom) + return ; + isAutoSwitch = isSwitch; + if(!isSwitch){ + stopSwitchImages(); + } + startSwitchImages(); +} + +/* +* 图片路径改变 +*/ +void Screensaver::backgroundPathChanged(QString path) +{ + backgroundPath = path; + if(!isCustom) + return ; + updateBackgroundPath();//更新图片路径 + stopSwitchImages(); + startSwitchImages(); +} + +void Screensaver::cycleTimeChanged(int cTime) +{ + cycleTime = cTime; + if(!isCustom || !autoSwitch) + return ; + stopSwitchImages(); + startSwitchImages(); +} + +void Screensaver::myTextChanged(QString text) +{ + if(!isCustom) + return ; + + myText = text; + + if(textIsCenter && centerWidget){ + if(centerlabel1) + centerlabel1->setText(myText); + if(centerlabel2){ + centerlabel2->setText(""); + centerlabel2->hide(); + } + if(authorlabel){ + authorlabel->setText(""); + authorlabel->hide(); + } + centerWidget->adjustSize(); + + centerWidget->setGeometry((width()-centerWidget->width())/2,(height()-centerWidget->height())/2, + centerWidget->width(),centerWidget->height()); + + if((height()-centerWidget->height())/2 < timeLayout->y() + timeLayout->height()) + centerWidget->setGeometry((width()-centerWidget->width())/2,timeLayout->y() + timeLayout->height(), + centerWidget->width(),centerWidget->height()); + }else{ + setRandomText(); + setRandomPos(); + if(centerWidget) + centerWidget->hide(); + } +} + +void Screensaver::showCRestTimeChanged(bool isShow) +{ + isCShowRestTime = isShow; + if(!isCustom) + return; + + setSleeptime(isCShowRestTime); +} + +void Screensaver::showURestTimeChanged(bool isShow) +{ + isUShowRestTime = isShow; + if(isCustom) + return; + + setSleeptime(isUShowRestTime); +} + +void Screensaver::textIsCenterChanged(bool isCenter) +{ + textIsCenter = isCenter; + if(!isCustom) + return ; + + if(isCenter){ + if(myTextWidget) + myTextWidget->hide(); + if(!centerWidget){ + setCenterWidget(); + resize(width(),height()); + } + else{ + centerWidget->show(); + myTextChanged(myText); + } + }else{ + if(centerWidget) + centerWidget->hide(); + setRandomText(); + setRandomPos(); + } +} + +bool Screensaver::eventFilter(QObject *obj, QEvent *event) +{ +#ifndef USE_INTEL + if(obj == this){ + if(event->type()==QEvent::MouseButtonPress){ + if(respondClick){ + if(!process){ + process = new QProcess(this); + } + process->start("ukui-screensaver-command -s"); + } + } + } +#endif + return false; +} + +void Screensaver::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + /*时间未同步的时候重新刷新一次,主要是避免睡眠唤醒时的时间跳变*/ +/* if (m_currentTime.hour() != QTime::currentTime().hour() || + m_currentTime.minute() != QTime::currentTime().minute()) { + updateTime(); + } +*/ + if(isCustom && imagePaths.count()==0){ + painter.setBrush(QColor("#000000")); + if(screenLabel->isHidden()){ + screenLabel->show(); + } + }else{ + if(background.isNull()){ + QColor cor = "#035290"; + painter.setBrush(cor); + painter.drawRect(-1,-1,this->width()+1,this->height()+1); + } else { + painter.drawPixmap(0,0,this->width(),this->height(), getPaddingPixmap()); + QPainterPath path; + QPainter painter1(this); + painter1.setOpacity(0.25); + painter1.setRenderHint(QPainter::Antialiasing); // 反锯齿; + painter1.setClipping(true); + painter1.setPen(Qt::transparent); + path.addRect(this->rect()); + path.setFillRule(Qt::WindingFill); + painter1.setBrush(QColor("#000000")); + painter1.setPen(Qt::transparent); + painter1.drawPath(path); + } + } + /*这里是为了不显示笔的线条*/ + //painter.drawRect(-1,-1,this->width()+1,this->height()+1); +} + +void Screensaver::isMovie() +{ + if(!currentPixmap.isEmpty()){ + currentPixmap.clear(); + currentCount = 0; + if(movieTimer){ + movieTimer->stop(); + movieTimer->deleteLater(); + movieTimer = nullptr; + } + } + if(!is_gif){ + repaint(); + return; + } + QMovie *movie = new QMovie(currentPath); + movie->setScaledSize(QSize(this->width(), this->height())); + for (int i =0; i< movie->frameCount(); ++i) { + movie->jumpToFrame(i); + currentPixmap.append(movie->currentPixmap()); + if(i == 0) + delayTime = movie->nextFrameDelay(); + } + if(!movieTimer){ + movieTimer = new QTimer(this); + connect(movieTimer, &QTimer::timeout, this, [&]{ + if(currentCount == currentPixmap.count() - 1) + currentCount = 0; + else + currentCount += 1; + background = currentPixmap.at(currentCount); + repaint(); + + }); + } + if(delayTime < 50) + movieTimer->start(50); + else + movieTimer->start(delayTime); + +} + +QPixmap Screensaver::getPaddingPixmap() +{ + if (background.width() == 0 || background.height() == 0) + { + return QPixmap(); + } + + bool useHeight; + float scaled = 0.0; + QPixmap scaledPixmap; + QPixmap paddingPixmap; + qint64 rw = qint64(this->height()) * qint64(background.width()) / qint64(background.height()); + + useHeight = (rw >= this->width()); + if (useHeight) { + scaled = float(this->height()) / float(background.height()); + scaledPixmap = background.scaled(background.width() * scaled, this->height()); + paddingPixmap = scaledPixmap.copy((background.width() * scaled - this->width()) / 2 , 0, this->width(), this->height()); + } else { + scaled = float(this->width()) / float(background.width()); + scaledPixmap = background.scaled(this->width(), background.height() * scaled); + paddingPixmap = scaledPixmap.copy(0 , (background.height() * scaled - this->height()) / 2,this->width(), this->height()); + } + + return paddingPixmap; +} + +void Screensaver::addClickedEvent(){ + respondClick = true; +} + +void Screensaver::resizeEvent(QResizeEvent */*event*/) +{ + float scale = 1.0; + scale = (float)width()/1920; + if(width() < 600 || height()<400){//当显示在控制面板上时,字体缩小三倍。 + if(flag == 0) + { + QList labelList = this->findChildren(); + for(int i = 0;ifont().pixelSize(); +#ifdef USE_INTEL + const QString SheetStyle = QString("font-size:%1px;").arg(fontsize/3); +#else + const QString SheetStyle = QString("font-size:%1px;").arg(fontsize/4); +#endif + labelList.at(i)->setStyleSheet(SheetStyle); + } + QList childList = timeLayout->findChildren(); + for (int i = 0; i < childList.count(); ++i) { + childList.at(i)->adjustSize(); + } + timeLayout->adjustSize(); + if(centerWidget) + centerWidget->adjustSize(); + } + flag = 1; +#ifndef USE_INTEL + if(myTextWidget){ + +// QColor highLightColor = palette().color(QPalette::Base); +// QString stringColor = QString("rgba(%1,%2,%3,82%)") +// .arg(highLightColor.red()) +// .arg(highLightColor.green()) +// .arg(highLightColor.blue()); +// QColor textColor = palette().color(QPalette::Text); +// QString textString = QString("rgb(%1,%2,%3)") +// .arg(textColor.red()) +// .arg(textColor.green()) +// .arg(textColor.blue()); +// QColor borderColor = palette().color(QPalette::BrightText); +// QString borderString = QString("rgba(%1,%2,%3,85%)") +// .arg(borderColor.red()) +// .arg(borderColor.green()) +// .arg(borderColor.blue()); + +// myTextLabel->setStyleSheet(QString("font-size:5px;border-radius: 2px;background: %1;color: %2;padding: 4px 8px 4px 8px;border-width: 1px;border-style: solid;border-color:%3;") \ +// .arg(stringColor).arg(textString).arg(borderString)); + if(curStyle == "ukui-dark" || curStyle == "ukui-black"){ + myTextLabel->setStyleSheet(QString("QLabel{font-size:5px;border-radius: 2px;padding: 4px 8px 4px 8px;border-width: 1px;\ + background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:16px}").arg(blur_Num * 0.01)); + cycleLabel->setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:8px}").arg(blur_Num * 0.01)); + } else{ + myTextLabel->setStyleSheet(QString("QLabel{font-size:5px;border-radius: 2px;padding: 4px 8px 4px 8px;border-width: 1px;\ + background: rgba(255, 255, 255, %1);}").arg(blur_Num * 0.01)); + cycleLabel->setStyleSheet(QString("QLabel{background: rgba(255, 255, 255, %1); border-radius:8px}").arg(blur_Num * 0.01)); + } + cycleLabel->setFixedSize(5, 5); + } + if(screenLabel) + screenLabel->adjustSize(); + if(sleepTime) + sleepTime->setSmallMode(); +#endif + scale = 0.1; + } + +#ifdef USE_INTEL + int x = 840*scale; + int y = 96*scale; + + m_weatherLaout->setGeometry((this->width()-m_weatherLaout->width())/2, y, m_weatherLaout->geometry().width(), m_weatherLaout->geometry().height()); + + timeLayout->setGeometry((this->width()-timeLayout->width())/2,m_weatherLaout->geometry().bottom()+33, + timeLayout->geometry().width(),timeLayout->geometry().height()); + + if(centerWidget){ + centerWidget->adjustSize(); + centerWidget->setGeometry((width()-centerWidget->width())/2,(height() * 85) / 100 - (centerWidget->height())/2, + centerWidget->width(),centerWidget->height()); + + if((height()-centerWidget->height())/2 < timeLayout->y() + timeLayout->height()) + centerWidget->setGeometry((width()-centerWidget->width())/2,timeLayout->y() + timeLayout->height(), + centerWidget->width(),centerWidget->height()); + } + + if (m_widgetNotice) + { + m_widgetNotice->setGeometry((this->width()-m_widgetNotice->width())/2, (centerWidget->y() + centerWidget->height() + 20), + m_widgetNotice->geometry().width(), m_widgetNotice->geometry().height()); + } +#else + int x = (this->width()-timeLayout->geometry().width())/2; + int y = 59*scale; + + timeLayout->setGeometry(x,y,timeLayout->geometry().width(),timeLayout->geometry().height()); + + if(sleepTime){ + x = 26*scale; + y = this->height() - sleepTime->geometry().height() - 26*scale; + sleepTime->setGeometry(x,y,sleepTime->geometry().width(),sleepTime->geometry().height()); + } + + if(screenLabel){ + screenLabel->setGeometry((width() - screenLabel->width())/2,y,screenLabel->width(),screenLabel->height()); + } + + if(centerWidget){ + centerWidget->adjustSize(); + centerWidget->setGeometry((width()-centerWidget->width())/2,(height()-centerWidget->height())/2, + centerWidget->width(),centerWidget->height()); + + if((height()-centerWidget->height())/2 < timeLayout->y() + timeLayout->height()) + centerWidget->setGeometry((width()-centerWidget->width())/2,timeLayout->y() + timeLayout->height(), + centerWidget->width(),centerWidget->height()); + } + + if(myTextWidget) + setRandomPos(); +#endif +} + +void Screensaver::setRandomPos() +{ + myTextWidget->adjustSize(); + int x1 = 10; + int x2 = width() - 10 - myTextWidget->width(); + int y1 = timeLayout->geometry().bottom() + 10; + int y2; + if(sleepTime) + y2 = sleepTime->geometry().top() - myTextWidget->height() - 10; + else + y2 = geometry().bottom() - myTextWidget->height() - 10; + + int x = 0; + int y = 0; + if(x2 > x1) + x = qrand()%(x2 - x1) + x1; + if(y2 > y1) + y = qrand()%(y2 - y1) + y1; + + myTextWidget->move(x,y); + +} + +void Screensaver::setUpdateCenterWidget() +{ + //QString lang = qgetenv("LANG"); + QString lang = QLocale::system().name(); + QString homePath=qgetenv("HOME"); + QString cwdPath="/usr/share/ukui-screensaver/"; + QString languageDirPath=cwdPath+"language/"; + QString defaultLanguageFilePath=languageDirPath+"screensaver-en_US.ini"; + qDebug()<<"homePath="< formats = QImageReader::supportedImageFormats(); + if(fileInfo.isDir()) { + QDir dir(backgroundPath); + QStringList files = dir.entryList(QDir::Files | QDir::Readable); + for(QString file : files) { + fileInfo.setFile(file); + QString suffix = fileInfo.suffix(); + if(formats.contains(suffix.toUtf8()) && file.right(4) != ".ico" && file.right(4) != ".tga"){ + // qDebug() << "file:" <=imagePaths.count() - 1 || currentIndex<0){ + currentIndex = 0; + }else{ + currentIndex ++; + } + background = QPixmap(imagePaths.at(currentIndex)); + currentPath = imagePaths.at(currentIndex); + is_gif = currentPath.endsWith(".gif"); + } + isMovie(); + }); + } + + switchTimer->start(cycleTime * 1000); + + isMovie(); + } +} + +void Screensaver::stopSwitchImages() +{ + if(switchTimer && switchTimer->isActive()) + switchTimer->stop(); +} + +void Screensaver::onBackgroundChanged() +{ + opacity = 1.0; + fadeTimer = new QTimer(this); + connect(fadeTimer, &QTimer::timeout, this, [&]{ + opacity -= 0.1; + if(opacity <= 0) + fadeTimer->stop(); + else + repaint(); + + }); + fadeTimer->start(50); +} +void Screensaver::updateCenterWidget(int index) +{ + if(!centerWidget ) + return ; + + QStringList qlist = qsettings->childGroups(); + if(qlist.count()<1) + return; + + if(index<=1){ + index = qrand() % qlist.count() + 1; + } + qsettings->beginGroup(QString::number(index)); + if(qsettings->contains("OL")){ + centerlabel1->setText(qsettings->value("OL").toString()); + centerlabel2->hide(); +#ifndef USE_INTEL + authorlabel->setText(qsettings->value("author").toString()); +#endif + } + else if(qsettings->contains("FL")) + { + centerlabel1->setText(qsettings->value("FL").toString()); + centerlabel2->setText(qsettings->value("SL").toString()); + centerlabel2->show(); +#ifndef USE_INTEL + authorlabel->setText(qsettings->value("author").toString()); +#endif + } + +#ifdef USE_INTEL + if(qsettings->contains("author") && !qsettings->value("author").toString().isEmpty()) + { + authorlabel->setText(qsettings->value("author").toString()); + authorlabel->show(); + } + else + { + authorlabel->setText(""); + authorlabel->hide(); + } +#endif + + centerWidget->adjustSize(); + +#ifdef USE_INTEL + centerWidget->setGeometry((width()-centerWidget->width())/2,(height() * 85) / 100 - (centerWidget->height())/2, + centerWidget->width(),centerWidget->height()); + + if((height()-centerWidget->height())/2 < timeLayout->y() + timeLayout->height()) + centerWidget->setGeometry((width()-centerWidget->width())/2,timeLayout->y() + timeLayout->height(), + centerWidget->width(),centerWidget->height()); + +#else + centerWidget->setGeometry((width()-centerWidget->width())/2,(height()-centerWidget->height())/2, + centerWidget->width(),centerWidget->height()); + + if((height()-centerWidget->height())/2 < timeLayout->y() + timeLayout->height()) + centerWidget->setGeometry((width()-centerWidget->width())/2,timeLayout->y() + timeLayout->height(), + centerWidget->width(),centerWidget->height()); +#endif + qsettings->endGroup(); + +} + +void Screensaver::initUI() +{ + QFile qssFile; + +#ifdef USE_INTEL + qssFile.setFileName(":/qss/assets/default-intel.qss"); +#else + qssFile.setFileName(":/qss/assets/default.qss"); +#endif + + if(qssFile.open(QIODevice::ReadOnly)) { + setStyleSheet(qssFile.readAll()); + } + qssFile.close(); + +#ifdef USE_INTEL + setWeatherLayout(); + setDatelayout(); + setCenterWidget(); + setNoticeLaout(); + m_weatherManager->getWeather(); + connect(m_weatherManager, &WeatherManager::onWeatherUpdate, + this, &Screensaver::getWeatherFinish); +#else + if(isCustom) + setSleeptime(isCShowRestTime); + else + setSleeptime(isUShowRestTime); + setDatelayout(); + setCenterWidget(); + setRandomText(); + if(textIsCenter || myText == ""){ + myTextWidget->hide(); + centerWidget->show(); + }else{ + centerWidget->hide(); + myTextWidget->show(); + } +#endif +} + +void Screensaver::setDatelayout() +{ + timeType = configuration->getTimeType(); + dateType = configuration->getDateType(); +#ifdef USE_INTEL + timeLayout = new QWidget(this); + timeLayout->setFixedSize(((timeType == 12) ? 397:326), 117); + + QHBoxLayout *htimeLayout = new QHBoxLayout(timeLayout); + htimeLayout->setContentsMargins(0,0,0,0); + + QWidget *timeWidget = new QWidget(this); + timeWidget->setFixedSize(235, 117); + QGridLayout *gtimeLayout = new QGridLayout(timeWidget); + gtimeLayout->setContentsMargins(0,0,0,12); + + this->dateOfLocaltimeHour = new QLabel(this); + this->dateOfLocaltimeHour->setObjectName("dateOfLocaltime"); + this->dateOfLocaltimeHour->setAlignment(Qt::AlignTop | Qt::AlignLeft); + this->dateOfLocaltimeHour->setFixedSize(107, 96); + + this->dateofLocaltimeColon = new QLabel(this); + this->dateofLocaltimeColon->setObjectName("dateOfLocaltime"); + this->dateofLocaltimeColon->setAlignment(Qt::AlignCenter); + this->dateofLocaltimeColon->setFixedSize(21, 96); + this->dateofLocaltimeColon->setText(":"); + + this->dateOfLocaltimeMinute = new QLabel(this); + this->dateOfLocaltimeMinute->setObjectName("dateOfLocaltime"); + this->dateOfLocaltimeMinute->setAlignment(Qt::AlignTop | Qt::AlignLeft); + this->dateOfLocaltimeMinute->setFixedSize(107, 96); + + gtimeLayout->setSpacing(0); + gtimeLayout->setRowMinimumHeight(0, 9); + gtimeLayout->setRowMinimumHeight(1, 87); + gtimeLayout->setRowMinimumHeight(2, 9); + + gtimeLayout->setColumnMinimumWidth(0, 107); + gtimeLayout->setColumnMinimumWidth(1, 21); + gtimeLayout->setColumnMinimumWidth(2, 107); + + gtimeLayout->addWidget(dateOfLocaltimeHour, 1, 0, 2, 1); + gtimeLayout->addWidget(dateofLocaltimeColon, 0, 1, 2, 1); + gtimeLayout->addWidget(dateOfLocaltimeMinute, 1, 2, 2, 1); + + QWidget *dateWidget = new QWidget(this); + dateWidget->setFixedSize(((timeType == 12) ? 154:83), 117); + QVBoxLayout *vDateLaout = new QVBoxLayout(dateWidget); + vDateLaout->setAlignment(Qt::AlignTop | Qt::AlignLeft); + vDateLaout->setContentsMargins(0,18,0,12); + + this->dateOfWeek = new QLabel(this); + this->dateOfWeek->setObjectName("dateOfWeek"); + this->dateOfWeek->setAlignment(Qt::AlignTop | Qt::AlignLeft); + this->dateOfWeek->setFixedWidth(83); + + this->dateOfDay = new QLabel(this); + this->dateOfDay->setObjectName("dateOfDay"); + this->dateOfDay->setAlignment(Qt::AlignTop | Qt::AlignLeft); + this->dateOfDay->setFixedSize(((timeType == 12) ? 154:83),32); + updateTime(); + updateDate(); + + this->dateOfWeek->adjustSize(); + vDateLaout->addWidget(dateOfWeek); + vDateLaout->setSpacing(4); + vDateLaout->addWidget(dateOfDay); + + htimeLayout->addWidget(timeWidget); + htimeLayout->addSpacing(8); + htimeLayout->addWidget(dateWidget); + #else + timeLayout = new QWidget(this); + QVBoxLayout *vtimeLayout = new QVBoxLayout(timeLayout); + + this->dateOfLocaltime = new QLabel(this); + if(timeType == 12) + this->dateOfLocaltime->setText(QDateTime::currentDateTime().toString("A hh:mm")); + else + this->dateOfLocaltime->setText(QDateTime::currentDateTime().toString("hh:mm")); + + this->dateOfLocaltime->setObjectName("dateOfLocaltime"); + this->dateOfLocaltime->setAlignment(Qt::AlignCenter); + this->dateOfLocaltime->adjustSize(); + vtimeLayout->addWidget(dateOfLocaltime); + + this->dateOfDay = new QLabel(this); + if(dateType == "cn") + this->dateOfDay->setText(QDate::currentDate().toString("yyyy/MM/dd ddd")); + else + this->dateOfDay->setText(QDate::currentDate().toString("yyyy-MM-dd ddd")); + this->dateOfDay->setObjectName("dateOfDay"); + this->dateOfDay->setAlignment(Qt::AlignCenter); + this->dateOfDay->adjustSize(); + + vtimeLayout->addWidget(this->dateOfDay); + timeLayout->adjustSize(); + updateDate(); +#endif + +} + +void Screensaver::setWeatherLayout() +{ + m_weatherLaout = new QWidget(this); + QHBoxLayout *hWeatherLayout = new QHBoxLayout(m_weatherLaout); + hWeatherLayout->setContentsMargins(0, 0, 0, 0); + + this->m_weatherIcon = new QLabel(this); + this->m_weatherArea = new QLabel(this); + this->m_weatherCond = new QLabel(this); + this->m_weatherTemperature = new QLabel(this); + + m_weatherIcon->setPixmap(m_weatherManager->getWeatherIcon()); + m_weatherArea->setText(m_weatherManager->getCityName()); + if (!m_weatherManager->getCond().isEmpty()) + m_weatherCond->setText("·" + m_weatherManager->getCond()); + m_weatherTemperature->setText(m_weatherManager->getTemperature()); + + m_weatherArea->setStyleSheet("font-size:26px;color:#ffffff"); + m_weatherCond->setStyleSheet("font-size:26px;color:#ffffff"); + m_weatherTemperature->setStyleSheet("font-size:26px;color:#ffffff"); + + hWeatherLayout->addWidget(m_weatherIcon); + hWeatherLayout->addSpacing(8); + hWeatherLayout->addWidget(m_weatherArea); + hWeatherLayout->addWidget(m_weatherCond); + hWeatherLayout->addSpacing(8); + hWeatherLayout->addWidget(m_weatherTemperature); + m_weatherLaout->adjustSize(); +} + +void Screensaver::setSleeptime(bool Isshow) +{ + if(!sleepTime) + sleepTime = new SleepTime(this); + + sleepTime->adjustSize(); + if(Isshow){ + sleepTime->show(); + } + else{ + sleepTime->hide(); + if(timer){ + timer->stop(); + } + } +} + +void Screensaver::updateDate() +{ + if(!timer){ + timer = new QTimer(this); + timer->setTimerType(Qt::PreciseTimer); + connect(timer, SIGNAL(timeout()), this, SLOT(updateTime())); + } + timer->start(800); + updateTime(); +} + +void Screensaver::updateTime() +{ +#ifdef USE_INTEL + QLocale locale(QLocale::system().name()); + + QTimeZone timeZone(QString::fromLatin1(QTimeZone::systemTimeZoneId()).toLatin1()); + QDateTime tzNow = QDateTime::currentDateTime().toTimeZone(timeZone); + + QString time; + + if (timeType == 12) + { + time = tzNow.toString("hh:mm AP").split(" ").at(0); + this->dateOfWeek->setText(tzNow.toString("AP")); + if(dateType == "en") + { + this->dateOfDay->setText(tzNow.toString("ddd MM-dd")); + } else { + this->dateOfDay->setText(tzNow.toString("ddd MM/dd")); + } + } else { + time = tzNow.toString("hh:mm"); + this->dateOfWeek->setText(tzNow.toString("ddd")); + if(dateType == "en") + { + this->dateOfDay->setText(tzNow.toString("MM-dd")); + } else { + this->dateOfDay->setText(tzNow.toString("MM/dd")); + } + } + + this->dateOfLocaltimeHour->setText(time.split(":").at(0)); + this->dateOfLocaltimeMinute->setText(time.split(":").at(1)); + + m_currentTime = QTime::currentTime(); +#else + if(timeType == 12) + this->dateOfLocaltime->setText(QDateTime::currentDateTime().toString("A hh:mm")); + else + this->dateOfLocaltime->setText(QDateTime::currentDateTime().toString("hh:mm")); + + if(dateType == "cn") + this->dateOfDay->setText(QDate::currentDate().toString("yyyy/MM/dd ddd")); + else + this->dateOfDay->setText(QDate::currentDate().toString("yyyy-MM-dd ddd")); + + if(sleepTime){ + if(!sleepTime->setTime(QDateTime::currentDateTime())){ + sleepTime->hide(); + delete sleepTime; + sleepTime=NULL; + } + } +#endif +} + +void Screensaver::setUpdateBackground() +{ + +} + +void Screensaver::updateBackground() +{ + QString path = m_background->getRand(); + if(!path.isEmpty() && ispicture(path)){ + background = QPixmap(path); + hasChanged=true; + isMovie(); + } + // updateCenterWidget(-1); +} + +void Screensaver::setRandomText() +{ + if(!myTextWidget){ + myTextWidget = new QWidget(this); + QHBoxLayout *layout = new QHBoxLayout(myTextWidget); + cycleLabel = new QLabel(this); + cycleLabel->setFixedSize(16,16); + layout->addWidget(cycleLabel); + layout->setSpacing(16); + myTextLabel = new QLabel(myTextWidget); + myTextLabel->setObjectName("myText"); +// myTextLabel->setBackgroundRole(QPalette::Base); +// myTextLabel->setAutoFillBackground(true); +// myTextLabel->setMaximumWidth(800); +// QColor highLightColor = palette().color(QPalette::Base); +// QString stringColor = QString("rgba(%1,%2,%3,82%)") +// .arg(highLightColor.red()) +// .arg(highLightColor.green()) +// .arg(highLightColor.blue()); +// QColor textColor = palette().color(QPalette::Text); +// QString textString = QString("rgb(%1,%2,%3)") +// .arg(textColor.red()) +// .arg(textColor.green()) +// .arg(textColor.blue()); +// QColor borderColor = palette().color(QPalette::BrightText); +// QString borderString = QString("rgba(%1,%2,%3,85%)") +// .arg(borderColor.red()) +// .arg(borderColor.green()) +// .arg(borderColor.blue()); +// myTextLabel->setStyleSheet(QString("font-size:18px;border-radius: 6px;background: %1;color: %2;padding: 24px 48px 24px 48px;border-width: 1px;border-style: solid;border-color:%3;") \ +// .arg(stringColor).arg(textString).arg(borderString)); + blur_Num = configuration->getBlurNumber(); + curStyle = configuration->getcurStyle(); + qDebug()<<"cu人Style= "<setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:16px}").arg(blur_Num * 0.01)); + cycleLabel->setStyleSheet(QString("QLabel{background: rgba(0, 0, 0, %1); color:#FFFFFF; border-radius:8px}").arg(blur_Num * 0.01)); + } else{ + myTextLabel->setStyleSheet(QString("QLabel{background: rgba(255, 255, 255, %1); border-radius:16px}").arg(blur_Num * 0.01)); + cycleLabel->setStyleSheet(QString("QLabel{background: rgba(255, 255, 255, %1); border-radius:8px}").arg(blur_Num * 0.01)); + } + layout->addWidget(myTextLabel); + } + + myTextLabel->setText(myText); + myTextWidget->adjustSize(); + if(myText != "") + myTextWidget->setVisible(true); + else + myTextWidget->setVisible(false); +} + +void Screensaver::setPreviewText(bool bVisible) +{ + if(!myPreviewLabel){ + myPreviewLabel = new QLabel(this); + myPreviewLabel->setFixedSize(58,30); + + //设置样式 + myPreviewLabel->setStyleSheet("background-color: rgb(38,38,38); border-radius: 0px; color:white;"); + + //先采取固定大小方式 + myPreviewLabel->move(120,142); + myPreviewLabel->setAlignment(Qt::AlignCenter); + } + + myPreviewLabel->setText(tr("View")); + myPreviewLabel->adjustSize(); + + myPreviewLabel->setVisible(bVisible); + +} + +void Screensaver::setCenterWidget() +{ + QStringList qlist = qsettings->childGroups(); + if(qlist.count()<1) + return; + + QDate date = QDate::currentDate(); + int days = date.daysTo(QDate(2100,1,1)); + int index = days%qlist.count()+1; + + QString configPath = QDir::homePath() + "/.ukui-screensaver-default.conf"; + QSettings settings1(configPath, QSettings::IniFormat); + if(settings1.value("FIRST").toString().isEmpty()){ + settings1.setValue("FIRST",QDate::currentDate().toString("yy/MM/dd")); + index = 1; + } + if(settings1.value("FIRST").toString() == QDate::currentDate().toString("yy/MM/dd")) + index = 1; + + qsettings->beginGroup(QString::number(index)); + if(isCustom){ + centerlabel1 = new QLabel(myText); + centerlabel2 = new QLabel(""); + centerlabel2->hide(); + authorlabel = new QLabel(""); + } + else if(qsettings->contains("OL")){ + centerlabel1 = new QLabel(qsettings->value("OL").toString()); + centerlabel2 = new QLabel(""); + centerlabel2->hide(); +#ifndef USE_INTEL + authorlabel = new QLabel(qsettings->value("author").toString()); +#endif + } + else if(qsettings->contains("FL")) + { + centerlabel1 = new QLabel(qsettings->value("FL").toString()); + centerlabel2 = new QLabel(qsettings->value("SL").toString()); + centerlabel2->show(); +#ifndef USE_INTEL + authorlabel = new QLabel(qsettings->value("author").toString()); +#endif + } + +#ifdef USE_INTEL + if(qsettings->contains("author") && !qsettings->value("author").toString().isEmpty()) + { + authorlabel = new QLabel(qsettings->value("author").toString()); + authorlabel->show(); + } + else + { + authorlabel = new QLabel(""); + authorlabel->hide(); + } +#endif + + centerlabel1->setObjectName("centerLabel"); + centerlabel2->setObjectName("centerLabel"); + authorlabel->setObjectName("authorLabel"); + + qsettings->endGroup(); + +#ifdef USE_INTEL + //设置背景透明,qss中更改为透明不生效 + centerlabel1->setStyleSheet("QLabel{background-color: transparent;}"); + centerlabel2->setStyleSheet("QLabel{background-color: transparent;}"); + authorlabel->setStyleSheet("QLabel{background-color: transparent;}"); + + centerWidget = new QWidget(this); + centerWidget->setStyleSheet("QWidget{background:rgb(0,0,0,64);border-radius:16px}"); + QVBoxLayout *layout = new QVBoxLayout(centerWidget); + +// QPushButton *line =new QPushButton(this); +// line->setWindowOpacity(0.08); +// line->setFocusPolicy(Qt::NoFocus); +// line->setMaximumHeight(1); + + layout->addWidget(centerlabel1); + layout->addWidget(centerlabel2); +// layout->addWidget(line); + layout->addWidget(authorlabel); + + + adjustSize(); + centerWidget->setVisible(true); +#else + centerWidget = new QWidget(this); + QVBoxLayout *layout = new QVBoxLayout(centerWidget); + layout->addWidget(centerlabel1); + layout->addWidget(centerlabel2); + + if(!isCustom){ + QPushButton *line =new QPushButton(this); + line->setWindowOpacity(0.08); + line->setFocusPolicy(Qt::NoFocus); + line->setMaximumHeight(1); + layout->addWidget(line); + } + + layout->addWidget(authorlabel); + + centerWidget->adjustSize(); + centerWidget->setGeometry((width()-centerWidget->width())/2,(height()-centerWidget->height())/2, + centerWidget->width(),centerWidget->height()); + centerWidget->setVisible(true); +#endif +} + +void Screensaver::getWeatherFinish(QString city, QString cond, QString tmp) +{ + qDebug() << "getWeatherFinish"; + qDebug() << city << "," << cond << "," << tmp; + + this->m_weatherIcon->setPixmap(m_weatherManager->getWeatherIcon(cond)); + this->m_weatherArea->setText(city); + + if(!cond.isEmpty()) + { + this->m_weatherCond->show(); + this->m_weatherCond->setText("·" + cond); + } + else + this->m_weatherCond->hide(); + + if(!tmp.isEmpty()) + { + this->m_weatherTemperature->show(); + this->m_weatherTemperature->setText(tmp); + } + else + this->m_weatherTemperature->hide(); + + m_weatherLaout->adjustSize(); + m_weatherLaout->setGeometry((this->width()-m_weatherLaout->width())/2,96 * (float)width()/1920, + m_weatherLaout->geometry().width(), m_weatherLaout->geometry().height()); +} + +void Screensaver::setNoticeLaout() +{ + m_widgetNotice = new QWidget(this); + QHBoxLayout *hNoticeLayout = new QHBoxLayout(m_widgetNotice); + hNoticeLayout->setContentsMargins(0, 0, 0, 0); + m_labelNoticeIcon = new QLabel(this); + m_labelNoticeMessage = new QLabel(this); + m_labelNoticeMessage->setStyleSheet("font-size:16px;color:#ffffff"); + + m_labelNoticeIcon->setPixmap(QPixmap(":/assets/message.png")); + + m_labelNoticeMessage->setText(tr("You have new notification")); + + int num = configuration->getMessageNumber(); + (configuration->getMessageShowEnable() && num > 0)? showNotice() : hideNotice(); + + hNoticeLayout->addWidget(m_labelNoticeIcon); + hNoticeLayout->addWidget(m_labelNoticeMessage); + m_widgetNotice->adjustSize(); +} + +//显示新消息通知 +void Screensaver::showNotice() +{ + m_widgetNotice->show(); +} + +void Screensaver::hideNotice() +{ + m_widgetNotice->hide(); +} +/* +void Screensaver::setDesktopBackground() +{ + vboxFrame->hide(); + QString mBackground; + + if(!hasChanged){ + mBackground=defaultBackground; + }else{ + if(m_background->getCurrent().isEmpty()) + return; + mBackground=m_background->getCurrent(); + } + + settings->set("picture-filename",QVariant(mBackground)); + + QDBusInterface * interface = new QDBusInterface("org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + "org.freedesktop.Accounts", + QDBusConnection::systemBus()); + + if (!interface->isValid()){ + return; + } + + QDBusReply reply = interface->call("FindUserByName", getenv("USER")); + QString userPath; + if (reply.isValid()){ + userPath = reply.value().path(); + } + else { + return; + } + + QDBusInterface * useriFace = new QDBusInterface("org.freedesktop.Accounts", + userPath, + "org.freedesktop.Accounts.User", + QDBusConnection::systemBus()); + + if (!useriFace->isValid()){ + return; + } + + QDBusMessage msg = useriFace->call("SetBackgroundFile", mBackground); + if (!msg.errorMessage().isEmpty()) + qDebug() << "update user background file error: " << msg.errorMessage(); + +}*/ diff --git a/screensaver/screensaver.h b/screensaver/screensaver.h new file mode 100644 index 0000000..cca782b --- /dev/null +++ b/screensaver/screensaver.h @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#ifndef SCREENSAVER_H +#define SCREENSAVER_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sleeptime.h" +#include "chinesedate.h" +#include "mbackground.h" +#include "checkbutton.h" +#include "scconfiguration.h" +#include "cyclelabel.h" +#include "weathermanager.h" + +class Screensaver : public QWidget +{ + Q_OBJECT + +public: + explicit Screensaver(QWidget *parent = 0); + ~Screensaver(); + void addClickedEvent(); + +private: + void initUI(); + void setDatelayout(); + void setWeatherLayout(); + void setNoticeLaout(); + void setSleeptime(bool Isshow); + void setCenterWidget(); + void updateDate(); + void setUpdateBackground(); + void setUpdateCenterWidget(); + void startSwitchImages(); + void stopSwitchImages(); + void onBackgroundChanged(); + void setRandomText(); + void setPreviewText(bool bVisible);//设置预览样式 + void setRandomPos(); + void connectSingles(); + void updateBackgroundPath(); + void enterEvent(QEvent*); + void leaveEvent(QEvent*); + void isMovie(); + + QTimer *switchTimer; + QTimer *fadeTimer; + QStringList imagePaths; + QString backgroundPath; + int cycleTime; + float opacity; + bool isCustom; + bool isCShowRestTime; + bool isUShowRestTime; + bool textIsCenter; + QString myText; + QLabel *myTextLabel; + QLabel *myPreviewLabel; + QLabel *cycleLabel; + + SCConfiguration *configuration; + void showNotice(); + void hideNotice(); + + QWidget *myTextWidget; + QLabel *dateOfLocaltime; + + QLabel *dateOfWeek; + QLabel *dateOfLocaltimeHour; + QLabel *dateofLocaltimeColon; + QLabel *dateOfLocaltimeMinute; + QLabel *dateOfDay; + QLabel *dateOfLunar; + QWidget *centerWidget; + + QWidget *timeLayout; + SleepTime *sleepTime; + QTimer *timer; + + QPixmap background; + + QPushButton *settingsButton; + QPushButton *WallpaperButton; + QWidget *buttonWidget; + QSettings *qsettings; + + MBackground *m_background; + + QLabel *centerlabel1; + QLabel *centerlabel2; + QLabel *authorlabel; + + checkButton *checkSwitch; + QLabel *autoSwitchLabel; + QFrame *autoSwitch; + + QFrame *vboxFrame; + bool isAutoSwitch; + + int flag; + bool hasChanged; + int timeType; + QString dateType; + QProcess *process; + QLabel *screenLabel; + bool respondClick; + static QTime m_currentTime; + int blur_Num; + QString curStyle; + + WeatherManager *m_weatherManager; + QWidget *m_weatherLaout; + QLabel *m_weatherIcon; + QLabel *m_weatherArea; + QLabel *m_weatherCond; + QLabel *m_weatherTemperature; + + QWidget *m_widgetNotice; + QLabel *m_labelNoticeIcon; + QLabel *m_labelNoticeMessage; + int currentIndex = 0; + + QString currentPath; + bool is_gif = false; + QList currentPixmap; + int delayTime; + QTimer *movieTimer = nullptr; + int currentCount = 0; + +protected: + void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *event); + bool eventFilter(QObject *obj, QEvent *event); + +private Q_SLOTS: + void updateTime(); + void updateBackground(); + void updateCenterWidget(int index); + void autoSwitchChanged(bool iswitch); + void backgroundPathChanged(QString path); + void cycleTimeChanged(int cTime); + void myTextChanged(QString text); + void showCRestTimeChanged(bool isShow); + void showURestTimeChanged(bool isShow); + void textIsCenterChanged(bool isCenter); + void themeChanged(); + void getWeatherFinish(QString city, QString cond, QString tmp); + void onMessageNumberChanged(int num); + void onMessageShowEnabledChanged(bool enabled); + void onTimeFormatChanged(int type); + void onDateFormatChanged(QString type); + void onBlurNumChanged(int num); + void onStyleChanged(QString style); + QPixmap getPaddingPixmap(); +}; + +#endif // MAINWINDOW_H diff --git a/screensaver/sleeptime.cpp b/screensaver/sleeptime.cpp new file mode 100644 index 0000000..9fd6650 --- /dev/null +++ b/screensaver/sleeptime.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#include "sleeptime.h" +#include +#include +#include + +SleepTime::SleepTime(QWidget *parent) : QWidget(parent), + sleepTime(0) +{ + init(); +} + +SleepTime::~SleepTime() +{ + +} + +void SleepTime::init() +{ + layout = new QHBoxLayout(this); + layout->setDirection(QBoxLayout::RightToLeft); + layout->setSpacing(4); + + for(int i=0;i<2;i++) + { + QLabel *label = new QLabel(this); + label->setText("0"); + label->setFixedSize(40,40); + label->setObjectName("clockTime"); + list.append(label); + } + + QLabel *colon = new QLabel(this); + colon->setText(":"); + colon->setObjectName("colon"); + list.append(colon); + + for(int i=0;i<2;i++) + { + QLabel *label = new QLabel(this); + label->setText("0"); + label->setFixedSize(40,40); + label->setObjectName("clockTime"); + list.append(label); + } + + for(int i=0;iaddWidget(list.at(i)); + } + + restTime = new QLabel(this); + restTime->setText(tr("You have rested:")); + restTime->setObjectName("restTime"); + restTime->setAlignment(Qt::AlignBottom); + restTime->adjustSize(); + + layout->addWidget(restTime); + + initTime = QDateTime::currentDateTime(); +} + +int SleepTime::setTime(QDateTime time) +{ + sleepTime = initTime.secsTo(time); + if(sleepTime>5999 || sleepTime<0){ + hide(); + return false; + } + + int sec = sleepTime % 60; + int min = sleepTime/60; + setSeconds(sec); + setMinute(min); + + return true; +} + +void SleepTime::setSeconds(int seconds) +{ + int sec1 = seconds%10; + int sec2 = seconds/10; + + list.at(0)->setText(QString::number(sec1)); + list.at(1)->setText(QString::number(sec2)); +} + +void SleepTime::setMinute(int minutes) +{ + + int min1 = minutes%10; + int min2 = minutes/10; + list.at(3)->setText(QString::number(min1)); + list.at(4)->setText(QString::number(min2)); +} + +void SleepTime::setSmallMode() +{ + for(int i = 0;i<5;i++) + list.at(i)->setFixedSize(8,8); + adjustSize(); +} diff --git a/screensaver/sleeptime.h b/screensaver/sleeptime.h new file mode 100644 index 0000000..bef0e32 --- /dev/null +++ b/screensaver/sleeptime.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#ifndef SLEEPTIME_H +#define SLEEPTIME_H + +#include +#include +#include +#include +#include +#include + +class SleepTime : public QWidget +{ + Q_OBJECT +public: + explicit SleepTime(QWidget *parent = nullptr); + ~SleepTime(); + int setTime(QDateTime time); + void setSmallMode(); + +private: + QLabel *restTime; + QList list; + QHBoxLayout *layout; + int sleepTime; + QDateTime initTime; + + void init(); + void setSeconds(int seconds); + void setMinute(int minutes); +}; + +#endif // SLEEPTIME_H diff --git a/screensaver/ukui-screensaver-default.pro b/screensaver/ukui-screensaver-default.pro new file mode 100644 index 0000000..5dd421d --- /dev/null +++ b/screensaver/ukui-screensaver-default.pro @@ -0,0 +1,49 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2020-01-10T17:10:24 +# +#------------------------------------------------- + +QT += core gui x11extras + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ukui-screensaver-default +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which as 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 + +LIBS += -lX11 + +SOURCES += \ + main.cpp \ + screensaver.cpp \ + sleeptime.cpp \ + chinesedate.cpp \ + mbackground.cpp \ + scconfiguration.cpp + +HEADERS += \ + screensaver.h \ + sleeptime.h \ + chinesedate.h \ + mbackground.h \ + scconfiguration.h + +TRANSLATIONS = ../i18n_ts/zh_CN.ts \ + ../i18n_ts/ru.ts \ + ../i18n_ts/fr.ts \ + ../i18n_ts/pt.ts \ + ../i18n_ts/es.ts + +RESOURCES = default.qrc + diff --git a/screensaver/weathermanager.cpp b/screensaver/weathermanager.cpp new file mode 100644 index 0000000..506b34c --- /dev/null +++ b/screensaver/weathermanager.cpp @@ -0,0 +1,375 @@ +/* + * 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 . + * + * Authors: ZHAI Kang-ning +**/ +#include "weathermanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const QString weatherServerAddr = "http://service.ubuntukylin.com:8001/weather/api/3.0/heweather_data_s6/"; +const QString defaultCityId = "101030100"; //"101030100" 默认天津 +const int weatherReqInterval = 1000 * 60 * 20; //定时更新天气,和麒麟天气保持一致 + +const QByteArray schemaWeather = "org.china-weather-data.settings"; + +static const QMap weatherMap { + {"晴", "100"},{"多云", "101"},{"少云", "102"},{"晴间多云", "103"},{"阴", "104"}, + {"有风", "200"},{"平静", "201"},{"微风", "202"},{"和风", "203"},{"清风", "204"},{"强风劲风", "205"},{"疾风", "206"},{"大风", "207"},{"烈风", "208"},{"风暴", "209"}, + {"狂暴风", "210"},{"飓风", "211"},{"龙卷风", "212"},{"热带风暴", "213"}, + {"阵雨", "300"},{"强阵雨", "301"},{"雷阵雨", "302"},{"强雷阵雨", "303"},{"雷阵雨伴有冰雹", "304"},{"小雨", "305"},{"中雨", "306"},{"大雨", "307"},{"极端降雨", "308"},{"毛毛雨细雨", "309"}, + {"暴雨", "310"},{"大暴雨", "311"},{"特大暴雨", "312"},{"冻雨", "313"},{"小到中雨", "314"},{"中到大雨", "315"},{"大到暴雨", "316"},{"暴雨到大暴雨", "317"},{"大暴雨到特大暴雨", "318"}, + {"雨", "399"}, + {"小雪", "400"},{"中雪", "401"},{"大雪", "402"},{"暴雪", "403"},{"雨夹雪", "404"},{"雨雪天气", "405"},{"阵雨夹雪", "406"},{"阵雪", "407"},{"小到中雪", "408"},{"中到大雪", "409"}, + {"大到暴雪", "410"},{"雪", "499"}, + {"薄雾", "500"},{"雾", "501"},{"霾", "502"},{"扬沙", "503"},{"浮尘", "504"},{"沙尘暴", "507"},{"强沙尘暴", "508"},{"大雾", "509"}, + {"强浓雾", "510"},{"中度霾", "511"},{"重度霾", "512"},{"严重霾", "513"},{"大雾", "514"},{"特强浓雾", "515"}, + {"热", "900"},{"冷", "901"}, + {"未知", "999"} +}; + +WeatherManager::WeatherManager(QObject *parent) : QObject(parent) +{ + //初始化m_net_manager请求天气 + m_net_manager = new QNetworkAccessManager(this); + QObject::connect(m_net_manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(replyFinished(QNetworkReply*))); + + m_timer = new QTimer(this); + m_timer->setInterval(weatherReqInterval); + + m_local_weather_info = new LocalWeatherInfo(this); + + connect(m_timer, &QTimer::timeout, this, &WeatherManager::weatherRequest); + + m_networkWatcher = new NetWorkWatcher(this); + connect(m_networkWatcher, &NetWorkWatcher::NetworkStateChanged, this, &WeatherManager::onNetworkStateChanged); + + m_networkWatcher->checkOnline(); +} + +void WeatherManager::onNetworkStateChanged(uint state) +{ + qDebug() << state; + if (NM_STATE_CONNECTED_GLOBAL != state) + emit onWeatherUpdate("天气不可用", NULL, NULL); + else + getWeather(); +} + +void WeatherManager::getWeather() +{ + weatherRequest(); + if (m_timer != NULL) + { + m_timer->start(); + } + return; +} + +void WeatherManager::weatherRequest() +{ + if (updateLocation()) + return; + QNetworkRequest request(QUrl(weatherServerAddr + m_city_id + "/")); + m_net_manager->get(request); +} + +bool WeatherManager::updateLocation() +{ + //更新城市信息 未实现 麒麟天气提供gsettings,完成后对接 + if (QGSettings::isSchemaInstalled(schemaWeather)) { + m_settings = new QGSettings(schemaWeather,"",this); //org/ukui/indicator-china-weather path + if(getLogcalWeather()) + { + emit onWeatherUpdate(m_local_weather_info->getCityName(), + m_local_weather_info->getCondText(), + m_local_weather_info->getTemperature()); + + + m_networkWatcher->checkOnline(); + return true; + } + m_city_id = getLogcalCityId(); + } + + if (m_city_id.isEmpty()) + m_city_id = defaultCityId; + + return false; +} + +bool WeatherManager::getLogcalWeather() +{ + if (m_settings != nullptr) + { + //"1920-08-27 10:17:42,101310204,澄迈,小雨,95%,25℃,北风,1级," 时间,城市编码,城市名称,天气,湿度,温度,风向,风力 + QString weather = m_settings->get("weather").toString(); + QStringList weatherInfoList = weather.split(","); + if (weatherInfoList.size() < 9) + return false; + m_local_weather_info->setTime(weatherInfoList.at(0)); + if(!m_local_weather_info->isTimeValid()) + return false; + + m_local_weather_info->setCityId(weatherInfoList.at(1)); + m_local_weather_info->setCityName(weatherInfoList.at(2)); + m_local_weather_info->setCondText(weatherInfoList.at(3)); + m_local_weather_info->setAirHumidity(weatherInfoList.at(4)); + m_local_weather_info->setTemperature(weatherInfoList.at(5)); + m_local_weather_info->setWindDirection(weatherInfoList.at(6)); + m_local_weather_info->setWindForce(weatherInfoList.at(7)); + return true; + } + + return false; +} + +QString WeatherManager::getLogcalCityId() +{ + if (m_settings != nullptr) { + QString citys = m_settings->get("citylist").toString();//"101010100," + if (citys.isEmpty()) + return ""; + + QStringList cityList = citys.split(","); + if (cityList.size() >= 1) + { + QString s = cityList.at(0); + qDebug() << "local city id = " << s; + return s; + } + } + return ""; +} + +void WeatherManager::replyFinished(QNetworkReply *reply) +{ + if(reply != nullptr && reply->error() != QNetworkReply::NoError) + { + qWarning() << "[WeatherManager][replyFinished] get weather error:(" + << reply->error() << ")" << reply->errorString(); + if (m_networkTryNum < 15) + { + m_networkTryNum++; + QTimer::singleShot(1000, this, [=]{ + weatherRequest(); + }); + } else { + m_networkTryNum = 0; + } + emit onWeatherUpdate("天气不可用", "", ""); + return; + } + + //注:天气信息只解析了锁屏需要展示的部分 + QByteArray BA; + QJsonDocument JD; + QJsonParseError JPE; + + BA = reply->readAll(); + // QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + // QString all = codec->toUnicode(BA); + // qDebug() << "reply is:" << all; + + JD = QJsonDocument::fromJson(BA, &JPE); + if (JPE.error == QJsonParseError::NoError) + { + if (JD.isObject()) + { + QJsonObject kylinWeatherObj = JD.object().value("KylinWeather").toObject(); + + QString nowWeather = kylinWeatherObj.value("weather").toObject().value("now").toString(); + m_city_name = kylinWeatherObj.value("weather").toObject().value("location").toString(); + QStringList nowList = nowWeather.split(","); + for(QString now : nowList) + { + if(now.contains("cond_txt")) { + m_cond_txt = now.mid(9); + } + + if (now.contains("tmp")){ + m_temperature = now.mid(4) + "°C"; + } + } + emit onWeatherUpdate(m_city_name, m_cond_txt, m_temperature); + } + } else { + qWarning() << "get weather info error : " << JPE.errorString(); + emit onWeatherUpdate("天气不可用", "", ""); + } + + reply->deleteLater(); +} + +QPixmap WeatherManager::getWeatherIcon() +{ + return getWeatherIcon(m_cond_txt); +} + +QPixmap WeatherManager::getWeatherIcon(QString cond) +{ + if (cond.isEmpty()) + { + qWarning() << "cond info is unknown"; + return QPixmap(":/weather/assets/weather-icon/999.svg").scaled(32,32); + } + + //根据m_cond_txt + QString numStr = weatherMap.value(cond); + if (!numStr.isEmpty()) { + qDebug() << "----------------numStr=" + numStr; + return QPixmap(":/weather/assets/weather-icon/" + numStr +".svg").scaled(32,32); + } + + qWarning() << "天气为|" << cond << "|"; + return QPixmap(":/weather/assets/weather-icon/999.svg").scaled(32,32); +} + +QString WeatherManager::getCityName() +{ + return ""; +} + +QString WeatherManager::getCond() +{ + return ""; +} + +QString WeatherManager::getTemperature() +{ + return ""; +} + +LocalWeatherInfo::LocalWeatherInfo(QObject *parent) +{ +} + +bool LocalWeatherInfo::isTimeValid() +{ + if (m_update_time != nullptr && !m_update_time.isEmpty()) + { + QString strBuffer; + QDateTime time = QDateTime::fromString(m_update_time, "yyyy-MM-dd hh:mm:ss"); + QDateTime currentTime = QDateTime::currentDateTime(); + + if (!time.isValid()) + return false; + + uint timeInterval = currentTime.toTime_t() - time.toTime_t(); + + if((timeInterval <= 21 * 60) + && (timeInterval > 0)) + { + //麒麟天气更新时间为20分钟,加入1分钟容错机制 + return true; + } + } + return false; +} + +void LocalWeatherInfo::setTime(QString time) +{ + m_update_time = time; +} + +QString LocalWeatherInfo::getTime() +{ + return m_update_time; +} + +void LocalWeatherInfo::setCityId(QString cityId) +{ + m_city_id = cityId; +} + +QString LocalWeatherInfo::getCityId() +{ + return m_city_id; +} + +void LocalWeatherInfo::setCityName(QString cityName) +{ + m_city_name = cityName; +} + +QString LocalWeatherInfo::getCityName() +{ + return m_city_name; +} + +void LocalWeatherInfo::setCondText(QString condText) +{ + m_cond_text = condText; +} + +QString LocalWeatherInfo::getCondText() +{ + return m_cond_text; +} + +void LocalWeatherInfo::setAirHumidity(QString airHumidity) +{ + m_air_humidity = airHumidity; +} + +QString LocalWeatherInfo::getAirHumidity() +{ + return m_air_humidity; +} + +void LocalWeatherInfo::setTemperature(QString temperature) +{ + m_temperature = temperature; +} + +QString LocalWeatherInfo::getTemperature() +{ + return m_temperature; +} + +void LocalWeatherInfo::setWindDirection(QString windDirection) +{ + m_wind_direction = windDirection; +} + +QString LocalWeatherInfo::getWindDirection() +{ + return m_wind_direction; +} + +void LocalWeatherInfo::setWindForce(QString windForce) +{ + m_wind_force = windForce; +} + +QString LocalWeatherInfo::getWindForce() +{ + return m_wind_force; +} diff --git a/screensaver/weathermanager.h b/screensaver/weathermanager.h new file mode 100644 index 0000000..3f29c40 --- /dev/null +++ b/screensaver/weathermanager.h @@ -0,0 +1,122 @@ +/* + * 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 . + * + * Authors: ZHAI Kang-ning +**/ +#ifndef WEATHERMANAGER_H +#define WEATHERMANAGER_H + +#include +#include +#include +#include + +#include "../src/networkwatcher.h" + +class QNetworkAccessManager; +class QNetworkReply; +class LocalWeatherInfo; + +class WeatherManager : public QObject +{ + Q_OBJECT +public: + explicit WeatherManager(QObject *parent = nullptr); + +Q_SIGNALS: + void onWeatherUpdate(QString city, QString cond, QString temperature); + +private Q_SLOTS: + void replyFinished(QNetworkReply *); + void onNetworkStateChanged(uint state); + +public: + void getWeather(); + QPixmap getWeatherIcon(); + QPixmap getWeatherIcon(QString cond); + + QString getCityName(); + QString getCond(); + QString getTemperature(); + +private: + bool updateLocation();//更新位置,从用户设置获取城市信息,如有多个,只取第一个,未对接 + void weatherRequest(); + + bool getLogcalWeather(); + QString getLogcalCityId(); + +private: + QString m_city_id; // "101030100" 默认天津 + QString m_city_name; + QString m_cond_txt; //天气条件 晴、阴等 + QString m_temperature;//温度 10、20等 + + QNetworkAccessManager *m_net_manager; + QTimer *m_timer; + QGSettings *m_settings; + + LocalWeatherInfo *m_local_weather_info; + NetWorkWatcher *m_networkWatcher; + + int m_networkTryNum = 0; +}; + +class LocalWeatherInfo : QObject +{ + //"1920-08-27 10:17:42,101310204,澄迈,小雨,95%,25℃,北风,1级," 时间,城市编码,城市名称,天气,湿度,温度,风向,风力 + Q_OBJECT +public: + explicit LocalWeatherInfo(QObject *parent = nullptr); + +private: + QString m_update_time; + QString m_city_id; + QString m_city_name; + QString m_cond_text; + QString m_air_humidity; + QString m_temperature; + QString m_wind_direction; + QString m_wind_force; +public: + bool isTimeValid(); + + void setTime(QString time); + QString getTime(); + + void setCityId(QString cityId); + QString getCityId(); + + void setCityName(QString cityName); + QString getCityName(); + + void setCondText(QString condText); + QString getCondText(); + + void setAirHumidity(QString airHumidity); + QString getAirHumidity(); + + void setTemperature(QString temperature); + QString getTemperature(); + + void setWindDirection(QString windDirection); + QString getWindDirection(); + + void setWindForce(QString windForce); + QString getWindForce(); +}; + +#endif // WEATHERMANAGER_H diff --git a/set4kScale/CMakeLists.txt b/set4kScale/CMakeLists.txt new file mode 100644 index 0000000..09b8eef --- /dev/null +++ b/set4kScale/CMakeLists.txt @@ -0,0 +1,25 @@ +project(set4kScale) + +pkg_check_modules(X11 REQUIRED x11) +pkg_check_modules(XCB REQUIRED xcb) +pkg_check_modules(QGS REQUIRED gsettings-qt) + +include_directories( + ${X11_INCLUDE_DIRS} + ${XCB_INCLUDE_DIRS} + ${QGS_INCLUDE_DIRS} + ) + +set(CMAKE_AUTOMOC ON) + +set(bin_SRCS + ${bin_SRCS} + main.cpp + ) + +add_executable(set4kScale ${bin_SRCS}) +target_link_libraries(set4kScale Qt5::Core Qt5::Widgets Qt5::X11Extras ${X11_LIBRARIES} ${XCB_LIBRARIES} ${QGS_LIBRARIES}) + +install(TARGETS + set4kScale + DESTINATION lib/ukui-screensaver) diff --git a/set4kScale/main.cpp b/set4kScale/main.cpp new file mode 100644 index 0000000..5ec6932 --- /dev/null +++ b/set4kScale/main.cpp @@ -0,0 +1,208 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +extern "C" { +#include +#include +} + + +#define XSETTINGS_SCHEMA "org.ukui.SettingsDaemon.plugins.xsettings" +#define MOUSE_SCHEMA "org.ukui.peripherals-mouse" +#define SCALING_KEY "scaling-factor" +#define CURSOR_SIZE "cursor-size" +#define CURSOR_THEME "cursor-theme" + + +/* 过滤低分辨率高缩放比情况 */ +void screenScaleJudgement(QGSettings *settings) +{ + qreal scaling = qApp->devicePixelRatio(); + double scale; + scale = settings->get(SCALING_KEY).toDouble(); + if (scale > 1.25) { + bool state = false; + bool mScale = false; + + for (QScreen *screen : QGuiApplication::screens()) { + int width = screen->geometry().width() * scaling; + int height = screen->geometry().height() * scaling; + + if (width < 1920 && height < 1080) { + state = true; + } else if (width == 1920 && height == 1080 && scale > 1.5) { + state = true; + } else if (width > 2560 && height > 1440) { + mScale = true; + } + } + + if (state && !mScale) { + QGSettings *mGsettings = new QGSettings(MOUSE_SCHEMA); + mGsettings->set(CURSOR_SIZE, 24); + settings->set(SCALING_KEY, 1.0); + delete mGsettings; + } + } +} + +/* 设置DPI环境变量 */ +void setXresources(int dpi) +{ + Display *dpy; + QGSettings *mouse_settings = new QGSettings(MOUSE_SCHEMA); + QString str = QString("Xft.dpi:\t%1\nXcursor.size:\t%2\nXcursor.theme:\t%3\n") + .arg(dpi) + .arg(mouse_settings->get(CURSOR_SIZE).toInt()) + .arg(mouse_settings->get(CURSOR_THEME).toString()); + + dpy = XOpenDisplay(NULL); + XChangeProperty(dpy, RootWindow(dpy, 0), XA_RESOURCE_MANAGER, XA_STRING, 8, + PropModeReplace, (unsigned char *) str.toLatin1().data(), str.length()); + XCloseDisplay(dpy); + + qDebug() << "setXresources:" << str; + + delete mouse_settings; +} + +/* 判断文件是否存在 */ +bool isFileExist(QString XresourcesFile) +{ + QFileInfo fileInfo(XresourcesFile); + if (fileInfo.isFile()) { + qDebug() << "File exists"; + return true; + } + + qDebug() << "File does not exis"; + + return false; +} + +/* 编写判断标志文件,更改 鼠标/DPI 配置大小*/ +void writeXresourcesFile(QString XresourcesFile, QGSettings *settings, double scaling) +{ + QFile file(XresourcesFile); + QString content = QString("Xft.dpi:%1\nXcursor.size:%2").arg(96.0 * scaling).arg(24.0 * scaling); + QByteArray str = content.toLatin1().data(); + + file.open(QIODevice::ReadWrite | QIODevice::Text); + file.write(str); + file.close(); + + QGSettings *Font = new QGSettings("org.ukui.font-rendering"); + QGSettings *mouse_settings = new QGSettings(MOUSE_SCHEMA); + + Font->set("dpi", 96.0); + settings->set(SCALING_KEY, scaling); + mouse_settings->set(CURSOR_SIZE, scaling * 24.0); + + qDebug() << " writeXresourcesFile: content = " << content + << " scalings = " << settings->get(SCALING_KEY).toDouble() + << "cursor size = " << mouse_settings->get(CURSOR_SIZE).toInt(); + delete Font; + delete mouse_settings; +} + +/* 判断是否为首次登陆 */ + +bool isTheFirstLogin(QGSettings *settings) +{ + QString homePath = getenv("HOME"); + QString XresourcesFile = homePath+"/.config/xresources"; + QString Xresources = homePath+"/.Xresources"; + qreal scaling = qApp->devicePixelRatio(); + bool zoom1 = false, zoom2 = false, zoom3 = false; + double mScaling; + bool xres, Xres; + + Xres = isFileExist(Xresources); + xres = isFileExist(XresourcesFile); //判断标志文件是否存在 + + if (xres && !Xres) { + return false; + } else if (xres && Xres) { + QFile::remove(Xresources); + return false; + } else if (Xres && !xres) { + QFile::rename(Xresources, XresourcesFile); + return false; + } + + for (QScreen *screen : QGuiApplication::screens()) { + int width = screen->geometry().width() * scaling; + int height = screen->geometry().height() * scaling; + + if (width <= 1920 && height <= 1080) { + zoom1 = true; + } else if (width > 1920 && height > 1080 && width <= 2560 && height <=1500) { + zoom2 = true; + } else if (width > 2560 && height > 1440) { + zoom3 = true; + } + } + + if (zoom1) { + mScaling = 1.0; + } else if (!zoom1 && zoom2) { + mScaling = 1.5; + } else if (!zoom1 && !zoom2 && zoom3) { + mScaling = 2.0; + } + + writeXresourcesFile(XresourcesFile, settings, mScaling); + + return true; +} + + +/* 配置新装系统、新建用户第一次登陆时,4K缩放功能*/ +void setHightResolutionScreenZoom() +{ + QGSettings *settings; + double dpi; + int ScreenNum = QApplication::screens().length(); + if (!QGSettings::isSchemaInstalled(XSETTINGS_SCHEMA) || !QGSettings::isSchemaInstalled("org.ukui.font-rendering") || + !QGSettings::isSchemaInstalled(MOUSE_SCHEMA)) { + qDebug() << "Error: ukui-settings-daemon's Schema is not installed, will not setting dpi!"; + delete settings; + return; + } + settings = new QGSettings(XSETTINGS_SCHEMA); + + if (isTheFirstLogin(settings)) { + qDebug() << "Set the default zoom value when logging in for the first time."; + goto end; + } + /* 过滤单双屏下小分辨率大缩放值 */ + + if (ScreenNum > 1) { + goto end; + } + + screenScaleJudgement(settings); + +end: + dpi = 0.0; + dpi = settings->get(SCALING_KEY).toDouble() * 96.0; + setXresources(dpi); + delete settings; +} + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + setHightResolutionScreenZoom(); + return 0; +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..c4b7f93 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,199 @@ +find_package(X11 REQUIRED) + +pkg_check_modules(XTST REQUIRED xtst) +pkg_check_modules(XCB REQUIRED xcb) +pkg_check_modules(QGS REQUIRED gsettings-qt) + +pkg_check_modules(GLIB REQUIRED glib-2.0) +pkg_check_modules(MMIX REQUIRED libmatemixer) + +find_library(PAM_LIBRARIES pam) + +include_directories(${PROJECT_BINARY_DIR}) +include_directories(${PROJECT_SOURCE_DIR}/VirtualKeyboard/src) +include_directories(${PROJECT_SOURCE_DIR}/BiometricAuth) +include_directories(${PROJECT_SOURCE_DIR}/Common) +include_directories(${PROJECT_SOURCE_DIR}/KylinNM) +include_directories(${PROJECT_SOURCE_DIR}/KylinNM/src) +include_directories(${PROJECT_SOURCE_DIR}/KylinNM/hot-spot) +include_directories(${PROJECT_SOURCE_DIR}/KylinNM/wireless-security) + +include_directories( + ${X11_INCLUDE_DIRS} + ${XTST_INCLUDE_DIRS} + ${XCB_INCLUDE_DIRS} + ${QGS_INCLUDE_DIRS} + ${GLIB_INCLUDE_DIRS} + ${MMIX_INCLUDE_DIRS} + ) + +set(EXTRA_LIBS + ${EXTRA_LIBS} + ${PAM_LIBRARIES} + ${X11_LIBRARIES} + ${XTST_LIBRARIES} + ${XCB_LIBRARIES} + ${QGS_LIBRARIES} + ${GLIB_LIBRARIES} + ${MMIX_LIBRARIES} + -lrt + -lpthread + ) + +qt5_wrap_ui(dialog_SRC + lockwidget.ui + surewindow.ui + ) + +qt5_add_resources(dialog_SRC + assets.qrc + ../KylinNM/nmqrc.qrc #暂时将麒麟网络的资源文件放到这里,否则显示不出来,暂时不知道原因 + ) + +# 头文件中包含了Xlib.h,需要单独拿出来处理,不知道原因 +qt5_wrap_cpp(dialog_SRC + pam-tally.h + fullbackgroundwidget.h + lockwidget.h + authdialog.h + loginoptionswidget.h + screensaverwidget.h + auth.h + auth-pam.h + screensaver.h + xeventmonitor.h + monitorwatcher.h + configuration.h + utils.h + users.h + hoverwidget.h + displaymanager.h + iconedit.h + imageutil.h + powermanager.h + logind.h + weathermanager.h + tabletlockwidget.h + gestureauthdialog.h + digitalauthdialog.h + switchbuttongroup.h + wechatauthdialog.h + verificationwidget.h + verticalVerificationwidget.h + common.h + eduplatforminterface.h + accountsinterface.h + networkwatcher.h + digitalkeyboard.h + surewindow.h + PhysicalDeviceSet/brightnessdeviceset.h + PhysicalDeviceSet/flightmodeset.h + PhysicalDeviceSet/sounddeviceset.h + PhysicalDeviceSet/touchscreenset.h + ) + +set(dialog_SRC + ${dialog_SRC} + pam-tally.c + ukui-screensaver-dialog.cpp + fullbackgroundwidget.cpp + lockwidget.cpp + authdialog.cpp + loginoptionswidget.cpp + screensaverwidget.cpp + auth-pam.cpp + xeventmonitor.cpp + monitorwatcher.cpp + grab-x11.cpp + configuration.cpp + screensaver.cpp + powermanager.cpp + utils.cpp + users.cpp + displaymanager.cpp + iconedit.cpp + imageutil.cpp + logind.cpp + hoverwidget.cpp + weathermanager.cpp + tabletlockwidget.cpp + gestureauthdialog.cpp + digitalauthdialog.cpp + switchbuttongroup.cpp + wechatauthdialog.cpp + verificationwidget.cpp + verticalVerificationwidget.cpp + eduplatforminterface.cpp + accountsinterface.cpp + networkwatcher.cpp + digitalkeyboard.cpp + surewindow.cpp + PhysicalDeviceSet/brightnessdeviceset.cpp + PhysicalDeviceSet/flightmodeset.cpp + PhysicalDeviceSet/sounddeviceset.cpp + PhysicalDeviceSet/touchscreenset.cpp + ) +add_executable(ukui-screensaver-dialog ${dialog_SRC}) + +target_link_libraries(ukui-screensaver-dialog + Qt5::Core + Qt5::Widgets + Qt5::DBus + Qt5::Svg + Qt5::X11Extras + Qt5::Network + ${EXTRA_LIBS} + BiometricAuth + VirtualKeyboard + Common + Kylin-nm + ukui-log4qt + ) +link_libraries(libmatemixer.so glib-2.0.so) + +qt5_add_dbus_adaptor(backend_SRC + org.ukui.ScreenSaver.xml + interface.h + Interface + ) + +qt5_wrap_cpp(backend_SRC + interface.h + sessionwatcher.h + logind.h + ) +set(backend_SRC + ${backend_SRC} + ukui-screensaver-backend.cpp + interface.cpp + sessionwatcher.cpp + logind.cpp + ) +add_executable(ukui-screensaver-backend ${backend_SRC}) +target_link_libraries(ukui-screensaver-backend Qt5::Core Qt5::DBus ${QGS_LIBRARIES} ukui-log4qt) + +set(command_SRC + ukui-screensaver-command.cpp + ) +add_executable(ukui-screensaver-command ${command_SRC}) +target_link_libraries(ukui-screensaver-command Qt5::Core Qt5::DBus ukui-log4qt) + +set(checkpass_SRC + ukui-screensaver-checkpass.cpp + ) +add_executable(ukui-screensaver-checkpass ${checkpass_SRC}) +target_link_libraries(ukui-screensaver-checkpass ${PAM_LIBRARIES}) + +install(TARGETS + ukui-screensaver-dialog + ukui-screensaver-backend + ukui-screensaver-command + ukui-screensaver-checkpass + DESTINATION bin) + +#set(test-act_SRC +# users.cpp +# test-accounts.cpp +# ) +#add_executable(test-accounts ${test-act_SRC}) +#target_link_libraries(test-accounts Qt5::Core Qt5::DBus) diff --git a/src/PhysicalDeviceSet/brightnessdeviceset.cpp b/src/PhysicalDeviceSet/brightnessdeviceset.cpp new file mode 100644 index 0000000..455c5d0 --- /dev/null +++ b/src/PhysicalDeviceSet/brightnessdeviceset.cpp @@ -0,0 +1,104 @@ +#include "brightnessdeviceset.h" + +int BrightnessDeviceSet::m_value = -1; +int BrightnessDeviceSet::m_maxBrightnessValue = -1; +bool BrightnessDeviceSet::m_isPowerSupply = false; +int BrightnessDeviceSet::m_curBrightnessValue = -1; + +BrightnessDeviceSet* BrightnessDeviceSet::instance(QObject *parent) +{ + static BrightnessDeviceSet* _instance = nullptr; + QMutex mutex; + mutex.lock(); + if(_instance == nullptr) + _instance = new BrightnessDeviceSet(parent); + mutex.unlock(); + return _instance; +} + +BrightnessDeviceSet::BrightnessDeviceSet(QObject *parent): + QObject(parent) +{ + init(); +} + +void BrightnessDeviceSet::init() +{ + //m_isPowerSupply = true; + m_isPowerSupply = isPowerSupply(); + if(!m_isPowerSupply){ + qWarning() << "info: [BrightnessDeviceSet][init]: current device not support brightness-change!"; + } + m_curBrightnessValue = getCurBrightness(); + m_maxBrightnessValue = getMaxBrightness(); + //m_maxBrightnessValue = 19200; + m_value = m_curBrightnessValue * 1.0 / m_maxBrightnessValue * 100; +} + +int BrightnessDeviceSet::getValue() +{ + return m_value; +} + +void BrightnessDeviceSet::setValue(int value) +{ + if(!m_isPowerSupply) return; + if(value == m_value) return; + if(value > 100) value = 100; + else if(value < 0) value = 0; + m_value = value; + //emit valueChanged(m_value); + // 调整亮度 + int val = value * 1.0 / 100 * m_maxBrightnessValue; + setBrightness(val); +} + +bool BrightnessDeviceSet::isPowerSupply() +{ + QProcess process; + QString command = "/usr/lib/ukui-greeter/greeter-backlight-helper --get-support-brightness"; + + process.start(command); + process.waitForFinished(3000); + QString result = process.readAll(); + + return result == "true"; +} + +int BrightnessDeviceSet::getMaxBrightness() +{ + if(!m_isPowerSupply) return 0; + QProcess process; + QString command = "/usr/lib/ukui-greeter/greeter-backlight-helper --get-max-brightness"; + + process.start(command); + process.waitForFinished(3000); + QString result = process.readAll(); + return result.toInt(); +} + +int BrightnessDeviceSet::getCurBrightness() +{ + if(!m_isPowerSupply) return 0; + QProcess process; + QString command = "/usr/lib/ukui-greeter/greeter-backlight-helper --get-brightness"; + + process.start(command); + process.waitForFinished(3000); + QString result = process.readAll(); + return result.toInt(); +} + +void BrightnessDeviceSet::setBrightness(int val) +{ + if(!m_isPowerSupply) return; + if(val > m_maxBrightnessValue) val = m_maxBrightnessValue; + else if(val < 100) val = 100; + + QString command = "/usr/lib/ukui-greeter/greeter-backlight-helper --set-brightness " + QString::number(val); + + QProcess process; + process.start(command); + process.waitForFinished(3000); + //QString result = process.readAll(); +} diff --git a/src/PhysicalDeviceSet/brightnessdeviceset.h b/src/PhysicalDeviceSet/brightnessdeviceset.h new file mode 100644 index 0000000..77cd162 --- /dev/null +++ b/src/PhysicalDeviceSet/brightnessdeviceset.h @@ -0,0 +1,40 @@ +#ifndef BRIGHTNESSDEVICESET_H +#define BRIGHTNESSDEVICESET_H + +#include +#include +#include +#include + +class BrightnessDeviceSet : public QObject +{ + Q_OBJECT +public: + static BrightnessDeviceSet* instance(QObject *parent = nullptr); + +public Q_SLOTS: + // val from 0 to 100 change + void setValue(int value); + int getValue(); + +private: + BrightnessDeviceSet(QObject *parent = nullptr); + void init(); + bool isPowerSupply(); + int getMaxBrightness(); + int getCurBrightness(); + // val from 0 to MaxBrightness change + void setBrightness(int val); + +Q_SIGNALS: + // val form to 100 change + //void valueChanged(int val); + +private: + static int m_value; + static int m_maxBrightnessValue; + static int m_curBrightnessValue; + static bool m_isPowerSupply; +}; + +#endif // BRIGHTNESSDEVICESET_H diff --git a/src/PhysicalDeviceSet/flightmodeset.cpp b/src/PhysicalDeviceSet/flightmodeset.cpp new file mode 100644 index 0000000..adcbf67 --- /dev/null +++ b/src/PhysicalDeviceSet/flightmodeset.cpp @@ -0,0 +1,20 @@ +#include "flightmodeset.h" + +bool FlightModeSet::m_isFlightModeOpen = false; + +FlightModeSet* FlightModeSet::instance(QObject *parent) +{ + static FlightModeSet* _instance = nullptr; + QMutex mutex; + mutex.lock(); + if(_instance == nullptr) + _instance = new FlightModeSet(parent); + mutex.unlock(); + return _instance; +} + +FlightModeSet::FlightModeSet(QObject *parent): + QObject(parent) +{ + +} diff --git a/src/PhysicalDeviceSet/flightmodeset.h b/src/PhysicalDeviceSet/flightmodeset.h new file mode 100644 index 0000000..57842a4 --- /dev/null +++ b/src/PhysicalDeviceSet/flightmodeset.h @@ -0,0 +1,28 @@ +#ifndef FLIGHTMODESET_H +#define FLIGHTMODESET_H +/*! + *@brief 设置飞行模式 + * 本想在登录界面加载时 提供实体键 飞行模式的功能 + * 后来发现有效。但是飞行模式具体设置是谁负责管理的 还未知。 + * 最初实现的策略是通过 nmcli networking off 的方式设置飞行模式。 + */ + + +#include +#include + +class FlightModeSet : public QObject +{ + Q_OBJECT +public: + static FlightModeSet* instance(QObject *parent = nullptr); + +private: + FlightModeSet(QObject *parent = nullptr); + +private: + static bool m_isFlightModeOpen; + +}; + +#endif // FLIGHTMODESET_H diff --git a/src/PhysicalDeviceSet/physical-device-set.pri b/src/PhysicalDeviceSet/physical-device-set.pri new file mode 100644 index 0000000..365f7bf --- /dev/null +++ b/src/PhysicalDeviceSet/physical-device-set.pri @@ -0,0 +1,11 @@ +HEADERS += \ + $$PWD/brightnessdeviceset.h \ + $$PWD/flightmodeset.h \ + $$PWD/sounddeviceset.h \ + $$PWD/touchscreenset.h + +SOURCES += \ + $$PWD/brightnessdeviceset.cpp \ + $$PWD/flightmodeset.cpp \ + $$PWD/sounddeviceset.cpp \ + $$PWD/touchscreenset.cpp diff --git a/src/PhysicalDeviceSet/sounddeviceset.cpp b/src/PhysicalDeviceSet/sounddeviceset.cpp new file mode 100644 index 0000000..f16ba8c --- /dev/null +++ b/src/PhysicalDeviceSet/sounddeviceset.cpp @@ -0,0 +1,221 @@ +#include "sounddeviceset.h" + +int SoundDeviceSet::m_value = -1; + +SoundDeviceSet* SoundDeviceSet::instance(QObject *parent) +{ + static SoundDeviceSet* _instance = nullptr; + QMutex mutex; + mutex.lock(); + if(!_instance) + _instance = new SoundDeviceSet(parent); + mutex.unlock(); + return _instance; +} + +SoundDeviceSet::SoundDeviceSet(QObject *parent): + QObject(parent) +{ + init(); +} + + +void SoundDeviceSet::init(){ + if (mate_mixer_init () == FALSE){ + qDebug()<<"matemixer init false"; + return ; + } + + context = mate_mixer_context_new (); + if (mate_mixer_context_open (context) == FALSE) { + qDebug()<<"matemixer context open context false."; + return ; + } + + MateMixerState state = mate_mixer_context_get_state (context); + + switch (state) { + case MATE_MIXER_STATE_READY: + connected (context); + break; + case MATE_MIXER_STATE_CONNECTING: + g_print ("Waiting for connection...\n"); + + /* The state will change asynchronously to either MATE_MIXER_STATE_READY + * or MATE_MIXER_STATE_FAILED, wait for the change in a main loop */ + g_signal_connect (G_OBJECT (context), + "notify::state", + G_CALLBACK (on_context_state_notify), + NULL); + break; + default: + qDebug()<<"it's can not reached"; + break; + } +} + +void SoundDeviceSet::emitSignal(bool val){ + emit muteChanged(val); +} + +void SoundDeviceSet::setValue(int val){ + if(!context) + return ; + if(val > 100) val = 100; + else if(val < 0) val = 0; + if(val == m_value) return; + m_value = val; + emit valueChanged(m_value); + + MateMixerStream *m_pOutputStream = mate_mixer_context_get_default_output_stream(context); + if(m_pOutputStream == NULL) + return; + + MateMixerStreamControl *control = mate_mixer_stream_get_default_control(m_pOutputStream); + + bool status = false; + int volume = val*65536/100; + + mate_mixer_stream_control_set_volume(control,guint(volume)); + if (val <= 0) { + status = true; + mate_mixer_stream_control_set_mute(control,status); + mate_mixer_stream_control_set_volume(control,0); + } + else { + mate_mixer_stream_control_set_mute(control,status); + } +} + +void SoundDeviceSet::onStreamControlMuteNotify(MateMixerStreamControl *m_pControl,GParamSpec *pspec,gpointer point){ + + if(!m_pControl) + return ; + + bool state = mate_mixer_stream_control_get_mute (m_pControl); + SoundDeviceSet::instance()->emitSignal(state); +} + +void SoundDeviceSet::onStreamControlVolumeNotify(MateMixerStreamControl *m_pControl,GParamSpec *pspec,gpointer point){ + + MateMixerStreamControlFlags flags; + guint volume = 0; + + if (m_pControl != nullptr) + flags = mate_mixer_stream_control_get_flags(m_pControl); + + if (flags&MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { + volume = mate_mixer_stream_control_get_volume(m_pControl); + } + + MateMixerDirection direction; + MateMixerStream *m_pStream = mate_mixer_stream_control_get_stream(m_pControl); + + direction = mate_mixer_stream_get_direction(m_pStream); + //设置输出滑动条的值 + int value = volume*100/65536.0 + 0.5; + if (direction == MATE_MIXER_DIRECTION_OUTPUT) { + SoundDeviceSet::instance()->setValue(value); + } +} + +void SoundDeviceSet::connected (MateMixerContext *context) +{ + + MateMixerStream *m_pOutputStream = mate_mixer_context_get_default_output_stream(context); + if(m_pOutputStream == NULL) + return; + + MateMixerStreamControl *control = mate_mixer_stream_get_default_control(m_pOutputStream); + + g_signal_connect ( G_OBJECT (control), + "notify::volume", + G_CALLBACK (onStreamControlVolumeNotify), + NULL); + + g_signal_connect (control, + "notify::mute", + G_CALLBACK (onStreamControlMuteNotify), + NULL); + + SoundDeviceSet::instance()->setDefaultVal(); +} + +void SoundDeviceSet::setDefaultVal() +{ + if(!context) + return ; + + MateMixerStream *m_pOutputStream = mate_mixer_context_get_default_output_stream(context); + if(m_pOutputStream == NULL) + return; + + MateMixerStreamControl *control = mate_mixer_stream_get_default_control(m_pOutputStream); + +// int volume = mate_mixer_stream_control_get_volume(control); +// int value = volume *100 /65536.0+0.5; + +// setValue(value); +} + +void SoundDeviceSet::on_context_state_notify (MateMixerContext *context,GParamSpec *pspec,gpointer point ) +{ + MateMixerState state; + + state = mate_mixer_context_get_state (context); + + switch (state) { + case MATE_MIXER_STATE_READY: + /* This state can be reached repeatedly if the context is connected + * to a sound server, the connection is dropped and then reestablished */ + connected (context); + break; + case MATE_MIXER_STATE_FAILED: + qDebug()<<"matemixser state failed"; + break; + default: + break; + } +} + +bool SoundDeviceSet::getIsMute(){ + if(!context) + return false; + + MateMixerState state; + state = mate_mixer_context_get_state (context); + if(state != MATE_MIXER_STATE_READY) + return false; + + MateMixerStream *m_pOutputStream = mate_mixer_context_get_default_output_stream(context); + if(m_pOutputStream == NULL) + return false; + + MateMixerStreamControl *control = mate_mixer_stream_get_default_control(m_pOutputStream); + + return mate_mixer_stream_control_get_mute(control); +} + +void SoundDeviceSet::setMute(bool val){ + if(!context) + return; + + MateMixerState state; + state = mate_mixer_context_get_state (context); + if(state != MATE_MIXER_STATE_READY) + return; + + MateMixerStream *m_pOutputStream = mate_mixer_context_get_default_output_stream(context); + if(m_pOutputStream == NULL) + return; + + MateMixerStreamControl *control = mate_mixer_stream_get_default_control(m_pOutputStream); + + mate_mixer_stream_control_set_mute(control,val); +} + +bool SoundDeviceSet::getIsReady(){ + MateMixerState state; + state = mate_mixer_context_get_state (context); + return state == MATE_MIXER_STATE_READY; +} diff --git a/src/PhysicalDeviceSet/sounddeviceset.h b/src/PhysicalDeviceSet/sounddeviceset.h new file mode 100644 index 0000000..2b98aaa --- /dev/null +++ b/src/PhysicalDeviceSet/sounddeviceset.h @@ -0,0 +1,48 @@ +#ifndef SOUNDDEVICESET_H +#define SOUNDDEVICESET_H + +#include +#include +#include +#include +#include +#include + +class SoundDeviceSet : public QObject +{ + Q_OBJECT +public: + static SoundDeviceSet* instance(QObject *parent = nullptr); + void setMute(bool val); + bool getIsMute(); + void setDefaultVal(); + int getValue(){ return m_value; } + +Q_SIGNALS: + void muteChanged(bool mute); + // val from 0 to 100 change + void valueChanged(int val); + +public Q_SLOTS: + // val from 0 to 100 change + void setValue(int val); + +private: + SoundDeviceSet(QObject *parent = nullptr); + +private: + MateMixerContext *context; + + static void onStreamControlMuteNotify(MateMixerStreamControl *m_pControl,GParamSpec *pspec,gpointer point); + static void onStreamControlVolumeNotify(MateMixerStreamControl *m_pControl,GParamSpec *pspec,gpointer point); + static void on_context_state_notify (MateMixerContext *context,GParamSpec *pspec,gpointer point ); + static void connected (MateMixerContext *context); + void init(); + void emitSignal(bool val); + bool getIsReady(); + + static int m_value; // 当前的音量值 + +}; + +#endif // SOUNDDEVICESET_H diff --git a/src/PhysicalDeviceSet/touchscreenset.cpp b/src/PhysicalDeviceSet/touchscreenset.cpp new file mode 100644 index 0000000..0ba4449 --- /dev/null +++ b/src/PhysicalDeviceSet/touchscreenset.cpp @@ -0,0 +1,30 @@ +#include "touchscreenset.h" + +#include + +TouchScreenSet* TouchScreenSet::instance(QObject *parent) +{ + static TouchScreenSet* _instance = nullptr; + QMutex mutex; + mutex.lock(); + if(!_instance) + _instance = new TouchScreenSet(parent); + mutex.unlock(); + return _instance; +} + +TouchScreenSet::TouchScreenSet(QObject *parent): + QObject(parent) +{ + init(); +} + +void TouchScreenSet::init() +{ + +} + +int TouchScreenSet::getTouchScreenID() +{ + +} diff --git a/src/PhysicalDeviceSet/touchscreenset.h b/src/PhysicalDeviceSet/touchscreenset.h new file mode 100644 index 0000000..fd6c5ef --- /dev/null +++ b/src/PhysicalDeviceSet/touchscreenset.h @@ -0,0 +1,18 @@ +#ifndef TOUCHSCREENSET_H +#define TOUCHSCREENSET_H + +#include + +class TouchScreenSet : public QObject +{ + Q_OBJECT +public: + TouchScreenSet *instance(QObject* parent = nullptr); + void init(); + int getTouchScreenID(); + +private: + TouchScreenSet(QObject *parent = nullptr); +}; + +#endif // TOUCHSCREENSET_H diff --git a/src/accountsinterface.cpp b/src/accountsinterface.cpp new file mode 100644 index 0000000..4b6abb5 --- /dev/null +++ b/src/accountsinterface.cpp @@ -0,0 +1,110 @@ +#include "accountsinterface.h" + +const QString STR_EDU_SERVICE = "cn.kylinos.SSOBackend"; +const QString STR_EDU_PATH = "/cn/kylinos/SSOBackend"; + +AccountsInterface* AccountsInterface::m_instance = nullptr; + +AccountsInterface::AccountsInterface(const QString &strService,const QString &strPath,\ + const QDBusConnection &connection, QObject *parent)\ + :QDBusAbstractInterface(strService,strPath,getInterfaceName(),connection,parent) +{ + +} + +AccountsInterface* AccountsInterface::getInstance() +{ + static QMutex mutex; + mutex.lock(); + if(m_instance == nullptr) + m_instance = new AccountsInterface(STR_EDU_SERVICE, STR_EDU_PATH, QDBusConnection::systemBus()); + mutex.unlock(); + return m_instance; +} + +DBusMsgCode AccountsInterface::SetAccountPincode(const QString &username, const QString &pincode) +{ + QDBusReply reply = call("SetAccountPincode", username, pincode); + if(!reply.isValid()) + { + qDebug() << "error: [AccountsInterface][SetAccountPincode]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + if(reply.value() != 0) + { + qDebug() << "error: [AccountsInterface][SetAccountPincode]: DBus request failed!"; + //return static_cast(reply.value()); + return DBusMsgCode::Error_NoReply; + } + + return DBusMsgCode::No_Error; +} + +DBusMsgCode AccountsInterface::GetAccountPincode(const QString &username, QString &pincode) +{ + QDBusMessage message = call("GetAccountPincode", username); + if(QDBusMessage::ErrorMessage == message.type()) + { + qDebug() << "error: [AccountsInterface][GetAccountPincode]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + QList argvs = message.arguments(); + if(argvs.size() != 2) + { + qDebug() << "error: [AccountsInterface][GetAccountPincode]: DBus arguments error!"; + return DBusMsgCode::Error_ArgCnt; + } + int state = argvs.at(1).value(); + if(state != 0) + { + qDebug() << "error: [AccountsInterface][GetAccountPincode]: DBus request failed!"; + //return static_cast(state); + return DBusMsgCode::Error_ArgCnt; + } + pincode = argvs.at(0).value(); + qDebug() << "pincode:" << pincode; + + return DBusMsgCode::No_Error; +} + +DBusMsgCode AccountsInterface::CheckUserIsNew(const QString &username, bool &isNewUser) +{ + QDBusReply reply = call("CheckUserIsNew", username); + if(!reply.isValid()) + { + qDebug() << "info: [AccountsInterface][CheckUserIsNew]: DBus connect failed!"; + return DBusMsgCode::Error_NoReply; + } + if(reply.value()) + { + qDebug() << "info: [AccountsInterface][CheckUserIsNew]: DBus request failed!"; + return DBusMsgCode::Error_UnknownReason; + } + + isNewUser = static_cast(reply.value()); + return DBusMsgCode::No_Error; +} + +DBusMsgCode AccountsInterface::GetUserPhone(const QString &username, QString &phonenum) +{ + QDBusMessage message = call("GetAccountBasicInfo", username); + if(QDBusMessage::ErrorMessage == message.type()) + { + qDebug() << "info: [AccountsInterface][GetUserPhone]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + QList argvs = message.arguments(); + if(argvs.size() != 7) + { + qDebug() << "info: [AccountsInterface][GetUserPhone]: DBus arguments =" << argvs.size() << "error!"; + return DBusMsgCode::Error_ArgCnt; + } + int role = argvs.at(0).value(); Q_UNUSED(role); + QString school = argvs.at(1).value(); Q_UNUSED(school); + QString province = argvs.at(2).value(); Q_UNUSED(province); + QString city = argvs.at(3).value(); Q_UNUSED(city); + QString county = argvs.at(4).value(); Q_UNUSED(county); + phonenum = argvs.at(5).value(); + int state = argvs.at(6).value(); Q_UNUSED(state); + return state ? DBusMsgCode::Error_UnknownReason : DBusMsgCode::No_Error; +} diff --git a/src/accountsinterface.h b/src/accountsinterface.h new file mode 100644 index 0000000..cc97edd --- /dev/null +++ b/src/accountsinterface.h @@ -0,0 +1,41 @@ +#ifndef ACCOUNTSINTERFACE_H +#define ACCOUNTSINTERFACE_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + +class AccountsInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char* getInterfaceName() + {return "cn.kylinos.SSOBackend.accounts";} +public: + static AccountsInterface* getInstance(); + + AccountsInterface(const QString &strService,const QString &strPath,\ + const QDBusConnection &connection, QObject *parent = 0); + + DBusMsgCode SetAccountPincode(const QString &username, const QString &pincode); + + DBusMsgCode GetAccountPincode(const QString &username, QString &pincode); + + // 检查用户是不是新用户 + DBusMsgCode CheckUserIsNew(const QString &username, bool &isNewUser); + // 获得用户的手机号 + DBusMsgCode GetUserPhone(const QString &username, QString &phone); +private: + static AccountsInterface *m_instance; +}; + +#endif // ACCOUNTSINTERFACE_H diff --git a/src/assets.qrc b/src/assets.qrc new file mode 100644 index 0000000..6059541 --- /dev/null +++ b/src/assets.qrc @@ -0,0 +1,129 @@ + + + assets/authdialog.qss + + + assets/show-password.png + assets/hide-password.png + assets/keyboard.png + assets/switchGreeter.png + assets/switchUser.png + assets/waiting.png + assets/capslock.png + assets/combobox_down.png + assets/scrollbar_down.png + assets/scrollbar_down_clicked.png + assets/scrollbar_down_hover.png + assets/scrollbar_up.png + assets/scrollbar_up_clicked.png + assets/scrollbar_up_hover.png + assets/unlock-button.png + assets/login-button-hover.svg + assets/capslock.svg + assets/login-button.svg + assets/unlock-button-hover.png + assets/unlock-button-pressed.png + assets/iconFace.png + assets/iconFace.svg + assets/powerManager.png + assets/lock.png + assets/logout.png + assets/shutdown.png + assets/suspend.png + assets/hibernate.png + assets/reboot.png + assets/bio-login.png + assets/password-login.png + assets/weather/68.png + assets/weather/67.png + assets/weather/66.png + assets/weather/63.png + assets/weather/62.png + assets/weather/60.png + assets/weather/59.png + assets/weather/58.png + assets/weather/56.png + assets/weather/55.png + assets/weather/53.png + assets/weather/52.png + assets/weather/51.png + assets/weather/49.png + assets/weather/48.png + assets/weather/47.png + assets/weather/45.png + assets/weather/43.png + assets/weather/41.png + assets/weather/40.png + assets/weather/39.png + assets/weather/38.png + assets/weather/36.png + assets/weather/35.png + assets/weather/33.png + assets/weather/31.png + assets/weather/30.png + assets/weather/29.png + assets/weather/28.png + assets/weather/27.png + assets/weather/24.png + assets/weather/22.png + assets/weather/21.png + assets/weather/20.png + assets/weather/19.png + assets/weather/18.png + assets/weather/17.png + assets/weather/16.png + assets/weather/15.png + assets/weather/14.png + assets/weather/13.png + assets/weather/11.png + assets/weather/10.png + assets/weather/9.png + assets/weather/8.png + assets/weather/7.png + assets/weather/6.png + assets/weather/5.png + assets/weather/4.png + assets/weather/3.png + assets/weather/2.png + assets/weather/1.png + assets/weather/0.png + assets/intel/message.png + assets/intel/more.png + assets/intel/slide_unlock.png + assets/intel/qr-code.png + assets/intel/wifi.png + assets/intel/delete.svg + assets/intel/pin.png + assets/intel/wechat.png + assets/intel/back.png + assets/intel/cancel.png + assets/intel/qr-reload.png + assets/intel/icon-wechat-noqrcode.png + assets/intel/icon-no-signal.png + assets/intel/icon-wired.png + assets/intel/icon-wifi.png + assets/intel/sms.png + assets/intel/phone.png + assets/intel/icon-backspace.png + assets/intel/lock.png + assets/intel/logout.png + assets/intel/shutdown.png + assets/intel/reboot.png + assets/intel/powerManager.png + assets/intel/keyboard.png + assets/ukui-qrcode-null.svg + assets/ukui-loginopt-voice.svg + assets/ukui-loginopt-qrcode.svg + assets/ukui-loginopt-iris.svg + assets/ukui-loginopt-fingervein.svg + assets/ukui-loginopt-finger.svg + assets/ukui-loginopt-face.svg + assets/ukui-loginopt-password.svg + assets/selected.svg + assets/keyboard.svg + assets/ukui-loginopt-smile.svg + assets/ukui-loginopt-lose.svg + assets/01-default-commercial.png + assets/01-default-community.png + + diff --git a/src/assets/01-default-commercial.png b/src/assets/01-default-commercial.png new file mode 100644 index 0000000..eda418c Binary files /dev/null and b/src/assets/01-default-commercial.png differ diff --git a/src/assets/01-default-community.png b/src/assets/01-default-community.png new file mode 100644 index 0000000..82ede85 Binary files /dev/null and b/src/assets/01-default-community.png differ diff --git a/src/assets/authdialog.qss b/src/assets/authdialog.qss new file mode 100644 index 0000000..cdf0026 --- /dev/null +++ b/src/assets/authdialog.qss @@ -0,0 +1,270 @@ +QPushButton{ + text-align:center; + color: rgb(255, 255, 255, 255); + border: none; + border-radius: 4px; + outline: none; +} +QPushButton::hover{ + background-color: rgb(255,255,255,15%); +} +QPushButton::pressed { + background-color: rgba(255,255,255,40%); +} + +QToolButton{ + text-align:center; + border: none; + border-radius: 6px; + outline: none; + background-color: rgba(255, 255, 255, 10%); +} +QToolButton::hover{ + background-color: rgba(255, 255, 255, 15%); +} +QToolButton::pressed { + background-color: rgba(255, 255, 255, 40%); +} +QToolButton::checked { + background-color: rgba(255, 255, 255, 40%); +} + +QLabel { + color: white; + font-size: 16px; +} + +QToolTip{ + border-radius:4px; + background-color:#FFFFFF; + color:black; + font-size:16px +} + +#userWidget{ +/* background: rgba(255, 0, 255, 30%);*/ +} + +/* 头像 */ +/* +#faceLabel { + border:2px solid white; +} +*/ + +/* 用户名 */ +#login_nameLabel{ + font-size: 24px; +} + +/* 密码输入框 */ +QLineEdit { + background: #FFFFFF; + border: 1px solid #FFFFFF; + border-radius: 6px; + color:black; + font-size: 14px; + lineedit-password-character:9679; +} + +QLineEdit::hover { + border: 1px solid #FFFFFF; +} +QLineEdit::focus{ + +} + +/* 大写提示 */ +#capsIconLabel{ + background-repeat: no-repeat; + background-position: center; + max-width: 16px; + max-height: 16px; + min-width: 16px; + min-height: 16px; +} + +/* echo mode */ +#echoModeButton { + background: transparent; + max-width: 30px; + min-width: 30px; + max-height: 14px; + min-height: 14px; + icon-size: 16px; +} +#echoModeButton::checked { +} +/* 登录按钮 */ +#loginButton{ + min-width: 24px; + max-width: 24px; + min-height: 24px; + max-height: 24px; + icon-size: 24px; + background:#3D6BE5; + border-radius:12px; +} + +/* PAM message提示*/ +#messageLabel { + font-size: 16px; + color: white; +} + +#messageButton{ + text-align:center; + font-size: 16px; + color: white; +} + +/* 切换用户 */ + +QMenu{ + background-color: rgb(255,255,255,15%); + color: white; + border-radius: 4px; + width:260px; + font-size: 16px; + padding: 5px 5px 5px 5px; +} + +QMenu::icon{ + padding: 2px 5px 2px 5px; +} +QMenu::item +{ + width:225px; + border-radius: 4px; + height:36px; + font-size:16px; + padding: 2px 10px 2px 10px; +} + +QMenu::item:selected { + border-radius: 4px; + background-color:rgb(255,255,255,40%); +} +QMenu::item:pressed { + border-radius: 4px; + background-color: rgb(255,255,255,40%); +} + +/* 虚拟键盘开启按钮、用户切换按钮 */ +#btnSwitchUser, #btnKeyboard,#btnPowerManager { + border-radius: 4px; +} +#btnKeyboard::hover, #btnSwitchUser::hover,#btnPowerManager::hover { + background-color: rgb(255, 255, 255, 15%); +} +#btnKeyboard::pressed, #btnSwitchUser::pressed,#btnPowerManager::pressed{ + background: rgba(255,255,255,40%); +} + + + +/********************** 下拉选项 *************************/ + +QComboBox{ + background: rgba(255, 255, 255, 20); + border: 1px solid rgb(255, 255, 255, 30); + font-size:18px; + color: white; + combobox-popup: 0; /* 配合setMaxVisibleItems设置下拉框显示的条数,超过的滚动显示 */ +} + +QComboBox::down-arrow{ + image:url(:/image/assets/combobox_down.png); +} +QComboBox::drop-down{ + width: 30px; + border: none; +} + +QComboBox QListView{ + border: 1px solid #5187bd; +/* background: #4682B4;*/ + background: rgba(255, 255, 255, 30%); + font-size: 18px; + color: white; +} +QComboBox QListView::item{ + background: rgba(255, 255, 255, 0); +} + +QComboBox QListView::item:hover{ + background: rgba(255, 255, 255, 20%); +} + +QComboBox QListView::item:selected{ + background-color: rgba(255, 255, 255, 30%); +} +/********************** 生物识别切换按钮 **************************/ +#biometricButton, #passwordButton, +#otherDeviceButton, #retryButton, +#OKButton +{ + background: rgba(255, 255, 255, 0); + font-size: 16px; + color: white; +} + +#biometricButton::hover, #passwordButton::hover, +#otherDeviceButton::hover, #retryButton::hover, +#OKButton::hover +{ + background: rgba(255, 255, 255, 20%); + border: 0px; +} + +#biometricButton::pressed, #passwordButton::pressed, +#otherDeviceButton::pressed, #retryButton::pressed, +#OKButton::pressed +{ + background: rgba(255,255,255,40%); + border: 0px; +} + + +/********************** 生物识别设备选择界面 ************************/ +#lblBioetricDevicesPrompt { + font-size: 30px; + color: white; +} + +#lblDeviceType, #lblDeviceName, +#cmbDeviceType, #cmbDeviceName{ + font-size: 18px; +} + +/***********************关机界面**********************************/ +QListWidget{ + background:rgba(255, 255, 255, 0%); + border: 0px; +} + +QListWidget::item{ + background:rgba(255, 255, 255, 0%); + border: 0px; + min-width: 128px; + max-width: 128px; + min-height: 128px; + max-height: 128px; + spacing: 0px; +} + +#switchFace,#logoutFace,#rebootFace,#shutdownFace, +#hibernateFace,#suspendFace{ + min-width: 128px; + max-width: 128px; + min-height: 128px; + max-height: 128px; + border-radius: 64px; + icon-size: 40px; + background:rgba(255, 255, 255, 15%); +} + +#switchFace::hover,#logoutFace::hover,#rebootFace::hover, +#shutdownFace::hover,#hibernateFace::hover,#suspendFace::hover{ + background:rgba(255, 255, 255, 40%); +} diff --git a/src/assets/bio-login.png b/src/assets/bio-login.png new file mode 100644 index 0000000..41858f8 Binary files /dev/null and b/src/assets/bio-login.png differ diff --git a/src/assets/capslock.png b/src/assets/capslock.png new file mode 100644 index 0000000..b4259ab Binary files /dev/null and b/src/assets/capslock.png differ diff --git a/src/assets/capslock.svg b/src/assets/capslock.svg new file mode 100644 index 0000000..04b86f9 --- /dev/null +++ b/src/assets/capslock.svg @@ -0,0 +1 @@ +画板 5 \ No newline at end of file diff --git a/src/assets/combobox_down.png b/src/assets/combobox_down.png new file mode 100644 index 0000000..e07de91 Binary files /dev/null and b/src/assets/combobox_down.png differ diff --git a/src/assets/hibernate.png b/src/assets/hibernate.png new file mode 100644 index 0000000..a6338b1 Binary files /dev/null and b/src/assets/hibernate.png differ diff --git a/src/assets/hide-password.png b/src/assets/hide-password.png new file mode 100644 index 0000000..bd85995 Binary files /dev/null and b/src/assets/hide-password.png differ diff --git a/src/assets/iconFace.png b/src/assets/iconFace.png new file mode 100644 index 0000000..41b35ad Binary files /dev/null and b/src/assets/iconFace.png differ diff --git a/src/assets/iconFace.svg b/src/assets/iconFace.svg new file mode 100644 index 0000000..7d361c2 --- /dev/null +++ b/src/assets/iconFace.svg @@ -0,0 +1 @@ +avatar_128 \ No newline at end of file diff --git a/src/assets/intel/back.png b/src/assets/intel/back.png new file mode 100644 index 0000000..c20cb56 Binary files /dev/null and b/src/assets/intel/back.png differ diff --git a/src/assets/intel/cancel.png b/src/assets/intel/cancel.png new file mode 100644 index 0000000..0895e27 Binary files /dev/null and b/src/assets/intel/cancel.png differ diff --git a/src/assets/intel/delete.svg b/src/assets/intel/delete.svg new file mode 100644 index 0000000..5893d68 --- /dev/null +++ b/src/assets/intel/delete.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/intel/icon-backspace.png b/src/assets/intel/icon-backspace.png new file mode 100644 index 0000000..ba8ff48 Binary files /dev/null and b/src/assets/intel/icon-backspace.png differ diff --git a/src/assets/intel/icon-no-signal.png b/src/assets/intel/icon-no-signal.png new file mode 100644 index 0000000..1a0de9e Binary files /dev/null and b/src/assets/intel/icon-no-signal.png differ diff --git a/src/assets/intel/icon-wechat-noqrcode.png b/src/assets/intel/icon-wechat-noqrcode.png new file mode 100644 index 0000000..df115f1 Binary files /dev/null and b/src/assets/intel/icon-wechat-noqrcode.png differ diff --git a/src/assets/intel/icon-wifi.png b/src/assets/intel/icon-wifi.png new file mode 100644 index 0000000..ce40b76 Binary files /dev/null and b/src/assets/intel/icon-wifi.png differ diff --git a/src/assets/intel/icon-wired.png b/src/assets/intel/icon-wired.png new file mode 100644 index 0000000..a64b6f0 Binary files /dev/null and b/src/assets/intel/icon-wired.png differ diff --git a/src/assets/intel/keyboard.png b/src/assets/intel/keyboard.png new file mode 100755 index 0000000..f02fb5f Binary files /dev/null and b/src/assets/intel/keyboard.png differ diff --git a/src/assets/intel/lock.png b/src/assets/intel/lock.png new file mode 100644 index 0000000..8ec6fd2 Binary files /dev/null and b/src/assets/intel/lock.png differ diff --git a/src/assets/intel/logout.png b/src/assets/intel/logout.png new file mode 100644 index 0000000..5af6ca7 Binary files /dev/null and b/src/assets/intel/logout.png differ diff --git a/src/assets/intel/message.png b/src/assets/intel/message.png new file mode 100644 index 0000000..cfe54a4 Binary files /dev/null and b/src/assets/intel/message.png differ diff --git a/src/assets/intel/more.png b/src/assets/intel/more.png new file mode 100644 index 0000000..b224a0c Binary files /dev/null and b/src/assets/intel/more.png differ diff --git a/src/assets/intel/phone.png b/src/assets/intel/phone.png new file mode 100755 index 0000000..fbc2112 Binary files /dev/null and b/src/assets/intel/phone.png differ diff --git a/src/assets/intel/pin.png b/src/assets/intel/pin.png new file mode 100644 index 0000000..5585fef Binary files /dev/null and b/src/assets/intel/pin.png differ diff --git a/src/assets/intel/powerManager.png b/src/assets/intel/powerManager.png new file mode 100644 index 0000000..aab83b4 Binary files /dev/null and b/src/assets/intel/powerManager.png differ diff --git a/src/assets/intel/qr-code.png b/src/assets/intel/qr-code.png new file mode 100644 index 0000000..5a56fb2 Binary files /dev/null and b/src/assets/intel/qr-code.png differ diff --git a/src/assets/intel/qr-reload.png b/src/assets/intel/qr-reload.png new file mode 100644 index 0000000..aeeff96 Binary files /dev/null and b/src/assets/intel/qr-reload.png differ diff --git a/src/assets/intel/reboot.png b/src/assets/intel/reboot.png new file mode 100644 index 0000000..995ee4b Binary files /dev/null and b/src/assets/intel/reboot.png differ diff --git a/src/assets/intel/shutdown.png b/src/assets/intel/shutdown.png new file mode 100644 index 0000000..c367f68 Binary files /dev/null and b/src/assets/intel/shutdown.png differ diff --git a/src/assets/intel/slide_unlock.png b/src/assets/intel/slide_unlock.png new file mode 100644 index 0000000..02f1f69 Binary files /dev/null and b/src/assets/intel/slide_unlock.png differ diff --git a/src/assets/intel/sms.png b/src/assets/intel/sms.png new file mode 100755 index 0000000..85c2cc5 Binary files /dev/null and b/src/assets/intel/sms.png differ diff --git a/src/assets/intel/wechat.png b/src/assets/intel/wechat.png new file mode 100644 index 0000000..c93885c Binary files /dev/null and b/src/assets/intel/wechat.png differ diff --git a/src/assets/intel/wifi.png b/src/assets/intel/wifi.png new file mode 100755 index 0000000..ce40b76 Binary files /dev/null and b/src/assets/intel/wifi.png differ diff --git a/src/assets/keyboard.png b/src/assets/keyboard.png new file mode 100644 index 0000000..4d93f1e Binary files /dev/null and b/src/assets/keyboard.png differ diff --git a/src/assets/keyboard.svg b/src/assets/keyboard.svg new file mode 100644 index 0000000..79d0b1c --- /dev/null +++ b/src/assets/keyboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/lock.png b/src/assets/lock.png new file mode 100644 index 0000000..ad21586 Binary files /dev/null and b/src/assets/lock.png differ diff --git a/src/assets/login-button-hover.svg b/src/assets/login-button-hover.svg new file mode 100644 index 0000000..02c8c9c --- /dev/null +++ b/src/assets/login-button-hover.svg @@ -0,0 +1 @@ +画板 3 \ No newline at end of file diff --git a/src/assets/login-button.svg b/src/assets/login-button.svg new file mode 100644 index 0000000..22861a2 --- /dev/null +++ b/src/assets/login-button.svg @@ -0,0 +1 @@ +画板 2 \ No newline at end of file diff --git a/src/assets/logout.png b/src/assets/logout.png new file mode 100644 index 0000000..cec5de0 Binary files /dev/null and b/src/assets/logout.png differ diff --git a/src/assets/password-login.png b/src/assets/password-login.png new file mode 100644 index 0000000..9fc4338 Binary files /dev/null and b/src/assets/password-login.png differ diff --git a/src/assets/powerManager.png b/src/assets/powerManager.png new file mode 100644 index 0000000..73089ad Binary files /dev/null and b/src/assets/powerManager.png differ diff --git a/src/assets/reboot.png b/src/assets/reboot.png new file mode 100644 index 0000000..5365f79 Binary files /dev/null and b/src/assets/reboot.png differ diff --git a/src/assets/scrollbar_down.png b/src/assets/scrollbar_down.png new file mode 100644 index 0000000..9dbebca Binary files /dev/null and b/src/assets/scrollbar_down.png differ diff --git a/src/assets/scrollbar_down_clicked.png b/src/assets/scrollbar_down_clicked.png new file mode 100644 index 0000000..fe8bc04 Binary files /dev/null and b/src/assets/scrollbar_down_clicked.png differ diff --git a/src/assets/scrollbar_down_hover.png b/src/assets/scrollbar_down_hover.png new file mode 100644 index 0000000..50da897 Binary files /dev/null and b/src/assets/scrollbar_down_hover.png differ diff --git a/src/assets/scrollbar_up.png b/src/assets/scrollbar_up.png new file mode 100644 index 0000000..8618cf9 Binary files /dev/null and b/src/assets/scrollbar_up.png differ diff --git a/src/assets/scrollbar_up_clicked.png b/src/assets/scrollbar_up_clicked.png new file mode 100644 index 0000000..20c6e3c Binary files /dev/null and b/src/assets/scrollbar_up_clicked.png differ diff --git a/src/assets/scrollbar_up_hover.png b/src/assets/scrollbar_up_hover.png new file mode 100644 index 0000000..9b2532c Binary files /dev/null and b/src/assets/scrollbar_up_hover.png differ diff --git a/src/assets/selected.svg b/src/assets/selected.svg new file mode 100644 index 0000000..ccd058a --- /dev/null +++ b/src/assets/selected.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/show-password.png b/src/assets/show-password.png new file mode 100644 index 0000000..afaf744 Binary files /dev/null and b/src/assets/show-password.png differ diff --git a/src/assets/shutdown.png b/src/assets/shutdown.png new file mode 100644 index 0000000..a7c9c62 Binary files /dev/null and b/src/assets/shutdown.png differ diff --git a/src/assets/suspend.png b/src/assets/suspend.png new file mode 100644 index 0000000..63f2a32 Binary files /dev/null and b/src/assets/suspend.png differ diff --git a/src/assets/switchGreeter.png b/src/assets/switchGreeter.png new file mode 100644 index 0000000..b5dbb10 Binary files /dev/null and b/src/assets/switchGreeter.png differ diff --git a/src/assets/switchUser.png b/src/assets/switchUser.png new file mode 100644 index 0000000..65b98ea Binary files /dev/null and b/src/assets/switchUser.png differ diff --git a/src/assets/ukui-loginopt-face.svg b/src/assets/ukui-loginopt-face.svg new file mode 100644 index 0000000..6eacd5e --- /dev/null +++ b/src/assets/ukui-loginopt-face.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-finger.svg b/src/assets/ukui-loginopt-finger.svg new file mode 100644 index 0000000..ed0d828 --- /dev/null +++ b/src/assets/ukui-loginopt-finger.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-fingervein.svg b/src/assets/ukui-loginopt-fingervein.svg new file mode 100644 index 0000000..fda3187 --- /dev/null +++ b/src/assets/ukui-loginopt-fingervein.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-iris.svg b/src/assets/ukui-loginopt-iris.svg new file mode 100644 index 0000000..64cbcf7 --- /dev/null +++ b/src/assets/ukui-loginopt-iris.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-lose.svg b/src/assets/ukui-loginopt-lose.svg new file mode 100644 index 0000000..516a33a --- /dev/null +++ b/src/assets/ukui-loginopt-lose.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-password.svg b/src/assets/ukui-loginopt-password.svg new file mode 100644 index 0000000..458d06f --- /dev/null +++ b/src/assets/ukui-loginopt-password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-qrcode.svg b/src/assets/ukui-loginopt-qrcode.svg new file mode 100644 index 0000000..0389ac3 --- /dev/null +++ b/src/assets/ukui-loginopt-qrcode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-smile.svg b/src/assets/ukui-loginopt-smile.svg new file mode 100644 index 0000000..6ff2371 --- /dev/null +++ b/src/assets/ukui-loginopt-smile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-loginopt-voice.svg b/src/assets/ukui-loginopt-voice.svg new file mode 100644 index 0000000..176036a --- /dev/null +++ b/src/assets/ukui-loginopt-voice.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/ukui-qrcode-null.svg b/src/assets/ukui-qrcode-null.svg new file mode 100644 index 0000000..9bcffed --- /dev/null +++ b/src/assets/ukui-qrcode-null.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/unlock-button-hover.png b/src/assets/unlock-button-hover.png new file mode 100644 index 0000000..39d20f1 Binary files /dev/null and b/src/assets/unlock-button-hover.png differ diff --git a/src/assets/unlock-button-pressed.png b/src/assets/unlock-button-pressed.png new file mode 100644 index 0000000..4b1b2df Binary files /dev/null and b/src/assets/unlock-button-pressed.png differ diff --git a/src/assets/unlock-button.png b/src/assets/unlock-button.png new file mode 100644 index 0000000..2a6d08f Binary files /dev/null and b/src/assets/unlock-button.png differ diff --git a/src/assets/waiting.png b/src/assets/waiting.png new file mode 100644 index 0000000..2136f8b Binary files /dev/null and b/src/assets/waiting.png differ diff --git a/src/assets/weather/0.png b/src/assets/weather/0.png new file mode 100644 index 0000000..adf7561 Binary files /dev/null and b/src/assets/weather/0.png differ diff --git a/src/assets/weather/1.png b/src/assets/weather/1.png new file mode 100644 index 0000000..edf4f22 Binary files /dev/null and b/src/assets/weather/1.png differ diff --git a/src/assets/weather/10.png b/src/assets/weather/10.png new file mode 100644 index 0000000..921b43b Binary files /dev/null and b/src/assets/weather/10.png differ diff --git a/src/assets/weather/11.png b/src/assets/weather/11.png new file mode 100644 index 0000000..921b43b Binary files /dev/null and b/src/assets/weather/11.png differ diff --git a/src/assets/weather/13.png b/src/assets/weather/13.png new file mode 100644 index 0000000..9c1f2f9 Binary files /dev/null and b/src/assets/weather/13.png differ diff --git a/src/assets/weather/14.png b/src/assets/weather/14.png new file mode 100644 index 0000000..3b0a2b2 Binary files /dev/null and b/src/assets/weather/14.png differ diff --git a/src/assets/weather/15.png b/src/assets/weather/15.png new file mode 100644 index 0000000..3d44078 Binary files /dev/null and b/src/assets/weather/15.png differ diff --git a/src/assets/weather/16.png b/src/assets/weather/16.png new file mode 100644 index 0000000..cf5e92f Binary files /dev/null and b/src/assets/weather/16.png differ diff --git a/src/assets/weather/17.png b/src/assets/weather/17.png new file mode 100644 index 0000000..cf5e92f Binary files /dev/null and b/src/assets/weather/17.png differ diff --git a/src/assets/weather/18.png b/src/assets/weather/18.png new file mode 100644 index 0000000..2caad27 Binary files /dev/null and b/src/assets/weather/18.png differ diff --git a/src/assets/weather/19.png b/src/assets/weather/19.png new file mode 100644 index 0000000..b828449 Binary files /dev/null and b/src/assets/weather/19.png differ diff --git a/src/assets/weather/2.png b/src/assets/weather/2.png new file mode 100644 index 0000000..2caad27 Binary files /dev/null and b/src/assets/weather/2.png differ diff --git a/src/assets/weather/20.png b/src/assets/weather/20.png new file mode 100644 index 0000000..850d972 Binary files /dev/null and b/src/assets/weather/20.png differ diff --git a/src/assets/weather/21.png b/src/assets/weather/21.png new file mode 100644 index 0000000..864b928 Binary files /dev/null and b/src/assets/weather/21.png differ diff --git a/src/assets/weather/22.png b/src/assets/weather/22.png new file mode 100644 index 0000000..31a93f2 Binary files /dev/null and b/src/assets/weather/22.png differ diff --git a/src/assets/weather/24.png b/src/assets/weather/24.png new file mode 100644 index 0000000..cee5033 Binary files /dev/null and b/src/assets/weather/24.png differ diff --git a/src/assets/weather/27.png b/src/assets/weather/27.png new file mode 100644 index 0000000..3d44078 Binary files /dev/null and b/src/assets/weather/27.png differ diff --git a/src/assets/weather/28.png b/src/assets/weather/28.png new file mode 100644 index 0000000..cf5e92f Binary files /dev/null and b/src/assets/weather/28.png differ diff --git a/src/assets/weather/29.png b/src/assets/weather/29.png new file mode 100644 index 0000000..4cbe3b9 Binary files /dev/null and b/src/assets/weather/29.png differ diff --git a/src/assets/weather/3.png b/src/assets/weather/3.png new file mode 100644 index 0000000..7dc38d8 Binary files /dev/null and b/src/assets/weather/3.png differ diff --git a/src/assets/weather/30.png b/src/assets/weather/30.png new file mode 100644 index 0000000..c1eb46a Binary files /dev/null and b/src/assets/weather/30.png differ diff --git a/src/assets/weather/31.png b/src/assets/weather/31.png new file mode 100644 index 0000000..dad9aba Binary files /dev/null and b/src/assets/weather/31.png differ diff --git a/src/assets/weather/33.png b/src/assets/weather/33.png new file mode 100644 index 0000000..dbfbf60 Binary files /dev/null and b/src/assets/weather/33.png differ diff --git a/src/assets/weather/35.png b/src/assets/weather/35.png new file mode 100644 index 0000000..b86b58b Binary files /dev/null and b/src/assets/weather/35.png differ diff --git a/src/assets/weather/36.png b/src/assets/weather/36.png new file mode 100644 index 0000000..6e68f01 Binary files /dev/null and b/src/assets/weather/36.png differ diff --git a/src/assets/weather/38.png b/src/assets/weather/38.png new file mode 100644 index 0000000..30affeb Binary files /dev/null and b/src/assets/weather/38.png differ diff --git a/src/assets/weather/39.png b/src/assets/weather/39.png new file mode 100644 index 0000000..9fbc83b Binary files /dev/null and b/src/assets/weather/39.png differ diff --git a/src/assets/weather/4.png b/src/assets/weather/4.png new file mode 100644 index 0000000..1ec73d2 Binary files /dev/null and b/src/assets/weather/4.png differ diff --git a/src/assets/weather/40.png b/src/assets/weather/40.png new file mode 100644 index 0000000..3ba20eb Binary files /dev/null and b/src/assets/weather/40.png differ diff --git a/src/assets/weather/41.png b/src/assets/weather/41.png new file mode 100644 index 0000000..c8b27b3 Binary files /dev/null and b/src/assets/weather/41.png differ diff --git a/src/assets/weather/43.png b/src/assets/weather/43.png new file mode 100644 index 0000000..9c1f2f9 Binary files /dev/null and b/src/assets/weather/43.png differ diff --git a/src/assets/weather/45.png b/src/assets/weather/45.png new file mode 100644 index 0000000..0e5c264 Binary files /dev/null and b/src/assets/weather/45.png differ diff --git a/src/assets/weather/47.png b/src/assets/weather/47.png new file mode 100644 index 0000000..61e165d Binary files /dev/null and b/src/assets/weather/47.png differ diff --git a/src/assets/weather/48.png b/src/assets/weather/48.png new file mode 100644 index 0000000..8b576ea Binary files /dev/null and b/src/assets/weather/48.png differ diff --git a/src/assets/weather/49.png b/src/assets/weather/49.png new file mode 100644 index 0000000..7c8f0cf Binary files /dev/null and b/src/assets/weather/49.png differ diff --git a/src/assets/weather/5.png b/src/assets/weather/5.png new file mode 100644 index 0000000..3d8c6b4 Binary files /dev/null and b/src/assets/weather/5.png differ diff --git a/src/assets/weather/51.png b/src/assets/weather/51.png new file mode 100644 index 0000000..623e19f Binary files /dev/null and b/src/assets/weather/51.png differ diff --git a/src/assets/weather/52.png b/src/assets/weather/52.png new file mode 100644 index 0000000..884723f Binary files /dev/null and b/src/assets/weather/52.png differ diff --git a/src/assets/weather/53.png b/src/assets/weather/53.png new file mode 100644 index 0000000..c476e95 Binary files /dev/null and b/src/assets/weather/53.png differ diff --git a/src/assets/weather/55.png b/src/assets/weather/55.png new file mode 100644 index 0000000..116ba1a Binary files /dev/null and b/src/assets/weather/55.png differ diff --git a/src/assets/weather/56.png b/src/assets/weather/56.png new file mode 100644 index 0000000..3d8c6b4 Binary files /dev/null and b/src/assets/weather/56.png differ diff --git a/src/assets/weather/58.png b/src/assets/weather/58.png new file mode 100644 index 0000000..1e75173 Binary files /dev/null and b/src/assets/weather/58.png differ diff --git a/src/assets/weather/59.png b/src/assets/weather/59.png new file mode 100644 index 0000000..db55fba Binary files /dev/null and b/src/assets/weather/59.png differ diff --git a/src/assets/weather/6.png b/src/assets/weather/6.png new file mode 100644 index 0000000..04ebaa5 Binary files /dev/null and b/src/assets/weather/6.png differ diff --git a/src/assets/weather/60.png b/src/assets/weather/60.png new file mode 100644 index 0000000..3d8c6b4 Binary files /dev/null and b/src/assets/weather/60.png differ diff --git a/src/assets/weather/62.png b/src/assets/weather/62.png new file mode 100644 index 0000000..a6ffa43 Binary files /dev/null and b/src/assets/weather/62.png differ diff --git a/src/assets/weather/63.png b/src/assets/weather/63.png new file mode 100644 index 0000000..623e19f Binary files /dev/null and b/src/assets/weather/63.png differ diff --git a/src/assets/weather/66.png b/src/assets/weather/66.png new file mode 100644 index 0000000..74d0087 Binary files /dev/null and b/src/assets/weather/66.png differ diff --git a/src/assets/weather/67.png b/src/assets/weather/67.png new file mode 100644 index 0000000..2c4746d Binary files /dev/null and b/src/assets/weather/67.png differ diff --git a/src/assets/weather/68.png b/src/assets/weather/68.png new file mode 100644 index 0000000..f0f8d70 Binary files /dev/null and b/src/assets/weather/68.png differ diff --git a/src/assets/weather/7.png b/src/assets/weather/7.png new file mode 100644 index 0000000..a00cbff Binary files /dev/null and b/src/assets/weather/7.png differ diff --git a/src/assets/weather/8.png b/src/assets/weather/8.png new file mode 100644 index 0000000..c655869 Binary files /dev/null and b/src/assets/weather/8.png differ diff --git a/src/assets/weather/9.png b/src/assets/weather/9.png new file mode 100644 index 0000000..47677fb Binary files /dev/null and b/src/assets/weather/9.png differ diff --git a/src/assets/weather/icon.htm b/src/assets/weather/icon.htm new file mode 100644 index 0000000..dd9e897 --- /dev/null +++ b/src/assets/weather/icon.htm @@ -0,0 +1,29 @@ + + + + +
文件名网络图标本地图标
+ + \ No newline at end of file diff --git a/src/auth-pam.cpp b/src/auth-pam.cpp new file mode 100644 index 0000000..aa01e1c --- /dev/null +++ b/src/auth-pam.cpp @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "auth-pam.h" + +#include + +#include +#include +#include +#define PAM_SERVICE_NAME "ukui-screensaver-qt" + +//通信管道的文件描述符 +int toParent[2], toChild[2]; +void sigchld_handler(int signo); +static void writeData(int fd, const void *buf, ssize_t count); +static void writeString(int fd, const char *data); +static int readData(int fd, void *buf, size_t count); +static char * readString(int fd); +static int pam_conversation(int msgLength, const struct pam_message **msg, + PAM_RESPONSE **resp, void *appData); +void sigchld_handler(int signo); +AuthPAM::AuthPAM(QObject *parent) + : Auth(parent), + pid(0), + nPrompts(0), + _isAuthenticated(false), + _isAuthenticating(false) +{ +// signal(SIGCHLD, sigchld_handler); +} + +void AuthPAM::authenticate(const QString &userName) +{ + stopAuth(); + + if(pipe(toParent) || pipe(toChild)) + qDebug()<< "create pipe failed: " << strerror(errno); + if((pid = fork()) < 0) + { + qDebug() << "fork error: " << strerror(errno); + } + else if(pid == 0) + { + prctl(PR_SET_PDEATHSIG, SIGHUP); + close(toParent[0]); + close(toChild[1]); + int arg1_int = toParent[1]; + int arg2_int = toChild[0]; + char arg1[128]; + char arg2[128]; + sprintf(arg1,"%d",arg1_int); + sprintf(arg2,"%d",arg2_int); + execlp ("ukui-screensaver-checkpass", + "ukui-screensaver-checkpass", + arg1, arg2,userName.toLocal8Bit().data(), NULL); + _exit (EXIT_FAILURE); + } + else + { + close(toParent[1]); + close(toChild[0]); + _isAuthenticating = true; + notifier = new QSocketNotifier(toParent[0], QSocketNotifier::Read); + connect(notifier, &QSocketNotifier::activated, this, &AuthPAM::onSockRead); + } +} + +void AuthPAM::stopAuth() +{ + if(pid != 0) + { + messageList.clear(); + responseList.clear(); + _isAuthenticating = false; + _isAuthenticated = false; + nPrompts = 0; + ::kill(pid, SIGKILL); + + close(toParent[0]); + close(toChild[1]); + if(notifier){ + notifier->deleteLater(); + notifier = nullptr; + } + pid = 0; + } +} + +void AuthPAM::respond(const QString &response) +{ + nPrompts--; + responseList.push_back(response); + +// for(auto msg : messageList) +// qDebug() << msg.msg; +// qDebug() << responseList; +// qDebug() << nPrompts; + + if(nPrompts == 0) + { + //发送响应到子进程 + int j = 0; + PAM_RESPONSE *resp = (PAM_RESPONSE*)calloc(messageList.size(), sizeof(PAM_RESPONSE)); + //响应的数量和消息的数量一致,如果消息类型不是PROMPT,则响应是空的 + for(int i = 0; i < messageList.size(); i++) + { + struct pam_message message = messageList[i]; + PAM_RESPONSE *r = &resp[i]; + if(message.msg_style == PAM_PROMPT_ECHO_OFF + || message.msg_style == PAM_PROMPT_ECHO_ON) + { + int respLength = responseList[j].length() + 1; + r->resp = (char *)malloc(sizeof(char) * respLength); + memcpy(r->resp, responseList[j].toLocal8Bit().data(), respLength); + j++; + } + } + _respond(resp); + free(resp); + messageList.clear(); + responseList.clear(); + } +} + +bool AuthPAM::isAuthenticated() +{ + return _isAuthenticated; +} + +bool AuthPAM::isAuthenticating() +{ + return _isAuthenticating; +} + + +void AuthPAM::onSockRead() +{ +// qDebug() << "has message"; + int msgLength; + int authComplete = 0; + readData(toParent[0], &authComplete, sizeof(authComplete)); + + if(authComplete) + { + int authRet = -1; + if(readData(toParent[0], (void*)&authRet, sizeof(authRet)) <= 0) + qDebug() << "get authentication result failed: " << strerror(errno); + qDebug() << "result: " << authRet; + _isAuthenticated = (authRet == PAM_SUCCESS); + _isAuthenticating = false; + if(notifier){ + notifier->deleteLater(); + notifier = nullptr; + } + Q_EMIT authenticateComplete(); + + } + else + { + readData(toParent[0], &msgLength, sizeof(msgLength)); +// qDebug() << "message length: " << msgLength; + + for(int i = 0; i < msgLength; i++) + { + //读取message + struct pam_message message; + readData(toParent[0], &message.msg_style, sizeof(message.msg_style)); + message.msg = readString(toParent[0]); + + qDebug() << message.msg; + + messageList.push_back(message); + + switch (message.msg_style) + { + case PAM_PROMPT_ECHO_OFF: + nPrompts++; + Q_EMIT showPrompt(message.msg, Auth::PromptTypeSecret); + break; + case PAM_PROMPT_ECHO_ON: + nPrompts++; + Q_EMIT showPrompt(message.msg, Auth::PromptTypeQuestion); + break; + case PAM_ERROR_MSG: + Q_EMIT showMessage(message.msg, Auth::MessageTypeInfo); + break; + case PAM_TEXT_INFO: + Q_EMIT showMessage(message.msg, Auth::MessageTypeError); + break; + } + } + + if(nPrompts == 0) + { + //不需要响应,发送一个空的 + PAM_RESPONSE *response = (PAM_RESPONSE*)calloc(messageList.size(), sizeof(PAM_RESPONSE)); + _respond(response); + free(response); + messageList.clear(); + } + } +} + +static void +writeData(int fd, const void *buf, ssize_t count) +{ + if(write(fd, buf, count) != count) + qDebug() << "write to parent failed: " << strerror(errno); +} + +static void +writeString(int fd, const char *data) +{ + int length = data ? strlen(data) : -1; + writeData(fd, &length, sizeof(length)); + if(data) + writeData(fd, data, sizeof(char) * length); +} + +static int +readData(int fd, void *buf, size_t count) +{ + ssize_t nRead = read(fd, buf, count); + if(nRead < 0) + qDebug() << "read data failed: " << strerror(errno); + return nRead; +} + +static char * +readString(int fd) +{ + int length; + + if(readData(fd, &length, sizeof(length)) <= 0) + return NULL; + if(length <= 0) + length = 0; + + char *value = (char *)malloc(sizeof(char) * (length + 1)); + readData(fd, value, length); + value[length] = '\0'; + + return value; +} + +void AuthPAM::_authenticate(const char *userName) +{ + qDebug() << "authenticate " << userName; + + pam_handle_t *pamh = NULL; + char *newUser; + int ret; + int authRet; + struct pam_conv conv; + + conv.conv = pam_conversation; + conv.appdata_ptr = NULL; + + ret = pam_start(PAM_SERVICE_NAME, userName, &conv, &pamh); + if(ret != PAM_SUCCESS) + { + qDebug() << "failed to start PAM: " << pam_strerror(NULL, ret); + } + + authRet = pam_authenticate(pamh, 0); + + ret = pam_get_item(pamh, PAM_USER, (const void **)&newUser); + if(ret != PAM_SUCCESS) + { + pam_end(pamh, 0); + qDebug() << "failed to get username"; + } + if(authRet == PAM_SUCCESS) + ret = pam_acct_mgmt(pamh, 0); + + if(ret != PAM_SUCCESS) + { + qDebug() << "failed to acct mgmt " << pam_strerror(NULL, ret); + } + + free(newUser); + fprintf(stderr, "authentication result: %d\n", authRet); + + // 发送认证结果 + int authComplete = 1; + writeData(toParent[1], (const void*)&authComplete, sizeof(authComplete)); + writeData(toParent[1], (const void *)&authRet, sizeof(authRet)); + qDebug() << "--- 认证完成"; + _exit(EXIT_SUCCESS); +} + +void AuthPAM::_respond(const PAM_RESPONSE *response) +{ + for(int i = 0; i < messageList.size(); i++) + { + const PAM_RESPONSE *resp = &response[i]; + writeData(toChild[1], (const void *)&resp->resp_retcode, + sizeof(resp->resp_retcode)); + writeString(toChild[1], resp->resp); + } +} + + +static int +pam_conversation(int msgLength, const struct pam_message **msg, + PAM_RESPONSE **resp, void */*appData*/) +{ + PAM_RESPONSE *response = (PAM_RESPONSE*)calloc(msgLength,sizeof(PAM_RESPONSE)); + + int authComplete = 0; + writeData(toParent[1], (const void*)&authComplete, sizeof(authComplete)); + writeData(toParent[1], (const void*)&msgLength, sizeof(msgLength)); + //发送pam消息 + for(int i = 0; i < msgLength; i++) + { + const struct pam_message *m = msg[i]; + writeData(toParent[1], (const void *)&m->msg_style, sizeof(m->msg_style)); + writeString(toParent[1], m->msg); + } + //读取响应 + for(int i = 0; i < msgLength; i++) + { + PAM_RESPONSE *r = &response[i]; + readData(toChild[0], &r->resp_retcode, sizeof(r->resp_retcode)); + r->resp = readString(toChild[0]); + } + *resp = response; + return PAM_SUCCESS; +} + +void sigchld_handler(int signo) +{ + if(signo == SIGCHLD) + { + ::waitpid(-1, NULL, WNOHANG); + } +} diff --git a/src/auth-pam.h b/src/auth-pam.h new file mode 100644 index 0000000..3fba36c --- /dev/null +++ b/src/auth-pam.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef AUTHPAM_H +#define AUTHPAM_H +#include "auth.h" +#include +#include + +#include + +typedef struct pam_message PAM_MESSAGE; +typedef struct pam_response PAM_RESPONSE; + +class AuthPAM : public Auth +{ + Q_OBJECT +public: + AuthPAM(QObject *parent = nullptr); + + void authenticate(const QString &userName); + void stopAuth(); + void respond(const QString &response); + bool isAuthenticated(); + bool isAuthenticating(); + +private: + void _authenticate(const char *userName); + void _respond(const struct pam_response *response); + +private Q_SLOTS: + void onSockRead(); + +private: + QString userName; + pid_t pid; + QSocketNotifier *notifier; + int nPrompts; + QStringList responseList; + QList messageList; + bool _isAuthenticated; //认证结果 + bool _isAuthenticating; +}; + +#endif // AUTHPAM_H diff --git a/src/auth.h b/src/auth.h new file mode 100644 index 0000000..b2f8193 --- /dev/null +++ b/src/auth.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef AUTH_H +#define AUTH_H + +#ifndef QT_NO_KEYWORDS +#define QT_NO_KEYWORDS +#endif + +#include + +class Auth : public QObject +{ + Q_OBJECT + + Q_ENUMS(PromptType MessageType) +public: + explicit Auth(QObject *parent = nullptr) + : QObject(parent) + { + + } + + enum PromptType { + PromptTypeQuestion, + PromptTypeSecret + }; + enum MessageType { + MessageTypeInfo, + MessageTypeError + }; + + +Q_SIGNALS: + void showPrompt(const QString &prompt, Auth::PromptType type); + void showMessage(const QString &message, Auth::MessageType type); + void authenticateComplete(); + +public: + virtual void authenticate(const QString &userName) = 0; + virtual void stopAuth() = 0; + virtual void respond(const QString &response) = 0; + virtual bool isAuthenticating() = 0; + virtual bool isAuthenticated() = 0; +}; + +#endif // AUTH_H diff --git a/src/authdialog.cpp b/src/authdialog.cpp new file mode 100644 index 0000000..4852dcc --- /dev/null +++ b/src/authdialog.cpp @@ -0,0 +1,1078 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "authdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "users.h" +#include "iconedit.h" +#include "biometricproxy.h" +#include "biometricauthwidget.h" +#include "biometricdeviceswidget.h" +#include "pam-tally.h" +#include "commonfunc.h" +#include "loginoptionswidget.h" + +AuthDialog::AuthDialog(const UserItem &user, QWidget *parent) : + QWidget(parent), + user(user), + auth(new AuthPAM(this)), + authMode(UNKNOWN), + m_deviceCount(-1), + m_biometricProxy(nullptr), + m_widgetLoginOpts(nullptr), + m_buttonsWidget(nullptr), + m_retryButton(nullptr), + isBioPassed(false), + m_bioTimer(nullptr), + m_timer(nullptr), + isLockingFlg(false), + m_nCurLockMin(0), + useFirstDevice(false) +{ + initUI(); + pam_tally_init(); //这里写函数声明 + + connect(auth, &Auth::showMessage, this, &AuthDialog::onShowMessage); + connect(auth, &Auth::showPrompt, this, &AuthDialog::onShowPrompt); + connect(auth, &Auth::authenticateComplete, this, &AuthDialog::onAuthComplete); + + useFirstDevice = getUseFirstDevice(); + m_failedTimes.clear(); +} + +void AuthDialog::startAuth() +{ + prompted = false; + unacknowledged_messages = false; + auth->authenticate(user.name); + + m_passwordEdit->clear(); + m_passwordEdit->readOnly(true); +} + +void AuthDialog::stopAuth() +{ + if(m_widgetLoginOpts) + { + if(m_bioTimer && m_bioTimer->isActive()) + m_bioTimer->stop(); + m_widgetLoginOpts->stopAuth(); + + m_widgetLoginOpts->hide(); + } + + clearMessage(); + // auth->stopAuth(); + m_passwordEdit->readOnly(true); +// if(m_passwdWidget) +// m_passwdWidget->hide(); +} + +QPixmap AuthDialog::PixmapToRound(const QPixmap &src, int radius) +{ + if (src.isNull()) { + return QPixmap(); + } + + QPixmap pixmapa(src); + QPixmap pixmap(radius*2,radius*2); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + QPainterPath path; + path.addEllipse(0, 0, radius*2, radius*2); + painter.setClipPath(path); + painter.drawPixmap(0, 0, radius*2, radius*2, pixmapa); + return pixmap; +} + +void AuthDialog::initUI() +{ + if (scale < 0.5) { + setFixedWidth(360); + } else { + setFixedWidth(600); + } + + m_userWidget = new QWidget(this); + m_userWidget->setObjectName(QStringLiteral("userWidget")); + + /* 头像 */ + const QString SheetStyle = QString("border-radius: %1px; border:0px solid white;").arg(77*scale); + m_labelHeadImg = new QLabel(m_userWidget); + m_labelHeadImg->setObjectName(QStringLiteral("faceLabel")); + m_labelHeadImg->setFocusPolicy(Qt::NoFocus); + m_labelHeadImg->setStyleSheet(SheetStyle); + m_labelHeadImg->setAlignment(Qt::AlignCenter); + m_labelHeadImg->hide(); + + QPixmap facePixmap(user.icon); + facePixmap = facePixmap.scaled(154*scale,154*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + facePixmap = PixmapToRound(facePixmap, 77*scale); + m_labelHeadImg->setAlignment(Qt::AlignCenter); + m_labelHeadImg->setPixmap(facePixmap); + + // 人脸识别 + m_labelFace = new QLabel(m_userWidget); + m_labelFace->setObjectName("faceLabel"); + m_labelFace->setAlignment(Qt::AlignCenter); + m_labelFace->hide(); + + // 二维码窗口 + m_labelLoginTypeTip = new QLabel(m_userWidget); + //m_labelLoginTypeTip->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + m_labelLoginTypeTip->setObjectName("loginTypeTipLabel"); + m_labelLoginTypeTip->setAlignment(Qt::AlignCenter); + QFont font = m_labelLoginTypeTip->font(); + font.setPixelSize(14); + m_labelLoginTypeTip->setFont(font); + m_labelQRCode = new QLabel(m_userWidget); + m_labelQRCode->setObjectName("qrCodeLabel"); + m_labelQRCode->setAlignment(Qt::AlignCenter); + m_labelQRCode->hide(); + QVBoxLayout *layoutQRCode = new QVBoxLayout(); + layoutQRCode->setAlignment(Qt::AlignCenter); + layoutQRCode->setSpacing(10); + m_labelQRCode->setLayout(layoutQRCode); + m_labelQRCodeTip = new QLabel(); + m_labelQRCodeTip->setFixedSize(22,22); + m_labelQRCodeTip->setPixmap(QIcon::fromTheme("ukui-dialog-warning").pixmap(QSize(22,22))); + layoutQRCode->addWidget(m_labelQRCodeTip, 0, Qt::AlignHCenter); + m_labelQRCodeMsg = new QLabel(); + m_labelQRCodeMsg->setFixedHeight(24); + font = m_labelQRCodeMsg->font(); + font.setPixelSize(16); + m_labelQRCodeMsg->setStyleSheet("QLabel{background-color:rgba(255,255,255,0);color:rgb(255,0,0)}"); + m_labelQRCodeMsg->setFont(font); + layoutQRCode->addWidget(m_labelQRCodeMsg, 0, Qt::AlignHCenter); + + /* 用户名 */ + m_nameLabel = new QLabel(m_userWidget); + m_nameLabel->setObjectName(QStringLiteral("login_nameLabel")); + m_nameLabel->setFocusPolicy(Qt::NoFocus); + m_nameLabel->setAlignment(Qt::AlignCenter); + m_nameLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + //m_nameLabel->setText(user.realName.isEmpty() ? user.name : user.realName); + QString text = user.realName.isEmpty() ? user.name : user.realName; + font = m_nameLabel->font(); + font.setPixelSize(24); + QString str = ElideText(font,500,text); + if(text != str) + m_nameLabel->setToolTip(text); + if(text == str) + m_nameLabel->setToolTip(""); + m_nameLabel->setText(str); + + + /* 密码框所在窗口 */ + m_passwdWidget = new QWidget(this); + m_passwdWidget->setObjectName(QStringLiteral("passwordWidget")); + + /* 密码框 */ + m_passwordEdit = new IconEdit(m_passwdWidget); + connect(m_passwordEdit,&IconEdit::clickedPassword, + this,&AuthDialog::onM_passwordEditClicked); + + m_passwdWidget->setInputMethodHints(Qt::ImhNone); + m_passwordEdit->setObjectName(QStringLiteral("passwordEdit")); + m_passwordEdit->setIcon(QIcon(":/image/assets/login-button.svg")); + m_passwordEdit->setFocusPolicy(Qt::StrongFocus); + m_passwordEdit->installEventFilter(this); + m_passwordEdit->readOnly(true); + m_passwordEdit->setType(QLineEdit::Password); + setFocusProxy(m_passwordEdit); + connect(m_passwordEdit, SIGNAL(clicked(const QString&)), + this, SLOT(onRespond(const QString&))); + + //m_passwdWidget->hide(); + + /* 密码认证信息显示列表 */ + m_messageLabel = new QLabel(m_passwdWidget); + m_messageLabel->setObjectName(QStringLiteral("messageLabel")); + m_messageLabel->setAlignment(Qt::AlignLeft); + font = m_messageLabel->font(); + font.setPixelSize(14); + m_messageLabel->setFont(font); + m_messageLabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + + m_messageButton = new QPushButton(m_passwdWidget); + m_messageButton->setObjectName(QStringLiteral("messageButton")); + m_messageButton->hide(); +} + +void AuthDialog::unlock_countdown() +{ + int failed_count = 0; + int time_left = 0; + int deny = 0; + int fail_time =0; + int unlock_time = 0; + pam_tally_unlock_time_left(user.uid, &failed_count, &time_left, &deny,&fail_time,&unlock_time); + + // qDebug() << "failed_count:" << failed_count << "time_left:" <= 60)//请多少分钟后重试 + { + int nMinuteleft = time_left/60; + if (isLockingFlg == false){ + m_nCurLockMin = unlock_time/60;//获取当前需要锁定的分钟数 + } + + //如果当前设置的不是1min钟锁定,那么1min显示成2min,由2min直接跳到59s || 剩余分钟数小于当前设置的锁定时间,并且大于1min,自增+1 + if ((nMinuteleft == 1 && m_nCurLockMin != 1) || (nMinuteleft > 1 && nMinuteleft < m_nCurLockMin)) + { + nMinuteleft = nMinuteleft + 1; + } + + m_messageLabel->setText(tr("Please try again in %1 minutes.").arg(nMinuteleft)); + m_messageLabel->setToolTip(tr("Please try again in %1 minutes.").arg(nMinuteleft)); + m_passwordEdit->clearText(); + m_passwordEdit->readOnly(true); + m_passwordEdit->setLocked(true); + isLockingFlg = true; + return ; + } + else if(time_left > 0 && time_left < 60)//请多少秒后重试 + { + m_messageLabel->setText(tr("Please try again in %1 seconds.").arg(time_left%60)); + m_messageLabel->setToolTip(tr("Please try again in %1 seconds.").arg(time_left%60)); + m_passwordEdit->clearText(); + m_passwordEdit->readOnly(true); + m_passwordEdit->setLocked(true); + isLockingFlg = true; + return ; + } + else if (failed_count == 0xFFFF)//账号被永久锁定 + { + m_messageLabel->setText(tr("Account locked permanently.")); + m_messageLabel->setToolTip(tr("Account locked permanently.")); + m_passwordEdit->clearText(); + m_passwordEdit->readOnly(true); + m_passwordEdit->setLocked(true); + isLockingFlg = true; + return ; + } + else + { + if(m_passwordEdit){ + m_passwordEdit->readOnly(false); + m_passwordEdit->setFocus(); + } + if (isLockingFlg) + { + onShowMessage("",Auth::MessageTypeError); + isLockingFlg = false; + m_passwordEdit->setLocked(false); + } + + m_timer->stop(); + } + return ; +} + +void AuthDialog::root_unlock_countdown() +{ + int failed_count = 0; + int time_left = 0; + int deny = 0; + int fail_time =0; + int unlock_time = 0; + pam_tally_root_unlock_time_left(&failed_count, &time_left, &deny,&fail_time,&unlock_time); + if(time_left >= 60)//请多少分钟后重试 + { + int nMinuteleft = time_left/60; + if (isLockingFlg == false){ + m_nCurLockMin = unlock_time/60;//获取当前需要锁定的分钟数 + } + + + //如果当前设置的不是1min钟锁定,那么1min显示成2min,由2min直接跳到59s || 剩余分钟数小于当前设置的锁定时间,并且大于1min,自增+1 + if ((nMinuteleft == 1 && m_nCurLockMin != 1) || (nMinuteleft > 1 && nMinuteleft < m_nCurLockMin)) + { + nMinuteleft = nMinuteleft + 1; + } + + m_messageLabel->setText(tr("Please try again in %1 minutes.").arg(nMinuteleft)); + m_messageLabel->setToolTip(tr("Please try again in %1 minutes.").arg(nMinuteleft)); + m_passwordEdit->clearText(); + m_passwordEdit->readOnly(true); + isLockingFlg = true; + return ; + } + else if(time_left > 0 && time_left < 60)//请多少秒后重试 + { + m_messageLabel->setText(tr("Please try again in %1 seconds.").arg(time_left%60)); + m_messageLabel->setToolTip(tr("Please try again in %1 seconds.").arg(time_left%60)); + m_passwordEdit->clearText(); + m_passwordEdit->readOnly(true); + isLockingFlg = true; + return ; + } + else if (failed_count == 0xFFFF)//账号被永久锁定 + { + m_messageLabel->setText(tr("Account locked permanently.")); + m_messageLabel->setToolTip(tr("Account locked permanently.")); + m_passwordEdit->clearText(); + m_passwordEdit->readOnly(true); + isLockingFlg = true; + return ; + } + else + { + if(m_passwordEdit){ + m_passwordEdit->readOnly(false); + m_passwordEdit->setFocus(); + } + if (isLockingFlg) + { + onShowMessage("",Auth::MessageTypeError); + isLockingFlg = false; + } + + m_timer->stop(); + } + return ; +} + +void AuthDialog::resizeEvent(QResizeEvent *) +{ + setChildrenGeometry(); +} + +void AuthDialog::setChildrenGeometry() +{ + if(scale < 0.5) + setFixedWidth(500); + // 用户信息显示位置 + m_userWidget->setGeometry(0, 0, + width(), 376*scale); + m_labelLoginTypeTip->setGeometry(0,0,m_userWidget->width(), 24); + m_labelLoginTypeTip->setAlignment(Qt::AlignCenter); + m_labelHeadImg->setStyleSheet(QString("border-radius: %1px; border:0px solid white;").arg(77*scale)); + m_labelHeadImg->setGeometry((width() - 154*scale) / 2 , m_labelLoginTypeTip->geometry().bottom()+24*scale, 154*scale, 154*scale); + QPixmap facePixmap(user.icon); + facePixmap = facePixmap.scaled(154*scale,154*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + facePixmap = PixmapToRound(facePixmap, 77*scale); + m_labelHeadImg->setPixmap(facePixmap); + + m_labelQRCode->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(255,255,255,100%);").arg(6*scale)); + m_labelQRCode->setGeometry((width() - 154*scale) / 2 , m_labelLoginTypeTip->geometry().bottom()+24*scale, 154*scale, 154*scale); + setQRCode(m_imgQRCode); + + m_labelFace->setStyleSheet(QString("border-radius: %1px; border:0px solid white;background-color: rgba(255,255,255,10%);").arg(77*scale)); + m_labelFace->setGeometry((width() - 154*scale) / 2 , m_labelLoginTypeTip->geometry().bottom()+24*scale, 154*scale, 154*scale); + QImage faceImg; + setFaceImg(faceImg); + + m_nameLabel->setGeometry(0, m_labelHeadImg->geometry().bottom() + 16*scale, + width(), 34); + + m_passwdWidget->setGeometry(0, m_nameLabel->geometry().bottom() + 24*scale, width(), 100); + m_passwordEdit->setGeometry((m_passwdWidget->width() - 240)/2, 0, 240, 40); + m_messageLabel->setGeometry((m_passwdWidget->width() - 240)/2, + m_passwordEdit->geometry().bottom() + 4, + width()-(m_passwdWidget->width() - 240)/2, 20); + + m_messageButton->setGeometry((m_passwdWidget->width() - 200)/2, 0, 200, 40); + + setBiometricWidgetGeometry(); +} + +void AuthDialog::switchLoginOptType(unsigned uLoginOptType) +{ + switch(uLoginOptType) { + case LOGINOPT_TYPE_PASSWORD: + { + m_labelHeadImg->show(); + m_labelQRCode->hide(); + m_labelFace->hide(); + } + break; + case LOGINOPT_TYPE_FACE: + { + m_labelHeadImg->hide(); + m_labelQRCode->hide(); + m_labelFace->show(); + } + break; + case LOGINOPT_TYPE_FINGERPRINT: + case LOGINOPT_TYPE_VOICEPRINT: + case LOGINOPT_TYPE_FINGERVEIN: + case LOGINOPT_TYPE_IRIS: + { + m_labelHeadImg->show(); + m_labelQRCode->hide(); + m_labelFace->hide(); + } + break; + case LOGINOPT_TYPE_QRCODE: + { + m_labelHeadImg->hide(); + setQRCodeMsg(""); + m_labelQRCode->show(); + m_labelFace->hide(); + } + break; + default: + return; + } + if (uLoginOptType != m_uCurLoginOptType || (m_deviceInfo && m_deviceInfo->id != m_nLastDeviceId)) { + clearMessage(); + switch(uLoginOptType) { + case LOGINOPT_TYPE_PASSWORD: + { + setLoginTypeTip(""); + } + break; + case LOGINOPT_TYPE_FACE: + { + setLoginTypeTip(tr("Verify face recognition or enter password to unlock")); + } + break; + case LOGINOPT_TYPE_FINGERPRINT: + { + setLoginTypeTip(tr("Press fingerprint or enter password to unlock")); + } + break; + case LOGINOPT_TYPE_VOICEPRINT: + { + setLoginTypeTip(tr("Verify voiceprint or enter password to unlock")); + } + break; + case LOGINOPT_TYPE_FINGERVEIN: + { + setLoginTypeTip(tr("Verify finger vein or enter password to unlock")); + } + break; + case LOGINOPT_TYPE_IRIS: + { + setLoginTypeTip(tr("Verify iris or enter password to unlock")); + } + break; + case LOGINOPT_TYPE_QRCODE: + { + setLoginTypeTip(tr("Use the bound wechat scanning code or enter the password to unlock")); + } + break; + default: + return; + } + } + if (m_deviceInfo) { + m_nLastDeviceId = m_deviceInfo->id; + } else { + m_nLastDeviceId = -1; + } + + m_uCurLoginOptType = uLoginOptType; +} + + +void AuthDialog::closeEvent(QCloseEvent *event) +{ + qDebug() << "AuthDialog::closeEvent"; + + if(auth && auth->isAuthenticating()) + { + auth->stopAuth(); + } + + //调用kylin的接口,重新初始化 + QDBusInterface interface("com.kylin.network", + "/com/kylin/network", + "com.kylin.network", + QDBusConnection::sessionBus()); + QDBusMessage result = interface.call("keyRingInit"); + + return QWidget::closeEvent(event); +} + + +void AuthDialog::onShowMessage(const QString &message, Auth::MessageType type) +{ + qDebug()<setMinimumHeight(36); + if (message.indexOf("account locked") != -1 || message.indexOf("账户已锁定") != -1 + || message.indexOf("Account locked") != -1 || message.indexOf("永久锁定") != -1) + { + if(!m_timer){ + m_timer = new QTimer(this); + m_timer->setInterval(800); + connect(m_timer, &QTimer::timeout, this, &AuthDialog::unlock_countdown); + } + m_timer->start(); + }else if (message.indexOf("No password received, please input password") != -1){ + m_messageLabel->setText(tr("Password cannot be empty")); + m_messageLabel->setToolTip(tr("Password cannot be empty")); + } + else{ + QString strText = message; + if (!m_preStrMessage.isEmpty() && m_preStrMessageType != type && m_preStrMessageType != -1) + { + strText = m_preStrMessage + "," + strText; + } + QFontMetrics font(m_messageLabel->font()); + QString strDisplay = font.elidedText(message, Qt::ElideRight, m_messageLabel->width()-8); + m_messageLabel->setText(strDisplay); + m_messageLabel->setToolTip(message); + } + unacknowledged_messages = true; + //stopWaiting(); +} + +void AuthDialog::pamBioSuccess() +{ + m_bioTimer->stop(); + if (!m_widgetLoginOpts) { + switchLoginOptType(LOGINOPT_TYPE_PASSWORD); + return ; + } + m_widgetLoginOpts->startAuth(m_deviceInfo, user.uid); + if (m_deviceInfo) { + switchLoginOptType(m_widgetLoginOpts->convertDeviceType(m_deviceInfo->deviceType)); + } else { + switchLoginOptType(LOGINOPT_TYPE_PASSWORD); + } +} + +void AuthDialog::startBioAuth(unsigned uTimeout) +{ + if (m_widgetLoginOpts) + m_widgetLoginOpts->stopAuth(); + if(!m_bioTimer){ + m_bioTimer = new QTimer(this); + connect(m_bioTimer, SIGNAL(timeout()), this, SLOT(pamBioSuccess())); + } + m_bioTimer->start(uTimeout); + +} + +void AuthDialog::setX11Focus() +{ + if(m_passwordEdit && m_passwordEdit->isVisible()){ + m_passwordEdit->setX11Focus(); + } +} + +void AuthDialog::onShowPrompt(const QString &prompt, Auth::PromptType type) +{ + qDebug() << "-------prompt: " << prompt; + QString text = prompt; + + if(text == BIOMETRIC_PAM || text == BIOMETRIC_PAM_DOUBLE || text == BIOMETRIC_PAM_QRCODE) { + if(isBioPassed){ + onRespond(BIOMETRIC_SUCCESS); + return ; + } + if(authMode == PASSWORD) { + skipBiometricAuth(); + } else { + performBiometricAuth(); + } + } else { + stopWaiting(); + if(!text.isEmpty()) { + m_passwordEdit->readOnly(false); + m_passwordEdit->show(); + } + + m_passwordEdit->setFocus(); + + prompted = true; + unacknowledged_messages = false; + m_preStrMessage = ""; + if (!m_deviceInfo) { + switchLoginOptType(LOGINOPT_TYPE_PASSWORD); + } + + if(text == "Password: " || text == "密码:"){ + text = tr("Password "); + } else if (text == "Input password" || text == "Input Password" || text == "输入密码") { + text = tr("Input Password"); + } + + m_passwordEdit->clear(); + m_passwordEdit->setPrompt(text); + m_passwordEdit->show(); + if(!m_timer){ + m_timer = new QTimer(this); + m_timer->setInterval(200); + connect(m_timer, &QTimer::timeout, this, &AuthDialog::unlock_countdown); + } + m_timer->start(); + } +} + +void AuthDialog::onAuthComplete() +{ + stopWaiting(); + qDebug()<<"--------------------"<isAuthenticated(); + if(auth->isAuthenticated()) { + if (m_widgetLoginOpts) { + m_widgetLoginOpts->stopAuth(); + } + + if((prompted && !unacknowledged_messages )||direct_login) { + direct_login = false; + Q_EMIT authenticateCompete(true); + } else { + qDebug()<<"prompted = "<show(); + m_passwordEdit->hide(); + m_messageButton->show(); + m_messageButton->setFocus(); + m_messageButton->setDefault(true); + + connect(m_messageButton, &QPushButton::clicked, + this, &AuthDialog::onMessageButtonClicked); + if(successful) + { + isretry = false; + m_messageButton->setText(tr("Login")); + switchLoginOptType(LOGINOPT_TYPE_PASSWORD); + } + else + { + isretry = true; + m_messageButton->setText(tr("Retry")); + } + +} + +void AuthDialog::onMessageButtonClicked() +{ + m_messageButton->setDefault(false); + if(!isretry) + { + Q_EMIT authenticateCompete(true); + } + else + { + m_messageButton->hide(); + authMode = PASSWORD; + + m_messageLabel->setText(""); + startAuth(); + } +} + +void AuthDialog::onRespond(const QString &text) +{ + unacknowledged_messages=false; + clearMessage(); + startWaiting(); + m_passwordEdit->readOnly(true); + auth->respond(text); +} + +void AuthDialog::onM_passwordEditClicked() +{ + Q_EMIT clickPassword(true); +} + +//void AuthDialog::onCapsLockChanged() +//{ +// m_passwordEdit->onCapsStateChanged(); +//} + +void AuthDialog::startWaiting() +{ + if(m_buttonsWidget) + { + m_buttonsWidget->setEnabled(false); + } +} + +void AuthDialog::stopWaiting() +{ + m_passwordEdit->stopWaiting(); + if(m_buttonsWidget) + { + m_buttonsWidget->setEnabled(true); + } +} + +void AuthDialog::clearMessage() +{ + m_messageLabel->clear(); + m_preStrMessage = ""; + m_preStrMessageType = -1; +} + +void AuthDialog::performBiometricAuth() +{ + if(!m_biometricProxy) + { + m_biometricProxy = new BiometricProxy(this); + isHiddenSwitchButton = GetHiddenSwitchButton(); + maxFailedTimes = GetFailedTimes(); + } + + //服务没启动,或者打开DBus连接出错 + if(!m_biometricProxy->isValid()) + { + qWarning() << "An error occurs when connect to the biometric DBus"; + skipBiometricAuth(); + if (m_deviceInfo) { + if (!m_widgetLoginOpts || !m_widgetLoginOpts->findDeviceById(m_deviceInfo->id) + || m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) { + m_deviceInfo = DeviceInfoPtr(); + } + } + return; + } + + //初始化生物识别认证UI + initBiometricWidget(); + + //初始化enableBiometriAuth + if(m_deviceCount <= 0) + { + m_deviceCount = m_widgetLoginOpts->getLoginOptCount(); + } + + //没有可用设备,不启用生物识别认证 + if(m_deviceCount < 1) + { + qWarning() << "No available devices"; + skipBiometricAuth(); + return; + } + + //获取默认设备 + if(m_deviceName.isEmpty()) + { + m_deviceName = GetDefaultDevice(user.name); + } + qDebug() << m_deviceName; + if (m_deviceInfo) { + if (!m_widgetLoginOpts || !m_widgetLoginOpts->findDeviceById(m_deviceInfo->id) + || m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) { + m_deviceInfo = DeviceInfoPtr(); + } + } + + //如果默认设备为空的话,第一次不启动生物识别认证 + if(m_deviceName.isEmpty() && !m_deviceInfo) + { + if(useFirstDevice == true) { + m_deviceInfo = m_widgetLoginOpts->getFirstDevInfo(); + } else { + skipBiometricAuth(); + return; + } + } + + //clearMessage(); + + if(!m_deviceInfo) + { + m_deviceInfo = m_widgetLoginOpts->findDeviceByName(m_deviceName); + if (!m_deviceInfo) + m_deviceInfo = m_widgetLoginOpts->getFirstDevInfo(); + } + if(!m_deviceInfo) + { + skipBiometricAuth(); + return; + } + switchLoginOptType(m_widgetLoginOpts->convertDeviceType(m_deviceInfo->deviceType)); + startBioAuth(); + skipBiometricAuth(); +} + +void AuthDialog::skipBiometricAuth() +{ + auth->respond(BIOMETRIC_IGNORE); +} + +void AuthDialog::initBiometricWidget() +{ + if(m_widgetLoginOpts) { + m_widgetLoginOpts->setUser(user.uid); + } else { + m_widgetLoginOpts = new LoginOptionsWidget(m_biometricProxy, user.uid, this); + connect(m_widgetLoginOpts, &LoginOptionsWidget::authComplete, + this, &AuthDialog::onBiometricAuthComplete); + connect(m_widgetLoginOpts, &LoginOptionsWidget::optionSelected, + this, &AuthDialog::onDeviceChanged); + connect(m_widgetLoginOpts, &LoginOptionsWidget::updateImage, + this, &AuthDialog::onLoginOptImage); + connect(m_widgetLoginOpts, &LoginOptionsWidget::notifyOptionsChange, + this, &AuthDialog::onLoginOptsCount); + connect(m_widgetLoginOpts, &LoginOptionsWidget::updateAuthMsg, + this, &AuthDialog::setLoginMsg); + } + + qDebug()<<"----------DeviceCount:"<getLoginOptCount(); + if (m_widgetLoginOpts->getLoginOptCount() < 1) + m_widgetLoginOpts->hide(); + else + m_widgetLoginOpts->show(); + m_widgetLoginOpts->setEnabled(true); + + setBiometricWidgetGeometry(); +} + +void AuthDialog::setBiometricWidgetGeometry() +{ + //生物识别 + if(m_widgetLoginOpts) + { + m_widgetLoginOpts->setGeometry(0, m_passwdWidget->geometry().bottom(), + width(), 84*scale); + qDebug()<<"LoginOptGeometry:"<geometry()<<","<geometry() + <<","<isHidden(); + } +} + +void AuthDialog::onDeviceChanged(unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo) +{ + if (!deviceInfo) + return; + qDebug() << "device changed: " << *deviceInfo; + if(m_failedTimes.contains(deviceInfo->id) && + m_failedTimes[deviceInfo->id] >= maxFailedTimes){ + qDebug() << "Failed MAX:"<id; + return ; + } + if (deviceInfo == m_deviceInfo) { + return ; + } + m_deviceInfo = deviceInfo; + switchLoginOptType(uCurLoginOptType); + if(!isBioPassed) + startBioAuth(); +} + +void AuthDialog::onBiometricAuthComplete(bool result, int nStatus) +{ + if(!result) { + if (nStatus >= 2) { + if (m_deviceInfo) { + if (m_failedTimes.contains(m_deviceInfo->id)) { + m_failedTimes[m_deviceInfo->id] = m_failedTimes[m_deviceInfo->id] + 1; + } else { + m_failedTimes[m_deviceInfo->id] = 1; + } + qDebug()<<"Failed count:"<id]<<",Max:"<id; + if (m_deviceInfo->deviceType == DeviceType::Face) { + QImage imgFailed; + setFaceImg(imgFailed, 1); + } + if(m_failedTimes[m_deviceInfo->id] >= maxFailedTimes){ + if (m_deviceInfo->deviceType == REMOTE_QRCODE_TYPE) { + setLoginTypeTip(tr("Failed to verify %1, please enter password to unlock").arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType))); + QImage nullImage; + setQRCode(nullImage); + } else { + setLoginTypeTip(tr("Unable to verify %1, please enter password to unlock").arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType))); + } + if (m_widgetLoginOpts) + m_widgetLoginOpts->setDeviceDisable(m_deviceInfo->id, true); + return ; + } + setLoginTypeTip(tr("Failed to verify %1, you still have %2 verification opportunities") + .arg(DeviceType::getDeviceType_tr(m_deviceInfo->deviceType)) + .arg(maxFailedTimes-m_failedTimes[m_deviceInfo->id])); + } + } + + if(!isBioPassed) { + if (nStatus <= 0) { + qDebug()<<"Biometric dbus error:"<= 2 && m_deviceInfo) { + if (m_deviceInfo->deviceType == DeviceType::Face) { + QImage imgFailed; + setFaceImg(imgFailed, 1); + } + } + } + } else { + direct_login = true; + isBioPassed = true; + onBiometricButtonClicked(); + } +} + +void AuthDialog::onBiometricButtonClicked() +{ + //当前没有设备 + if (!m_deviceInfo) { + qWarning()<<"未选择生物设备--"; + return ; + } + authMode = BIOMETRIC; + startAuth(); +} + +void AuthDialog::onPasswordButtonClicked() +{ + skipBiometricAuth(); +} + +void AuthDialog::onOtherDevicesButtonClicked() +{ + if (m_widgetLoginOpts) + m_widgetLoginOpts->stopAuth(); +} + +void AuthDialog::onRetryButtonClicked() +{ + if (m_widgetLoginOpts) + m_widgetLoginOpts->startAuth(m_deviceInfo, user.uid); + //m_retryButton->setVisible(false); +} + +void AuthDialog::setQRCode(QImage& imgQRCode) +{ + if (imgQRCode.isNull()) { + m_imgQRCode.load(":/image/assets/ukui-qrcode-null.svg"); + } else { + m_imgQRCode = imgQRCode; + } + m_imgQRCode = m_imgQRCode.scaled(QSize(150*scale, 150*scale)); + m_labelQRCode->setAlignment(Qt::AlignCenter); + m_labelQRCode->setPixmap(QPixmap::fromImage(m_imgQRCode)); +} + +void AuthDialog::setQRCodeMsg(QString strMsg) +{ + if (strMsg.isEmpty()) { + m_labelQRCodeMsg->hide(); + m_labelQRCodeTip->hide(); + } else { + m_labelQRCodeMsg->setText(strMsg); + m_labelQRCodeMsg->show(); + m_labelQRCodeTip->show(); + } +} + +void AuthDialog::setFaceImg(QImage& imgFace, int nStatus) +{ + QPixmap faceImage; + m_labelFace->setFixedSize(154*scale,154*scale); + //如果头像文件不存在,则使用默认头像 + if(!imgFace.isNull()) { + faceImage = PixmapToRound(QPixmap::fromImage(imgFace),77*scale); + } else { + switch(nStatus){ + case 1: + faceImage = QPixmap(":/image/assets/ukui-loginopt-lose.svg"); + break; + default: + faceImage = QPixmap(":/image/assets/ukui-loginopt-smile.svg"); + break; + } + } + + m_labelFace->setAlignment(Qt::AlignCenter); + m_labelFace->setPixmap(faceImage); +} + +void AuthDialog::setLoginTypeTip(QString strLoginTypeTip) +{ + m_strLoginTypeTip = strLoginTypeTip; + if (!m_strLoginTypeTip.isEmpty()) { + QFontMetrics font(m_labelLoginTypeTip->font()); + QString strDisplay = font.elidedText(m_strLoginTypeTip, Qt::ElideRight, m_messageLabel->width()-8); + m_labelLoginTypeTip->setText(strDisplay); + m_labelLoginTypeTip->setToolTip(m_strLoginTypeTip); + m_labelLoginTypeTip->show(); + } else { + m_labelLoginTypeTip->hide(); + } +} + +void AuthDialog::setLoginMsg(QString strLoginMsg) +{ + setLoginTypeTip(strLoginMsg); +} + +void AuthDialog::onLoginOptsCount(unsigned uCount) +{ + qDebug()<<"----------------------onLoginOptsCount Count:"< 0) { + setBiometricWidgetGeometry(); + m_widgetLoginOpts->show(); + } else { + switchLoginOptType(LOGINOPT_TYPE_PASSWORD); + m_widgetLoginOpts->hide(); + } + + if (!m_deviceInfo || !m_widgetLoginOpts->findDeviceById(m_deviceInfo->id) + || m_widgetLoginOpts->isDeviceDisable(m_deviceInfo->id)) { + m_widgetLoginOpts->stopAuth(); + authMode = BIOMETRIC; + startAuth(); + } +} + +void AuthDialog::onLoginOptImage(QImage img) +{ +// if (img.isNull()) { +// return ; +// } + if (m_uCurLoginOptType == LOGINOPT_TYPE_FACE) { + setFaceImg(img); + } else if (m_uCurLoginOptType == LOGINOPT_TYPE_QRCODE) { + setQRCode(img); + } +} diff --git a/src/authdialog.h b/src/authdialog.h new file mode 100644 index 0000000..73ecd16 --- /dev/null +++ b/src/authdialog.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef AUTHDIALOG_H +#define AUTHDIALOG_H + +#ifndef QT_NO_KEYWORDS +#define QT_NO_KEYWORDS +#endif + +#include +#include +#include +#include "auth-pam.h" +#include "types.h" +#include "users.h" +#include "biometricdeviceinfo.h" +#include "pam-tally.h" + +namespace Ui { +class AuthDialog; +} + +class QLabel; +class QPushButton; +class IconEdit; +class Auth; +class BiometricProxy; +class BiometricAuthWidget; +class BiometricDevicesWidget; +class PamTally; +class LoginOptionsWidget; + +extern float scale; +class AuthDialog : public QWidget +{ + Q_OBJECT + +public: + explicit AuthDialog(const UserItem &user, QWidget *parent = 0); + void resizeEvent(QResizeEvent *event); + void closeEvent(QCloseEvent *event); + void setUserOfAuth(); + void setX11Focus(); +private: + void initUI(); + void startWaiting(); + void stopWaiting(); + void clearMessage(); + void performBiometricAuth(); + void skipBiometricAuth(); + void initBiometricWidget(); + void setChildrenGeometry(); + void setBiometricWidgetGeometry(); + QPixmap PixmapToRound(const QPixmap &src, int radius); + void startBioAuth(unsigned uTimeout = 1000); + void show_authenticated (bool successful = true); + void setLoginTypeTip(QString strLoginTypeTip); + +private Q_SLOTS: + void onShowMessage(const QString &message, Auth::MessageType type); + void onShowPrompt(const QString &prompt, Auth::PromptType type); + void onAuthComplete(); + void onRespond(const QString &text); +// void onBioAuthStart(); +// void onBioAuthStop(); +// void setBioMovieImage(); +// void updateIcon(); + void onDeviceChanged(unsigned uCurLoginOptType, const DeviceInfoPtr &deviceInfo); + void onBiometricAuthComplete(bool result, int nStatus); + void onBiometricButtonClicked(); + void onPasswordButtonClicked(); + void onOtherDevicesButtonClicked(); + void onRetryButtonClicked(); + void pamBioSuccess(); + void onMessageButtonClicked(); + void switchLoginOptType(unsigned uLoginOptType); + void onLoginOptsCount(unsigned uCount); + void onLoginOptImage(QImage img); + void setLoginMsg(QString strLoginMsg); + void setQRCode(QImage& imgQRCode); + void setFaceImg(QImage& imgFace, int nStatus = 0); + void onM_passwordEditClicked(); + void setQRCodeMsg(QString strMsg); + +public Q_SLOTS: +// void switchToBiometric(); +// void switchToPassword(); +// void switchToDevices(); +// void onCapsLockChanged(); + void startAuth(); + void stopAuth(); + +Q_SIGNALS: + void authenticateCompete(bool result); + void clickPassword(bool clicked); +private: + UserItem user; + Auth *auth; + + enum AuthMode { PASSWORD, BIOMETRIC, UNKNOWN }; + + AuthMode authMode; + + // biometric auth + int m_deviceCount; + QString m_deviceName; + DeviceInfoPtr m_deviceInfo = nullptr; + BiometricProxy *m_biometricProxy; + BiometricAuthWidget *m_biometricAuthWidget; + QWidget *m_buttonsWidget; + QPushButton *m_biometricButton; + QPushButton *m_passwordButton; + QPushButton *m_otherDeviceButton; + QPushButton *m_retryButton; + + LoginOptionsWidget *m_widgetLoginOpts = nullptr; + + // UI +// QPushButton *m_backButton; //返回用户列表 + QWidget *m_userWidget; //放置用户信息Label + QLabel *m_labelHeadImg = nullptr; //头像 + QLabel *m_nameLabel; //用户名 +// QLabel *m_isLoginLabel; //提示是否已登录 + + QWidget *m_passwdWidget; //放置密码输入框和信息列表 + IconEdit *m_passwordEdit; //密码输入框 + QLabel *m_messageLabel; //PAM消息显示 + QPushButton *m_messageButton; + + QLabel *m_labelFace = nullptr; + QLabel *m_labelLoginTypeTip = nullptr; // 登录类型提示 + QLabel *m_labelQRCode = nullptr; // 二维码图标 + QLabel *m_labelQRCodeMsg = nullptr; // 二维码状态消息提示 + QLabel *m_labelQRCodeTip = nullptr; + + bool isBioPassed; // 生物认证是否成功 + int maxFailedTimes; + bool isHiddenSwitchButton; + QMap m_failedTimes; + QTimer *m_bioTimer; + bool useFirstDevice; + bool isLockingFlg; //判断当前是否正在锁定倒计时 + int m_nCurLockMin; //当前锁定的分钟数 + bool prompted = false; + bool unacknowledged_messages = false; + bool direct_login = false; + bool isretry = true; + QString m_preStrMessage = ""; + int m_preStrMessageType = -1; + + void root_unlock_countdown(); + void unlock_countdown(); + QTimer *m_timer; + + QImage m_imgQRCode; + unsigned m_uCurLoginOptType = LOGINOPT_TYPE_PASSWORD; // 当前登录验证方式 + QString m_strLoginTypeTip = ""; + int m_nLastDeviceId = -1; +}; + +#endif // AUTHDIALOG_H diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..b7ed8c8 --- /dev/null +++ b/src/common.h @@ -0,0 +1,61 @@ +#ifndef LOCKCOMMON_H +#define LOCKCOMMON_H + +enum SwitchPage{ + SwitchToPin = 0, + SwitchToWechat, + SwitchToCheck, + SwitchToResetPWD, + SwitchToConfigPWD +}; + +// 和后台规定好的 错误码固定值 +enum DBusMsgCode{ + + Error_QR_Get_Timeout = -8, // 二维码获取时间超时 + Error_NetWork = -7, // 网络错误 未能如期获得对应的数据 + Error_VerifyCode_Timeout = -6, // 验证码失效 + Error_RepeatedRequests = -5, // 重复请求二维码服务 + Error_NoReply = -4, // DBus接口连接失败导致的无回复错误 + Error_UnknownReason = -3, // 未知原因 + Error_ArgCnt = -2, // 参数个数错误 + Error_SetPsw_SameAsOriPsw = -1, // 设置新密码时 与原密码相同 + No_Error = 0, // 获取消息无错误 + Error_TelHaveBinded = 9009, // 手机号已绑定 -> 更换手机号后再试 + Error_VerifyCodeDiff = 9000, // 验证码错误 -> 请填写正确的验证码 + Error_AccessTokenInvalid = 9007,// Access Token 失效 -> 登录状态已过期,请重新扫码登录 + Error_ErrTimesOverMax = 9014, // 手机号登录时验证码错误次数超限 + // 账号密码登录时密码错误次数超限 + // 1小时内连续错10次触发 -> 1小时后再试 + Error_UserInfo = 9017, // 用户微信信息不存在 ->老用户,联系管理员处理 + Error_WechatHaveBinded = 9022, // 微信号已被其他账号绑定 -> 更换微信号再试 + Error_DeviceHaveBinded = 9027, // 当前设备已被绑定 -> 请联系管理员或班主任解绑 + Error_HaveBindOtherDevice = 9028, // 用户已绑定其他设备 -> 请联系管理员或班主任解绑 + + //以下错误码保留 + Error_NWUnused = 6, // 网络异常,请检查网络链接哦~ + Error_TencentUnused = 7, // 腾讯服务异常,请稍后再试~ + Error_NWDelay = 28, // 网络延迟大,请更换良好网络~ + Error_ResMalloc = 301, // 资源分配异常,请重启尝试 + Error_DBOpen = 101, // 数据库打开异常,请重试,或重启再试 + Error_DBGetKey = 102, // 获取数据库密钥失败,请重试 + Error_DBRetrieve = 103, // 数据库检索数据失败,请重试 + Error_DBDecryption = 105, // 数据库解密过程失败,请重试 +}; + + + +/*! + * \brief The QRCodeSwepState enum + * WaitingSwep 在DBus、SSOBackend、1.617 版本中未启用 + */ +enum QRCodeSwepState{ + WaitingSwep = 0, //等待用户扫码 + HaveSwep = 2, // 用户扫码、等待用户确认 + CancelSwep = 3, // 用户扫码后、取消确认 + ConfirmSuccess = 4, // 扫码确认成功 + QRCodeInvalid = 5, // 二维码失效 + QRCodeTimeout = 6, //二维码超时 +}; + +#endif // LOCKCOMMON_H diff --git a/src/configuration.cpp b/src/configuration.cpp new file mode 100644 index 0000000..ac964a0 --- /dev/null +++ b/src/configuration.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "configuration.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "commonfunc.h" +#define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" +#define KEY_MODE "mode" +#define KEY_THEMES "themes" +#define KEY_IDLE_ACTIVATION_ENABLED "idle-activation-enabled" +#define KEY_LOCK_ENABLED "lock-enabled" +#define KEY_IMAGE_TRANSITION_EFFECT "image-transition-effect" +#define KEY_IMAGE_SWITCH_INTERVAL "image-switch-interval" +#define KEY_BACKGROUND "background" +#define XSCREENSAVER_DIRNAME "/usr/lib/xscreensaver" +#define KEY_IDLE_DELAY "idleDelay" +#define KEY_IDLE_LOCK "idleLock" + +Configuration* Configuration::instance_ = nullptr; + +Configuration::Configuration(QObject *parent) : QObject(parent) +{ + /* QGSettings for screensaver */ + gsettings = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); + connect(gsettings, &QGSettings::changed, + this, &Configuration::onConfigurationChanged); + + /* Initiailization */ + mode = gsettings->get(KEY_MODE).toString(); + themes = gsettings->get(KEY_THEMES).toStringList(); + idleDelay = gsettings->get( + KEY_IDLE_DELAY).toInt(); + lockEnabled = gsettings->get(KEY_LOCK_ENABLED).toBool(); + idleLock = gsettings->get(KEY_IDLE_LOCK).toInt(); + imageSwitchInterval = gsettings->get(KEY_IMAGE_SWITCH_INTERVAL).toInt(); + imageTSEffect = gsettings->get(KEY_IMAGE_TRANSITION_EFFECT).toInt(); + background = gsettings->get(KEY_BACKGROUND).toString(); + + qDebug() << mode << themes; + qDebug() << imageSwitchInterval << imageTSEffect; + + int FileisExist = 0; + if(!background.isEmpty()) + { + QFileInfo file(background); + if(file.exists()==false) + FileisExist = 0; + else + FileisExist = 1; + } + + //如果org.ukui.screensaver background中的背景图片为空,则设为桌面背景 + if(background.isEmpty()||0==FileisExist) + { + QString currentDesktop = qgetenv("XDG_CURRENT_DESKTOP"); + if(currentDesktop == "UKUI" || currentDesktop == "MATE") + { + bgGsettings = new QGSettings("org.mate.background"); + background = bgGsettings->get("picture-filename").toString(); + } + else if(currentDesktop == "ubuntu:GNOME") + { + bgGsettings = new QGSettings("org.gnome.desktop.background"); + background = bgGsettings->get("picture-uri").toString(); + //去除前缀:file:///usr/share/background/xxx.png + background.remove(0, 7); + } + } + qDebug() << "background: " << background; + + if(themes.count() == 1 && themes[0] == "kyccss-personal-slideshow") + mode ="image"; +} + +Configuration* Configuration::instance(QObject *parent) +{ + if(instance_ == nullptr) + instance_ = new Configuration(parent); + return instance_; +} + +/* Update member value when GSettings changed */ +void Configuration::onConfigurationChanged(QString key) +{ + qDebug() << "GSettings value changed, key = " << key; + if (key == KEY_MODE) + mode = gsettings->get(KEY_MODE).toString(); + else if (key == KEY_THEMES) + themes = gsettings->get(KEY_THEMES).toStringList(); + else if (key == KEY_IDLE_DELAY) + idleDelay = gsettings->get(KEY_IDLE_DELAY).toInt(); + else if (key == KEY_IDLE_LOCK) + idleLock = gsettings->get(KEY_IDLE_LOCK).toInt(); + else if(key == KEY_IMAGE_TRANSITION_EFFECT) + imageTSEffect = gsettings->get(KEY_IMAGE_TRANSITION_EFFECT).toInt(); + else if(key == KEY_IMAGE_SWITCH_INTERVAL) + imageSwitchInterval = gsettings->get(KEY_IMAGE_SWITCH_INTERVAL).toInt(); +} + +/* + * Getter + */ + +/* Get the executable path of xscreensaver */ +ScreenSaver *Configuration::getScreensaver() +{ + QStringList modeStr{"blank-only", "random", "single", "image","default-ukui","default-ukui-custom"}; + ScreenSaver *saver = new ScreenSaver; + int index = modeStr.indexOf(mode); + saver->mode = SaverMode(index); + saver->interval = imageSwitchInterval; + saver->effect = TransitionEffect(imageTSEffect); + + switch(index){ + case SAVER_BLANK_ONLY: + break; + case SAVER_RANDOM: + { + if(themes.count()==0){ + saver->path = "/usr/lib/ukui-screensaver/ukui-screensaver-default"; + break; + } + qsrand((unsigned)time(0)); + int index = qrand() % themes.count(); + while(QString::compare(themes[index], "kyccss-personal-slideshow")==0) + { + index = qrand() % themes.count(); + } + saver->path = getXScreensaverPath(themes[index]); + break; + } + case SAVER_SINGLE: + if(themes.count()==0){ + saver->path = "/usr/lib/ukui-screensaver/ukui-screensaver-default"; + break; + } + saver->path = getXScreensaverPath(themes[0]); + break; + case SAVER_IMAGE: + { + QString lang = qgetenv("LANG"); + if (!lang.isEmpty()){ + qDebug()<<"lang = "<path = QDir::homePath() + "/图片"; + break; + } + } + saver->path = QDir::homePath() + "/" + QStandardPaths::displayName(QStandardPaths::PicturesLocation); + break; + } + case SAVER_DEFAULT: + saver->path = "/usr/lib/ukui-screensaver/ukui-screensaver-default"; + break; + case SAVER_DEFAULT_CUSTOM: + saver->path = "/usr/lib/ukui-screensaver/ukui-screensaver-default"; + break; + default: + break; + } + return saver; +} + +QString Configuration::getXScreensaverPath(const QString &theme) +{ + /* screensavers-ukui-binaryring => binaryring */ + QStringList strs = theme.split("-"); + QString str = strs.at(strs.size() - 1); + QString filePath = QString("%1/%2").arg(XSCREENSAVER_DIRNAME, str); + //除了判断gsetting值是否为空,还需要判断屏保文件是否存在,不存在就使用默认屏保。 + if(QFile(filePath).exists()) + return filePath; + else + return "/usr/lib/ukui-screensaver/ukui-screensaver-default"; +} + +QString Configuration::getBackground() +{ + if(ispicture(background)) + return background; + + return "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg"; +} + +int Configuration::xscreensaverActivatedWhenIdle() +{ + return idleDelay; +} + +bool Configuration::lockWhenXScreensaverActivated() +{ + return lockEnabled; +} diff --git a/src/configuration.h b/src/configuration.h new file mode 100644 index 0000000..a138775 --- /dev/null +++ b/src/configuration.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#ifndef QT_NO_KEYWORDS +#define QT_NO_KEYWORDS +#endif + +//#include "gsettings.h" + +#include +#include "screensaver.h" + +class QGSettings; + +class Configuration : public QObject +{ + Q_OBJECT +public: + explicit Configuration(QObject *parent = nullptr); + +public: + ScreenSaver *getScreensaver(); + static Configuration *instance(QObject *parent = nullptr); + QString getBackground(); + int xscreensaverActivatedWhenIdle(); + bool lockWhenXScreensaverActivated(); + +public Q_SLOTS: + void onConfigurationChanged(QString key); + +private: + QString getXScreensaverPath(const QString &theme); + +private: + QGSettings *gsettings; + QGSettings *bgGsettings; + QString mode; + QList themes; + QString background; + bool idleActivationEnabled; + bool lockEnabled; + int idleDelay; + int idleLock; + int imageTSEffect; + int imageSwitchInterval; + static Configuration *instance_; +}; + +#endif // CONFIGURATION_H diff --git a/src/digitalauthdialog.cpp b/src/digitalauthdialog.cpp new file mode 100644 index 0000000..6646352 --- /dev/null +++ b/src/digitalauthdialog.cpp @@ -0,0 +1,834 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#include "digitalauthdialog.h" +#include +#include +#include +#include +#include +#include + +#include "auth-pam.h" +#include "permissioncheck.h" +#include "eduplatforminterface.h" + +DigitalAuthDialog::DigitalAuthDialog(QWidget *parent) : QWidget(parent), + m_bgColor("#000000"), //整个wigidt背景颜色 + m_outCircleColor("#000000"), + m_tipLineColor("#ff0000"), + m_circleRingColor("#ddffff"), + m_radius(40), + m_margin(5), + m_pressed(false), + m_showText(true), + m_inputPassword(""), + m_circleColor("#ffffff"),//按钮的颜色 + m_statusRadius(8), + m_auth(new AuthPAM(this)), + m_isAuthing(false), + m_buttonWidth(96), + m_buttonHeight(64), + m_buttonRadius(16), + m_buttonStep(16), + m_resetPassword(""), + m_resetOrAuthFailure(new QLabel(this)), + m_digitalKeyBoard(new DigitalKeyBoard(this)) +{ + //获取键盘事件 此操作会使得其他控件无法获取键盘事件,使用releaseKeyboard可释放 +// grabKeyboard(); + m_posInCircle.isIn = false; +// qDebug() <<"-----------init width=" << width() << ",height=" << height(); + m_title = new QLabel(tr("LoginByUEdu"), this); + m_title->setStyleSheet("font-size:30px;color:#ffffff"); + m_title->adjustSize(); + + m_labelReset = new MyLabel(tr("ResetPWD?"), this); + m_labelReset->setStyleSheet("QLabel{font-size:16px;color:rgba(255, 255, 255, 45);}" + "QLabel:hover{color:rgba(255, 255, 255, 100);}"); + m_labelReset->adjustSize(); + + m_authMessage = new QLabel(this); + m_authMessage->setStyleSheet("font-size:14px;color:#ffffff"); + + //设置字体大小 + QFont f; + f.setPixelSize(m_radius * 24/40); + setFont(f); + + //调整适当的大小 + resize(350,600); + m_title->setGeometry((this->width() - m_title->width())/2, 6, m_title->width(), m_title->height()); + m_labelReset->setGeometry((this->width()- m_labelReset->width())/2, this->height() - 120, m_labelReset->width(),m_labelReset->height()); + + + setMouseTracking(true); + connect(m_digitalKeyBoard, &DigitalKeyBoard::numbersButtonPress, this, &DigitalAuthDialog::onNumerPress); + connect(m_auth, &Auth::showMessage, this, &DigitalAuthDialog::onShowMessage); + connect(m_auth, &Auth::showPrompt, this, &DigitalAuthDialog::onShowPrompt); + connect(m_auth, &Auth::authenticateComplete, this, &DigitalAuthDialog::onAuthComplete); + connect(m_labelReset, &MyLabel::onClick, this, [=]{ +// qDebug() << "-------------------onClick"; + m_title->setText(tr("SetNewUEduPWD")); + m_title->adjustSize(); + m_resetOrAuthFailure->clear(); + m_title->setGeometry((this->width() - m_title->width())/2, 5, m_title->width(), m_title->height()); + m_inputPassword.clear(); + m_loginType = LoginType::RESET; + m_labelReset->hide(); +// PermissionCheck *check = new PermissionCheck(this); +// QVBoxLayout *v = new QVBoxLayout(this); +// v->addWidget(check); +// this->hide(); + Q_EMIT requestPasswordReset(); + }); + +// m_timer = new QTimer(this); +// connect(m_timer,&QTimer::timeout,this,[=]{ +// if(m_isAuthing) +// { +// qDebug() << "Auth respond timeout , restart"; +// startAuth(); +// } +// }); + + m_digitalKeyBoard->move(9,143); +} + +DigitalAuthDialog::~DigitalAuthDialog() +{ + +} + +void DigitalAuthDialog::onNumerPress(int btn_id) +{ + qDebug() << btn_id; + //nothing + if(m_authMessage) + cleanMessage(); + if(m_resetOrAuthFailure) + m_resetOrAuthFailure->clear(); + m_pressed = true; + + if(m_isAuthing) + { + qWarning() << "authenticating"; + return; + } + + if(btn_id == 11) + { + //点击了清空按钮 + m_inputPassword.clear(); + } else if (btn_id == 10) + { + if (!m_inputPassword.isEmpty()) + m_inputPassword.remove(m_inputPassword.size() -1, 1); + } else { + int num = btn_id; + m_inputPassword.append(QString::number(num == 11 ? 0 : num)); + if (m_inputPassword.size() >= 6) + { + checkPassword(); + } + } + repaint(); +} + +void DigitalAuthDialog::paintEvent(QPaintEvent *event) +{ + int width = this->width(); + int height = this->height(); + int side = qMin(width, height); +// qDebug() <<"-----------width=" << width << ",height=" << height << ",side=" << side; + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.translate(width / 2, height / 2); + painter.scale(side / 200, side / 200); + +// drawBg(&painter); + drawStatusCircle(&painter); +//// drawOutCircle(&painter); +// drawFilledCircle(&painter); +//// drawTipLine(&painter); +// drawInCircle(&painter); +//// drawJoinLine(&painter); +// drawHoverCircle(&painter); +} + +//画背景颜色 +void DigitalAuthDialog::drawBg(QPainter *painter) +{ + painter->save(); + + int width = this->width(); + int height = this->height(); + + painter->setPen(Qt::NoPen); + m_bgColor.setAlpha(0); + painter->setBrush(m_bgColor); + painter->drawRect(-width / 2, -height / 2, width, height); + + painter->restore(); +} + +//绘制按钮的颜色 +void DigitalAuthDialog::drawFilledCircle(QPainter *painter) +{ + painter->save(); + m_circleColor.setAlphaF(0.15); + QPen pen(m_circleColor); + painter->setPen(pen); + painter->setBrush(m_circleColor); + + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 3; j++) + { + int x = -3 * (m_buttonWidth / 2) + j * m_buttonWidth + (j - 1) * m_buttonStep; + int y = -2 * m_buttonHeight + i * m_buttonHeight + m_buttonStep * i - 3 * (m_buttonStep / 2); + QRect rect(x, y, m_buttonWidth, m_buttonHeight); +// painter->drawEllipse(rect); + painter->drawRoundedRect(rect, m_buttonRadius, m_buttonRadius); + if (m_showText) + { + painter->save(); + painter->setPen(QColor("#ffffff")); + painter->setBrush(QColor("#ffffff")); + + int number = posToNumber(i, j); + if (number == 11) + { + number = 0; + } else if(number == 10) + { + // 数字10的地方是清空按钮 + x = (j - 1) * m_buttonWidth + (j - 1) * m_buttonStep;; + y = -3 * (m_buttonHeight / 2) + i * m_buttonHeight + m_buttonStep * i - 3 * (m_buttonStep / 2); + QString text = tr("clear"); + int textWidth = fontMetrics().width(text); + QFont font = painter->font(); + font.setPixelSize(m_radius * 20/40); + painter->setFont(font); + painter->drawText(x - textWidth / 2 + 3, y + textWidth / 2 - 18, text); + painter->restore(); + continue; + } + else if (number == 12) + { + // 画删除符号(3,2) + x = m_buttonWidth / 2 + m_buttonStep; + y = m_buttonHeight + 3 * (m_buttonStep / 2); + painter->drawPixmap(x + m_buttonWidth/2 - 15,y + m_buttonHeight/2 - 15, QPixmap(":/image/assets/intel/delete.svg")); + painter->restore(); + continue; + } + + QString text = QString::number(number); + x = (j - 1) * m_buttonWidth + (j - 1) * m_buttonStep;; + y = -3 * (m_buttonHeight / 2) + i * m_buttonHeight + m_buttonStep * i - 3 * (m_buttonStep / 2); + int textWidth = fontMetrics().width(text); + int textHeight = fontMetrics().height(); + painter->drawText(x - textWidth / 2, y + textWidth / 2 + 4, text); + painter->restore(); + } + } + } + painter->restore(); +} + +//画外圆 +void DigitalAuthDialog::drawOutCircle(QPainter *painter) +{ + painter->save(); + QPen pen(m_outCircleColor, 2); + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 3; j++) + { + int x = -3 * (m_buttonWidth / 2) + j * m_buttonWidth + (j - 1) * m_buttonStep; + int y = -2 * m_buttonHeight + i * m_buttonHeight + m_buttonStep * i - 3 * (m_buttonStep / 2); + QRect rect(x, y, m_buttonWidth, m_buttonHeight); +// painter->drawEllipse(rect); + painter->drawRoundedRect(rect, m_buttonRadius, m_buttonRadius); +// painter->drawEllipse(x, y, m_radius * 2, m_radius * 2); + if (m_showText) + { + int number = posToNumber(i, j); + QString text = QString::number(number); + x = -2 * m_radius + j * 2 * m_radius + (j - 1) * 16; + y = -3 * m_radius + i * 2 * m_radius + 16 * i - 24; + int textWidth = fontMetrics().width(text); + int textHeight = fontMetrics().height(); + painter->drawText(x - textWidth / 2, y + textWidth / 2, text); + } + } + } + + painter->restore(); +} + +void DigitalAuthDialog::drawTipLine(QPainter *painter) +{ + painter->save(); + + int offset = 3; + + if (m_posInCircle.isIn) + { + if (!m_pressed) + { + painter->setPen(m_tipLineColor); + painter->setBrush(Qt::NoBrush); + int x = -3 * (m_buttonWidth / 2) + m_posInCircle.j * m_buttonWidth + (m_posInCircle.j - 1) * m_buttonStep - offset; + int y = -2 * m_buttonHeight + m_posInCircle.i * m_buttonHeight + m_buttonStep * m_posInCircle.i - 3 * (m_buttonStep / 2) - offset; + QRect rect(x, y, m_buttonWidth, m_buttonHeight); + painter->drawRoundedRect(rect, m_buttonRadius, m_buttonRadius); + } + } + + painter->restore(); +} + +//绘制点击时的颜色 +void DigitalAuthDialog::drawInCircle(QPainter *painter) +{ + painter->save(); + + if (m_pressed) + { + if (m_posInCircle.isIn) + { + m_circleColor.setAlphaF(0.05); + painter->setPen(m_circleColor); + painter->setBrush(m_circleColor); + int x = -3 * (m_buttonWidth / 2) + m_posInCircle.j * m_buttonWidth + (m_posInCircle.j - 1) * m_buttonStep; + int y = -2 * m_buttonHeight + m_posInCircle.i * m_buttonHeight + m_buttonStep * m_posInCircle.i - 3 * (m_buttonStep / 2); + int w = m_buttonWidth; + int h = m_buttonHeight; + QRect rect = QRect(x, y, w, h); + painter->drawRoundedRect(rect, m_buttonRadius, m_buttonRadius); + } + } + + painter->restore(); +} + +//绘制悬浮时的颜色 +void DigitalAuthDialog::drawHoverCircle(QPainter *painter) +{ + painter->save(); + if (!m_pressed) + { + if (m_posInCircle.isIn) + { + m_circleColor.setAlphaF(0.35); + painter->setPen(m_circleColor); + painter->setBrush(m_circleColor); + int x = -3 * (m_buttonWidth / 2) + m_posInCircle.j * m_buttonWidth + (m_posInCircle.j - 1) * m_buttonStep; + int y = -2 * m_buttonHeight + m_posInCircle.i * m_buttonHeight + m_buttonStep * m_posInCircle.i - 3 * (m_buttonStep / 2); + int w = m_buttonWidth; + int h = m_buttonHeight; + QRect rect = QRect(x, y, w, h); + painter->drawRoundedRect(rect, m_buttonRadius, m_buttonRadius); + } + + } + + painter->restore(); +} + + +void DigitalAuthDialog::drawJoinLine(QPainter *painter) +{ + painter->save(); + + QPen pen(m_outCircleColor, 3); + painter->setPen(pen); + //绘制连接线段 + for (int i = 0; i < m_vecInputPoints.count() - 1; i++) + { + painter->drawLine(m_vecInputPoints[i], m_vecInputPoints[i + 1]); + } + + int offset1 = 1;//圆环偏移量 + int offset2 = 3;//内圆偏移量 + //绘制连接圆 + for (int i = 0; i < m_vecInputPoints.count(); i++) + { + int x = m_vecInputPoints[i].x() - m_radius + offset1; + int y = m_vecInputPoints[i].y() - m_radius + offset1; + int w = 2 * (m_radius - offset1); + int h = 2 * (m_radius - offset1); + painter->setPen(m_circleRingColor); + painter->setBrush(m_circleRingColor); + painter->drawEllipse(x, y, w, h); + + x = m_vecInputPoints[i].x() - m_radius + offset2; + y = m_vecInputPoints[i].y() - m_radius + offset2; + w = 2 * (m_radius - offset2); + h = 2 * (m_radius - offset2); + painter->setPen(m_outCircleColor); + painter->setBrush(m_outCircleColor); + painter->drawEllipse(x, y, w, h); + } + //绘制跟随线 + if (m_pressed && m_vecInputPoints.count() < 9) + { + int width = this->width(); + int height = this->height(); + int side = qMin(width, height); + int gestureScale = side / 200; + int x = (m_followPoint.x() - width / 2) / gestureScale; + int y = (m_followPoint.y() - height / 2) / gestureScale; + if (m_vecInputPoints.count() > 0) + { + painter->setPen(pen); + painter->drawLine(m_vecInputPoints.last(), QPoint(x, y)); + } + } + + painter->restore(); +} + +void DigitalAuthDialog::mouseMoveEvent(QMouseEvent *event) +{ +// bool temp = false; +// //nothing +// int x = (event->x() - this->width()/2) / (qMin(width(), height())/200); +// int y = (event->y() - this->height()/2) / (qMin(width(), height())/200); + +// for (int i = 0; i < 4; i++) +// { +// for (int j = 0; j < 3; j++) +// { +// int x1 = -3 * (m_buttonWidth / 2) + j * m_buttonWidth + (j - 1) * m_buttonStep; +// int y1 = -2 * m_buttonHeight + i * m_buttonHeight + m_buttonStep * i - 3 * (m_buttonStep / 2); +// if (isInButtonArea(x, y, x1, y1)) +// { +// m_posInCircle.i = i; +// m_posInCircle.j = j; +// m_posInCircle.isIn = true; +// temp = true; +// repaint(); +// } +// } +// } + +// if (!temp) +// { +// m_posInCircle.isIn = false; +// repaint(); +// } + +} + +void DigitalAuthDialog::mousePressEvent(QMouseEvent *event) +{ + //nothing +// if(m_authMessage) +// cleanMessage(); +// if(m_resetOrAuthFailure) +// m_resetOrAuthFailure->clear(); +// m_pressed = true; +// int x = (event->x() - this->width()/2) / (qMin(width(), height())/200); +// int y = (event->y() - this->height()/2) / (qMin(width(), height())/200); + +// for (int i = 0; i < 4; i++) +// { +// for (int j = 0; j < 3; j++) +// { +// int x1 = -3 * (m_buttonWidth / 2) + j * m_buttonWidth + (j - 1) * m_buttonStep; +// int y1 = -2 * m_buttonHeight + i * m_buttonHeight + m_buttonStep * i - 3 * (m_buttonStep / 2); +// if (isInButtonArea(x, y, x1, y1)) +// { +// if(m_isAuthing) +// { +// qWarning() << "authenticating"; +// return; +// } +// m_posInCircle.i = i; +// m_posInCircle.j = j; +// m_posInCircle.isIn = true; +// if(posToNumber(i, j) == 10) +// { +// //点击了清空按钮 +// m_inputPassword.clear(); +// } else if (posToNumber(i, j) == 12) +// { +// if (!m_inputPassword.isEmpty()) +// m_inputPassword.remove(m_inputPassword.size() -1, 1); +// } else { +// int num = posToNumber(i,j); +// m_inputPassword.append(QString::number(num == 11 ? 0 : num)); +// if (m_inputPassword.size() >= 6) +// { +// checkPassword(); +// } +//// qDebug() << "---------------选中了"<< posToNumber(i,j); +// } +// repaint(); +// } +// } +// } +} + +void DigitalAuthDialog::mouseReleaseEvent(QMouseEvent *event) +{ +// //nothing +// m_pressed = false; +// //m_posInCircle.isIn = false; +// repaint(); +} + +////监听键盘输入 +void DigitalAuthDialog::keyPressEvent(QKeyEvent *event) +{ + qDebug() << "keyPressEvent " << event->key(); + if (m_isAuthing) + { + qWarning() << "authenticating"; + return; + } + if(event->key() == Qt::Key_Backspace) + { + if (!m_inputPassword.isEmpty()) + m_inputPassword.remove(m_inputPassword.size() -1, 1); + } else if (event->key() >= Qt::Key_0 && event->key() <= Qt::Key_9 ) + { + if(m_resetOrAuthFailure) + m_resetOrAuthFailure->clear(); + m_inputPassword.append(event->text()); + if (m_inputPassword.size() >= 6) + { + checkPassword(); + m_inputPassword.clear(); + } + } else { + return; + } + repaint(); +} + +////监听键盘输入 +//void DigitalAuthDialog::RecieveKey(int key) +//{ +// qDebug() << "keyPressEvent " << key; +// if (m_isAuthing) +// { +// qWarning() << "authenticating"; +// return; +// } +// if(key == 10) +// { +// if (!m_inputPassword.isEmpty()) +// m_inputPassword.remove(m_inputPassword.size() -1, 1); +// } else if (key >= 0 && key <= 9 ) +// { +// if(m_resetOrAuthFailure) +// m_resetOrAuthFailure->clear(); +// m_inputPassword.append(QString::number(key)); +// if (m_inputPassword.size() >= 6) +// { +// checkPassword(); +// m_inputPassword.clear(); +// } +// } else { +// return; +// } +// repaint(); +//} + +double DigitalAuthDialog::distance(int x1, int y1, int x2, int y2) +{ + //nothing + double x = x1 - x2; + double y = y1 - y2; + return sqrt(x*x + y*y); +} + +int DigitalAuthDialog::posToNumber(int i, int j) +{ + //nothing + return ((3*i) + j +1); +} + +void DigitalAuthDialog::setPassword(const QString password) +{ + //ToDo + Q_EMIT setPinCode(password); +} + +QString DigitalAuthDialog::getPassword() +{ + //nothing +} + +bool DigitalAuthDialog::checkPassword() +{ + if(m_loginType == LoginType::AUTHENTICATE) + { + m_password = m_inputPassword; + qDebug() << "Input finished" << m_password; + m_auth->respond(m_password); + m_isAuthing = true; +// m_timer->start(5000); +// onShowMessage(tr("now is authing, wait a moment"), Auth::MessageTypeInfo); + } else if (m_loginType == LoginType::RESET) + { + m_resetPassword = m_inputPassword; + m_title->setText(tr("ConfirmNewUEduPWD")); + m_title->adjustSize(); + m_title->setGeometry((this->width() - m_title->width())/2, 5, m_title->width(), m_title->height()); + m_inputPassword.clear(); + m_loginType = LoginType::SECONDCONFIRMATION; + Q_EMIT switchToReset(false); + } else if (m_loginType == LoginType::SECONDCONFIRMATION) + { + if (m_resetPassword == m_inputPassword) + { + setPassword(m_resetPassword); + } else { + m_resetOrAuthFailure->setText(tr("The two password entries are inconsistent, please reset")); + m_resetOrAuthFailure->setStyleSheet("font-size:14px;color:rgba(255, 255, 255, 255)"); + m_resetOrAuthFailure->adjustSize(); + m_resetOrAuthFailure->setGeometry((this->width()- m_resetOrAuthFailure->width())/2, 120, + m_resetOrAuthFailure->width(),m_resetOrAuthFailure->height()); + showResetPasswordPage(); + Q_EMIT switchToReset(true); + } + } + return false; +} + +//画密码状态的圆圈 +void DigitalAuthDialog::drawStatusCircle(QPainter *painter) +{ + painter->save(); + + m_circleColor.setAlphaF(0.45); + QPen pen(m_circleColor, 2); + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + + for(int i = 0; i < 6; i++) + { + int x = -11 * m_statusRadius + i * 4 * m_statusRadius; + int y = -2 * m_buttonHeight - (11 * m_buttonStep) / 2; + if (i < m_inputPassword.size()) { + painter->save(); + painter->setBrush(QColor("#ffffff")); + QRect rect(x, y, 2 * m_statusRadius, 2 * m_statusRadius); + painter->drawEllipse(rect); + painter->restore(); + } else { + painter->drawEllipse(x, y, 2 * m_statusRadius, 2 * m_statusRadius); + } + } + painter->restore(); +} + +void DigitalAuthDialog::onShowMessage(const QString &message, Auth::MessageType type) +{ + m_authMessage->setText(message); + m_authMessage->adjustSize(); + m_authMessage->setGeometry((this->width()-m_authMessage->width())/2, this->height() -20, m_authMessage->width(),m_authMessage->height()); +} + +void DigitalAuthDialog::cleanMessage() +{ + m_authMessage->clear(); +} + +void DigitalAuthDialog::onShowPrompt(const QString &prompt, Auth::PromptType type) +{ + qDebug() << "prompt: " << prompt; +} + +void DigitalAuthDialog::onAuthComplete() +{ + qDebug() << "Auth Complete"; +// m_timer->stop(); + DBusMsgCode errcode = EduPlatformInterface::getInstance()->CheckToken(getenv("USER")); + if(m_auth->isAuthenticated()) + { + /* + DBusMsgCode errcode = EduPlatformInterface::getInstance()->CheckToken(getenv("USER")); + + if(DBusMsgCode::Error_AccessTokenInvalid == errcode){ + m_resetOrAuthFailure->setText(tr("登录状态已过期,请重新扫码登录")); + m_resetOrAuthFailure->setStyleSheet("font-size:14px;color:rgba(255, 255, 255, 255)"); + m_resetOrAuthFailure->adjustSize(); + m_resetOrAuthFailure->setGeometry((this->width()- m_resetOrAuthFailure->width())/2, 120, + m_resetOrAuthFailure->width(),m_resetOrAuthFailure->height()); + + startAuth(); + m_inputPassword.clear(); + m_password.clear(); + m_isAuthing = false; + repaint(); + return; + } + */ + Q_EMIT authenticateCompete(true); + m_isAuthing = false; + } + else + { + qWarning() << "auth failed"; + if(m_loginType == LoginType::AUTHENTICATE) + { + m_resetOrAuthFailure->setText(tr("Password entered incorrectly, please try again")); + m_resetOrAuthFailure->setStyleSheet("font-size:14px;color:rgba(255, 255, 255, 255)"); + m_resetOrAuthFailure->adjustSize(); + m_resetOrAuthFailure->setGeometry((this->width()- m_resetOrAuthFailure->width())/2, 120, + m_resetOrAuthFailure->width(),m_resetOrAuthFailure->height()); + } + //认证失败,重新认证 + startAuth(); + } + m_inputPassword.clear(); + m_password.clear(); + m_isAuthing = false; + repaint(); +} + +void DigitalAuthDialog::startAuth() +{ + m_inputPassword.clear(); + m_password.clear(); + m_auth->authenticate(getenv("USER")); + m_isAuthing = false; + repaint(); +} + +void DigitalAuthDialog::stopAuth() +{ + m_isAuthing = false; +} + +void DigitalAuthDialog::startWaiting() +{ + +} + +void DigitalAuthDialog::stopWaiting() +{ + +} + +void DigitalAuthDialog::closeEvent(QCloseEvent *event) +{ + qDebug() << "DigitalAuthDialog::closeEvent"; + + if(m_auth && m_auth->isAuthenticating()) + { + m_auth->stopAuth(); + } + return QWidget::closeEvent(event); +} + +bool DigitalAuthDialog::isInButtonArea(int x1, int y1, int x2, int y2) +{ + if (x1 >= x2 && x1 <= (x2 + m_buttonWidth) && y1 >= y2 && y1 <= (y2 + m_buttonHeight)) + return true; + return false; +} + +void DigitalAuthDialog::reset() +{ + m_title->setText(tr("LoginByUEdu")); + m_title->adjustSize(); + m_title->setGeometry((this->width() - m_title->width())/2, 5, m_title->width(), m_title->height()); + + m_labelReset->show(); + m_inputPassword.clear(); + m_resetPassword.clear(); + m_loginType = LoginType::AUTHENTICATE; + repaint(); +} + +/** + * @brief DigitalAuthDialog::showResetPasswordPage + * 重新展示重置密码页 + */ +void DigitalAuthDialog::showResetPasswordPage() +{ + m_title->setText(tr("SetNewUEduPWD")); + m_title->adjustSize(); + m_title->setGeometry((this->width() - m_title->width())/2, 5, m_title->width(), m_title->height()); + m_loginType = LoginType::RESET; + m_resetPassword.clear(); + m_inputPassword.clear(); + repaint(); + Q_EMIT switchToReset(true); +} + +int DigitalAuthDialog::getStatus() +{ + return m_loginType; +} + +void DigitalAuthDialog::showErrorMessage(QString message) +{ + m_resetOrAuthFailure->setText(message); + m_resetOrAuthFailure->setStyleSheet("font-size:14px;color:rgba(255, 255, 255, 255)"); + m_resetOrAuthFailure->adjustSize(); + m_resetOrAuthFailure->setGeometry((this->width()- m_resetOrAuthFailure->width())/2, 120, + m_resetOrAuthFailure->width(),m_resetOrAuthFailure->height()); + + QTimer::singleShot(3000,[=](){ + m_resetOrAuthFailure->clear(); + }); +} + +MyLabel::MyLabel(const QString & text,QWidget *parent) : QLabel(parent) +{ + setText(text); +} + +MyLabel::MyLabel(QWidget *parent) : QLabel(parent) +{ + +} + +void MyLabel::mousePressEvent(QMouseEvent *event) +{ + //Qt::LeftButton + //Qt::RightButton + if(event->button()== Qt::LeftButton) + { + this->setStyleSheet("QLabel{font-size:16px;color:rgba(255, 255, 255, 0.45);}"); + } +} + +void MyLabel::mouseReleaseEvent(QMouseEvent *event) +{ + //Qt::LeftButton + //Qt::RightButton + if(event->button()== Qt::LeftButton) + { + this->setStyleSheet("QLabel{font-size:16px;color:rgba(255, 255, 255, 0.35);}" + "QLabel:hover{color:rgba(255, 255, 255, 1);}"); + Q_EMIT onClick(); + } +} diff --git a/src/digitalauthdialog.h b/src/digitalauthdialog.h new file mode 100644 index 0000000..630f9be --- /dev/null +++ b/src/digitalauthdialog.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#ifndef DIGITALAUTHDIALOG_H +#define DIGITALAUTHDIALOG_H + +#include +#include +#include +#include +#include +#include +#include "auth.h" +#include "digitalkeyboard.h" +#include + +class Auth; +class MyLabel; + +class DigitalAuthDialog : public QWidget +{ + Q_OBJECT +public: + struct PosInCircle + { + int i; //行 + int j; //列 + bool isIn; //是否在范围内 + }; + + enum LoginType{ + AUTHENTICATE = 0, + RESET, + SECONDCONFIRMATION, + }; + + explicit DigitalAuthDialog(QWidget *parent = nullptr); + ~DigitalAuthDialog(); + + void setPassword(const QString password); + QString getPassword(); + bool checkPassword(); + void reset(); + void showResetPasswordPage(); + int getStatus(); + void showErrorMessage(QString message); +// void RecieveKey(int key); +protected: + void paintEvent(QPaintEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; + void closeEvent(QCloseEvent *evert) override; + + void drawBg(QPainter *painter); + void drawOutCircle(QPainter *painter); + void drawFilledCircle(QPainter *painter); + void drawTipLine(QPainter *painter); + void drawInCircle(QPainter *painter); + void drawJoinLine(QPainter *painter); + void drawStatusCircle(QPainter *painter); + void drawHoverCircle(QPainter *painter); +private: + /** + * 圆形按钮,测量距离中心的距离 + * @brief distance + * @param x1 + * @param y1 + * @param x2 圆心x坐标 + * @param y2 圆心y坐标 + * @return + */ + double distance(int x1, int y1, int x2, int y2); + + bool isInButtonArea(int x1, int y1, int x2, int y2); + int posToNumber(int i, int j); + +// void onShowMessage(const QString &message); + void cleanMessage(); + + void startWaiting(); + void stopWaiting(); +Q_SIGNALS: + void correctPassword(bool isCorrect, QString password); + void authenticateCompete(bool result); + void requestPasswordReset(); + void setPinCode(QString pinCode); + void switchToReset(bool isReset); +private Q_SLOTS: + void onShowMessage(const QString &message, Auth::MessageType type); + void onShowPrompt(const QString &prompt, Auth::PromptType type); + void onAuthComplete(); +public Q_SLOTS: + void startAuth(); + void stopAuth(); + void onNumerPress(int btn_id); +private: + QColor m_bgColor; //背景色 + QColor m_outCircleColor; //外圆颜色 + QColor m_tipLineColor; //提示线颜色 + QColor m_circleRingColor; //圆环颜色 + QColor m_circleColor; //实心圆颜色 + int m_margin; //外边距 + int m_radius; //圆相对半径 + int m_buttonRadius; //按钮圆角半径 + int m_buttonWidth; //按钮宽度 + int m_buttonHeight; //按钮高度 + int m_buttonStep; //按钮间距 + PosInCircle m_posInCircle; //判断点是否在圆内 + bool m_pressed; //鼠标按下 + bool m_showText; //是否显示文字 + + QVector m_vecInputPoints; //鼠标移动选点 + QPoint m_followPoint; //鼠标跟随点 + QString m_password; //原密码 + QString m_inputPassword; //鼠标移动选点转换为密码 + + //label + QLabel *m_title; + MyLabel *m_labelReset; + + //密码状态更新布局 + int m_statusRadius; + + //认证中? + bool m_isAuthing; + + //数字键盘 + DigitalKeyBoard *m_digitalKeyBoard; + + /** + * 二次认证相关成员变量 + */ + int m_loginType = LoginType::AUTHENTICATE; + QString m_resetPassword; + QLabel *m_resetOrAuthFailure; + + QLabel *m_authMessage; + + //pam auth + Auth *m_auth; + +// QTimer *m_timer; +}; + +class MyLabel : public QLabel{ + Q_OBJECT +public: + MyLabel(const QString & text, QWidget *parent); + MyLabel(QWidget *parent); + +Q_SIGNALS: + void onClick(); + +protected: + void mouseReleaseEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; +}; + +#endif // DIGITALAUTHDIALOG_H diff --git a/src/digitalkeyboard.cpp b/src/digitalkeyboard.cpp new file mode 100644 index 0000000..77239ba --- /dev/null +++ b/src/digitalkeyboard.cpp @@ -0,0 +1,129 @@ +#include "digitalkeyboard.h" + +#include +#include +#include + +DigitalKeyBoard::DigitalKeyBoard(QWidget *parent): + QWidget(parent) +{ + initUI(); + initConnect(); + setQSS(); +} + +void DigitalKeyBoard::initUI() +{ + setFocusPolicy(Qt::NoFocus); + QGridLayout* mainLayout = new QGridLayout(this); + setLayout(mainLayout); + + for(int i = 1;i <= 9;i++) + { + m_pNumerPressBT[i] = new QPushButton(this); + m_pNumerPressBT[i]->setText(QString(QChar(i + '0'))); + m_pNumerPressBT[i]->setProperty("class", "numberPressBT"); + m_pNumerPressBT[i]->setFocusPolicy(Qt::NoFocus); + mainLayout->addWidget(m_pNumerPressBT[i], (i - 1) / 3, (i - 1) % 3); + } + m_pNumerPressBT[0] = new QPushButton(this); + m_pNumerPressBT[0]->setText(QString(QChar('0'))); + m_pNumerPressBT[0]->setFocusPolicy(Qt::NoFocus); + m_pNumerPressBT[0]->setProperty("class", "numberPressBT"); + mainLayout->addWidget(m_pNumerPressBT[0], 3, 1); + + m_pNumerPressBT[10] = new QPushButton(this); + m_pNumerPressBT[10]->setIcon(QPixmap(":/image/assets/intel/icon-backspace.png")); + m_pNumerPressBT[10]->setIconSize(QSize(30, 30)); + m_pNumerPressBT[10]->setFocusPolicy(Qt::NoFocus); + m_pNumerPressBT[10]->setProperty("class", "numberPressBT"); + mainLayout->addWidget(m_pNumerPressBT[10], 3, 2); + + m_pNumerPressBT[11] = new QPushButton(this); + m_pNumerPressBT[11]->setText("清空"); + m_pNumerPressBT[11]->setFocusPolicy(Qt::NoFocus); + m_pNumerPressBT[11]->setProperty("class", "numberPressBT"); + mainLayout->addWidget(m_pNumerPressBT[11], 3, 0); + + mainLayout->setSpacing(16); + mainLayout->setVerticalSpacing(16); +} + +void DigitalKeyBoard::initConnect() +{ + connect(m_pNumerPressBT[0], &QPushButton::clicked, this, [=](){ qDebug() << "DigitalKeyBoard press";emit numbersButtonPress(0); }); + connect(m_pNumerPressBT[1], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(1); }); + connect(m_pNumerPressBT[2], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(2); }); + connect(m_pNumerPressBT[3], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(3); }); + connect(m_pNumerPressBT[4], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(4); }); + connect(m_pNumerPressBT[5], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(5); }); + connect(m_pNumerPressBT[6], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(6); }); + connect(m_pNumerPressBT[7], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(7); }); + connect(m_pNumerPressBT[8], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(8); }); + connect(m_pNumerPressBT[9], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(9); }); + connect(m_pNumerPressBT[10], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(10); }); + connect(m_pNumerPressBT[11], &QPushButton::clicked, this, [=](){ emit numbersButtonPress(11); }); +} + +void DigitalKeyBoard::setQSS() +{ + setStyleSheet(".numberPressBT{" + "font-size:20px;" + "min-width:96px;" + "min-height:64px;" + "max-width:96px;" + "max-height:64px;" + "background:rgba(255, 255, 255, 15);" + "border-radius:16px;" + "}" + ".numberPressBT:hover{" + "background:rgba(255, 255, 255, 35);" + "}" + ".numberPressBT:pressed{" + "background:rgba(255, 255, 255, 5);" + "}"); +} + + +void DigitalKeyBoard::onKeyReleaseEvent(QKeyEvent *event) +{ +// switch(event->key()) +// { +// case Qt::Key_0: +// emit numbersButtonPress(0); +// break; +// case Qt::Key_1: +// emit numbersButtonPress(1); +// break; +// case Qt::Key_2: +// emit numbersButtonPress(2); +// break; +// case Qt::Key_3: +// emit numbersButtonPress(3); +// break; +// case Qt::Key_4: +// emit numbersButtonPress(4); +// break; +// case Qt::Key_5: +// emit numbersButtonPress(5); +// break; +// case Qt::Key_6: +// emit numbersButtonPress(6); +// break; +// case Qt::Key_7: +// emit numbersButtonPress(7); +// break; +// case Qt::Key_8: +// emit numbersButtonPress(8); +// break; +// case Qt::Key_9: +// emit numbersButtonPress(9); +// break; +// case Qt::Key_Backspace: +// emit numbersButtonPress(10); +// break; +// default: +// break; +// } +} + diff --git a/src/digitalkeyboard.h b/src/digitalkeyboard.h new file mode 100644 index 0000000..107a115 --- /dev/null +++ b/src/digitalkeyboard.h @@ -0,0 +1,31 @@ +#ifndef DIGITALKEYBOARD_H +#define DIGITALKEYBOARD_H + +#include +#include +#include + +class DigitalKeyBoard : public QWidget +{ + Q_OBJECT + +public: + explicit DigitalKeyBoard(QWidget *parent = nullptr); + +public Q_SLOTS: + void onKeyReleaseEvent(QKeyEvent *event); + +Q_SIGNALS: + void numbersButtonPress(int btn_id); + +private: + void initUI(); + void initConnect(); + void setQSS(); + +private: + QPushButton *m_pNumerPressBT[12]; // 0~9 是数字按键 10是删除键 11是清空键 +}; + +#endif // DIGITALKEYBOARD_H + diff --git a/src/displaymanager.cpp b/src/displaymanager.cpp new file mode 100644 index 0000000..abc9e0b --- /dev/null +++ b/src/displaymanager.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "displaymanager.h" +#include +#include +#include +#include +#include +#include "types.h" + +DisplayManager::DisplayManager(QObject *parent) : + QObject(parent), + _canSwitch(false), + _displayType(""), + process(nullptr) +{ + + if(getenv("XDG_SEAT_PATH")){ + _displayType = "lightdm"; + } + else if(process_is_running ("gdm") || process_is_running("gdm3") || process_is_running("gdm-binary")){ + _displayType = "gdm"; + process = new QProcess(this); + } + + if(_displayType == "lightdm"){ + char *seatPath = getenv("XDG_SEAT_PATH"); + qDebug() << seatPath; + + dmService = new QDBusInterface(DM_DBUS_SERVICE, + seatPath, + DBUS_PROP_INTERFACE, + QDBusConnection::systemBus()); + dmSeatService = new QDBusInterface(DM_DBUS_SERVICE, + seatPath, + DM_SEAT_INTERFACE, + QDBusConnection::systemBus()); + getProperties(); + }else if(_displayType == "gdm"){ + _canSwitch = true; + } +} + +bool DisplayManager::canSwitch() +{ + return _canSwitch; +} + +bool DisplayManager::hasGuestAccount() +{ + return _hasGuestAccount; +} + +QString DisplayManager::getDisplayType() +{ + return _displayType; +} + +void DisplayManager::switchToGreeter() +{ + qDebug()<<"111111111111111111111111111111111111111111111111111111"; + if(_displayType == "lightdm"){ + QDBusMessage ret = dmSeatService->call("SwitchToGreeter"); + handleDBusError(ret); + } + else if(_displayType == "gdm"){ + QString cmd = "gdmflexiserver"; + if(QFile("/usr/bin/gdmflexiserver").exists()){ + process->waitForFinished(3000); + process->start(cmd); + } + } +} + +void DisplayManager::switchToUser(const QString &userName) +{ + if(_displayType != "lightdm") + return ; + + QDBusMessage ret = dmSeatService->call("SwitchToUser", userName, ""); + + handleDBusError(ret); +} + +void DisplayManager::switchToGuest() +{ + if(_displayType != "lightdm") + return ; + + QDBusMessage ret = dmSeatService->call("SwitchToGuest", ""); + + handleDBusError(ret); +} + +void DisplayManager::getProperties() +{ + QDBusMessage ret = dmService->call("GetAll", DM_SEAT_INTERFACE); + handleDBusError(ret); + const QDBusArgument &arg = ret.arguments().at(0).value(); + qDebug() << arg.currentType(); + + arg.beginMap(); + while(!arg.atEnd()) + { + QString key; + QVariant value; + arg.beginMapEntry(); + arg >> key >> value; + arg.endMapEntry(); + if(key == "CanSwitch") + { + _canSwitch = value.toBool(); + } + else if(key == "HasGuestAccount") + { + _hasGuestAccount = value.toBool(); + } + } + arg.endMap(); +} + +bool DisplayManager::process_is_running(QString name) +{ + int num_processes; + QString command = "pidof " + name + " | wc -l"; + FILE *fp = popen(command.toLatin1().data(), "r"); + + if (fscanf(fp, "%d", &num_processes) != 1) + num_processes = 0; + + pclose(fp); + + if (num_processes > 0) { + return true; + } else { + return false; + } +} + +void DisplayManager::handleDBusError(const QDBusMessage &msg) +{ + if(msg.type() == QDBusMessage::ErrorMessage) + { + qWarning() << msg.errorMessage(); + } +} diff --git a/src/displaymanager.h b/src/displaymanager.h new file mode 100644 index 0000000..741be7d --- /dev/null +++ b/src/displaymanager.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef DISPLAYMANAGER_H +#define DISPLAYMANAGER_H + +#include +#include + +class QDBusInterface; +class QDBusMessage; + +class DisplayManager : public QObject +{ + Q_OBJECT +public: + explicit DisplayManager(QObject *parent = nullptr); + void switchToGreeter(); + void switchToUser(const QString &userName); + void switchToGuest(); + bool canSwitch(); + bool hasGuestAccount(); + + QString getDisplayType(); + +private: + void getProperties(); + void handleDBusError(const QDBusMessage &msg); + bool process_is_running(QString name); + +private: + bool _canSwitch; + bool _hasGuestAccount; + QString _displayType; + + QDBusInterface *dmService; + QDBusInterface *dmSeatService; + QProcess *process; +}; + +#endif // DISPLAYMANAGER_H diff --git a/src/eduplatforminterface.cpp b/src/eduplatforminterface.cpp new file mode 100644 index 0000000..47084ef --- /dev/null +++ b/src/eduplatforminterface.cpp @@ -0,0 +1,375 @@ +#include "eduplatforminterface.h" + +const QString STR_EDU_SERVICE = "cn.kylinos.SSOBackend"; +const QString STR_EDU_PATH = "/cn/kylinos/SSOBackend"; + +EduPlatformInterface* EduPlatformInterface::m_instance = nullptr; + +EduPlatformInterface::EduPlatformInterface(const QString &strService,const QString &strPath,\ + const QDBusConnection &connection, QObject *parent)\ + :QDBusAbstractInterface(strService,strPath,getInterfaceName(),connection,parent) +{ + initConnect(); +} + +EduPlatformInterface* EduPlatformInterface::getInstance() +{ + static QMutex mutex; + mutex.lock(); + if(m_instance == nullptr || !m_instance->isValid()) + m_instance = new EduPlatformInterface(STR_EDU_SERVICE, STR_EDU_PATH, QDBusConnection::systemBus()); + mutex.unlock(); + return m_instance; +} + +void EduPlatformInterface::initConnect() +{ + +} + +DBusMsgCode EduPlatformInterface::GetLoginQR(QPixmap &qrcode) +{ + QDBusMessage message = call("GetLoginQR"); + if(QDBusMessage::ErrorMessage == message.type()) + { + qDebug() << "info: [EduPlatformInterface][GetLoginQR]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + QList argvs = message.arguments(); + if(argvs.size() != 2) + { + qDebug() << "info: [EduPlatformInterface][GetLoginQR]: DBus arguments error!"; + return DBusMsgCode::Error_ArgCnt; + } + int state = argvs.at(1).value(); + if(state != 0) + { + qDebug() << "info: [EduPlatformInterface][GetLoginQR]: DBus request failed!"; + //return static_cast(state); + return DBusMsgCode::Error_ArgCnt; + } + const QString url = argvs.at(0).value(); + + DBusMsgCode download_errcode = getQRCodeFromURL(url, qrcode); + if(download_errcode != DBusMsgCode::No_Error) return download_errcode; + qrcode = beautifyQRCode(qrcode); + return DBusMsgCode::No_Error; +} + +DBusMsgCode EduPlatformInterface::GetLoginQRUrl(QString &url) +{ + QDBusMessage message = call("GetLoginQR"); + if(QDBusMessage::ErrorMessage == message.type()) + { + qDebug() << "info: [EduPlatformInterface][GetLoginQR]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + QList argvs = message.arguments(); + if(argvs.size() != 2) + { + qDebug() << "info: [EduPlatformInterface][GetLoginQR]: DBus arguments error!"; + return DBusMsgCode::Error_ArgCnt; + } + int state = argvs.at(1).value(); + if(state != 0) + { + qDebug() << "info: [EduPlatformInterface][GetLoginQR]: DBus request failed!"; + //return static_cast(state); + return DBusMsgCode::Error_ArgCnt; + } + url = argvs.at(0).value(); + return DBusMsgCode::No_Error; +} + +DBusMsgCode EduPlatformInterface::BindPhoneNum(const QString &username, const QString &phonenum, const QString &vcode) +{ + QDBusReply reply = call("BindPhoneNum", username, phonenum, vcode); + if(!reply.isValid()) + { + qDebug() << "info: [EduPlatformInterface][BindPhoneNum]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + if(reply.value() != 0) + { + qDebug() << "info: [EduPlatformInterface][BindPhoneNum]: DBus request failed!"; + //return static_cast(reply.value()); + return DBusMsgCode::Error_NoReply; + } + + return DBusMsgCode::No_Error; +} + +DBusMsgCode EduPlatformInterface::GetVerifyCode(const QString &phonenum) +{ + QDBusReply reply = call("GetVerifyCode", phonenum); + if(!reply.isValid()) + { + qDebug() << "info: [EduPlatformInterface][GetVerifyCode]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + // + if(reply.value() != 0) // 默认0为成功 + { + qDebug() << "info: [EduPlatformInterface][GetVerifyCode]: DBus request failed!"; + //return static_cast(reply.value()); + return DBusMsgCode::Error_NoReply; + } + + return DBusMsgCode::No_Error; +} + +DBusMsgCode EduPlatformInterface::SetPinCode(const QString &username, const QString &pincode) +{ + QDBusReply reply = call("SetPinCode", username, pincode); + if(!reply.isValid()) + { + qDebug() << "info: [][]: DBus connect failed!"; + return DBusMsgCode::Error_NoReply; + } + if(!reply.value()) + { + return DBusMsgCode::No_Error; + } + return DBusMsgCode::Error_NoReply; +} + +DBusMsgCode EduPlatformInterface::CheckToken(const QString &username) +{ + QDBusReply reply = call("CheckToken", username); + if(!reply.isValid()) + { + qDebug() << "info: [EduPlatformInterface][RefreshToken]: DBus connect failed!"; + return DBusMsgCode::Error_NoReply; + } +// if(reply.value()) +// { +// qDebug() << "info: [EduPlatformInterface][RefreshToken]: DBus return-result failed!"; +// } + switch (reply.value()) { + case 0: return DBusMsgCode::No_Error; + default: return static_cast(reply.value()); + } +} + +DBusMsgCode EduPlatformInterface::CheckPhoneNumBind(const QString &username, bool &isBind) +{ + QDBusReply reply = call("CheckPhoneNumBind", username); + if(!reply.isValid()) + { + qDebug() << "info: [EduPlatformInterface][CheckPhoneNumBind]: DBus connect failed!"; + return DBusMsgCode::Error_NoReply; + } + // TODO 需要改接口 接口有问题 + if(reply.value() == 0) + { + isBind = false; + return DBusMsgCode::No_Error; + } + if(reply.value() == 1) + { + isBind = true; + return DBusMsgCode::No_Error; + } + isBind = true; + return DBusMsgCode::Error_NoReply; +} + +DBusMsgCode EduPlatformInterface::CheckPincodeSet(const QString &username, bool &isBind) +{ + QDBusReply reply = call("CheckPincodeSet", username); + if(!reply.isValid()) + { + qDebug() << "info: [EduPlatformInterface][CheckPincodeSet]: DBus connect failed!"; + return DBusMsgCode::Error_NoReply; + } + + if(reply.value() == 0) + { + isBind = true; + return DBusMsgCode::No_Error; + } + if(reply.value() == 1) + { + isBind = false; + return DBusMsgCode::No_Error; + } + + return DBusMsgCode::Error_NoReply; +} + +DBusMsgCode EduPlatformInterface::CheckUserByPhone(const QString &username, const QString &phonenum, const QString &vcode) +{ + QDBusReply reply = call("CheckUserByPhone", username, phonenum, vcode); + if(!reply.isValid()) + { + qDebug() << "info: [EduPlatformInterface][CheckUserByPhone]: DBus connect failed!"; + return DBusMsgCode::Error_NoReply; + } + return static_cast(reply.value()); +} + +DBusMsgCode EduPlatformInterface::CheckUserByQR(QPixmap &qrcode) +{ + QDBusMessage message = call("CheckUserByQR"); + if(QDBusMessage::ErrorMessage == message.type()) + { + qDebug() << "info: [EduPlatformInterface][CheckUserByQR]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + QList argvs = message.arguments(); + if(argvs.size() != 2) + { + qDebug() << "info: [EduPlatformInterface][CheckUserByQR]: DBus arguments error!"; + return DBusMsgCode::Error_ArgCnt; + } + int state = argvs.at(1).value(); + if(state != 0) + { + qDebug() << "info: [EduPlatformInterface][CheckUserByQR]: DBus request failed!"; + //return static_cast(state); + return static_cast(state); + } + const QString url = argvs.at(0).value(); + + DBusMsgCode download_errcode = getQRCodeFromURL(url, qrcode); + if(download_errcode != DBusMsgCode::No_Error) return download_errcode; + qrcode = beautifyQRCode(qrcode); + return DBusMsgCode::No_Error; +} + +DBusMsgCode EduPlatformInterface::CheckUserByQR(QString &url) +{ + QDBusMessage message = call("CheckUserByQR"); + if(QDBusMessage::ErrorMessage == message.type()) + { + qDebug() << "info: [EduPlatformInterface][CheckUserByQR]: DBus Connect Failed!"; + return DBusMsgCode::Error_NoReply; + } + QList argvs = message.arguments(); + if(argvs.size() != 2) + { + qDebug() << "info: [EduPlatformInterface][CheckUserByQR]: DBus arguments error!"; + return DBusMsgCode::Error_ArgCnt; + } + int state = argvs.at(1).value(); + if(state != 0) + { + qDebug() << "info: [EduPlatformInterface][CheckUserByQR]: DBus request failed!"; + //return static_cast(state); + return static_cast(state); + } + url = argvs.at(0).value(); + return DBusMsgCode::No_Error; +} + +DBusMsgCode EduPlatformInterface::getQRCodeFromURL(const QString &url, QPixmap &qrcode) +{ + // 从网络上下载二维码 并加载到qrcode + QNetworkRequest request; + QNetworkAccessManager networkManager; + request.setUrl(url); + QNetworkReply *reply = networkManager.get(request); + + // 超时 \ 同步处理 + QEventLoop loop; + QTimer timer; + connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + connect(&timer, &QTimer::timeout, &timer, &QTimer::stop); + connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + timer.start(3000); + loop.exec(); + + if(!timer.isActive()) + { + reply->abort(); + qDebug() << "info: [EduPlatformInterface][GetLoginQR]: Get QRCode timeout!"; + return DBusMsgCode::Error_QR_Get_Timeout; + } + timer.stop(); + + // 生成二维码 + if(reply->error() != QNetworkReply::NoError) + { + qDebug() << "info: [EduPlatformInterface][GetLoginQR]: Network error!" << reply->errorString(); + return DBusMsgCode::Error_NetWork; + } + QByteArray bytes = reply->readAll(); + qrcode.loadFromData(bytes); + return DBusMsgCode::No_Error; +} + +// 美化图片 +QPixmap EduPlatformInterface::beautifyQRCode(QPixmap &pixImg) +{ + // 去除白边 + QImage img = pixImg.toImage(); + int rect_x, rect_y, rect_width, rect_height; + for(int i = 0;i < img.size().width();i++) + { + bool isEnd = false; + for(int j = 0;j < img.size().height();j++) + { + if(img.pixel(i, j) != qRgb(255, 255, 255)) + { + rect_x = i - 1; + rect_y = j - 1; + rect_width = img.size().width() - 2 * rect_x; + rect_height = img.size().height() - 2 * rect_y; + isEnd = true; + break; + } + } + if(isEnd) break; + } + QPixmap dealImg = QPixmap::fromImage(img.copy(rect_x, rect_y, rect_width, rect_height)).scaledToWidth(150); + img = dealImg.toImage(); + + // 添加微信log +// QPixmap piximg_wechat(WECHAT_LOG_PATH); +// QImage img_wechat = piximg_wechat.scaledToWidth(150).toImage(); +// for(int i = 0;i < img.size().width();++i) +// { +// for(int j = 0;j < img.size().height(); ++j) +// { +// if(img.pixel(i, j) > qRgb(125, 125, 125)) +// { +// int r = qRed(img_wechat.pixel(i, j)); +// int g = qGreen(img_wechat.pixel(i, j)); +// int b = qBlue(img_wechat.pixel(i, j)); +// int alpha = qAlpha(img_wechat.pixel(i, j)); +// if(alpha == 0) r = 255, b = 255, g = 255; +// else r = 0x25, g = 0xAC, b = 0x36; +// img.setPixelColor(i, j, QColor(r, g, b, alpha)); +// //img.setPixel(i, j, qRgb(0, 255, 0)); +// } +// } +// } + dealImg = QPixmap::fromImage(img); + return dealImg; +} + +//void EduPlatformInterface::onScanState(QString username, QString password, int state) +//{ +// switch(state) +// { +// case 4: // 扫码并确认完成 +// qDebug() << "=================扫码并确认完成" << username << password; +// emit qrcodeScanState(QRCodeSwepState::ConfirmSuccess, username, password); +// break; +// case 2: // 用户扫码 +// qDebug() << "=================用户扫码" << username << password; +// emit qrcodeScanState(QRCodeSwepState::HaveSwep, "", ""); +// break; +// case 3: // 用户取消扫码 +// qDebug() << "=================用户取消扫码" << username << password; +// emit qrcodeScanState(QRCodeSwepState::CancelSwep, "", ""); +// break; +// case 5: // 二维码超时 +// qDebug() << "=================二维码超时" << username << password; +// emit qrcodeScanState(QRCodeSwepState::QRCodeInvalid, "", ""); +// break; +// default: +// break; +// } +//} + diff --git a/src/eduplatforminterface.h b/src/eduplatforminterface.h new file mode 100644 index 0000000..60e72dc --- /dev/null +++ b/src/eduplatforminterface.h @@ -0,0 +1,66 @@ +#ifndef EDUPLATFORMINTERFACE_H +#define EDUPLATFORMINTERFACE_H +#include +#include +#include +#include "common.h" +#include + +#include +#include +#include +#include +#include + +class EduPlatformInterface: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char* getInterfaceName() + {return "cn.kylinos.SSOBackend.eduplatform";} +public: + EduPlatformInterface(const QString &strService,const QString &strPath,\ + const QDBusConnection &connection, QObject *parent = 0); + + static EduPlatformInterface* getInstance(); + + // 得到登录二维码地址 + DBusMsgCode GetLoginQRUrl(QString &url); + // 绑定手机号 + DBusMsgCode BindPhoneNum(const QString &username, const QString &phonenum, const QString &vcode); + // 得到登录二维码 + DBusMsgCode GetLoginQR(QPixmap &qrcode); + // 得到验证码 + DBusMsgCode GetVerifyCode(const QString &phonenum); + // 设置Pin码 + DBusMsgCode SetPinCode(const QString &username, const QString &pincode); + // 检查手机号绑定 + DBusMsgCode CheckPhoneNumBind(const QString &username, bool &isBind); + // 检查Pin码设置 + DBusMsgCode CheckPincodeSet(const QString &username, bool &isBind); + // 验证手机号正确性 + DBusMsgCode CheckUserByPhone(const QString &username, const QString &phonenum, const QString &vcode); + // 通过二维码检查用户身份 + DBusMsgCode CheckUserByQR(QPixmap &qrcode); + // 通过二维码检查用户身份:获取二维码地址 + DBusMsgCode CheckUserByQR(QString &url); + + // 通过url获取二维码图片数据 + DBusMsgCode getQRCodeFromURL(const QString &url, QPixmap &qrcode); + + // 获取用户登录状态 + DBusMsgCode CheckToken(const QString &username); +private: + void initConnect(); + QPixmap beautifyQRCode(QPixmap &); + + static EduPlatformInterface *m_instance; + +Q_SIGNALS: + void QRStatusChange(QString,QString,int); + +private: + +}; + +#endif // EDUPLATFORMINTERFACE_H diff --git a/src/fullbackgroundwidget.cpp b/src/fullbackgroundwidget.cpp new file mode 100644 index 0000000..c199287 --- /dev/null +++ b/src/fullbackgroundwidget.cpp @@ -0,0 +1,1154 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "fullbackgroundwidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "lockwidget.h" +#include "xeventmonitor.h" +#include "monitorwatcher.h" +#include "configuration.h" +#include "screensaver.h" +#include "screensaverwidget.h" +#include "grab-x11.h" +#include "tabletlockwidget.h" +#include "sessionwatcher.h" +// 实现键盘f1 - f2 的功能键 +#include "PhysicalDeviceSet/sounddeviceset.h" +#include "PhysicalDeviceSet/brightnessdeviceset.h" + +#include "config.h" + +enum { + SWITCH_TO_LINUX = 0, + SWITCH_TO_ANDROID = 1, + BACK_TO_DESKTOP = 2, + TEST_CONNECTION = 3, +}; + +QT_BEGIN_NAMESPACE +extern void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); +QT_END_NAMESPACE + +#define BLUR_RADIUS 300 +#define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" +#define KEY_IDLE_DELAY "idleDelay" +#define KEY_IDLE_LOCK "idleLock" +#define KEY_IDLE_LOCK_ENABLED "idleLockEnabled" + +QPixmap scaledPixmap(int width, int height, QString url) +{ + QFile imgFile(url); + if(!imgFile.exists()){ + qDebug()<< "not find the pixmap file"; + return QPixmap(); + } + QImage image(url); + QPixmap pixmap = QPixmap::fromImage(image); + if(pixmap.isNull()) { + qDebug() << "pixmap is null"; + QProcess exec; + QString program("file " + url); + exec.start(program); + exec.waitForFinished(1000); + QString output = exec.readAllStandardOutput(); + qDebug() << output; + if(output.contains("SVG")){ + qDebug() << "image format is SVG"; + QSvgRenderer render(url); + QImage image(width, height, QImage::Format_ARGB32); + image.fill(Qt::transparent); + QPainter painter(&image); + render.render(&painter, image.rect()); + pixmap.convertFromImage(image); + } else if(output.contains("TIFF")) { + qDebug() << "image format is TIFF"; + + } + } + + return pixmap.scaled(width, height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); +} + +int connect_to_switch(const char* path) +{ + int ret; + int connect_fd; + struct sockaddr_un srv_addr; + + connect_fd = socket(PF_UNIX,SOCK_STREAM,0); + if(connect_fd < 0) { + + return -1; + } + + srv_addr.sun_family=AF_UNIX; + strcpy(srv_addr.sun_path, path); + + ret = connect(connect_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)); + if(ret < 0) { + perror("cannot connect to the server"); + close(connect_fd); + return -1; + } + + return connect_fd; +} + +int switch_to_linux(const char* container) +{ + int connect_fd; + int32_t switch_to = BACK_TO_DESKTOP; + + char path[1024] = {0}; + sprintf(path, "/var/lib/kydroid/%s/sockets/%s", container, "desktop-switch"); + printf("path = %s\n",path); + connect_fd = connect_to_switch(path); + + if(connect_fd < 0) + return -1; + + write(connect_fd, &switch_to, sizeof(switch_to)); + close(connect_fd); + return 0; +} + +void x11_get_screen_size(int *width,int *height) +{ + Display* display; + + display = XOpenDisplay(NULL); + if (display == NULL) { + fprintf(stderr, "Cannot connect to X server %s/n", "simey:0"); + exit (-1); + } + int screen_num; + + screen_num = DefaultScreen(display); + + *width = DisplayWidth(display, screen_num); + *height = DisplayHeight(display, screen_num); + XCloseDisplay(display); + +} + +QPixmap blurPixmap(QPixmap pixmap) +{ + QPainter painter(&pixmap); + QImage srcImg = pixmap.toImage(); + qt_blurImage(&painter, srcImg, BLUR_RADIUS, false, false); + + //在设置Qt::WA_TranslucentBackground属性后,模糊图片会导致锁屏界面透明 + //因此这里修改image图形的alpha值为255. + for (int y = 0;y < srcImg.height();++y) { + QRgb *row = (QRgb*)srcImg.scanLine(y); + for (int x = 0; x < srcImg.width(); ++x) { + ((unsigned char*)&row[x])[3] = 255; + } + } + + painter.end(); + return QPixmap::fromImage(srcImg); +} + +FullBackgroundWidget::FullBackgroundWidget(QWidget *parent) + : QWidget(parent), + lockWidget(nullptr), + xEventMonitor(new XEventMonitor(this)), + //monitorWatcher(new MonitorWatcher(this)), + configuration(Configuration::instance()), + isLocked(false), + isPassed(false), + lockState(false), + screenStatus(UNDEFINED), + isBlank(false), + m_delay(false) +{ + qDebug() << "init - screenStatus: " << screenStatus; + setMouseTracking(true); + // connect(monitorWatcher, &MonitorWatcher::monitorCountChanged, + // this, &FullBackgroundWidget::onScreenCountChanged); + QDesktopWidget *desktop = QApplication::desktop(); + + connect(desktop, &QDesktopWidget::resized, + this, &FullBackgroundWidget::onDesktopResized); + connect(desktop, &QDesktopWidget::workAreaResized, + this, &FullBackgroundWidget::onDesktopResized); + connect(desktop, &QDesktopWidget::primaryScreenChanged, + this, &FullBackgroundWidget::onDesktopResized); + connect(desktop, &QDesktopWidget::screenCountChanged, + this, &FullBackgroundWidget::onDesktopResized); + + QDBusInterface *iface = new QDBusInterface("org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + QDBusConnection::systemBus(), + this); + connect(iface, SIGNAL(PrepareForSleep(bool)), this, SLOT(onPrepareForSleep(bool))); + + QDBusInterface *interfaceScreensaver = new QDBusInterface( + SS_DBUS_SERVICE, + SS_DBUS_PATH, + SS_DBUS_INTERFACE, + QDBusConnection::sessionBus()); + + connect(interfaceScreensaver, SIGNAL(SessionIdle()), + this, SLOT(showScreensaver())); + + settings_delay = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); + connect(settings_delay, &QGSettings::changed, + this, &FullBackgroundWidget::onConfigurationDelayChanged); + idleDelay = settings_delay->get("idle-delay").toInt(); + qDebug()<<"idleDelay="<get("idle-lock").toInt(); + +// lockEnabled_Key = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); +// connect(lockEnabled_Key, &QGSettings::changed, +// this, &FullBackgroundWidget::lockEnabledChanged); +// lockEnabled = lockEnabled_Key->get("idle-lock-enabled").toBool(); +// qDebug()<, QStringList))); +#endif + + init(); + qApp->installNativeEventFilter(this); + installEventFilter(this); + QTimer::singleShot(500,this,SLOT(switchToLinux())); + + LogindIntegration *m_logind = new LogindIntegration(this); + + + connect(m_logind, &LogindIntegration::requestUnlock, this, + [this]() { + closeScreensaver(); + }); + +} + +#ifdef USE_INTEL +void FullBackgroundWidget::propertiesChangedSlot(QString property, QMap propertyMap, QStringList propertyList) +{ + Q_UNUSED(property); + Q_UNUSED(propertyList); + if (propertyMap.keys().contains("LidIsClosed")) { + qDebug() <<"LidIsClosed" << propertyMap.value("LidIsClosed").toBool(); +// if(!(propertyMap.value("LidIsClosed").toBool())) +// { +// m_isSuspend = true; +// } + } +} +#endif + +void FullBackgroundWidget::switchToLinux() +{ + struct passwd *pwd; + pwd = getpwuid(getuid()); + char *username = pwd->pw_name; + int uid = pwd->pw_uid; + char container[100]= {0}; + + sprintf(container,"kydroid2-%d-%s",uid,username); + + switch_to_linux(container); + +} + +void FullBackgroundWidget::laterActivate() +{ + activateWindow(); + raise(); + setFocus(); + if(lockWidget && lockWidget->isVisible()) + lockWidget->setFocus(); +} + +void FullBackgroundWidget::onConfigurationDelayChanged(QString key) +{ + if(key == KEY_IDLE_DELAY){ + idleDelay = settings_delay->get("idle-delay").toInt(); + } +} + +void FullBackgroundWidget::onConfigurationLockChanged(QString key) +{ + if(key == KEY_IDLE_LOCK){ + idleLock = settings_lock->get("idle-lock").toInt(); + } +} + +//void FullBackgroundWidget::lockEnabledChanged(QString key) +//{ +// if(key == KEY_IDLE_LOCK_ENABLED){ +// lockEnabled = lockEnabled_Key->get("idle-lock-enabled").toBool(); +// } +//} + +void FullBackgroundWidget::setLockState() +{ + if(lockState == true) + return ; + + lockState = true; + + QDBusInterface *interface = new QDBusInterface(SS_DBUS_SERVICE, + SS_DBUS_PATH, + SS_DBUS_INTERFACE); + QDBusMessage msg = interface->call("SetLockState"); + if(msg.type() == QDBusMessage::ErrorMessage) + qDebug() << msg.errorMessage(); + +} + +bool FullBackgroundWidget::eventFilter(QObject *obj, QEvent *event) +{ + if(event->type() == QEvent::WindowDeactivate){ + QTimer::singleShot(50,this,SLOT(laterActivate())); + }else if(event->type() == QEvent::WindowActivate){ + QTimer::singleShot(500,this,SLOT(setLockState())); + QTimer::singleShot(200,this,SLOT(killWindow())); + } + return false; +} + +void FullBackgroundWidget::killWindow() +{ + if(isStartup && !process){ + process = new QProcess(this); + process->start("killall screensaver-focus-helper"); + } +} + +void FullBackgroundWidget::setIsStartup(bool val) +{ + isStartup = val; +} + +void FullBackgroundWidget::paintEvent(QPaintEvent *event) +{ + if(future.isRunning()){ + qDebug()<<"------------------------------------------------------------等待加载背景完成1"; + future.waitForFinished(); + qDebug()<<"------------------------------------------------------------加载背景完成1"; + }else{ + if(!future.isFinished() && future.isStarted()){ + qDebug()<<"------------------------------------------------------------等待加载背景完成2"; + future.waitForFinished(); + qDebug()<<"------------------------------------------------------------加载背景完成2"; + } + } + + for(auto screen : QGuiApplication::screens()) + { + QPainter painter(this); + if(background.isNull()){ + QColor cor = "#035290"; + painter.setBrush(cor); + painter.drawRect(screen->geometry()); + } else { + painter.drawPixmap(screen->geometry(), background); + QPainterPath path; + painter.setOpacity(0.25); + painter.setRenderHint(QPainter::Antialiasing); // 反锯齿; + painter.setClipping(true); + painter.setPen(Qt::transparent); + path.addRect(this->rect()); + path.setFillRule(Qt::WindingFill); + painter.setBrush(QColor("#000000")); + painter.setPen(Qt::transparent); + painter.drawPath(path); + } + } + return QWidget::paintEvent(event); +} + +void FullBackgroundWidget::closeEvent(QCloseEvent *event) +{ + qDebug() << "FullBackgroundWidget::closeEvent"; + +#ifdef USE_INTEL + //蓝牙连接后 唤醒信号会有延迟 以防退出时未收到信号导致kwin compositor未resume + QDBusInterface *interface = new QDBusInterface("org.ukui.KWin", + "/Compositor", + "org.ukui.kwin.Compositing", + QDBusConnection::sessionBus(), + this); + + if (!interface->isValid()){ + syslog(LOG_DEBUG, "interface error"); + return; + } + QDBusMessage msg = interface->call("resume"); + syslog(LOG_DEBUG, "after close resume kwin "); +#endif + + for(auto obj: children()) + { + QWidget *widget = dynamic_cast(obj); + if(widget) + widget->close(); + } + closeGrab(); + + return QWidget::closeEvent(event); +} + +void FullBackgroundWidget::showEvent(QShowEvent *event) +{ + // XSetWindowAttributes top_attrs; + // top_attrs.override_redirect = False; + // XChangeWindowAttributes(QX11Info::display(), this->winId(), CWOverrideRedirect, &top_attrs); + // XRaiseWindow(QX11Info::display(), this->winId()); + // raise(); + + return QWidget::showEvent(event); +} + + +bool FullBackgroundWidget::nativeEventFilter(const QByteArray &eventType, void *message, long *result) +{ + if (qstrcmp(eventType, "xcb_generic_event_t") != 0) { + return false; + } + xcb_generic_event_t *event = reinterpret_cast(message); + const uint8_t responseType = event->response_type & ~0x80; + if (responseType == XCB_CONFIGURE_NOTIFY) { + xcb_configure_notify_event_t *xc = reinterpret_cast(event); + if(xc->window == winId()) + return false; + XWindowAttributes window_attributes; + XGetWindowAttributes (QX11Info::display(), xc->window,&window_attributes); + XClassHint ch; + ch.res_name = NULL; + ch.res_class = NULL; + XGetClassHint (QX11Info::display(), xc->window, &ch); + if(QString(ch.res_name) == "ukui-screensaver-dialog") + return false; + + laterActivate(); + }else if(responseType == XCB_MAP_NOTIFY){ + xcb_map_notify_event_t *xm = reinterpret_cast(event); + if(xm->window == winId()) + return false; + XWindowAttributes window_attributes; + XGetWindowAttributes (QX11Info::display(), xm->window,&window_attributes); + XClassHint ch; + ch.res_name = NULL; + ch.res_class = NULL; + XGetClassHint (QX11Info::display(), xm->window, &ch); + if(QString(ch.res_name) == "ukui-screensaver-dialog") + return false; + laterActivate(); + } + return false; +} + +void FullBackgroundWidget::mouseMoveEvent(QMouseEvent *e) +{ + onCursorMoved(QCursor::pos()); + return QWidget::mouseMoveEvent(e); +} + +void FullBackgroundWidget::mousePressEvent(QMouseEvent *e) +{ +#ifdef USE_INTEL + if(screenStatus == SCREEN_LOCK_AND_SAVER) + { + ScreenSaver *saver = configuration->getScreensaver(); + if(saver->path == "/usr/lib/ukui-screensaver/ukui-screensaver-default") + return ; + clearScreensavers(); + } +#endif +} + +void FullBackgroundWidget::init() +{ +/*捕获键盘,如果捕获失败,则可能是由于弹出菜单项已经捕获,那么模拟一次esc按键来退出菜单,如果仍捕获失败,则放弃锁屏,避免密码无法输入*/ + if(establishGrab()) + qDebug()<<"establishGrab : true"; + else { + qDebug()<<"establishGrab : false"; + XTestFakeKeyEvent(QX11Info::display(), XKeysymToKeycode(QX11Info::display(),XK_Escape), True, 1); + XTestFakeKeyEvent(QX11Info::display(), XKeysymToKeycode(QX11Info::display(),XK_Escape), False, 1); + XFlush(QX11Info::display()); + sleep(1); + if(!establishGrab()) + { + exit(1); + } + } + + qDebug()<<"----------------------------------------------------------------开始异步调用"; + future = QtConcurrent::run([=](){ + QImageReader reader; + reader.setFileName(configuration->getBackground()); + reader.setAutoTransform(true); + reader.setScaledSize(QApplication::primaryScreen()->size()); + background = QPixmap::fromImageReader(&reader); + + if(!background.isNull()){ + background = blurPixmap(background); + } + }); + + setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint + | Qt::X11BypassWindowManagerHint); + setAttribute(Qt::WA_TranslucentBackground); + + XWindowAttributes rootAttr; + XGetWindowAttributes(QX11Info::display(), QX11Info::appRootWindow(), &rootAttr); + XSelectInput( QX11Info::display(), QX11Info::appRootWindow(), + SubstructureNotifyMask|rootAttr.your_event_mask ); + + // 监听session信号 +// smInterface = new QDBusInterface(SM_DBUS_SERVICE, +// SM_DBUS_PATH, +// SM_DBUS_INTERFACE, +// QDBusConnection::sessionBus()); +// connect(smInterface, SIGNAL(StatusChanged(uint)), +// this, SLOT(onSessionStatusChanged(uint))); + + connect(xEventMonitor, SIGNAL(keyPress(const QString &)), + this, SLOT(onGlobalKeyPress(const QString &))); + connect(xEventMonitor, SIGNAL(keyRelease(const QString &)), + this, SLOT(onGlobalKeyRelease(const QString &))); + connect(xEventMonitor, SIGNAL(buttonDrag(int, int)), + this, SLOT(onGlobalButtonDrag(int, int))); + connect(xEventMonitor, SIGNAL(buttonPress(int, int)), + this, SLOT(onGlobalButtonPressed(int, int))); + + +// int totalWidth = 0; +// int totalHeight = 0; +// for(auto screen : QGuiApplication::screens()) +// { +// totalWidth += screen->geometry().width(); +// totalHeight += screen->geometry().height(); +// } +// setGeometry(0, 0, totalWidth, totalHeight); + QDesktopWidget *desktop = QApplication::desktop(); + setGeometry(desktop->geometry()); + + xEventMonitor->start(); + +#ifdef USE_INTEL + SoundDeviceSet::instance(); +#endif +} + +void FullBackgroundWidget::onCursorMoved(const QPoint &pos) +{ + if(!lockWidget) + { + return; + } + for(auto screen : QGuiApplication::screens()) + { +#ifdef USE_INTEL + if(screen == qApp->primaryScreen()){ + lockWidget->setGeometry(screen->geometry()); + break; + } +#else + if(screen->geometry().contains(pos)) + { + if(lockWidget->geometry() == screen->geometry()) + return ; + /*避免切换时闪烁*/ + qDebug()<geometry()<geometry(); + lockWidget->hide(); + lockWidget->setGeometry(screen->geometry()); + lockWidget->show(); + break; + } +#endif + } +} + +void FullBackgroundWidget::lock() +{ + showLockWidget(); + if(lockWidget){ + lockWidget->show(); + lockWidget->startAuth(); + } +#ifndef USE_INTEL + inhibit(); +#endif +} + +void FullBackgroundWidget::showLock() +{ + screenStatus = (ScreenStatus)(screenStatus | SCREEN_LOCK); + //qDebug() << "showLockWidget - screenStatus: " << screenStatus; +} + +void FullBackgroundWidget::showLockWidget() +{ +#ifdef USE_INTEL + screenStatus = /*(ScreenStatus)(screenStatus | SCREEN_LOCK)*/SCREEN_LOCK; +#else + screenStatus = (ScreenStatus)(screenStatus | SCREEN_LOCK); +#endif + qDebug() << "showLockWidget - screenStatus: " << screenStatus; + + if(!lockWidget) + { +#ifdef USE_INTEL + lockWidget = new TabletLockWidget(this); + connect(lockWidget, &TabletLockWidget::closed, + this, &FullBackgroundWidget::close); + connect(lockWidget, &TabletLockWidget::screenSaver, + this, [=] { + showScreensaver(); + }); + connect(lockWidget, &TabletLockWidget::blackSaver, + this, [=] { + onShowBlackBackGround(); + }); +#else + lockWidget = new LockWidget(this); + connect(lockWidget, &LockWidget::closed, + this, &FullBackgroundWidget::close); +#endif + } + onCursorMoved(QCursor::pos()); + lockWidget->setFocus(); + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + activateWindow(); + repaint(); +} + +void FullBackgroundWidget::showScreensaver() +{ + if(screenStatus & SCREEN_SAVER){ + return ; + } +#ifdef USE_INTEL + screenStatus = /*(ScreenStatus)(screenStatus | SCREEN_SAVER)*/SCREEN_LOCK_AND_SAVER; +#else + screenStatus = (ScreenStatus)(screenStatus | SCREEN_SAVER); +#endif + qDebug() << "showScreensaver - screenStatus: " << screenStatus; + + for(auto screen : QGuiApplication::screens()) + { + ScreenSaver *saver = configuration->getScreensaver(); + ScreenSaverWidget *saverWidget = new ScreenSaverWidget(saver, this); + qDebug() << " new ScreenSaverWidget"; + widgetXScreensaverList.push_back(saverWidget); + //深色模式有一像素的白边,所以主屏幕向左,向右移一个像素点;这种操作后,外显上方仍旧会有一个像素的白边,暂时不对外显做偏移处理 + if(screen == qApp->primaryScreen()) { + saverWidget->setGeometry(screen->geometry().x()-1, screen->geometry().y()-1, + screen->geometry().width()+1, screen->geometry().height()+1); + } else { + saverWidget->setGeometry(screen->geometry()); + } + + } + setCursor(Qt::BlankCursor); + + //显示屏保时,停止认证(主要针对生物识别) + if(lockWidget) + { + lockWidget->stopAuth(); + lockWidget->hide(); + } +} + +void FullBackgroundWidget::clearScreensavers() +{ +#ifdef USE_INTEL + screenStatus = /*(ScreenStatus)(screenStatus & ~SCREEN_SAVER)*/SCREEN_LOCK; +#else + screenStatus = (ScreenStatus)(screenStatus & ~SCREEN_SAVER); +#endif + for(auto widget : widgetXScreensaverList) + { + widget->close(); + } + widgetXScreensaverList.clear(); + + qDebug() << "clearScreensavers - screenStatus: " << screenStatus; + + unsetCursor(); + if(screenStatus == UNDEFINED) + { + close(); + } + else + { + lock(); + } +} + +int FullBackgroundWidget::onSessionStatusChanged(uint status) +{ + qDebug() << "session status changed: " << status; + if(status != SESSION_IDLE) + { + //当前session没有处于空闲状态 + return -1; + } + qDebug() << "onSessionStatusChanged - screenStatus: " << screenStatus; + + if(!configuration->xscreensaverActivatedWhenIdle()) + { + return -1; + } +#ifdef USE_INTEL + if(screenStatus == SCREEN_LOCK_AND_SAVER) +#else + if(screenStatus & SCREEN_SAVER) +#endif + { + return -1; + } +#ifdef USE_INTEL + else if(screenStatus == SCREEN_LOCK) +#else + else if(screenStatus & SCREEN_LOCK) +#endif + { + showScreensaver(); + } + else if(screenStatus == UNDEFINED) + { +#ifdef USE_INTEL + //显示锁屏和屏保 + showLockWidget(); + showScreensaver(); +#else + if(configuration->xscreensaverActivatedWhenIdle() != -1 && configuration->lockWhenXScreensaverActivated()) + { + //显示锁屏和屏保 + showLockWidget(); + showScreensaver(); + } + else if(configuration->xscreensaverActivatedWhenIdle() != -1) + { + if( idleDelay == idleLock && idleLock != -1){ + //显示锁屏和屏保 + showLockWidget(); + showScreensaver(); + }else{ + //只显示屏保 + showScreensaver(); + } + } +#endif + } + return 0; +} + +void FullBackgroundWidget::onBlankScreensaver() +{ + showLockWidget(); + screenStatus = (ScreenStatus)(screenStatus | SCREEN_SAVER | SCREEN_LOCK); + qDebug() << "showScreensaver - screenStatus: " << screenStatus; + + for(auto screen : QGuiApplication::screens()) + { + ScreenSaver *saver = configuration->getScreensaver(); + saver->mode = SaverMode(SAVER_BLANK_ONLY); + ScreenSaverWidget *saverWidget = new ScreenSaverWidget(saver, this); + widgetXScreensaverList.push_back(saverWidget); + saverWidget->setGeometry(screen->geometry()); + } + setCursor(Qt::BlankCursor); + isBlank = true; +} + +void FullBackgroundWidget::onScreensaver() +{ + showLockWidget(); + showScreensaver(); +} + +void FullBackgroundWidget::onGlobalKeyPress(const QString &key) +{ +#ifdef USE_INTEL + qDebug() << "onGlobalKeyPress " << key << "screenStatus " << screenStatus; + + if(m_delay) + { + qDebug() << "it is delay time ,ignore"; + return; + } + + if(!key.isEmpty() && (screenStatus == SCREEN_LOCK_AND_SAVER)) + { + clearScreensavers(); + }/*else{ + lockWidget->startAuth(); + inhibit(); + }*/ +// if(screenStatus == SCREEN_LOCK) +// { +// checkNumLock(); +// int keyValue = numberMatch(key);; +// if (keyValue >= 0 && keyValue <= 10 ) +// { +// lockWidget->RecieveKey(keyValue); +// } +// } +#endif +} + +void FullBackgroundWidget::onGlobalKeyRelease(const QString &key) +{ +// if(key == "Caps_Lock") +// { +// lockWidget->capsLockChanged(); +// } +#ifdef USE_INTEL + + // 声音、亮度等调整 + // 取消声音快捷键设置,由settings-deamon控制 有一个bug,音量为零时再按静音键,静音指示灯会熄灭,可解决,但是不用锁屏做了 +// if(key == "XF86AudioRaiseVolume") +// { +// SoundDeviceSet::instance()->setValue(SoundDeviceSet::instance()->getValue() + 5); +// } +// else if(key == "XF86AudioLowerVolume") +// { +// SoundDeviceSet::instance()->setValue(SoundDeviceSet::instance()->getValue() - 5); +// } +// else if(key == "XF86AudioMute") +// { +// SoundDeviceSet::instance()->setMute(!(SoundDeviceSet::instance()->getIsMute())); +// } +// else + + if (key == "XF86MonBrightnessUp") // 亮度调整 + { + //qDebug() << "up"; + BrightnessDeviceSet* pBrightness = BrightnessDeviceSet::instance(); + pBrightness->setValue(pBrightness->getValue() + 5); + } + else if (key == "XF86MonBrightnessDown") + { + //qDebug() << "down"; + BrightnessDeviceSet* pBrightness = BrightnessDeviceSet::instance(); + pBrightness->setValue(pBrightness->getValue() - 5); + } + else if (key == "XF86RFKill") // 飞行模式 + { + // 键盘上的飞行模式实体键 生效,不需要在登录界面进行设置 + } + else if (key == "") // num_lock + { + // 键盘上的num_lock生效、不需要登录界面进行管理 + } +#else + if(key == "Escape" && screenStatus == SCREEN_LOCK) + { + bool canShow = true; + if (lockWidget && !lockWidget->exitSubWidget()) + canShow = false; + if (canShow) + showScreensaver(); + } + else if(screenStatus & SCREEN_SAVER && !isBlank) + { + clearScreensavers(); + } +#endif +} + +void FullBackgroundWidget::onGlobalButtonDrag(int xPos, int yPos) +{ +#ifdef USE_INTEL + if(screenStatus == SCREEN_LOCK_AND_SAVER) + { + ScreenSaver *saver = configuration->getScreensaver(); + if(saver->path == "/usr/lib/ukui-screensaver/ukui-screensaver-default") + return ; + clearScreensavers(); + } +#else + if(screenStatus & SCREEN_SAVER && !isBlank) + { + ScreenSaver *saver = configuration->getScreensaver(); + if(isPassed || saver->path != "/usr/lib/ukui-screensaver/ukui-screensaver-default"){ + clearScreensavers(); + } + isPassed = true; + } +#endif +} + +void FullBackgroundWidget::onGlobalButtonPressed(int xPos, int yPos) +{ +#ifndef USE_INTEL + if(screenStatus & SCREEN_SAVER && !isBlank) + { + clearScreensavers(); + } +#endif +} + +void FullBackgroundWidget::closeScreensaver() +{ + if(screenStatus & SCREEN_SAVER){ + clearScreensavers(); + } + + if(screenStatus & SCREEN_LOCK){ + if(lockWidget){ + lockWidget->stopAuth(); + lockWidget->close(); + } + } + + close(); +} + +void FullBackgroundWidget::onScreenCountChanged(int) +{ +#ifdef USE_INTEL + QDesktopWidget *desktop = QApplication::desktop(); + setGeometry(desktop->geometry()); + //repaint(); + update(); + clearScreensavers(); +#else + QDesktopWidget *desktop = QApplication::desktop(); + setGeometry(desktop->geometry()); + //repaint(); + if(screenStatus & SCREEN_SAVER) + { + clearScreensavers(); + } + update(); +#endif +} + + +void FullBackgroundWidget::onDesktopResized() +{ +#ifdef USE_INTEL + qDebug() << "[FullBackgroundWidget] [onDesktopResized]"; + QDesktopWidget *desktop = QApplication::desktop(); + if(NULL == desktop) + { + qWarning() << " get desktop size failed"; + return; + } + setGeometry(desktop->geometry()); + if(lockWidget) + onCursorMoved(cursor().pos()); +// clearScreensavers(); + //repaint(); + update(); + if(screenStatus == SCREEN_LOCK_AND_SAVER) + { + clearScreensavers(); + showScreensaver(); + } +#else + QDesktopWidget *desktop = QApplication::desktop(); + setGeometry(desktop->geometry()); + if(lockWidget) + onCursorMoved(QCursor::pos()); + if(screenStatus & SCREEN_SAVER) + { + clearScreensavers(); + } + //repaint(); + update(); +#endif +} + +void FullBackgroundWidget::laterInhibit(bool val) +{ + if(val){ + inhibit(); + }else{ + uninhibit(); + } +} + +void FullBackgroundWidget::laterStartAuth() +{ + if (lockWidget) + lockWidget->startAuth(); + inhibit(); +} + +void FullBackgroundWidget::onPrepareForSleep(bool sleep) +{ + ///系统休眠时,会关闭总线,导致设备不可用,发生错误 + ///在系统休眠之前停止认证,在系统唤醒后重新开始认证 + if(sleep) + { + if(lockWidget) + lockWidget->stopAuth(); + uninhibit(); + } + else + { + if(screenStatus & SCREEN_SAVER) + { + isBlank = false; + clearScreensavers(); + }else{ + repaint(); + if(lockWidget) + lockWidget->startAuth(); + inhibit(); + } + } +} + +void FullBackgroundWidget::inhibit() +{ + if (m_inhibitFileDescriptor.isValid()) { + return; + } + + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + QStringLiteral("Inhibit")); + message.setArguments(QVariantList({QStringLiteral("sleep"), + "Screen Locker", + "Ensuring that the screen gets locked before going to sleep", + QStringLiteral("delay")})); + QDBusPendingReply reply = QDBusConnection::systemBus().call(message); + if (!reply.isValid()) { + return; + } + reply.value().swap(m_inhibitFileDescriptor); +} + +void FullBackgroundWidget::uninhibit() +{ + if (!m_inhibitFileDescriptor.isValid()) { + return; + } + m_inhibitFileDescriptor = QDBusUnixFileDescriptor(); +} + +/** + * @brief FullBackgroundWidget::getPaddingPixmap + * @param pixmap 需要填充的图像 + * @param width 容器宽度 + * @param height 容器高度 + * @return + */ +QPixmap FullBackgroundWidget::getPaddingPixmap(QPixmap pixmap, int width, int height) +{ + if (pixmap.isNull() || pixmap.width() == 0 || pixmap.height() == 0) + { + return QPixmap(); + } + + bool useHeight; + float scaled = 0.0; + QPixmap scaledPixmap; + QPixmap paddingPixmap; + qint64 rw = qint64(height) * qint64(pixmap.width()) / qint64(pixmap.height()); + + useHeight = (rw >= width); + if (useHeight) { + scaled = float(height) / float(pixmap.height()); + scaledPixmap = pixmap.scaled(pixmap.width() * scaled, height); + paddingPixmap = scaledPixmap.copy((pixmap.width() * scaled - width) / 2 , 0, width, height); + } else { + scaled = float(width) / float(pixmap.width()); + scaledPixmap = pixmap.scaled(width, pixmap.height() * scaled); + paddingPixmap = scaledPixmap.copy(0 , (pixmap.height() * scaled - height) / 2,width, height); + } + + return paddingPixmap; +} + +#ifdef USE_INTEL +void FullBackgroundWidget::onShowBlackBackGround() +{ + screenStatus = SCREEN_BLACK; + qDebug() << "showBlackBackGround - screenStatus: " << screenStatus; + + for(auto screen : QGuiApplication::screens()) + { +// BlackWidget *blackWidget = new BlackWidget(this); +// qDebug() << " new BlackWidget"; +// widgetBlackList.push_back(blackWidget); + ScreenSaver *saver = configuration->getScreensaver(); + saver->mode = SaverMode(SAVER_BLANK_ONLY); + ScreenSaverWidget *saverWidget = new ScreenSaverWidget(saver, this); + widgetBlackList.push_back(saverWidget); + saverWidget->setGeometry(screen->geometry()); + + //深色模式有一像素的白边,所以主屏幕向左,向右移一个像素点;这种操作后,外显上方仍旧会有一个像素的白边,暂时不对外显做偏移处理 + if(screen == qApp->primaryScreen()) { + saverWidget->setGeometry(screen->geometry().x()-1, screen->geometry().y()-1, + screen->geometry().width()+1, screen->geometry().height()+1); + } else { + saverWidget->setGeometry(screen->geometry()); + } + + + } + setCursor(Qt::BlankCursor); +} +#endif diff --git a/src/fullbackgroundwidget.h b/src/fullbackgroundwidget.h new file mode 100644 index 0000000..991e2be --- /dev/null +++ b/src/fullbackgroundwidget.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef FULLBACKGROUNDWIDGET_H +#define FULLBACKGROUNDWIDGET_H + +#ifndef QT_NO_KEYWORDS +#define QT_NO_KEYWORDS +#endif +#include +#include +#include +#include "types.h" +#include +#include +#include +#include "logind.h" +#include "config.h" + +void x11_get_screen_size(int *width,int *height); + +class LockWidget; +class XEventMonitor; +class MonitorWatcher; +class Configuration; +class QDBusInterface; +class TabletLockWidget; +class QProcess; +class FullBackgroundWidget : public QWidget , public QAbstractNativeEventFilter +{ + Q_OBJECT +public: + explicit FullBackgroundWidget(QWidget *parent = nullptr); + void paintEvent(QPaintEvent *event); + void closeEvent(QCloseEvent *event); + void showEvent(QShowEvent *event); + virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override; + void mouseMoveEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e); + void onScreensaver(); + void onBlankScreensaver(); + void closeScreensaver(); + void setIsStartup(bool val); + +public Q_SLOTS: + void onCursorMoved(const QPoint &pos); + void lock(); + void showLockWidget(); + void showLock(); + void showScreensaver(); + int onSessionStatusChanged(uint status); + void inhibit(); + void uninhibit(); +#ifdef USE_INTEL + void propertiesChangedSlot(QString, QMap, QStringList); + void onShowBlackBackGround(); +#endif +private: + void init(); + void clearScreensavers(); + bool eventFilter(QObject *obj, QEvent *event); + + QPixmap getPaddingPixmap(QPixmap pixmap, int width, int height); +// void checkNumLock(); +// int numberMatch(const QString &key); + +private Q_SLOTS: + void onScreenCountChanged(int); + void onDesktopResized(); + void onGlobalKeyPress(const QString &key); + void onGlobalKeyRelease(const QString &key); + void onGlobalButtonDrag(int xPos, int yPos); + void onGlobalButtonPressed(int xPos, int yPos); + void onPrepareForSleep(bool sleep); + void switchToLinux(); + void laterActivate(); + void setLockState(); + void killWindow(); + void laterInhibit(bool val); + void laterStartAuth(); + void onConfigurationDelayChanged(QString key); + void onConfigurationLockChanged(QString key); +// void lockEnabledChanged(QString key); + +private: + QDBusInterface *smInterface; +#ifdef USE_INTEL + TabletLockWidget *lockWidget; +#else + LockWidget *lockWidget; +#endif + XEventMonitor *xEventMonitor; + MonitorWatcher *monitorWatcher; + Configuration *configuration; + QList widgetXScreensaverList; + QList widgetBlackList; + QList xscreensaverPidList; + bool isLocked; + bool lockState; + ScreenStatus screenStatus; + QPixmap background; + QDBusUnixFileDescriptor m_inhibitFileDescriptor; + bool isPassed; + bool m_delay; + int isBlank; + QGSettings *settings_delay; + QGSettings *settings_lock; + QGSettings *lockEnabled_Key; + QProcess *process = nullptr; + int idleDelay; + int idleLock; + bool lockEnabled; + bool isStartup = false; + QFuture future; +}; + +#endif // FULLBACKGROUNDWIDGET_H diff --git a/src/generalauthwidget.cpp b/src/generalauthwidget.cpp new file mode 100644 index 0000000..eaa2efa --- /dev/null +++ b/src/generalauthwidget.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "generalauthwidget.h" + +GeneralAuthWidget::GeneralAuthWidget(QWidget *parent) : QWidget(parent) +{ + +} diff --git a/src/generalauthwidget.h b/src/generalauthwidget.h new file mode 100644 index 0000000..47f2c57 --- /dev/null +++ b/src/generalauthwidget.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef GENERALAUTHWIDGET_H +#define GENERALAUTHWIDGET_H + +#include + +class GeneralAuthWidget : public QWidget +{ + Q_OBJECT +public: + explicit GeneralAuthWidget(QWidget *parent = nullptr); + +signals: + +public slots: +}; + +#endif // GENERALAUTHWIDGET_H \ No newline at end of file diff --git a/src/gestureauthdialog.cpp b/src/gestureauthdialog.cpp new file mode 100644 index 0000000..ca657dc --- /dev/null +++ b/src/gestureauthdialog.cpp @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#include "gestureauthdialog.h" + +#include +#include +#include +#include +#include +#include + +int gestureScale = 1; + +/** + * @author zhaikangning + * @date 2020/09/15 + * 手势密码页 + * 功能未完善 未对接pam + * 未来进化 所有登录均继承认证父类 该父类含有密码校验等基本功能 + */ + +GestureAuthDialog::GestureAuthDialog(QWidget *parent) : QWidget(parent), + m_bgColor("#000000"), + m_outCircleColor("#fff333"), + m_tipLineColor("#ff0000"), + m_circleRingColor("#ddffff"), + m_radius(20), + m_margin(5), + m_pressed(false), + m_showText(true), + m_inputPassword(""), + m_is_set_password(false), + m_is_check_password(false) +{ + m_posInCircle.isIn = false; + qDebug() <<"-----------init width=" << width() << ",height=" << height(); + + m_set_password = new QPushButton(this); + m_set_password->setGeometry(0,0,m_set_password->width(),m_set_password->height()); + m_set_password->setText("设置密码"); + connect(m_set_password, &QPushButton::clicked,this, [=] { + m_chech_result->setText("请输入密码"); + m_is_set_password = true; + }); + + + m_unlock = new QPushButton(this); + m_unlock->setText("解锁"); + m_unlock->setGeometry(0,m_set_password->height() + 2,m_unlock->width(),m_unlock->height()); + connect(m_unlock,&QPushButton::clicked, this, [=] { + m_chech_result->setText("密码校验"); + m_is_check_password = true; + }); + + m_chech_result = new QLabel("校验结果", this); + m_chech_result->setStyleSheet("color:#ffeeff;"); + m_chech_result->setGeometry(0,m_set_password->height() + m_unlock->height() +2, m_chech_result->width(), m_chech_result->height()); + + resize(640,480); +} + +GestureAuthDialog::~GestureAuthDialog() +{ + +} + +void GestureAuthDialog::paintEvent(QPaintEvent *event) +{ + int width = this->width(); + int height = this->height(); + int side = qMin(width, height); + qDebug() <<"-----------width=" << width << ",height=" << height << ",side=" << side; + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.translate(width / 2, height / 2); + painter.scale(side / 200, side / 200); + gestureScale = side/200; + + drawBg(&painter); + drawOutCircle(&painter); + drawTipLine(&painter); + drawInCircle(&painter); + drawJoinLine(&painter); +} +void GestureAuthDialog::drawBg(QPainter *painter) +{ + painter->save(); + + int width = this->width(); + int height = this->height(); + + painter->setPen(Qt::NoPen); + m_bgColor.setAlpha(100); + painter->setBrush(m_bgColor); + painter->drawRect(-width / 2, -height / 2, width, height); + + painter->restore(); +} + +void GestureAuthDialog::drawOutCircle(QPainter *painter) +{ + painter->save(); + QPen pen(m_outCircleColor, 2); + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + int x = -5 * m_radius + j * 4 * m_radius; + int y = -5 * m_radius + i * 4 * m_radius; + painter->drawEllipse(x, y, m_radius * 2, m_radius * 2); +//qDebug() << "-------------x,y=" << x << ","<< y; + if (m_showText) + { + int number = posToNumber(i, j); + QString text = QString::number(number); + x = -4 * m_radius + j * 4 * m_radius; + y = -4 * m_radius + i * 4 * m_radius; + int textWidth = fontMetrics().width(text); + int textHeight = fontMetrics().height(); + painter->drawText(x - textWidth / 2, y + textWidth / 2, text); + } + } + } + + painter->restore(); +} + +void GestureAuthDialog::drawTipLine(QPainter *painter) +{ + painter->save(); + + int offset = 3; + + if (m_posInCircle.isIn) + { + if (!m_pressed) + { + painter->setPen(m_tipLineColor); + painter->setBrush(Qt::NoBrush); + + int x = -m_radius * 5 + m_posInCircle.j * 4 * m_radius - offset; + int y = -m_radius * 5 + m_posInCircle.i * 4 * m_radius - offset; + int w = (m_radius + offset) * 2; + int h = (m_radius + offset) * 2; + QRect rect(x, y, w, h); + painter->drawEllipse(rect); + } + } + + painter->restore(); +} + +void GestureAuthDialog::drawInCircle(QPainter *painter) +{ + painter->save(); + + if (m_pressed) + { + int offset1 = 1;//圆环偏移量 + int offset2 = 3;//内圆偏移量 + + if (m_posInCircle.isIn) + { + //绘制圆环 + painter->setPen(m_circleRingColor); + painter->setBrush(m_circleRingColor); + int x = -m_radius * 5 + m_posInCircle.j * 4 * m_radius + offset1; + int y = -m_radius * 5 + m_posInCircle.i * 4 * m_radius + offset1; + int w = (m_radius - offset1) * 2; + int h = (m_radius - offset1) * 2; + QRect rect(x, y, w, h); + painter->drawEllipse(rect); + + painter->setPen(m_outCircleColor); + painter->setBrush(m_outCircleColor); + x = -m_radius * 5 + m_posInCircle.j * 4 * m_radius + offset2; + y = -m_radius * 5 + m_posInCircle.i * 4 * m_radius + offset2; + w = (m_radius - offset2) * 2; + h = (m_radius - offset2) * 2; + rect = QRect(x, y, w, h); + painter->drawEllipse(rect); + + x = -m_radius * 4 + m_posInCircle.j * 4 * m_radius; + y = -m_radius * 4 + m_posInCircle.i * 4 * m_radius; + + if (!m_vecInputPoints.contains(QPoint(x, y))) + { + m_vecInputPoints.push_back(QPoint(x, y)); + int number = posToNumber(m_posInCircle.i, m_posInCircle.j); + m_inputPassword += QString::number(number); + } + } + } + + painter->restore(); +} + +void GestureAuthDialog::drawJoinLine(QPainter *painter) +{ + painter->save(); + + QPen pen(m_outCircleColor, 3); + painter->setPen(pen); + //绘制连接线段 + for (int i = 0; i < m_vecInputPoints.count() - 1; i++) + { + painter->drawLine(m_vecInputPoints[i], m_vecInputPoints[i + 1]); + } + + int offset1 = 1;//圆环偏移量 + int offset2 = 3;//内圆偏移量 + //绘制连接圆 + for (int i = 0; i < m_vecInputPoints.count(); i++) + { + int x = m_vecInputPoints[i].x() - m_radius + offset1; + int y = m_vecInputPoints[i].y() - m_radius + offset1; + int w = 2 * (m_radius - offset1); + int h = 2 * (m_radius - offset1); + painter->setPen(m_circleRingColor); + painter->setBrush(m_circleRingColor); + painter->drawEllipse(x, y, w, h); + + x = m_vecInputPoints[i].x() - m_radius + offset2; + y = m_vecInputPoints[i].y() - m_radius + offset2; + w = 2 * (m_radius - offset2); + h = 2 * (m_radius - offset2); + painter->setPen(m_outCircleColor); + painter->setBrush(m_outCircleColor); + painter->drawEllipse(x, y, w, h); + } + //绘制跟随线 + if (m_pressed && m_vecInputPoints.count() < 9) + { + int width = this->width(); + int height = this->height(); + int side = qMin(width, height); + int gestureScale = side / 200; + int x = (m_followPoint.x() - width / 2) / gestureScale; + int y = (m_followPoint.y() - height / 2) / gestureScale; + if (m_vecInputPoints.count() > 0) + { + painter->setPen(pen); + painter->drawLine(m_vecInputPoints.last(), QPoint(x, y)); + } + } + + painter->restore(); +} + +void GestureAuthDialog::mouseMoveEvent(QMouseEvent *event) +{ + //nothing + qDebug() << "--------mouseMoveEvent(" << event->x() << "," << event->y() << ")"; + // qDebug() << "-------------gestureScale=" << gestureScale; + int x = (event->x() - this->width()/2) / gestureScale; + int y = (event->y() - this->height()/2) / gestureScale; + // qDebug() << "--------mousePressEvent转化后 x,y(" << x << "," << y << ")"; + int jMax = 0; + if (x >=0) + jMax = 1; + + for (int i = 0; i < 3; i++) + { + for (int j = jMax; j < 3; j++) + { + + int x1 = -4 * m_radius + j * 4 * m_radius; + int y1 = -4 * m_radius + i * 4 * m_radius; + // qDebug() << "--------每个圆心的位置 x1,y1(" << x1 << "," << y1 << ")"; + if (distance(x , y, x1, y1) <= m_radius) + { + QString numStr = QString::number(posToNumber(i,j), 10); + if (m_inputPassword.contains(numStr)) + { + qWarning() << "已选过该区域"; + return; + } + m_inputPassword.append(numStr); + + m_posInCircle.i = i; + m_posInCircle.j = j; +// m_posInCircle.isIn = true; + qDebug() << "---------------选中了"<< posToNumber(i,j); + + + m_vecInputPoints.append(QPoint(x1, y1)); //鼠标移动选点 + m_followPoint = QPoint(x, y); + repaint(); + } + } + } +} + +void GestureAuthDialog::mousePressEvent(QMouseEvent *event) +{ + //nothing + qDebug() << "--------mousePressEvent(" << event->x() << "," << event->y() << ")"; +// qDebug() << "-------------gestureScale=" << gestureScale; + int x = (event->x() - this->width()/2) / gestureScale; + int y = (event->y() - this->height()/2) / gestureScale; +// qDebug() << "--------mousePressEvent转化后 x,y(" << x << "," << y << ")"; + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + int x1 = -4 * m_radius + j * 4 * m_radius; + int y1 = -4 * m_radius + i * 4 * m_radius; +// qDebug() << "--------每个圆心的位置 x1,y1(" << x1 << "," << y1 << ")"; + if (distance(x , y, x1, y1) <= m_radius) + { + m_posInCircle.i = i; + m_posInCircle.j = j; + m_posInCircle.isIn = true; + + m_vecInputPoints.append(QPoint(x1, y1)); //鼠标移动选点 + m_followPoint = QPoint(x1, y1); + qDebug() << "---------------选中了"<< posToNumber(i,j); + repaint(); + } + } + } +} + +void GestureAuthDialog::mouseReleaseEvent(QMouseEvent *event) +{ + //nothing + qDebug() << "--------mouseReleaseEvent(" << event->x() << "," << event->y() << ")"; + m_posInCircle.isIn = false; + if (m_is_set_password && !m_inputPassword.isEmpty()) + { + m_password = m_inputPassword; + m_chech_result->setText("密码设置成功"); + qDebug() << "---------密码:" << m_password; + m_is_set_password = false; + } + + if (m_is_check_password) { + if (m_inputPassword == m_password) + { + m_chech_result->setText("密码正确"); + qDebug() << "---------密码:" << m_password << " 输入的是:" << m_inputPassword; + emit authenticateCompete(true); +// m_is_check_password = false; + } else { + m_chech_result->setText("密码错误"); + qDebug() << "---------密码:" << m_password << " 输入的是:" << m_inputPassword; + } + } + m_vecInputPoints.clear(); + m_inputPassword.clear(); + repaint(); +} + +double GestureAuthDialog::distance(int x1, int y1, int x2, int y2) +{ + //nothing + double x = x1 - x2; + double y = y1 - y2; + return sqrt(x*x + y*y); +} + +int GestureAuthDialog::posToNumber(int i, int j) +{ + //nothing + return ((3*i) + j +1); +} + +void GestureAuthDialog::setPassword(const QString password) +{ + //nothing +} + +QString GestureAuthDialog::getPassword() +{ + //nothing +} + +bool GestureAuthDialog::checkPassword() +{ + //nothing +} diff --git a/src/gestureauthdialog.h b/src/gestureauthdialog.h new file mode 100644 index 0000000..ad32bc7 --- /dev/null +++ b/src/gestureauthdialog.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#ifndef GESTUREAUTHDIALOG_H +#define GESTUREAUTHDIALOG_H + +#include +#include +#include +#include +#include +#include + +class GestureAuthDialog : public QWidget +{ + Q_OBJECT +public: + struct PosInCircle + { + int i; //行 + int j; //列 + bool isIn; //是否在范围内 + }; + explicit GestureAuthDialog(QWidget *parent = nullptr); + ~GestureAuthDialog(); + + void setPassword(const QString password); + QString getPassword(); + bool checkPassword(); +protected: + void paintEvent(QPaintEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void drawBg(QPainter *painter); + void drawOutCircle(QPainter *painter); + void drawTipLine(QPainter *painter); + void drawInCircle(QPainter *painter); + void drawJoinLine(QPainter *painter); +private: + double distance(int x1, int y1, int x2, int y2); + int posToNumber(int i, int j); +Q_SIGNALS: + void correctPassword(bool isCorrect, QString password); + void authenticateCompete(bool result); +public Q_SLOTS: +private: + QColor m_bgColor; //背景色 + QColor m_outCircleColor; //外圆颜色 + QColor m_tipLineColor; //提示线颜色 + QColor m_circleRingColor; //圆环颜色 + int m_margin; //外边距 + int m_radius; //圆相对半径 + PosInCircle m_posInCircle; //判断点是否在圆内 + bool m_pressed; //鼠标按下 + bool m_showText; //是否显示文字 + + QVector m_vecInputPoints; //鼠标移动选点 + QPoint m_followPoint; //鼠标跟随点 + QString m_password; //原密码 + QString m_inputPassword; //鼠标移动选点转换为密码 + + QPushButton *m_set_password; + bool m_is_set_password; + QPushButton *m_unlock; + bool m_is_check_password; + QLabel *m_chech_result; +}; + +#endif // GESTUREAUTHDIALOG_H diff --git a/src/grab-x11.cpp b/src/grab-x11.cpp new file mode 100644 index 0000000..a03d14d --- /dev/null +++ b/src/grab-x11.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "grab-x11.h" +#include +#include +#include + +class XServerGraber{ +public: + XServerGraber() { + xcb_grab_server(QX11Info::connection()); + } + ~XServerGraber() { + xcb_ungrab_server(QX11Info::connection()); + xcb_flush(QX11Info::connection()); + } +}; + +static bool grabKeyboard() +{ + int rv = XGrabKeyboard(QX11Info::display(), QX11Info::appRootWindow(), + True, GrabModeAsync, GrabModeAsync, CurrentTime); + return (rv == GrabSuccess); +} + +static bool grabMouse() +{ +#define GRABEVENTS ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \ + EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask + int rv = XGrabPointer(QX11Info::display(), QX11Info::appRootWindow(), + True, GRABEVENTS, GrabModeAsync, GrabModeAsync, None, + None, CurrentTime); +#undef GRABEVENTS + + return (rv == GrabSuccess); +} + +bool establishGrab() +{ + XSync(QX11Info::display(), False); + XServerGraber xserverGraber; + + Q_UNUSED(xserverGraber); + + if(!grabKeyboard()) + return false; + + if(!grabMouse()) { + XUngrabKeyboard(QX11Info::display(), CurrentTime); + XFlush(QX11Info::display()); + return false; + } + + return true; +} + +bool closeGrab() +{ + XSync(QX11Info::display(), False); + XServerGraber xserverGraber; + + Q_UNUSED(xserverGraber); + + XUngrabKeyboard(QX11Info::display(), CurrentTime); + XUngrabPointer(QX11Info::display(), CurrentTime); + XFlush(QX11Info::display()); + return true; +} diff --git a/src/grab-x11.h b/src/grab-x11.h new file mode 100644 index 0000000..2821f08 --- /dev/null +++ b/src/grab-x11.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef GRABX11_H +#define GRABX11_H + + +bool establishGrab(); +bool closeGrab(); + +#endif // GRABX11_H diff --git a/src/hoverwidget.cpp b/src/hoverwidget.cpp new file mode 100644 index 0000000..67f142d --- /dev/null +++ b/src/hoverwidget.cpp @@ -0,0 +1,60 @@ +/* -*- 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 "hoverwidget.h" + +#include +#include + +#include +#define THEME_QT_SCHEMA "org.ukui.style" +#define MODE_QT_KEY "style-name" + +HoverWidget::HoverWidget(QString mname, QWidget *parent) : + QWidget(parent), + _name(mname) +{ + setAttribute(Qt::WA_DeleteOnClose); +} + +HoverWidget::~HoverWidget() +{ +} + +void HoverWidget::enterEvent(QEvent *event){ + emit enterWidget(_name); + + QWidget::enterEvent(event); +} + +void HoverWidget::leaveEvent(QEvent *event){ + emit leaveWidget(_name); + + QWidget::leaveEvent(event); +} + +//子类化一个QWidget,为了能够使用样式表,则需要提供paintEvent事件。 +//这是因为QWidget的paintEvent()是空的,而样式表要通过paint被绘制到窗口中。 +void HoverWidget::paintEvent(QPaintEvent *event){ + Q_UNUSED(event) + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} diff --git a/src/hoverwidget.h b/src/hoverwidget.h new file mode 100644 index 0000000..bcb811e --- /dev/null +++ b/src/hoverwidget.h @@ -0,0 +1,50 @@ +/* -*- 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 HOVERWIDGET_H +#define HOVERWIDGET_H + +#include +#include +#include +#include +#include + +class HoverWidget : public QWidget +{ + Q_OBJECT + +public: + explicit HoverWidget(QString mname, QWidget *parent = 0); + ~HoverWidget(); + +public: + QString _name; + +protected: + virtual void enterEvent(QEvent * event); + virtual void leaveEvent(QEvent * event); + virtual void paintEvent(QPaintEvent * event); +Q_SIGNALS: + void enterWidget(QString name); + void leaveWidget(QString name); +}; + +#endif // HOVERWIDGET_H + diff --git a/src/iconedit.cpp b/src/iconedit.cpp new file mode 100644 index 0000000..a620826 --- /dev/null +++ b/src/iconedit.cpp @@ -0,0 +1,309 @@ +/* iconedit.cpp + * Copyright (C) 2018 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, 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 "iconedit.h" +#include "imageutil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define GSETTINGS_SCHEMA_PERIPHERALS_KEYBOARD "org.ukui.peripherals-keyboard" +#define CAPSLOCK_STATUS "capslock_state" +/** + * @brief 判断大写键状态 + * @return true: 大写锁定 + */ +//bool checkCapsLockState() +//{ +// bool capsState = false; +// unsigned int n; +// XkbGetIndicatorState(QX11Info::display(), XkbUseCoreKbd, &n); +// capsState = (n & 0x01) == 1; + +// return capsState; +//} + + +IconEdit::IconEdit(QWidget *parent) + : QWidget(parent), + m_timer(nullptr) +{ + m_edit = new QLineEdit(this); + m_edit->setObjectName(QStringLiteral("passwdEdit")); + m_edit->setAttribute(Qt::WA_InputMethodEnabled, false); //禁用输入法 + m_edit->setContextMenuPolicy(Qt::NoContextMenu); //禁用右键菜单 + m_edit->installEventFilter(this); + + m_capsIcon = new QSvgWidget(this); + m_capsIcon->setObjectName(QStringLiteral("capsIconLabel")); + settings = new QGSettings(GSETTINGS_SCHEMA_PERIPHERALS_KEYBOARD, "", this); + connect(settings, &QGSettings::changed, + this, &IconEdit::onCapsChanged); + capsState = settings->get("capslock-state").toBool(); + m_capsIcon->setVisible(capsState); + m_capsIcon->load(QString(":/image/assets/capslock.svg")); + + m_iconButton = new QPushButton(this); + m_iconButton->setObjectName(QStringLiteral("loginButton")); + m_iconButton->setFocusPolicy(Qt::NoFocus); + m_iconButton->setCursor(QCursor(Qt::PointingHandCursor)); + m_iconButton->installEventFilter(this); + + m_modeButton = new QPushButton(this); + m_modeButton->setObjectName(QStringLiteral("echoModeButton")); + m_modeButton->setCheckable(true); + m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic")); + m_modeButton->setFocusPolicy(Qt::NoFocus); + m_modeButton->setCursor(Qt::PointingHandCursor); + m_modeButton->installEventFilter(this); + connect(m_modeButton, &QPushButton::clicked, this, [&](bool checked){ + setType(checked ? QLineEdit::Normal : QLineEdit::Password); + }); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setContentsMargins(1, 1, 8, 1); + layout->setSpacing(0); + layout->addStretch(); + layout->addWidget(m_capsIcon); + layout->addWidget(m_modeButton); + layout->addWidget(m_iconButton); + + connect(m_edit, &QLineEdit::returnPressed, this, &IconEdit::clicked_cb); + connect(m_iconButton, &QPushButton::clicked, this, &IconEdit::clicked_cb); + + setFocusProxy(m_edit); + //setCapsState(checkCapsState()); +} + +bool IconEdit::eventFilter(QObject *obj, QEvent *event) +{ + if(obj == m_edit){ + if(event->type() == 6){ //禁止复制粘贴功能。 + QKeyEvent *keyEvent = static_cast(event); + if(keyEvent->matches(QKeySequence::Copy) || keyEvent->matches(QKeySequence::Cut) || keyEvent->matches(QKeySequence::Paste)){ + event->ignore(); + return true; + }else if((keyEvent->modifiers() & Qt::MetaModifier) || (keyEvent->modifiers() & Qt::AltModifier)){//当meta或者alt键被按下时,忽略按键事件 + event->ignore(); + return true; + } + } + if(event->type() == 2) + { + Q_EMIT clickedPassword(true); + } + if(event->type() == 23) + { + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + update(); + }else if(event->type() == QEvent::MouseButtonPress){ + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + update(); + } + } + if(obj == m_iconButton){ + if(m_timer && m_timer->isActive()) + { + return false; + } + if(event->type() == 2) + { + Q_EMIT clickedPassword(true); + } + if(event->type() == QEvent::HoverEnter){ + setIcon(QIcon(":/image/assets/login-button-hover.svg")); + } + else if(event->type() == QEvent::HoverLeave){ + setIcon(QIcon(":/image/assets/login-button.svg")); + } + } + if(obj == m_modeButton){ + if(event->type() == 2) + { + Q_EMIT clickedPassword(true); + } + } + return false; +} + +void IconEdit::setType(QLineEdit::EchoMode type) +{ + m_edit->setEchoMode(type); + if(type == 0){ + m_modeButton->setChecked(true); + m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic")); + } + else{ + m_modeButton->setChecked(false); + m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic")); + } +} + +void IconEdit::resizeEvent(QResizeEvent *) +{ + // 设置输入框中文件输入区,不让输入的文字在被隐藏在按钮下 + int w = m_iconButton->width() + m_modeButton->width(); + m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 8 : w, 1); + m_edit->setFixedSize(size()); +} + + +void IconEdit::setX11Focus() +{ + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + update(); +} + +void IconEdit::clicked_cb() +{ + startWaiting(); + emit clicked(m_edit->text()); +} + +void IconEdit::onCapsChanged() +{ + capsState = settings->get("capslock-state").toBool(); + m_capsIcon->setVisible(capsState); + int w = m_iconButton->width() + m_modeButton->width(); + m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 8 : w, 1); +} + +//void IconEdit::onCapsStateChanged() +//{ +// bool capsState = m_capsIcon->isHidden(); + +//} + +void IconEdit::setIcon(const QString &text) +{ + m_iconButton->setIcon(QIcon()); + m_iconButton->setText(text); + m_iconText = text; + m_icon = QIcon(); +} + +void IconEdit::setIcon(const QIcon &icon) +{ + m_iconButton->setIcon(icon); + m_iconButton->setText(""); + m_icon = icon; + m_iconText = ""; +} + +void IconEdit::clear() +{ + m_edit->setText(""); + setPrompt(""); +} + +void IconEdit::clearText() +{ + m_edit->setText(""); +} + +void IconEdit::setPrompt(const QString &prompt) +{ + m_edit->setPlaceholderText(prompt); + QPalette palette = m_edit->palette(); + palette.setColor(QPalette::Normal, QPalette::PlaceholderText, Qt::gray); + m_edit->setPalette(palette); +} + +const QString IconEdit::text() +{ + return m_edit->text(); +} + +void IconEdit::readOnly(bool enabled) +{ + m_edit->setEnabled(!enabled); + m_edit->setReadOnly(enabled); +} + +void IconEdit::setLocked(bool lock) +{ + m_iconButton->blockSignals(lock); +} + +void IconEdit::startWaiting() +{ + m_edit->setReadOnly(true); + //m_iconButton->setEnabled(false); + + if(!m_timer) + { + m_timer = new QTimer(this); + m_timer->setInterval(150); + connect(m_timer, &QTimer::timeout, this, &IconEdit::updatePixmap); + } + + //m_waitingPixmap.load(":/image/assets/ukui-loginopt-face.svg"); + +// m_iconButton->setProperty("useIconHighlightEffect", true); +// m_iconButton->setProperty("iconHighlightEffectMode", 1); +// m_waitingPixmap = ImageUtil::loadSvg(":/image/assets/ukui-loginopt-face.svg", "white", 24); +// m_iconButton->setIcon(QIcon(m_waitingPixmap)); + + QPixmap icon = QIcon::fromTheme("ukui-loading-symbolic-0").pixmap(16,16); + m_waitingPixmap = ImageUtil::drawSymbolicColoredPixmap(icon, "white"); + m_iconButton->setIcon(m_waitingPixmap); + m_timer->start(); +} + + +void IconEdit::stopWaiting() +{ + if(m_timer && m_timer->isActive()) + { + m_timer->stop(); + } + m_iconButton->setAttribute(Qt::WA_TransparentForMouseEvents, false); + m_edit->setReadOnly(false); + //m_iconButton->setEnabled(true); + if(!m_icon.isNull()) + m_iconButton->setIcon(m_icon); + else + m_iconButton->setText(m_iconText); +} + +void IconEdit::updatePixmap() +{ + m_iconButton->setEnabled(true); + m_iconButton->setAttribute(Qt::WA_TransparentForMouseEvents, true); + QMatrix matrix; + matrix.rotate(90.0); + m_waitingPixmap = m_waitingPixmap.transformed(matrix, Qt::FastTransformation); + m_iconButton->setIcon(QIcon(m_waitingPixmap)); +} +/* +void IconEdit::setCapsState(bool capsState) +{ + m_capsIcon->setVisible(capsState); + int w = m_iconButton->width() + m_modeButton->width(); + m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() : w, 1); +} +*/ diff --git a/src/iconedit.h b/src/iconedit.h new file mode 100644 index 0000000..7a66db7 --- /dev/null +++ b/src/iconedit.h @@ -0,0 +1,80 @@ +/* iconedit.h + * Copyright (C) 2018 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, 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 ICONEDIT_H +#define ICONEDIT_H + +#include +#include +#include +#include +#include +#include +#include + +class IconEdit : public QWidget +{ + Q_OBJECT +public: + IconEdit(QWidget *parent = 0); + + void setIcon(const QString &text); + void setIcon(const QIcon &icon); + void clear(); + void clearText(); + void setPrompt(const QString &); + const QString text(); + void setType(QLineEdit::EchoMode type = QLineEdit::Password); + void startWaiting(); + void stopWaiting(); + void setX11Focus(); + void readOnly(bool enabled); + void setLocked(bool lock); + //void setEnabled(bool enabled); + +protected: + void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; + bool eventFilter(QObject *obj, QEvent *event); + +private: + void updatePixmap(); + +Q_SIGNALS: + void clicked(const QString &); + void focusOut(); + void clickedPassword(bool clicked); +public Q_SLOTS: + void clicked_cb(); + void onCapsChanged(); +// void onCapsStateChanged(); + +private: + QLineEdit *m_edit; + QSvgWidget *m_capsIcon; + QPushButton *m_iconButton; + QPushButton *m_modeButton; + QTimer *m_timer; + QPixmap m_waitingPixmap; + QString m_iconText; //文字作为图标 + QIcon m_icon; + QGSettings *settings; + bool capsState = false; +}; + +#endif // ICONEDIT_H diff --git a/src/image.qrc b/src/image.qrc new file mode 100644 index 0000000..ca67c5d --- /dev/null +++ b/src/image.qrc @@ -0,0 +1,7 @@ + + + image/hide-password.png + image/show-password.png + image/warn.png + + diff --git a/src/imageutil.cpp b/src/imageutil.cpp new file mode 100644 index 0000000..928d63f --- /dev/null +++ b/src/imageutil.cpp @@ -0,0 +1,81 @@ +/* -*- 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 "imageutil.h" + +#include +#include +const QPixmap ImageUtil::loadSvg(const QString &path, const QString color, int size) +{ + int origSize = size; + const auto ratio = qApp->devicePixelRatio(); + if ( 2 == ratio) { + size += origSize; + } else if (3 == ratio) { + size += origSize; + } + QPixmap pixmap(size, size); + QSvgRenderer renderer(path); + pixmap.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pixmap); + renderer.render(&painter); + painter.end(); + + pixmap.setDevicePixelRatio(ratio); + return drawSymbolicColoredPixmap(pixmap, color); +} + +QPixmap ImageUtil::drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor) +{ + QImage img = source.toImage(); + for (int x = 0; x < img.width(); x++) { + for (int y = 0; y < img.height(); y++) { + auto color = img.pixelColor(x, y); + if (color.alpha() > 0) { + if ( "white" == cgColor) { + color.setRed(255); + color.setGreen(255); + color.setBlue(255); + img.setPixelColor(x, y, color); + } else if( "black" == cgColor) { + color.setRed(0); + color.setGreen(0); + color.setBlue(0); + img.setPixelColor(x, y, color); + } else if ("gray"== cgColor) { + color.setRed(152); + color.setGreen(163); + color.setBlue(164); + img.setPixelColor(x, y, color); + } else if ("blue" == cgColor){ + color.setRed(61); + color.setGreen(107); + color.setBlue(229); + img.setPixelColor(x, y, color); + } else { + return source; + } + } + } + } + return QPixmap::fromImage(img); +} diff --git a/src/imageutil.h b/src/imageutil.h new file mode 100644 index 0000000..92c09d8 --- /dev/null +++ b/src/imageutil.h @@ -0,0 +1,35 @@ +/* -*- 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 IMAGEUTIL_H +#define IMAGEUTIL_H + +#include +#include +#include + +class ImageUtil +{ +public: + static const QPixmap loadSvg(const QString &path, const QString color, int size = 16); + static QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor); +}; + +#endif // IMAGEUTIL_H diff --git a/src/interface.cpp b/src/interface.cpp new file mode 100644 index 0000000..12d5b60 --- /dev/null +++ b/src/interface.cpp @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "interface.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Interface::Interface(QObject *parent) + : QObject(parent), + m_timerCount(0), + settings(nullptr), + m_timer(nullptr) +{ + lockState = false; + slpState = false; + m_logind = new LogindIntegration(this); + connect(m_logind, &LogindIntegration::requestLock, this, + [this]() { + this->onShowScreensaver(); + } + ); + + connect(m_logind, &LogindIntegration::requestUnlock, this, + [this]() { +// process.terminate(); +// 因为fullbackgroundwidget.cpp会监听这个信号,因此这个信号没必要监听了 +// process.kill(); + } + ); + + connect(&process, static_cast(&QProcess::finished), + [=](int exitCode, QProcess::ExitStatus exitStatus){ + emitLockState(false); + }); + + settings = new QGSettings("org.ukui.screensaver","",this); + + QDBusInterface *iface = new QDBusInterface("org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + QDBusConnection::systemBus(), + this); + connect(iface, SIGNAL(PrepareForSleep(bool)), this, SLOT(onPrepareForSleep(bool))); + inhibit(); + +} + +bool Interface::GetSlpState() +{ + return ((process.state() != QProcess::NotRunning) && slpState); +} + +bool Interface::GetLockState() +{ + return ((process.state() != QProcess::NotRunning) && lockState); +} + +void Interface::SetLockState() +{ + lockState = true; +} + +void Interface::emitLockState(bool val) +{ + QDBusMessage message; + if(val){ + message = QDBusMessage::createSignal(SS_DBUS_PATH, + SS_DBUS_INTERFACE, + "lock"); + }else{ + message = QDBusMessage::createSignal(SS_DBUS_PATH, + SS_DBUS_INTERFACE, + "unlock"); + } + QDBusConnection::sessionBus().send(message); +} + +void Interface::UnLock() +{ + if(process.state() != QProcess::NotRunning) + process.kill(); +} + +void Interface::Lock() +{ + if(process.state() != QProcess::NotRunning) + return ; + qDebug() << "Lock requested"; + lockState = false; + QString cmd = QString("/usr/bin/ukui-screensaver-dialog --lock"); + qDebug() << cmd; + + process.start(cmd); + emitLockState(true); +} + +void Interface::onSessionIdleReceived() +{ + if(process.state() != QProcess::NotRunning) + return ; + + qDebug() << "emit SessionIdle"; + lockState = false; + QString cmd = QString("/usr/bin/ukui-screensaver-dialog --session-idle"); + qDebug() << cmd; + process.start(cmd); + emitLockState(true); +} + +void Interface::onShowBlankScreensaver() +{ + if(process.state() != QProcess::NotRunning) + return ; + + qDebug() << "lock and show screensaver"; + lockState = false; + slpState = false; + QString cmd = QString("/usr/bin/ukui-screensaver-dialog --blank"); + qDebug() << cmd; + + process.start(cmd); + emitLockState(true); +} + +void Interface::onShowScreensaver() +{ + if(process.state() != QProcess::NotRunning) + return ; + + slpState = true; + qDebug() << "lock and show screensaver"; + lockState = false; + QString cmd = QString("/usr/bin/ukui-screensaver-dialog --lock-screensaver"); + qDebug() << cmd; + + process.start(cmd); + emitLockState(true); +} + +bool Interface::checkExistChild() +{ + char cmd[128] = {0}; + char str[4]; + FILE *fp; + int num; + + sprintf(cmd, "ps -aux | grep ukui-screensaver-dialog | grep %s | grep -v grep | wc -l", getenv("USER")); + + fp = popen(cmd, "r"); + if(fgets(str, sizeof(str)-1, fp) == NULL) + qDebug() << "fgets: " << strerror(errno); + pclose(fp); + + num = atoi(str); + + qDebug() << (num > 0 ? "exist dialog running" : ""); + + return num > 0; +} + +void Interface::onNameLost(const QString &serviceName) +{ + if(serviceName == "cn.kylinos.ScreenSaver") + exit(0); +} + +void Interface::onPrepareForSleep(bool sleep) +{ + if(sleep) + { + if(!settings->get("sleep-activation-enabled").toBool()){ + uninhibit(); + return; + } + + if(GetLockState()){ + uninhibit(); + return; + } + + if(GetSlpState()){ + uninhibit(); + return; + } + + this->onShowBlankScreensaver(); + + if(!m_timer){ + m_timer = new QTimer(this); + connect(m_timer, &QTimer::timeout, this, [&]{ + m_timerCount+=1; + + if(GetLockState() || m_timerCount>20){ + m_timer->stop(); + m_timerCount = 0; + uninhibit(); + } + }); + } + m_timer->start(200); + } + else + { + inhibit(); + } +} + +void Interface::ShowScreensaver() +{ + if(process.state() != QProcess::NotRunning) + return ; + + qDebug() << "lock and show screensaver"; + lockState = false; + QString cmd = QString("/usr/bin/ukui-screensaver-dialog --screensaver"); + qDebug() << cmd; + + process.start(cmd); + emitLockState(true); +} + +void Interface::inhibit() +{ + if (m_inhibitFileDescriptor.isValid()) { + return; + } + + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + QStringLiteral("Inhibit")); + message.setArguments(QVariantList({QStringLiteral("sleep"), + "Screen Locker Backend", + "Ensuring that the screen gets locked before going to sleep", + QStringLiteral("delay")})); + QDBusPendingReply reply = QDBusConnection::systemBus().call(message); + if (!reply.isValid()) { + return; + } + reply.value().swap(m_inhibitFileDescriptor); +} + +void Interface::uninhibit() +{ + if (!m_inhibitFileDescriptor.isValid()) { + return; + } + + m_inhibitFileDescriptor = QDBusUnixFileDescriptor(); +} diff --git a/src/interface.h b/src/interface.h new file mode 100644 index 0000000..411ce5c --- /dev/null +++ b/src/interface.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef INTERFACE_H +#define INTERFACE_H + +#include +#include +#include +#include +#include +#include "types.h" +#include "logind.h" + +class QGSettings; +class Interface : public QObject, protected QDBusContext +{ + Q_OBJECT + + Q_CLASSINFO("D-Bus Interface", SS_DBUS_SERVICE) + +public: + explicit Interface(QObject *parent = nullptr); + LogindIntegration *m_logind; +Q_SIGNALS: + void SessionIdle(); + +public Q_SLOTS: + /** + * Lock the screen + */ + void Lock(); + void UnLock(); + void ShowScreensaver(); + bool GetLockState(); + bool GetSlpState(); + void SetLockState(); + void onSessionIdleReceived(); + void onShowScreensaver(); + void onShowBlankScreensaver(); + void onNameLost(const QString&); + void onPrepareForSleep(bool sleep); + +private: + bool checkExistChild(); + void inhibit(); + void uninhibit(); + bool lockState; + bool slpState; + void emitLockState(bool); + int m_timerCount; + QGSettings *settings; + QTimer *m_timer; + QDBusUnixFileDescriptor m_inhibitFileDescriptor; + +private: + QProcess process; +}; + +#endif // INTERFACE_H diff --git a/src/lockwidget.cpp b/src/lockwidget.cpp new file mode 100644 index 0000000..19678ae --- /dev/null +++ b/src/lockwidget.cpp @@ -0,0 +1,987 @@ +/* + * Copyright (C) 2018 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 . + * +**/ + +#include "lockwidget.h" + +#include "powermanager.h" +#include "ui_lockwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "authdialog.h" +#include "virtualkeyboard.h" +#include "users.h" +#include "displaymanager.h" +#include "config.h" +#include "commonfunc.h" +#include "hoverwidget.h" +#include "kylinnm.h" + +#include +#include +#include + +#define TIME_TYPE_SCHEMA "org.ukui.control-center.panel.plugins" +#define CONFIG_FILE "/etc/lightdm/ukui-greeter.conf" +float scale; +LockWidget::LockWidget(QWidget *parent) + : QWidget(parent), + ui(new Ui::LockWidget), + usersMenu(nullptr), + scrollArea(nullptr), + users(new Users(this)), + displayManager(new DisplayManager(this)), + timeType(24), + m_kylinNM(nullptr) +{ + scale = 1.0; + ui->setupUi(this); + // m_kylinNM->installEventFilter(this); + + UserItem user = users->getUserByName(getenv("USER")); + authDialog = new AuthDialog(user, this); + authDialog->installEventFilter(this); + connect(authDialog, &AuthDialog::authenticateCompete, + this, &LockWidget::closed); + connect(authDialog,&AuthDialog::clickPassword, + this,&LockWidget::hideNetManager); +// connect(this, &LockWidget::capsLockChanged, +// authDialog, &AuthDialog::onCapsLockChanged); + +// connect(m_kylinNM, &KylinNM::onConnectChanged, this,[=](){ +// updateNetIcon(m_kylinNM->getConnectStatus()); +// }); + + xEventMonitor = new XEventMonitor(this); + connect(xEventMonitor, SIGNAL(keyPress(const QString &)), this, + SLOT(onGlobalKeyPress(const QString &))); + connect(xEventMonitor, SIGNAL(keyRelease(const QString &)), this, + SLOT(onGlobalkeyRelease(const QString &))); + xEventMonitor->start(); + + this->installEventFilter(this); + initUI(); + + if(users->getUsers().count() < 2){ + ui->btnSwitchUser->hide(); + } +} + +LockWidget::~LockWidget() +{ + delete ui; +} + +void LockWidget::closeEvent(QCloseEvent *event) +{ + qDebug() << "LockWidget::closeEvent"; + authDialog->close(); + return QWidget::closeEvent(event); +} + +bool LockWidget::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == m_kylinNM) + return true; + + if(event->type() == 2){ + if(obj == ui->btnPowerManager || obj == ui->btnSwitchUser || obj == ui->btnNetworkManager) + return false; + + if(scrollArea && scrollArea->isVisible()){ + scrollArea->hide(); + } + if(powermanager && powermanager->isVisible()){ + authDialog->setFocus(); + authDialog->show(); + powermanager->hide(); + } + if(m_kylinNM && m_kylinNM->isVisible()){ + m_kylinNM->hide(); + } + } + + if (obj == scrollContents ){ + if (event->type() == 76 ) { + usersMenu->show(); + //qDebug()<<"````````````````````````````````````````````"<type(); + } + } + + if(event->type() == QEvent::WindowActivate){ + if(!isNetFinished){ + isNetFinished = true; + QTimer::singleShot(2000, this, [=](){ + m_kylinNM = new KylinNM(this); + m_kylinNM->installEventFilter(this); + connect(m_kylinNM, &KylinNM::onConnectChanged, this,[=](){ + updateNetIcon(m_kylinNM->getConnectStatus()); + }); + m_kylinNM->hide(); + QtConcurrent::run([=](){ + updateNetIcon(getNetStatus()); + }); + }); + } + } + + return false; +} + +void LockWidget::onGlobalKeyPress(const QString &key) +{ +} + +void LockWidget::onGlobalkeyRelease(const QString &key) +{ + if (key == "Escape") { + + } else if (key == "Up" || key == "Down" || key == "Return" || key == "KP_Enter") { + qDebug()<<" key = "<isVisible()) + keyBdRelease(key); + } +} + +void LockWidget::keyBdRelease(QString key) +{ + //usersMenu->setFocus(); + QString focus = "focus"; + QString normal = "normal"; + if(key == "Up"){ +// if(nowAt == -1){ +// nowAt = 0; +// setButtonStyle(focus); +// } + for(int i = 0; i < list.count(); i++){ + if(nowAt == i){ + if(i == 0) + return ; + list.at(i)->setStyleSheet("HoverWidget{background-color:transparent;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + list.at(i-1)->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + nowAt = i-1; + + /*else if(i == 0){ + qDebug()<<"enheng???111"<setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + nowAt = list.count() -1; + }*/ + } + } + } else if(key == "Down") { + for(int i = list.count(); i >= 0; i--){ + if(nowAt == i){ + if(i == list.count() - 1) + return ; + list.at(i)->setStyleSheet("HoverWidget{background-color:transparent;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + list.at(i+1)->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + nowAt = i+1; + /*else if(i == list.count() - 1){ + qDebug()<<"enheng???111"<setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + nowAt = 0; + }*/ + } + } + } else if(key == "Return" || key == "KP_Enter"){ + if(authDialog) + { + authDialog->stopAuth(); + } + if(list.at(nowAt)->objectName() == "Guest") + { + displayManager->switchToGuest(); + } + else if(list.at(nowAt)->objectName() == "SwitchUser") + { + displayManager->switchToGreeter(); + } + else + { + displayManager->switchToUser(list.at(nowAt)->objectName()); + } + } +} + +void LockWidget::startAuth() +{ + if(authDialog) + { + authDialog->startAuth(); + } +} + +void LockWidget::stopAuth() +{ + if(authDialog) + { + authDialog->stopAuth(); + } +} + +void LockWidget::setX11Focus() +{ + if(authDialog){ + authDialog->setX11Focus(); + } +} + +void LockWidget::initUI() +{ + setFocusProxy(authDialog); + + if(QGSettings::isSchemaInstalled(TIME_TYPE_SCHEMA)){ + QGSettings *time_type = new QGSettings(TIME_TYPE_SCHEMA); + QStringList keys = time_type->keys(); + if (keys.contains("hoursystem")) { + timeType = time_type->get("hoursystem").toInt(); + } + if (keys.contains("date")) { + dateType = time_type->get("date").toString(); + } + } + + //显示系统时间 + timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, [&]{ + if(timeType == 12) + ui->lblTime->setText(QDateTime::currentDateTime().toString("A hh:mm")); + else + ui->lblTime->setText(QDateTime::currentDateTime().toString("hh:mm")); + + if(dateType == "cn") + ui->lblDate->setText(QDate::currentDate().toString("yyyy/MM/dd ddd")); + else + ui->lblDate->setText(QDate::currentDate().toString("yyyy-MM-dd ddd")); + }); + + if(timeType == 12) + ui->lblTime->setText(QDateTime::currentDateTime().toString("A hh:mm")); + else + ui->lblTime->setText(QDateTime::currentDateTime().toString("hh:mm")); + + ui->lblTime->setStyleSheet("QLabel{color:white; font-size: 36px;}"); + ui->lblTime->setAlignment(Qt::AlignCenter); + ui->lblTime->adjustSize(); + timer->start(1000); + +// QString date = QDate::currentDate().toString("yyyy/MM/dd ddd"); +// qDebug() << "current date: " << date; +// ui->lblDate->setText(date); + if(dateType == "cn") + ui->lblDate->setText(QDate::currentDate().toString("yyyy/MM/dd ddd")); + else + ui->lblDate->setText(QDate::currentDate().toString("yyyy-MM-dd ddd")); + + ui->lblDate->setStyleSheet("QLabel{color:white; font-size: 18px;}"); + ui->lblDate->setAlignment(Qt::AlignCenter); + ui->lblDate->adjustSize(); + ui->widgetTime->adjustSize(); + + //电源管理 + ui->btnPowerManager->setIcon(QIcon(":/image/assets/powerManager.png")); + ui->btnPowerManager->setFixedSize(48,48); + ui->btnPowerManager->setIconSize(QSize(24,24)); + ui->btnPowerManager->setFocusPolicy(Qt::NoFocus); + ui->btnPowerManager->installEventFilter(this); + + connect(ui->btnPowerManager,&QPushButton::clicked + ,this,&LockWidget::showPowerManager); + + + QtConcurrent::run([=](){ + updateNetIcon(getNetStatus()); + }); + + ui->btnNetworkManager->setFixedSize(48,48); + ui->btnNetworkManager->setIconSize(QSize(24,24)); + ui->btnNetworkManager->setFocusPolicy(Qt::NoFocus); +// ui->btnNetworkManager->setStyleSheet("QPushButton:Hover{border-radius:24px;background-color:rgba(255, 255, 255, 0.15);}" +// "QPushButton:Pressed{border-radius:24px;background-color:rgba(255, 255, 255, 0.05);}"); + ui->btnNetworkManager->installEventFilter(this); + + connect(ui->btnNetworkManager,&QPushButton::clicked + ,this,&LockWidget::showNetManager); + + //虚拟键盘 + ui->btnKeyboard->setIcon(QIcon(":/image/assets/keyboard.svg")); + ui->btnKeyboard->setFixedSize(48, 48); + ui->btnKeyboard->setIconSize(QSize(24, 24)); + ui->btnKeyboard->setFocusPolicy(Qt::NoFocus); + ui->btnKeyboard->installEventFilter(this); +/* connect(ui->btnKeyboard, &QPushButton::clicked, + this, [&]{ + qDebug() << vKeyboard->isHidden(); + vKeyboard->setVisible(vKeyboard->isHidden()); + }); +*/ + connect(ui->btnKeyboard, &QPushButton::clicked, + this, &LockWidget::showVirtualKeyboard); + + //用户切换 + if(displayManager->canSwitch()) + { + //initUserMenu(); + ui->btnSwitchUser->setIcon(QIcon(":/image/assets/switchUser.png")); + ui->btnSwitchUser->setIconSize(QSize(24, 24)); + ui->btnSwitchUser->setFixedSize(48, 48); + ui->btnSwitchUser->setFocusPolicy(Qt::NoFocus); + ui->btnSwitchUser->raise(); + + connect(ui->btnSwitchUser, &QPushButton::clicked, + this, [&]{ + if(!usersMenu){ + initUserMenu(); + } + + if(scrollArea && scrollArea->isVisible()){ + scrollArea->hide(); + } + else{ + scrollArea->show(); + if(m_kylinNM && m_kylinNM->isVisible()) + m_kylinNM->hide(); + scrollArea->setFocus(); + } + }); + } + +} + +void LockWidget::showVirtualKeyboard() +{ + if(!vKeyboard){ + vKeyboard = new VirtualKeyboard(this); + vKeyboard->hide(); + + connect(vKeyboard, &VirtualKeyboard::aboutToClose, + vKeyboard, &VirtualKeyboard::hide); + } + + vKeyboard->setVisible(vKeyboard->isHidden()); + if(!vKeyboard->isHidden()){ + vKeyboard->raise(); + } + setVirkeyboardPos(); +} + +void LockWidget::showPowerManager() +{ + if(!powermanager){ + powermanager = new PowerManager(this); + sureWidget = new SureWindow(this); + powermanager->hide(); + connect(powermanager,SIGNAL(lock()) + ,this,SLOT(showPowerManager())); + connect(powermanager,SIGNAL(switchToUser()) + ,this,SLOT(switchToGreeter())); + connect(powermanager, SIGNAL(mulUsersLogined(int)), + this,SLOT(switchToSureDialog(int))); + sureWidget->adjustSize(); + sureWidget->move((width()-sureWidget->geometry().width())/2, (height()-sureWidget->geometry().height())/2); + sureWidget->hide(); + connect(sureWidget, SIGNAL(cantelButtonclicked()), + this, SLOT(hideSureDialog())); + connect(sureWidget, SIGNAL(confirmButtonclicked()), + this, SLOT(confirmClicked())); + } + + if(m_kylinNM && m_kylinNM->isVisible()) + m_kylinNM->hide(); + if(scrollArea && scrollArea->isVisible()) + scrollArea->hide(); + if(sureWidget && sureWidget->isVisible()) + sureWidget->hide(); + if(powermanager->isVisible()){ + authDialog->setFocus(); + authDialog->show(); + powermanager->hide(); + } + else{ + authDialog->hide(); + powermanager->show(); + powermanager->setFocus(); +#ifndef USE_INTEL + powermanager->showNormalSize(); +#endif + powermanager->setGeometry((width()-powermanager->width())/2, + (height()-powermanager->height())/2, + powermanager->width(),powermanager->height()); + } +} + +void LockWidget::switchToSureDialog(int type) +{ + powermanagerType = type; + if(m_kylinNM && m_kylinNM->isVisible()) + m_kylinNM->hide(); + if(scrollArea && scrollArea->isVisible()) + scrollArea->hide(); + + authDialog->hide(); + powermanager->hide(); + sureWidget->show(); + sureWidget->setFocus(); + ui->widgetTime->hide(); + ui->btnPowerManager->hide(); + ui->btnNetworkManager->hide(); + ui->btnSwitchUser->hide(); + ui->btnKeyboard->hide(); +} + +void LockWidget::hideSureDialog() +{ + sureWidget->hide(); + powermanager->show(); + ui->widgetTime->show(); + ui->btnPowerManager->show(); + ui->btnNetworkManager->show(); + ui->btnSwitchUser->show(); + ui->btnKeyboard->show(); +} + +void LockWidget::confirmClicked() +{ + if(m_kylinNM && m_kylinNM->isVisible()) + m_kylinNM->hide(); + if(scrollArea && scrollArea->isVisible()) + scrollArea->hide(); + sureWidget->hide(); + powermanager->hide(); + authDialog->show(); + ui->widgetTime->show(); + ui->btnPowerManager->show(); + ui->btnNetworkManager->show(); + ui->btnSwitchUser->show(); + ui->btnKeyboard->show(); + powermanager->doEvent(powermanagerType); +} + +void LockWidget::showNetManager() +{ + if(!m_kylinNM){ + return; + } + + if(m_kylinNM->isVisible()) + { + m_kylinNM->hide(); + } else { + m_kylinNM->show(); + if(scrollArea && scrollArea->isVisible()) + scrollArea->hide(); + m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - 100, + m_kylinNM->width(), + m_kylinNM->height()); + m_kylinNM->updateWifiList(); + } +} + +void LockWidget::hideNetManager() +{ + if(!m_kylinNM){ + return; + } + + if(m_kylinNM && m_kylinNM->isVisible()) + m_kylinNM->hide(); + if(scrollArea && scrollArea->isVisible()) + scrollArea->hide(); +} + +int LockWidget::getNetStatus() +{ + int ret = -1; + QString actLanName = "--"; + QString actWifiName = "--"; + + activecon *act = kylin_network_get_activecon_info(); + int index = 0; + while (act[index].con_name != NULL) { + if (QString(act[index].type) == "ethernet" || QString(act[index].type) == "802-3-ethernet") { + actLanName = QString(act[index].con_name); + } + if (QString(act[index].type) == "wifi" || QString(act[index].type) == "802-11-wireless") { + actWifiName = QString(act[index].con_name); + } + index ++; + } + + // 设置图标 + if (actLanName != "--") { + ret = 0; + } else if (actWifiName != "--") { + ret = 1; + } else { + ret = -1; + } + qDebug() << "[KylinNM] [getConnectStatus] getConnectStatus = " << ret; + //KylinDBus::checkConnectivity(); + return ret; +} + +void LockWidget::updateNetIcon(int status) +{ + switch(status) { + case 0: + //有线 + ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wired.png")); + break; + case 1: + //无线 + ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wifi.png")); + break; + case 2: + //有线+无线 + ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-wired.png")); + break; + default: + //无连接 + ui->btnNetworkManager->setIcon(QIcon(":/image/assets/intel/icon-no-signal.png")); + } +} + +void LockWidget::switchToGreeter() +{ + if(authDialog) + { + authDialog->stopAuth(); + } + displayManager->switchToGreeter();; +} + +void LockWidget::setVirkeyboardPos() +{ + if(vKeyboard) + { + vKeyboard->setGeometry(0, + height() - height()/3, + width(), height()/3); + + } +} + + +void LockWidget::initUserMenu() +{ + scrollArea = new QScrollArea(this); + scrollArea->installEventFilter(this); +// scrollArea->setAttribute(Qt::WA_TranslucentBackground); //设置背景透明 +// scrollArea->viewport()->setAttribute(Qt::WA_TranslucentBackground); //设置背景透明 + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //屏蔽水平滚动条 + scrollArea->setStyleSheet("QScrollArea {background-color: rgba(255,255,255,15%);border-radius:8px;}"); + scrollArea->viewport()->setStyleSheet("background-color:transparent;"); + scrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false); + scrollArea->verticalScrollBar()->setContextMenuPolicy(Qt::NoContextMenu); + scrollContents = new QWidget(scrollArea); + scrollContents->installEventFilter(this); + scrollArea->setWidget(scrollContents); + scrollArea->hide(); + + if(!usersMenu) + { + usersMenu = new QMenu(scrollContents); + usersMenu->setObjectName("usersMenu"); + usersMenu->setToolTipsVisible(true); +// usersMenu->setStyleSheet("QMenu{background-color:transparent;color:white;padding:5px 5px 5px 8px}"); + //QToolTip{border-radius:4px;background-color:rgb(255,255,255,40%);color:white;} + //如果没有设置x11属性,则由于弹出菜单受窗口管理器管理,而主窗口不受,在点击菜单又点回主窗口会闪屏。 + usersMenu->setWindowFlags(Qt::X11BypassWindowManagerHint); + //usersMenu->hide(); + connect(usersMenu, &QMenu::triggered, + this, &LockWidget::onUserMenuTrigged); + } + + if(displayManager->getDisplayType() == "gdm"){ +// QAction *action = new QAction(QIcon(users->getDefaultIcon()), +// tr("SwitchUser"), this); + QWidgetAction *action = new QWidgetAction(usersMenu); + HoverWidget *widget = new HoverWidget(""); + widget->setStyleSheet("HoverWidget:hover{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + widget->setObjectName("SwitchUser"); + list.append(widget); + widget->setFixedSize(240, 40); + QLabel *iconlabel =new QLabel(widget); + QPixmap p(users->getDefaultIcon()); + p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + p = PixmapToRound(p, 16*scale); + iconlabel->setPixmap(p); + iconlabel->setGeometry(8,4,32,32); + QLabel *textlabel =new QLabel(widget); + textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + textlabel->setGeometry(48,8,190,24); + action->setToolTip("SwitchUser"); + action->setData("SwitchUser"); + usersMenu->addAction(action); + list.append(widget); + } + + else if(displayManager->getDisplayType() == "lightdm"){ + connect(users, &Users::userAdded, this, &LockWidget::onUserAdded); + connect(users, &Users::userDeleted, this, &LockWidget::onUserDeleted); + + for(auto user : users->getUsers()) + { + onUserAdded(user); + } + + if(displayManager->hasGuestAccount()) + { +// QAction *action = new QAction(QIcon(users->getDefaultIcon()), +// tr("Guest"), this); + QWidgetAction *action = new QWidgetAction(usersMenu); + HoverWidget *widget = new HoverWidget(""); + widget->setStyleSheet("HoverWidget:hover{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + widget->setObjectName("Guest"); + list.append(widget); + widget->setFixedSize(240, 40); + QLabel *iconlabel =new QLabel(widget); + QPixmap p(users->getDefaultIcon()); + p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + p = PixmapToRound(p, 16*scale); + iconlabel->setPixmap(p); + iconlabel->setGeometry(8,4,32,32); + QLabel *textlabel =new QLabel(widget); + textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + textlabel->setGeometry(48,8,190,24); + action->setData("Guest"); + action->setToolTip("Guest"); + usersMenu->addAction(action); + list.append(widget); + } + } + UserItem currentUser = users->getUserByName(getenv("USER")); + for(int i = 0;i < list.count(); i++){ + if(list.at(i)->objectName() == currentUser.name){ + list.at(i)->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,40%);border-radius: 6px;}"); + nowAt = i; + } else { + list.at(i)->setStyleSheet("HoverWidget{background-color:transparent;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + } + } + scrollContents->setFixedSize(usersMenu->width() - 14, usersMenu->height()); + //设置弹出菜单,设置弹出菜单的坐标为切换用户按钮的上方,中间保持一定间隔。 + if(scrollArea){ + if(scrollContents->height() < height()/2){ + scrollArea->setFixedSize(usersMenu->width(),scrollContents->height()+1); + }else{ + scrollArea->setFixedSize(usersMenu->width() + 4, height()/2); + } + scrollArea->move(ui->btnSwitchUser->geometry().x()- scrollArea->width()/2 + 24, \ + height() - 72 - scrollArea->height() - 5); + } + +} + +void LockWidget::keyReleaseEvent(QKeyEvent *e) +{ + if(e->key() == Qt::Key_K){ + if(e->modifiers() & Qt::ControlModifier) + showVirtualKeyboard(); + } +} + +/* lockscreen follows cursor */ +void LockWidget::resizeEvent(QResizeEvent *event) +{ + QSize size = event->size(); + //重新计算缩放比例 + scale = QString::number(size.width() / 1920.0, 'f', 1).toFloat(); + + //系统时间 + ui->widgetTime->move((width()-ui->widgetTime->geometry().width())/2, 59*scale); + if(sureWidget) + sureWidget->move((width()-sureWidget->geometry().width())/2, (height()-sureWidget->geometry().height())/2); + + //认证窗口 + //设置认证窗口左右居中 + if(scale >= 1) + authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4-0.65*scale), \ + authDialog->width(), (height()*3/4)); + else + authDialog->setGeometry((width()-authDialog->geometry().width())/2,height()/(4+0.65*scale), \ + authDialog->width(), (height()*3/4)); + + if(scale > 1) + scale = 1; + + //右下角按钮,x,y的初始值代表距离右下角的距离。 + int x=24,y=72; + x = x + ui->btnPowerManager->width(); + ui->btnPowerManager->move(width() - x,height() - y); + + x = x+ui->btnKeyboard->width()+16; + ui->btnKeyboard->move(width() - x, height() - y); + + x = x + ui->btnNetworkManager->width()+16; + ui->btnNetworkManager->move(width() - x, height() - y); + + x = x + ui->btnSwitchUser->width()+16; + ui->btnSwitchUser->move(width() - x, height() - y); + setVirkeyboardPos(); + + if(scrollContents && usersMenu) + scrollContents->setFixedSize(usersMenu->width() - 14, usersMenu->height()); + //设置弹出菜单,设置弹出菜单的坐标为切换用户按钮的上方,中间保持一定间隔。 + if(scrollArea){ + if(scrollContents->height() < height()/2){ + scrollArea->setFixedSize(usersMenu->width(),scrollContents->height()+1); + }else{ + scrollArea->setFixedSize(usersMenu->width() + 4, height()/2); + } + scrollArea->move(ui->btnSwitchUser->geometry().x()- scrollArea->width()/2 + 24, \ + height() - y - scrollArea->height() - 5); + } + + if(m_kylinNM){ + m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - 100, + m_kylinNM->width(), + m_kylinNM->height()); + } + + if(powermanager){ +#ifndef USE_INTEL + if(width() < 1280) + powermanager->showSmallSize(); + else + powermanager->showNormalSize(); +#endif + powermanager->setGeometry((width()- powermanager->width())/2, + (height()-powermanager->height())/2, + powermanager->width(),powermanager->height()); + + } + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); +} + + +void LockWidget::onUserAdded(const UserItem &user) +{ +// QAction *action = new QAction(QIcon(user.icon), user.realName, this); +// action->setCheckable(true); + + QWidgetAction *action = new QWidgetAction(usersMenu); + HoverWidget *widget = new HoverWidget(""); + widget->setStyleSheet("HoverWidget:hover{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + widget->setObjectName(user.name); + list.append(widget); + widget->setFixedSize(240, 40); + QLabel *iconlabel =new QLabel(widget); + QPixmap p(user.icon); + p = p.scaled(32*scale,32*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + p = PixmapToRound(p, 16*scale); + iconlabel->setPixmap(p); + //iconlabel->setStyleSheet("background-color:transparent;"); + iconlabel->setGeometry(8,4,32,32); + QLabel *textlabel =new QLabel(widget); + textlabel->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + textlabel->setGeometry(48,8,190,24); + if(getLoadStatus(user.name)){ + QLabel *statusIcon = new QLabel(widget); + QPixmap status(":/image/assets/selected.svg"); + status = status.scaled(14*scale,14*scale, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + p = PixmapToRound(status, 7*scale); + statusIcon->setPixmap(status); + statusIcon->setGeometry(32, 5, 14, 14); + } + action->setDefaultWidget(widget); + + QFont font; + font.setPixelSize(16); + QString str = ElideText(font,189,user.realName); + if(user.realName != str){ + textlabel->setToolTip(user.realName); + textlabel->setText(str); + } else { + textlabel->setText(user.realName); + } + action->setData(user.name); + usersMenu->addAction(action); + usersMenu->adjustSize(); +} + +QPixmap LockWidget::PixmapToRound(const QPixmap &src, int radius) +{ + if (src.isNull()) { + return QPixmap(); + } + + QPixmap pixmapa(src); + QPixmap pixmap(radius*2,radius*2); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + QPainterPath path; + path.addEllipse(0, 0, radius*2, radius*2); + painter.setClipPath(path); + painter.drawPixmap(0, 0, radius*2, radius*2, pixmapa); + return pixmap; +} + +void LockWidget::onUserDeleted(const UserItem &user) +{ + for(auto action : usersMenu->actions()) + { + if(action->data() == user.name) + usersMenu->removeAction(action); + } +} + +bool LockWidget::getLoadStatus(const QString &name) +{ + QDBusInterface interface(LG_DBUS_SERVICE, + LG_DBUS_PATH, + LG_DBUS_INTERFACE, + QDBusConnection::systemBus()); + QDBusMessage result = interface.call("ListUsers"); + QList outArgs = result.arguments(); + QVariant first = outArgs.at(0); + QDBusArgument dbvFirst = first.value(); + QVariant vFirst = dbvFirst.asVariant(); + const QDBusArgument &dbusArgs = vFirst.value(); + + QVector loginedUsers; + + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + userInfo user; + dbusArgs >> user; + loginedUsers.push_back(user); + } + for (userInfo user : loginedUsers) { + QDBusInterface userPertyInterface("org.freedesktop.login1", + user.userPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + QDBusReply reply = userPertyInterface.call("Get", "org.freedesktop.login1.User", "State"); + if (reply.isValid()) { + QString status = reply.value().toString(); + if ("closing" != status) { + m_loginedUser.append(user.userName); + } + } + } + int count = 0; + for(int i = 0 ;i 0) + return true; + else + return false; +} + +void LockWidget::onUserMenuTrigged(QAction *action) +{ + qDebug() << action->data().toString() << "selected"; + + if(authDialog) + { + authDialog->stopAuth(); + } + + QString userName = action->data().toString(); + for (int i =0; i < list.count(); i++) + { + if(list.at(i)->objectName() == userName){ + list.at(i)->setStyleSheet("HoverWidget{background-color:rgb(255,255,255,40%);border-radius: 6px;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,40%);border-radius: 6px;}"); + } else { + list.at(i)->setStyleSheet("HoverWidget{background-color:transparent;}" + "HoverWidget:hover:!pressed{background-color:rgb(255,255,255,15%);border-radius: 6px;}"); + } + } + if(userName == "Guest") + { + displayManager->switchToGuest(); + } + else if(userName == "SwitchUser") + { + displayManager->switchToGreeter(); + } + else + { + displayManager->switchToUser(userName); + } +} + +bool LockWidget::exitSubWidget() +{ + bool allExited = true; + if(scrollArea && scrollArea->isVisible()){ + scrollArea->hide(); + allExited = false; + } + if(powermanager && powermanager->isVisible()){ + authDialog->setFocus(); + authDialog->show(); + powermanager->hide(); + allExited = false; + } + if(m_kylinNM && m_kylinNM->isVisible()){ + m_kylinNM->hide(); + allExited = false; + } + return allExited; +} + +QDBusArgument &operator <<(QDBusArgument &arg, const userInfo &usersInfo) +{ + arg.beginStructure(); + arg << usersInfo.userId + << usersInfo.userName + << usersInfo.userPath; + arg.endStructure(); + return arg; +} +const QDBusArgument &operator >>(const QDBusArgument &arg, userInfo &usersInfo) +{ + arg.beginStructure(); + arg >> usersInfo.userId + >> usersInfo.userName + >> usersInfo.userPath; + arg.endStructure(); + return arg; +} + + + diff --git a/src/lockwidget.h b/src/lockwidget.h new file mode 100644 index 0000000..c8352c3 --- /dev/null +++ b/src/lockwidget.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef LOCKWIDGET_H +#define LOCKWIDGET_H + +#ifndef QT_NO_KEYWORDS +#define QT_NO_KEYWORDS +#endif + +#include +#include +#include +#include "surewindow.h" +#include "xeventmonitor.h" + +namespace Ui { +class LockWidget; +} + + +struct userInfo { + int userId; + QString userName; + QDBusObjectPath userPath; +}; + +QDBusArgument &operator <<(QDBusArgument &arg, const userInfo &usersInfo); +const QDBusArgument &operator >>(const QDBusArgument &arg, userInfo &usersInfo); + +class VirtualKeyboard; +class PowerManager; +class AuthDialog; +class Users; +class UserItem; +class DisplayManager; +class QMenu; +class QScrollArea; +class KylinNM; + +class LockWidget : public QWidget +{ + Q_OBJECT + +public: + explicit LockWidget(QWidget *parent = 0); + ~LockWidget(); + void closeEvent(QCloseEvent *event); + void startAuth(); + void stopAuth(); + void setX11Focus(); + bool exitSubWidget(); +Q_SIGNALS: + void closed(); +// void capsLockChanged(); + +private: + void initUI(); + void initUserMenu(); + void setVirkeyboardPos(); + void updateNetIcon(int status); + bool getLoadStatus(const QString &name); + int getNetStatus(); + QPixmap PixmapToRound(const QPixmap &src, int radius); + void keyBdRelease(QString key); +private Q_SLOTS: + void onUserAdded(const UserItem &user); + void onUserDeleted(const UserItem &user); + void onUserMenuTrigged(QAction *action); + void showVirtualKeyboard(); + void showPowerManager(); + void showNetManager(); + void switchToGreeter(); + void switchToSureDialog(int type); + void hideSureDialog(); + void confirmClicked(); + void hideNetManager(); + void onGlobalKeyPress(const QString &key); + void onGlobalkeyRelease(const QString &key); +protected: + bool eventFilter(QObject *obj, QEvent *event); + void resizeEvent(QResizeEvent *event); + void keyReleaseEvent(QKeyEvent *e); + +private: + Ui::LockWidget *ui; + AuthDialog *authDialog; + VirtualKeyboard *vKeyboard = nullptr; + PowerManager *powermanager = nullptr; + SureWindow *sureWidget = nullptr; + QTimer *timer; + QMenu *usersMenu = nullptr; + QList list; + Users *users; + DisplayManager *displayManager; + int timeType; + QString dateType; + QScrollArea *scrollArea; + QWidget *scrollContents; + + KylinNM *m_kylinNM = nullptr; + QWidget *m_NetManagerWidget; + QStringList m_loginedUser; + bool isNetFinished = false; + int powermanagerType; + XEventMonitor *xEventMonitor; + int nowAt = -1; +}; + +#endif // LOCKWIDGET_H diff --git a/src/lockwidget.ui b/src/lockwidget.ui new file mode 100644 index 0000000..22caea6 --- /dev/null +++ b/src/lockwidget.ui @@ -0,0 +1,118 @@ + + + LockWidget + + + + 0 + 0 + 748 + 433 + + + + Form + + + + + 550 + 10 + 80 + 26 + + + + PointingHandCursor + + + Qt::NoFocus + + + + + + + + + 10 + 280 + 54 + 70 + + + + + + + Time + + + + + + + Date + + + + + + + + + 460 + 10 + 80 + 26 + + + + PointingHandCursor + + + Qt::NoFocus + + + + + + + + + 650 + 10 + 80 + 26 + + + + PointingHandCursor + + + + + + + + + 370 + 10 + 80 + 26 + + + + PointingHandCursor + + + Qt::NoFocus + + + + + + + + + diff --git a/src/logind.cpp b/src/logind.cpp new file mode 100644 index 0000000..34c00ed --- /dev/null +++ b/src/logind.cpp @@ -0,0 +1,61 @@ +/* + * 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 . + * +**/ +#include "logind.h" +#include +#include +#include +#include +#include + +const static QString login1Service = QStringLiteral("org.freedesktop.login1"); +const static QString login1Path = QStringLiteral("/org/freedesktop/login1"); +const static QString login1ManagerInterface = QStringLiteral("org.freedesktop.login1.Manager"); +const static QString login1SessionInterface = QStringLiteral("org.freedesktop.login1.Session"); + +LogindIntegration::LogindIntegration(QObject *parent) + : QObject(parent) +{ + QDBusInterface loginInterface(login1Service, + login1Path, + login1ManagerInterface, + QDBusConnection::systemBus()); + QDBusReply sessionPath = loginInterface.call("GetSessionByPID",(quint32) QCoreApplication::applicationPid()); + if(!sessionPath.isValid()){ + qWarning()<< "Get session error:" << sessionPath.error(); + } + else{ + + QString session = sessionPath.value().path(); + QDBusConnection::systemBus().connect(login1Service, + session, + login1SessionInterface, + QStringLiteral("Lock"), + this, + SIGNAL(requestLock())); + QDBusConnection::systemBus().connect(login1Service, + session, + login1SessionInterface, + QStringLiteral("Unlock"), + this, + SIGNAL(requestUnlock())); + } + return; +} + +LogindIntegration::~LogindIntegration() = default; + diff --git a/src/logind.h b/src/logind.h new file mode 100644 index 0000000..f1e27ed --- /dev/null +++ b/src/logind.h @@ -0,0 +1,42 @@ +/* + * 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 . + * +**/ +#ifndef LOGIND_H +#define LOGIND_H + +#include +#include + +class QDBusServiceWatcher; + +class LogindIntegration : public QObject +{ + Q_OBJECT +public: + explicit LogindIntegration(QObject *parent = nullptr); + ~LogindIntegration() override; + +Q_SIGNALS: + void requestLock(); + void requestUnlock(); + void connectedChanged(); + +private: + +}; + +#endif diff --git a/src/loginoptionswidget.cpp b/src/loginoptionswidget.cpp new file mode 100644 index 0000000..c35e09d --- /dev/null +++ b/src/loginoptionswidget.cpp @@ -0,0 +1,680 @@ +#include "loginoptionswidget.h" + +#include +#include + +#include +#include "giodbus.h" +#include "biometricdeviceinfo.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LoginOptionsWidget::LoginOptionsWidget(BiometricProxy* proxy, int uid, QWidget *parent) + : QWidget(parent) + , m_biomericProxy(proxy) + , m_uid(uid) +{ + initUI(); + initConnections(); + m_mapDisableDev.clear(); +} + +LoginOptionsWidget::~LoginOptionsWidget() +{ + +} + +void LoginOptionsWidget::initUI() +{ + this->setFixedHeight(86); + // 初始化UI + m_layoutMain = new QVBoxLayout(); + m_layoutMain->setContentsMargins(0,0,0,0); + m_layoutMain->setSpacing(16); + m_layoutOptBtns = new QHBoxLayout(); + m_layoutOptBtns->setContentsMargins(0,0,0,0); + m_layoutOptBtns->setSpacing(16); + + m_labelOptTitle = new QLabel(); + m_labelOptTitle->setAlignment(Qt::AlignCenter); + m_labelOptTitle->setText(tr("Login Options")); + m_labelOptTitle->setFixedHeight(22); + m_layoutMain->addWidget(m_labelOptTitle); + + m_btnGroup = new QButtonGroup(this); + m_btnGroup->setExclusive(true); + + m_layoutOptBtns->setAlignment(Qt::AlignCenter); + m_layoutMain->addLayout(m_layoutOptBtns); + + m_layoutMain->addStretch(); + this->setLayout(m_layoutMain); +} + +void LoginOptionsWidget::initConnections() +{ + if(m_biomericProxy && m_biomericProxy->isValid()) + { + connect(m_biomericProxy, &BiometricProxy::StatusChanged, + this, &LoginOptionsWidget::onStatusChanged); + + connect(m_biomericProxy, &BiometricProxy::FrameWritten, + this, &LoginOptionsWidget::onFrameWritten); + connect(m_biomericProxy, &BiometricProxy::USBDeviceHotPlug, + this, &LoginOptionsWidget::onUSBDeviceHotPlug); + readDevicesInfo(); + } + connect(m_btnGroup, SIGNAL(buttonClicked(int)), this, SLOT(onOptionSelected(int))); +} + +bool LoginOptionsWidget::getCurLoginOpt(int& nLoginOptType, int& nDrvId) +{ + if (m_curDevInfo) { + nLoginOptType = convertDeviceType(m_curDevInfo->deviceType); + nDrvId = m_curDevInfo->id; + return true; + } + return false; +} + +unsigned LoginOptionsWidget::getLoginOptCount() +{ + return m_mapDevices.size(); +} + +DeviceInfoPtr LoginOptionsWidget::getFirstDevInfo() +{ + DeviceInfoPtr devInfo = nullptr; + int nDrvId = GetLastDevice(getpwuid(m_uid)->pw_name); + if (nDrvId >= 0) { + qDebug()<<"GetLastDevice:"<id == nDrvId) { + if (!isDeviceDisable(devinfo->id)) { + devInfo = devinfo; + break; + } + } + } + if (devInfo) { + break; + } + } + } + if (!devInfo) { + DeviceMap::iterator itDevInfo = m_mapDevices.begin(); + for (; itDevInfo != m_mapDevices.end(); itDevInfo++) { + for (auto devinfo : itDevInfo.value()) { + if (devinfo && !isDeviceDisable(devinfo->id)) { + devInfo = devinfo; + break; + } + } + if (devInfo) { + break; + } + } + } + return devInfo; +} + +void LoginOptionsWidget::addOptionButton(unsigned uLoginOptType, int nDrvId, QString strDrvName) +{ + if (m_mapOptBtns.contains(nDrvId)) { + return ; + } + QToolButton *newButton = new QToolButton(); + QVBoxLayout *layoutBtn = new QVBoxLayout(); + newButton->setLayout(layoutBtn); + QLabel *newLabel = new QLabel(); + layoutBtn->setAlignment(Qt::AlignCenter); + layoutBtn->addWidget(newLabel); + newButton->setCheckable(true); + newButton->setChecked(false); + newButton->setFocusPolicy(Qt::NoFocus); + if (nDrvId == -1) { + //newButton->setEnabled(false); + newButton->setChecked(true); + //屏蔽鼠标事件 + newButton->setAttribute(Qt::WA_TransparentForMouseEvents, true); + } else { + int nLength = m_btnGroup->buttons().length(); + m_btnGroup->addButton(newButton, nLength); + m_listDriveId.append(nDrvId); + } + QPixmap iconPixmap; + switch (uLoginOptType) { + case LOGINOPT_TYPE_PASSWORD: + iconPixmap = loadSvg(":/image/assets/ukui-loginopt-password.svg", "white", 16); + break; + case LOGINOPT_TYPE_FACE: + iconPixmap = loadSvg(":/image/assets/ukui-loginopt-face.svg", "white", 16); + break; + case LOGINOPT_TYPE_FINGERPRINT: + iconPixmap = loadSvg(":/image/assets/ukui-loginopt-finger.svg", "white", 16); + break; + case LOGINOPT_TYPE_IRIS: + iconPixmap = loadSvg(":/image/assets/ukui-loginopt-iris.svg", "white", 16); + break; + case LOGINOPT_TYPE_VOICEPRINT: + iconPixmap = loadSvg(":/image/assets/ukui-loginopt-voice.svg", "white", 16); + break; + case LOGINOPT_TYPE_FINGERVEIN: + iconPixmap = loadSvg(":/image/assets/ukui-loginopt-fingervein.svg", "white", 16); + break; + case LOGINOPT_TYPE_QRCODE: + iconPixmap = loadSvg(":/image/assets/ukui-loginopt-qrcode.svg", "white", 16); + break; + } + newLabel->setPixmap(iconPixmap); + newButton->setToolTip(strDrvName); + newButton->setStyleSheet("QToolTip{border-radius:4px;background-color:#FFFFFF;color:black;font-size:16px}"); + newButton->setFixedSize(48, 48); + if (isDeviceDisable(nDrvId)) { + newButton->setDisabled(true); + } else { + newButton->setDisabled(false); + } + + m_layoutOptBtns->addWidget(newButton); + m_mapOptBtns[nDrvId] = newButton; +} + +void LoginOptionsWidget::clearOptionButtons() +{ + QMap::iterator itMapBtn = m_mapOptBtns.begin(); + for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { + if (itMapBtn.value()) { + m_btnGroup->removeButton(itMapBtn.value()); + m_layoutOptBtns->removeWidget(itMapBtn.value()); + itMapBtn.value()->deleteLater(); + } + } + m_listDriveId.clear(); + m_mapOptBtns.clear(); +} + +void LoginOptionsWidget::updateOptionButtons() +{ + clearOptionButtons(); + //addOptionButton(LOGINOPT_TYPE_PASSWORD, -1, tr("Password")); + DeviceMap::iterator itMapDev = m_mapDevices.begin(); + for ( ; itMapDev != m_mapDevices.end(); itMapDev++) { + for (DeviceInfoPtr devPtr : itMapDev.value()) { + if (devPtr) { + addOptionButton(itMapDev.key(), devPtr->id, DeviceType::getDeviceType_tr(devPtr->deviceType)); + } + } + } + qDebug()<<"m_mapOptBtns.size():"<hide(); + QMap::iterator itMapBtn = m_mapOptBtns.begin(); + for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { + if (itMapBtn.value()) { + itMapBtn.value()->hide(); + } + } + } else { + m_labelOptTitle->show(); + QMap::iterator itMapBtn = m_mapOptBtns.begin(); + for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { + if (itMapBtn.value()) { + itMapBtn.value()->show(); + } + } + } +} + +void LoginOptionsWidget::setUser(int uid) +{ + m_uid = uid; + readDevicesInfo(); +} + +void LoginOptionsWidget::readDevicesInfo() +{ + m_mapDevices.clear(); + bool isAuthEnable = GetAuthEnable(); + bool isQRCodeEnable = GetQRCodeEnable(); + DeviceList deviceList = m_biomericProxy->GetDevList(); + for(auto pDeviceInfo : deviceList) + { + qDebug()<<"BeginGetFeature------!"; + int nDevFeatureCount = m_biomericProxy->GetUserDevFeatureCount(m_uid,pDeviceInfo->id); + qDebug() << *pDeviceInfo << ",feautres:"< 0) { + if (!isAuthEnable && pDeviceInfo->deviceType <= DeviceType::VoicePrint) + continue; + if (!isQRCodeEnable && pDeviceInfo->deviceType == REMOTE_QRCODE_TYPE) + continue; + int nDevType = LOGINOPT_TYPE_OTHERS; + nDevType = convertDeviceType(pDeviceInfo->deviceType); + m_mapDevices[nDevType].push_back(pDeviceInfo); + } + } + updateOptionButtons(); +} + +void LoginOptionsWidget::startAuth(DeviceInfoPtr device, int uid) +{ + if(!m_biomericProxy) + { + qWarning() << "BiometricProxy doesn't exist."; + return; + } + if (!device) { + qWarning() << "Biometric Auth device invalid."; + return ; + } + + if(m_isInAuth) + { + qDebug() << "Identification is currently under way, stop it"; + stopAuth(); + } + qDebug()<<"deviceInfo:"<id; + this->m_curDevInfo = device; + this->m_uid = uid; + this->m_strUserName = getpwuid(uid)->pw_name; + this->m_isStopped = false; + this->m_curLoginOptType = convertDeviceType(this->m_curDevInfo->deviceType); + updateUIStatus(); + SetLastDevice(this->m_strUserName, this->m_curDevInfo->id); + startAuth_(); +} + +void LoginOptionsWidget::startAuth_() +{ + if (!m_curDevInfo) + return ; + qDebug().noquote() << QString("Identify:[drvid: %1, uid: %2]").arg(m_curDevInfo->id).arg(m_uid); + + m_isInAuth = true; + m_dupFD = -1; + + QDBusPendingCall call = m_biomericProxy->Identify(m_curDevInfo->id, m_uid); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + this, &LoginOptionsWidget::onIdentifyComplete); +} + +void LoginOptionsWidget::stopAuth() +{ + m_isStopped = true; + if(!m_isInAuth || !m_curDevInfo) + { + return; + } + m_biomericProxy->StopOps(m_curDevInfo->id); + if(m_retrytimer&&m_retrytimer->isActive()){ + m_retrytimer->stop(); + delete m_retrytimer; + m_retrytimer = nullptr; + } + m_isInAuth = false; + Q_EMIT updateImage(QImage()); +} + +void LoginOptionsWidget::onIdentifyComplete(QDBusPendingCallWatcher *watcher) +{ + if(m_isStopped == true) + return ; + + QDBusPendingReply reply = *watcher; + if(reply.isError()) + { + qWarning() << "Identify error: " << reply.error().message(); + Q_EMIT authComplete(false, -1); + return; + } + int result = reply.argumentAt(0).toInt(); + int authUid = reply.argumentAt(1).toInt(); + qDebug() << result << authUid << m_uid; + + // 特征识别成功,而且用户id匹配 + if(result == DBUS_RESULT_SUCCESS && authUid == m_uid) { + qDebug() << "Identify success"; + Q_EMIT authComplete(true, 0); + } else if(result == DBUS_RESULT_NOTMATCH) { // 特征识别不匹配 + qDebug() << "Identify failed"; + Q_EMIT authComplete(false, 2); + } else if(result == DBUS_RESULT_ERROR) { //识别发生错误 + StatusReslut ret = m_biomericProxy->UpdateStatus(m_curDevInfo->id); + qDebug()<<"StatusReslut:"<id != drvid) || !m_isInAuth) { + return ; + } + if(m_dupFD == -1){ + m_dupFD = get_server_gvariant_stdout(drvid); + } + + if(m_dupFD <= 0) + return ; + + cv::Mat img; + lseek(m_dupFD, 0, SEEK_SET); + char base64_bufferData[1024*1024]; + int rc = read(m_dupFD, base64_bufferData, 1024*1024); + printf("rc = %d\n", rc); + + cv::Mat mat2(1, sizeof(base64_bufferData), CV_8U, base64_bufferData); + img = cv::imdecode(mat2, cv::IMREAD_COLOR); + if (!img.data) + return ; + cv::cvtColor(img,img,cv::COLOR_BGR2RGB); + + QImage srcQImage = QImage((uchar*)(img.data), img.cols, img.rows, QImage::Format_RGB888); + Q_EMIT updateImage(srcQImage); +} + +void LoginOptionsWidget::onStatusChanged(int drvid, int status) +{ + if(!m_isInAuth || !m_curDevInfo) + { + return; + } + if(drvid != m_curDevInfo->id) + { + return; + } + +// // 显示来自服务的提示信息 +// if(status == STATUS_NOTIFY) +// { +// QString notifyMsg = m_biomericProxy->GetNotifyMesg(drvid); +// Q_EMIT updateAuthMsg(notifyMsg); +// } +} + +void LoginOptionsWidget::setCurrentDevice(int drvid) +{ + DeviceInfoPtr pDeviceInfo = findDeviceById(drvid); + if(pDeviceInfo) + { + setCurrentDevice(pDeviceInfo); + } +} + +void LoginOptionsWidget::setCurrentDevice(const QString &deviceName) +{ + DeviceInfoPtr pDeviceInfo = findDeviceByName(deviceName); + if(pDeviceInfo) + { + setCurrentDevice(pDeviceInfo); + } +} + +void LoginOptionsWidget::setCurrentDevice(const DeviceInfoPtr &pDeviceInfo) +{ + this->m_curDevInfo = pDeviceInfo; +} + +DeviceInfoPtr LoginOptionsWidget::findDeviceById(int drvid) +{ + for(int type : m_mapDevices.keys()) + { + DeviceList &deviceList = m_mapDevices[type]; + auto iter = std::find_if(deviceList.begin(), deviceList.end(), + [&](DeviceInfoPtr ptr){ + return ptr->id == drvid; + }); + if(iter != deviceList.end()) + { + return *iter; + } + } + return DeviceInfoPtr(); +} + +DeviceInfoPtr LoginOptionsWidget::findDeviceByName(const QString &name) +{ + for(int type : m_mapDevices.keys()) + { + DeviceList &deviceList = m_mapDevices[type]; + auto iter = std::find_if(deviceList.begin(), deviceList.end(), + [&](DeviceInfoPtr ptr){ + return ptr->shortName == name; + }); + if(iter != deviceList.end()) + { + return *iter; + } + } + return DeviceInfoPtr(); +} + +void LoginOptionsWidget::onUSBDeviceHotPlug(int drvid, int action, int /*devNum*/) +{ + int savedDeviceId = (m_curDevInfo ? m_curDevInfo->id : -1); + int savedCount = 0; + for(int type : m_mapDevices.keys()) + savedCount += m_mapDevices.value(type).count(); + + switch(action) + { + case ACTION_ATTACHED: + { + //插入设备后,需要更新设备列表 + readDevicesInfo(); + break; + } + case ACTION_DETACHED: + { + DeviceInfoPtr pDeviceInfo = findDeviceById(drvid); + if(pDeviceInfo) + { + int nDevType = LOGINOPT_TYPE_PASSWORD; + nDevType = convertDeviceType(pDeviceInfo->deviceType); + if (savedDeviceId == drvid) { + if (m_isInAuth) { + Q_EMIT updateAuthMsg(tr("Identify device removed!")); + } + } + m_mapDevices[nDevType].removeOne(pDeviceInfo); + if(m_mapDevices[nDevType].isEmpty()) { + m_mapDevices.remove(nDevType); + } + } + break; + } + } + + int count = 0; + for(int type : m_mapDevices.keys()) + count += m_mapDevices.value(type).count(); + + //设备数量发生了变化 + if(count != savedCount) { + updateOptionButtons(); + Q_EMIT notifyOptionsChange(count); + } +} + +bool LoginOptionsWidget::getAuthDouble() +{ + QSettings settings("/etc/biometric-auth/ukui-biometric.conf", QSettings::IniFormat); + bool distribId = settings.value("DoubleAuth").toBool(); + return distribId; +} + +void LoginOptionsWidget::updateUIStatus() +{ + if (m_mapOptBtns.contains(-1)) { + QToolButton* btn = m_mapOptBtns[-1]; + if (btn) { + btn->setChecked(true); + } + } + if (m_curDevInfo) { + if (m_mapOptBtns.contains(m_curDevInfo->id)) { + QToolButton* btn = m_mapOptBtns[m_curDevInfo->id]; + if (btn) { + btn->setChecked(true); + } + } + } +} + +void LoginOptionsWidget::onOptionSelected(int nIndex) +{ + if (nIndex < 0) + return; + if (nIndex < m_listDriveId.size()) { + DeviceInfoPtr info = findDeviceById(m_listDriveId[nIndex]); + if (info && !isDeviceDisable(info->id)) { + Q_EMIT optionSelected(convertDeviceType(info->deviceType), info); + } + } +} + +int LoginOptionsWidget::convertDeviceType(int nDevType) +{ + int nLoginOptType = LOGINOPT_TYPE_OTHERS; + switch (nDevType) { + case BioT_FingerPrint: + nLoginOptType = LOGINOPT_TYPE_FINGERPRINT; + break; + case BioT_FingerVein: + nLoginOptType = LOGINOPT_TYPE_FINGERVEIN; + break; + case BioT_Iris: + nLoginOptType = LOGINOPT_TYPE_IRIS; + break; + case BioT_Face: + nLoginOptType = LOGINOPT_TYPE_FACE; + break; + case BioT_VoicePrint: + nLoginOptType = LOGINOPT_TYPE_VOICEPRINT; + break; + case UniT_Remote: + nLoginOptType = LOGINOPT_TYPE_QRCODE; + break; + default: + nLoginOptType = LOGINOPT_TYPE_OTHERS; + break; + } + return nLoginOptType; +} + +void LoginOptionsWidget::setDeviceDisable(int nDevId, bool bDisable) +{ + if (bDisable) { + m_mapDisableDev[m_uid][nDevId] = true; + QMap::iterator itMapBtn = m_mapOptBtns.begin(); + for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { + if (itMapBtn.key() == nDevId && itMapBtn.value()) { + itMapBtn.value()->setDisabled(true); + break; + } + } + } else { + m_mapDisableDev[m_uid][nDevId] = false; + QMap::iterator itMapBtn = m_mapOptBtns.begin(); + for ( ; itMapBtn != m_mapOptBtns.end(); itMapBtn++) { + if (itMapBtn.key() == nDevId && itMapBtn.value()) { + itMapBtn.value()->setDisabled(false); + break; + } + } + } +} + +bool LoginOptionsWidget::isDeviceDisable(int nDevId) +{ + if (m_mapDisableDev[m_uid].contains(nDevId)) { + return m_mapDisableDev[m_uid][nDevId]; + } + return false; +} + +QPixmap LoginOptionsWidget::loadSvg(QString path, QString color, int size) +{ + int origSize = size; + const auto ratio = qApp->devicePixelRatio(); + if ( 2 == ratio) { + size += origSize; + } else if (3 == ratio) { + size += origSize; + } + QPixmap pixmap(size, size); + QSvgRenderer renderer(path); + pixmap.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pixmap); + renderer.render(&painter); + painter.end(); + + pixmap.setDevicePixelRatio(ratio); + return drawSymbolicColoredPixmap(pixmap, color); +} + +QPixmap LoginOptionsWidget::drawSymbolicColoredPixmap(QPixmap &source, QString cgColor) +{ + QImage img = source.toImage(); + for (int x = 0; x < img.width(); x++) { + for (int y = 0; y < img.height(); y++) { + auto color = img.pixelColor(x, y); + if (color.alpha() > 0) { + if ( "white" == cgColor) { + color.setRed(255); + color.setGreen(255); + color.setBlue(255); + img.setPixelColor(x, y, color); + } else if( "black" == cgColor) { + color.setRed(0); + color.setGreen(0); + color.setBlue(0); + img.setPixelColor(x, y, color); + } else if ("gray"== cgColor) { + color.setRed(152); + color.setGreen(163); + color.setBlue(164); + img.setPixelColor(x, y, color); + } else if ("blue" == cgColor){ + color.setRed(61); + color.setGreen(107); + color.setBlue(229); + img.setPixelColor(x, y, color); + } else { + return source; + } + } + } + } + return QPixmap::fromImage(img); +} diff --git a/src/loginoptionswidget.h b/src/loginoptionswidget.h new file mode 100644 index 0000000..c53a0bc --- /dev/null +++ b/src/loginoptionswidget.h @@ -0,0 +1,120 @@ +#ifndef LOGINOPTIONSWIDGET_H +#define LOGINOPTIONSWIDGET_H + +#include +#include "biometricproxy.h" +#include "biometricdeviceinfo.h" + +class QLabel; +class QButtonGroup; +class QHBoxLayout; +class QVBoxLayout; +class QToolButton; +class QTimer; +class QPixmap; + +typedef enum { + BioT_FingerPrint, /** 指纹 **/ + BioT_FingerVein, /** 指静脉 **/ + BioT_Iris, /** 虹膜 **/ + BioT_Face, /** 人脸 **/ + BioT_VoicePrint, /** 声纹 **/ + + UniT_KCM, /** 安全管控 **/ + UniT_General_Ukey, /** 普通的Ukey **/ + UniT_Advanced_Ukey, /** 高阶的Ukey **/ + UniT_Remote, /** 远程账户 **/ +}BioType; + +class LoginOptionsWidget : public QWidget +{ + Q_OBJECT +public: + explicit LoginOptionsWidget(BiometricProxy* proxy, int uid, QWidget *parent = nullptr); + virtual ~LoginOptionsWidget(); + + bool getCurLoginOpt(int& nLoginOptType, int& nDrvId); + unsigned getLoginOptCount(); + DeviceInfoPtr getFirstDevInfo(); + int convertDeviceType(int nDevType); + + void setUser(int uid); + void setCurrentDevice(int drvid); + void setCurrentDevice(const QString &deviceName); + void setCurrentDevice(const DeviceInfoPtr &pDeviceInfo); + DeviceInfoPtr findDeviceById(int drvid); + DeviceInfoPtr findDeviceByName(const QString &name); + void setDeviceDisable(int nDevId, bool bDisable = true); + bool isDeviceDisable(int nDevId); + + /** + * @brief 进行生物识别认证 + * @param deviceInfo 使用的设备 + * @param uid 待认证的用户id + */ + void startAuth(DeviceInfoPtr device, int uid); + + /** + * @brief 终止生物识别认证 + */ + void stopAuth(); + + /** + * @brief 是否正在认证 + * @return + */ + bool isAuthenticating() { + return m_isInAuth; + } + +public Q_SLOTS: + void readDevicesInfo(); + void onIdentifyComplete(QDBusPendingCallWatcher *watcher); + void onStatusChanged(int drvid, int status); + void onFrameWritten(int drvid); + void onUSBDeviceHotPlug(int drvid, int action, int devNum); + void onOptionSelected(int nIndex); + +Q_SIGNALS: + void notifyOptionsChange(unsigned uOptionsCount); + void optionSelected(unsigned uLoginOptType, const DeviceInfoPtr &deviceInfo); + void updateImage(QImage img); + void authComplete(bool bResult, int nStatus); + void updateAuthMsg(QString strMsg); + +private: + void initUI(); + void initConnections(); + void addOptionButton(unsigned uLoginOptType, int nDrvId, QString strDrvName); + void clearOptionButtons(); + void updateOptionButtons(); + void startAuth_(); + bool getAuthDouble(); + void updateUIStatus(); + QPixmap loadSvg(QString path, QString color, int size); + QPixmap drawSymbolicColoredPixmap(QPixmap &source, QString cgColor); + +private: + BiometricProxy* m_biomericProxy = nullptr; + DeviceMap m_mapDevices; + unsigned m_curLoginOptType = LOGINOPT_TYPE_PASSWORD; + int m_uid; + QString m_strUserName; + DeviceInfoPtr m_curDevInfo = nullptr; // 当前选择的设备信息 + int m_dupFD = -1; // 透传的图像文件句柄 + bool m_isInAuth = false; // 是否正在验证 + bool m_isStopped = false; // 是否被强制终止 + QTimer *m_retrytimer = nullptr; // 重试定时器 + + // UI + QVBoxLayout *m_layoutMain = nullptr; + QHBoxLayout *m_layoutOptBtns = nullptr; + + QLabel *m_labelOptTitle = nullptr; + QButtonGroup *m_btnGroup = nullptr; + QList m_listDriveId; + QMap m_mapOptBtns; + QMap> m_mapDisableDev; +}; + +#endif // LOGINOPTIONSWIDGET_H diff --git a/src/monitorwatcher.cpp b/src/monitorwatcher.cpp new file mode 100644 index 0000000..60009ec --- /dev/null +++ b/src/monitorwatcher.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "monitorwatcher.h" +#include +#include +#include +#include + +#define DRM_DIR "/sys/class/drm/" + +MonitorWatcher::MonitorWatcher(QObject *parent) + : QThread(parent), + virtualSize(0, 0), + monitorCount(0), + firstDetect(true) +{ + +} + +MonitorWatcher::~MonitorWatcher() +{ + requestInterruption(); + terminate(); + wait(); +} + +void MonitorWatcher::run() +{ + QDir drmDir(DRM_DIR); + QStringList drms = drmDir.entryList(QDir::Dirs); + for(auto iter = drms.begin(); iter != drms.end(); ) { + if((*iter).indexOf("card") == 0 || iter->length() > 5) + iter++; + else + iter = drms.erase(iter); + } + + FILE * fp = popen("xrandr", "r"); + Q_UNUSED(fp) + + /* 每隔3秒遍历一次显卡接口的连接状态 */ + while(!isInterruptionRequested()) { + int width = 0; + int height = 0; + QMap tmpStatus; + for(const QString & drm : drms) { + QFile drmStatusFile(DRM_DIR + drm + "/status"); + if(drmStatusFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&drmStatusFile); + QString status = in.readLine(); + tmpStatus[drm] = status; + + if(status == "connected") { + QSize maxMode = getMonitorMaxSize(drm); + width += maxMode.width(); + height = height > maxMode.height() ? height : maxMode.height(); + } + } + } + if(drmStatus != tmpStatus) { + drmStatus = tmpStatus; + int count = 0; + for(auto &pair : tmpStatus) + if(pair == "connected") + count++; + qDebug() << "monitor count changed ---" << count; + if(monitorCount != count) { + monitorCount = count; + if(!firstDetect) { + firstDetect = false; + Q_EMIT monitorCountChanged(count); + } + } + FILE *fp = popen("xrandr", "r"); + Q_UNUSED(fp) + } + + virtualSize = QSize(width, height); + sleep(3); + } +} + +/** + * 获取显示器的最大分辨率 + */ +QSize MonitorWatcher::getMonitorMaxSize(const QString &drm) +{ + int width = 0, height = 0; + QFile drmModeFile(DRM_DIR + drm + "/modes"); + if(drmModeFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in2(&drmModeFile); + QString maxMode = in2.readLine(); + int xpos = maxMode.indexOf('x', 0); + width = maxMode.left(xpos).toInt(); + int ipos = maxMode.indexOf('i', 0); + if(ipos != -1) + height = maxMode.mid(xpos+1, ipos-xpos-1).toInt(); + else + height = maxMode.mid(xpos+1).toInt(); + } + return QSize(width, height); +} + +QSize MonitorWatcher::getVirtualSize() +{ + return virtualSize; +} + +int MonitorWatcher::getMonitorCount() +{ + return monitorCount; +} diff --git a/src/monitorwatcher.h b/src/monitorwatcher.h new file mode 100644 index 0000000..224aeac --- /dev/null +++ b/src/monitorwatcher.h @@ -0,0 +1,56 @@ +/* monitorwatcher.h + * Copyright (C) 2018 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, 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 MONITORWATCHER_H +#define MONITORWATCHER_H + +#include +#include +#include + +/*! + * \brief The MonitorWatcher class + * 监控显示器的插拔 + */ +class MonitorWatcher : public QThread +{ + Q_OBJECT + +public: + MonitorWatcher(QObject *parent=nullptr); + ~MonitorWatcher(); + QSize getVirtualSize(); + int getMonitorCount(); + +Q_SIGNALS: + void monitorCountChanged(int newCount); + void virtualSizeChanged(const QSize &newVirtualSize); + +protected: + void run(); + +private: + QSize getMonitorMaxSize(const QString &drm); + + QMap drmStatus; + QSize virtualSize; + int monitorCount; + bool firstDetect; +}; + +#endif // MONITORWATCHER_H diff --git a/src/networkwatcher.cpp b/src/networkwatcher.cpp new file mode 100644 index 0000000..313eabb --- /dev/null +++ b/src/networkwatcher.cpp @@ -0,0 +1,93 @@ +#include +#include +#include +#include + +#include "networkwatcher.h" + +const int port = 80; + +NetWorkWatcher::NetWorkWatcher(QObject *parent) +{ + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), + QString("/org/freedesktop/NetworkManager"), + QString("org.freedesktop.NetworkManager"), + QString("StateChanged"), this, SLOT(onNetworkStateChanged(uint))); + + network = new QDBusInterface("org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.NetworkManager", + QDBusConnection::systemBus()); +} + +void NetWorkWatcher::onNetworkStateChanged(uint state) +{ + qDebug() << "NetWork state already changed to" << state; + emit NetworkStateChanged(state); +} + +//网络是否可以连接 +void NetWorkWatcher::checkOnline() +{ + QHostInfo::lookupHost("www.baidu.com", this, SLOT(getIp(QHostInfo))); //异步非阻塞 + /*QHostInfo info = QHostInfo::fromName("www.baidu.com"); //阻塞 + if(info.error() != QHostInfo::NoError) + return false; + QString ipAddress = info.addresses().first().toString(); + + QTcpSocket tcpClient; + tcpClient.abort(); + tcpClient.connectToHost(ipAddress, port); + //150毫秒没有连接上则判断不在线 + return tcpClient.waitForConnected(150);*/ +} + +//是否连接网络 +bool NetWorkWatcher::isConnect() +{ + QDBusMessage message = network->call("state"); + if(QDBusMessage::ErrorMessage == message.type()) + { + qDebug() << "error: NetWorkManager DBus Connect Failed!"; + return false; + } + + QList argvs = message.arguments(); + uint state = argvs.at(0).value(); + + qDebug() << "NetWorkManager state:" << state; + + if(state == NM_STATE_CONNECTED_SITE || state == NM_STATE_CONNECTED_LOCAL || state == NM_STATE_CONNECTED_GLOBAL) + return true; + + return false; +} + +void NetWorkWatcher::getIp(QHostInfo info) +{ + if(!isConnect()) + { + emit NetworkStateChanged(NM_STATE_DISCONNECTED); + return; + } + + if(info.error() != QHostInfo::NoError) + { + emit NetworkStateChanged(NM_STATE_CONNECTED_LIMIT); + return; + } + + QString ipAddress = info.addresses().first().toString(); + + QTcpSocket tcpClient; + tcpClient.abort(); + tcpClient.connectToHost(ipAddress, port); + //150毫秒没有连接上则判断不在线 + if(!tcpClient.waitForConnected(150)) + { + emit NetworkStateChanged(NM_STATE_CONNECTED_LIMIT); + return; + } + emit NetworkStateChanged(NM_STATE_CONNECTED_GLOBAL); +} + diff --git a/src/networkwatcher.h b/src/networkwatcher.h new file mode 100644 index 0000000..71d3d28 --- /dev/null +++ b/src/networkwatcher.h @@ -0,0 +1,42 @@ +#ifndef NETWORKWATCHER_H +#define NETWORKWATCHER_H +#include +#include +#include + +enum NMState{ + NM_STATE_UNKNOWN = 0, + NM_STATE_ASLEEP = 10, + NM_STATE_DISCONNECTED = 20, + NM_STATE_DISCONNECTING = 30, + NM_STATE_CONNECTING = 40, + NM_STATE_CONNECTED_LOCAL = 50, + NM_STATE_CONNECTED_SITE = 60, + NM_STATE_CONNECTED_GLOBAL = 70, + NM_STATE_CONNECTED_LIMIT = 80 +}; + +class NetWorkWatcher : public QObject +{ + Q_OBJECT + +public: + NetWorkWatcher(QObject *parent=nullptr); + +Q_SIGNALS: + void NetworkStateChanged(uint state); + +private Q_SLOTS: + void onNetworkStateChanged(uint state); + void getIp(QHostInfo info); + +public: + void checkOnline(); + bool isConnect(); + +private: + QDBusInterface *network; + +}; + +#endif diff --git a/src/org.ukui.ScreenSaver.xml b/src/org.ukui.ScreenSaver.xml new file mode 100644 index 0000000..482c477 --- /dev/null +++ b/src/org.ukui.ScreenSaver.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/pam-tally.c b/src/pam-tally.c new file mode 100644 index 0000000..d32f578 --- /dev/null +++ b/src/pam-tally.c @@ -0,0 +1,478 @@ +/* + * Copyright (C) 2018 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 . + * + **/ + +#include "pam-tally.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char shm_tally_real[128]; + +#define FILE_MODE (S_IRUSR | S_IWUSR) + +#define CONFIG_FILE "/usr/share/lightdm/lightdm.conf.d/96-kylin-setting.conf" + +struct tallylog { + char fail_line[52]; /* rhost or tty of last failure */ + uint16_t reserved; /* reserved for future use */ + uint16_t fail_cnt; /* failures since last success */ + uint64_t fail_time; /* time of last failure */ +}; + + + static +int get_is_open_other_authentication() +{ + char buf[128]; + FILE *config_file; + + if( (config_file = fopen(CONFIG_FILE, "r")) == NULL) + { + //gs_debug("open %s failed", CONFIG_FILE); + return 0; + } + + int open_other_authentication = 0; + while(fgets(buf, sizeof(buf), config_file)) { + if(strlen(buf) == 0 || buf[0] == '#') + { + memset(buf, sizeof(buf), 0); + continue; + } + if(buf[strlen(buf)-1] == '\n') + buf[strlen(buf)-1] = '\0'; + + char *p = strchr(buf, '='); + if(!p) + continue; + *p = '\0'; + + size_t len = strlen(buf); + if(len == 0) + continue; + //去掉=之前的空格 + while(len--) + if(buf[len] == ' ' || buf[len] == '\t') + buf[len] = '\0'; + if(strcmp(buf, "open-other-authentication") != 0) + continue; + + p++; + len = strlen(p); + if(len == 0) + break; + //去掉等号之后的空格 + while(*p == ' ' || *p == '\t') + { + p++; + len--; + } + //去掉尾部空格 + while(len--) + if(*(p+len) == ' ' || *(p+len) == '\t') + *(p+len) = '\0'; + + if(*p == '0') + break; + if(*p == '1') + { + open_other_authentication = 1; + break; + } + } + fclose(config_file); + return open_other_authentication; +} + + static +int get_pam_tally(int *deny, int *unlock_time , int *root_unlock_time) +{ + char buf[128]; + FILE *auth_file; + + if( (auth_file = fopen("/etc/pam.d/common-auth", "r")) == NULL) + return -1; + + while(fgets(buf, sizeof(buf), auth_file)) { + if(strlen(buf) == 0 || buf[0] == '#') + continue; + if(!strstr(buf, "deny")) + continue; + + char *ptr = strtok(buf, " \t"); + while(ptr) { + if(strncmp(ptr, "deny=", 5)==0){ + sscanf(ptr, "deny=%d", deny); + // fprintf(stderr, "-------------------- deny=%d\n", *deny); + } + if(strncmp(ptr, "unlock_time=", 12)==0){ + sscanf(ptr, "unlock_time=%d", unlock_time); + // fprintf(stderr, "-------------------- unlock_time=%d\n", *unlock_time); + } + if(strncmp(ptr, "root_unlock_time=", 17)==0){ + sscanf(ptr, "root_unlock_time=%d", root_unlock_time); + // fprintf(stderr, "-------------------- root_unlock_time=%d\n", *root_unlock_time); + } + ptr = strtok(NULL, " \t"); + } + return 1; + } + return 0; +} + + static +void set_shm_tally_real() +{ + sprintf(shm_tally_real, "%s_%d", SHM_TALLY, getuid()); +} + +int pam_tally_init() +{ + int fd; + int deny = 0, unlock_time = 0 , root_unlock_time = 0; + pam_tally *tally_ptr; + + set_shm_tally_real(); + + printf("shm path =========== : %s\n", shm_tally_real); + + shm_unlink(shm_tally_real); + + if(get_is_open_other_authentication()) + { + return 0; + } + + if(!get_pam_tally(&deny, &unlock_time,&root_unlock_time)) + { + return 0; + } + + if(deny <= 0) + deny = 0; + if(unlock_time <= 0) + unlock_time = 0; + + if( (fd = shm_open(shm_tally_real, O_RDWR | O_CREAT, FILE_MODE)) == -1) + { + printf("shm_open error: %s\n", strerror(errno)); + return -1; + } + + ftruncate(fd, sizeof(pam_tally)); + + if( (tally_ptr = mmap(NULL, sizeof(pam_tally), + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) + { + close(fd); + return -1; + } + close(fd); + tally_ptr->deny = deny; + tally_ptr->unlock_time = unlock_time; + tally_ptr->failed = 0; + tally_ptr->lock_start_time = 0; + tally_ptr->root_unlock_time = root_unlock_time; + + return 1; +} + + static +pam_tally* pam_tally_memory() +{ + int fd; + pam_tally *tally_ptr; + + set_shm_tally_real(); + + if( (fd = shm_open(shm_tally_real, O_RDWR, FILE_MODE)) == -1) + { + return NULL; + } + + if( (tally_ptr = mmap(NULL, sizeof(pam_tally), + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) + { + close(fd); + return NULL; + } + close(fd); + return tally_ptr; +} + +int pam_tally_is_enbled() +{ + int fd; + + set_shm_tally_real(); + + if( (fd = shm_open(shm_tally_real, O_RDONLY, FILE_MODE)) == -1) + { + printf("shm_open error: %s\n", strerror(errno)); + close(fd); + return 0; + } + + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL){ + close(fd); + return -1; + } + + if(tally_ptr->deny == 0 || tally_ptr->unlock_time == 0){ + close(fd); + return 0; + } + close(fd); + + return 1; +} + +int pam_tally_add_failed() +{ + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL) + return -1; + + tally_ptr->failed++; + + //如果失败次数达到上限,开始计时 + if(tally_ptr->failed >= tally_ptr->deny) + tally_ptr->lock_start_time = time(NULL); + + return 0; +} + +int pam_tally_clear_failed() +{ + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL) + return -1; + + tally_ptr->failed = 0; + tally_ptr->lock_start_time = 0; + return 0; +} + +int pam_tally_failure_is_out() +{ + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL) + return -1; + + return (tally_ptr->failed >= tally_ptr->deny ? 1 : 0); +} + +int pam_tally_deny() +{ + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL) + return -1; + + return tally_ptr->deny; +} + +int pam_tally_failed_count() +{ + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL) + return -1; + + return tally_ptr->failed; +} + +int pam_tally_unlock_time() +{ + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL) + return -1; + + printf("########################### unlock time = %d\n", tally_ptr->unlock_time); + return tally_ptr->unlock_time; +} + +int pam_tally_is_canUnlock() +{ + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL) + return -1; + + if(tally_ptr->failed >= tally_ptr->deny && + time(NULL) - tally_ptr->lock_start_time < tally_ptr->unlock_time) + return 0; + return 1; +} + + int +pam_modutil_read(int fd, char *buffer, int count) +{ + int block, offset = 0; + + while (count > 0) { + block = read(fd, &buffer[offset], count); + + if (block < 0) { + if (errno == EINTR) continue; + return block; + } + if (block == 0) return offset; + + offset += block; + count -= block; + } + + return offset; +} + +void get_tally(uid_t uid, int *tfile, struct tallylog *tally) +{ + char filename[50]={0}; + sprintf(filename,"%s","/tmp/.tallylog"); + + void *void_tally = tally; + if ((*tfile = open(filename, O_RDONLY)) == -1){ + fprintf(stderr, "open tallylog failed \n"); + return ; + } + + if (lseek(*tfile, (off_t)uid*(off_t)sizeof(*tally), SEEK_SET) == (off_t)-1) { + fprintf(stderr, "lseek tallylog failed \n"); + close(*tfile); + return ; + } + + if (pam_modutil_read(*tfile, void_tally, sizeof(*tally)) != sizeof(*tally)) { + fprintf(stderr, "read tallylog failed \n"); + memset(tally, 0, sizeof(*tally)); + } + + close(*tfile); + tally->fail_line[sizeof(tally->fail_line)-1] = '\0'; +} + +int pam_tally_unlock_time_left(int uid, int *fail_cnt,int *left_time, int *deny, int *fail_time, int *unlock_time1) +{ + pam_tally *tally_ptr; + + if((tally_ptr = pam_tally_memory()) == NULL) + return 0; + + int unlock_time = tally_ptr->unlock_time; + *deny = tally_ptr->deny; + if(unlock_time == 0) + return 0; + + int tfile = -1; + struct tallylog tally; + tally.reserved = 0; + tally.fail_cnt = 0; + tally.fail_time = 0; + + get_tally(uid,&tfile,&tally); + + if(tally.fail_cnt<*deny) + return 0; + + //连续输错,时间累加 + if (tally.fail_cnt >= (*deny)*2 && tally.fail_cnt < (*deny)*3){ + unlock_time = unlock_time*2; + } + else if(tally.fail_cnt >= (*deny)*3 && tally.fail_cnt < (*deny)*4){ + unlock_time = unlock_time*8; + } + else if (tally.fail_cnt >= (*deny)*4){ + *fail_cnt = 0xFFFF;//永久锁定 + return 0; + } + + + int unlock_time_left = unlock_time - ((long)time(NULL) - tally.fail_time); + + *fail_time = tally.fail_time; + *unlock_time1 = unlock_time; + + *left_time = unlock_time_left > 0 ? unlock_time_left : 0; + *fail_cnt = tally.fail_cnt; + + return *left_time; +} + +int pam_tally_root_unlock_time_left(int *fail_cnt,int *left_time, int *deny1, int *fail_time, int *unlock_time1) +{ + + pam_tally *tally_ptr; + if((tally_ptr = pam_tally_memory()) == NULL){ + return 0; + } + int root_unlock_time = tally_ptr->root_unlock_time; + int deny = tally_ptr->deny; + if(root_unlock_time == 0) + return 0; + + int tfile = -1; + uid_t uid = getuid(); + struct tallylog tally; + tally.reserved = 0; + tally.fail_cnt = 0; + tally.fail_time = 0; + + get_tally(uid,&tfile,&tally); + if(tally.fail_cnt= (deny)*2 && tally.fail_cnt < (deny)*3){ + root_unlock_time = root_unlock_time*2; + } + else if(tally.fail_cnt >= (deny)*3 && tally.fail_cnt < (deny)*4){ + root_unlock_time = root_unlock_time*8; + } + else if (tally.fail_cnt >= (deny)*4){ + *fail_cnt = 0xFFFF;//永久锁定 + return 0; + } + + int root_unlock_time_left = root_unlock_time - ((long)time(NULL) - tally.fail_time); + + *fail_time = tally.fail_time; + *unlock_time1 = root_unlock_time; + + *left_time = root_unlock_time_left > 0 ? root_unlock_time_left : 0; + + *fail_cnt = tally.fail_cnt; + + return *left_time; +} + + diff --git a/src/pam-tally.cpp b/src/pam-tally.cpp new file mode 100644 index 0000000..ba82fec --- /dev/null +++ b/src/pam-tally.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2018 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, 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 "pam-tally.h" +#include +#include +#include +#include +#include +#define PAM_CONFIG_FILE "/etc/pam.d/common-auth" + +PamTally* PamTally::instance_ = nullptr; + +PamTally::PamTally(QObject *parent) + : QObject(parent) +{ + parsePamConfig(); +} + +PamTally* PamTally::instance(QObject *parent) +{ + if(instance_ == nullptr) + instance_ = new PamTally(parent); + return instance_; +} + +int PamTally::parsePamConfig() +{ + deny = 0; + unlock_time = 0; + root_unlock_time = 0; + + QFile file(PAM_CONFIG_FILE); + if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){ + qDebug()<<"open /etc/pam.d/common-auth failed"; + return -1; + } + + QStringList list; + list.clear(); + + while(!file.atEnd()){ + QString line = (QString)file.readLine(); + line = line.trimmed(); + + if(line.startsWith("#") || !line.contains("unix",Qt::CaseSensitive)) + continue; + + list << line; + } + file.close(); + + if(list.size() > 0) + { + QString line = list.at(0); + QStringList strs = line.split(" "); + foreach (QString str, strs) { + if(str.contains("deny",Qt::CaseSensitive)) + { + deny = str.split("=").at(1).toUInt(); + } + if(str.contains("unlock_time",Qt::CaseSensitive)) + { + unlock_time = str.split("=").at(1).toULongLong(); + } + if(str.contains("root_unlock_time",Qt::CaseSensitive)) + { + root_unlock_time = str.split("=").at(1).toULongLong(); + } + } + } + qDebug()<<"deny = "<. + * +**/ +#include "pam.h" + +extern "C" { + #include + #include + #include +} + +#define TO_AUTHCHILD_RD_SHIFT 16 +#define TO_PARENT_WR_SHIFT 0 +#define PIPE_FD_MASK ((1 << TO_AUTHCHILD_RD_SHIFT) - 1) + +void authenticate(int toParent[2], int toAuthChild[2]) +{ + pam_handle_t *pamh = NULL; + char *username; + int retval; + int auth_status; + struct pam_conv conv; + unsigned long fd = 0; + fd = fd | toAuthChild[0] << TO_AUTHCHILD_RD_SHIFT + | toParent[1] << TO_PARENT_WR_SHIFT; + /* authentication child process */ + username=getenv("USER"); + conv.conv = pam_conversation; + conv.appdata_ptr = (void *)fd; + retval = pam_start("ukui-screensaver-qt", username, &conv, &pamh); + if(retval == PAM_SUCCESS) + qDebug("PAM started successfully."); + else + qDebug("PAM started unsuccessfully."); + qDebug("Invoke pam authentication."); + auth_status = pam_authenticate(pamh, 0); + qDebug("Complete pam authentication."); + if(pam_end(pamh, retval) != PAM_SUCCESS){ + qDebug("Failed to terminate PAM."); + _exit(1); + } + qDebug("PAM ended successfully."); + kill(getppid(), SIGUSR1); + char buffer[16]; + sprintf(buffer, "%d", auth_status); + PIPE_OPS_SAFE( + write(toParent[1], buffer, strlen(buffer) + 1) + ); + qDebug("Auth status has been written to pipe."); + ::close(toParent[1]); + ::close(toAuthChild[0]); + qDebug("Authenticate child process now exits."); + _exit(0); +} + +#define MAX_PASSWORD_LENGTH 1024 +int pam_conversation(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + unsigned long fd; + int read_from_parent; + int write_to_parent; + int count; + char *password; + struct pam_response *tmp_save; + + qDebug("Into pam_conversation"); + + fd = (unsigned long)appdata_ptr; + read_from_parent = (fd >> TO_AUTHCHILD_RD_SHIFT) & PIPE_FD_MASK; + write_to_parent = (fd >> TO_PARENT_WR_SHIFT) & PIPE_FD_MASK; + count = num_msg; + password = (char *)malloc(MAX_PASSWORD_LENGTH); + *resp = (struct pam_response *)malloc(num_msg * + sizeof(struct pam_response)); + tmp_save = (struct pam_response *)(*resp); + memset(*resp, 0, num_msg * sizeof(struct pam_response)); + qDebug("Resolve PAM messages."); + while(count-- >= 1){ + struct pam_message_object pam_msg_obj; + pam_msg_obj.msg_style = (*msg)->msg_style; + strncpy(pam_msg_obj.msg, (*msg)->msg, MAX_MSG_LENGTH); + PIPE_OPS_SAFE( + write(write_to_parent, &pam_msg_obj, sizeof(pam_msg_obj)); + ); + qDebug("PAM message has been written to pipe."); + kill(getppid(), SIGUSR1); + + if ((*msg)->msg_style == PAM_PROMPT_ECHO_OFF + || (*msg)->msg_style == PAM_PROMPT_ECHO_ON){ + int n; + PIPE_OPS_SAFE( + n = read(read_from_parent, password, MAX_PASSWORD_LENGTH); + ); + qDebug("%d bytes response received from pipe.", n); + (*resp)->resp = password; + (*resp)->resp_retcode = 0; + } else { + ; + } + if(count != 0){ + msg++; + (*resp)++; + } + } + + (*resp) = tmp_save; + + qDebug("Out pam_conversation."); + return PAM_SUCCESS; +} + diff --git a/src/pam.h b/src/pam.h new file mode 100644 index 0000000..317098d --- /dev/null +++ b/src/pam.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef PAM_H +#define PAM_H + +#include +#include +#include + +void authenticate(int toParent[2], int toAuthChild[2]); + +int pam_conversation(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr); + +#define MAX_MSG_LENGTH 1024 +struct pam_message_object { + int msg_style; + char msg[MAX_MSG_LENGTH + 1]; +} __attribute__((packed)); + +#define PIPE_OPS_SAFE(statement) do { \ + int return_value = statement; \ + if (return_value == -1)\ + qWarning("PIPE write/read error: %s", strerror(errno)); \ +} while (0) + +#endif // PAM_H diff --git a/src/permissioncheck.cpp b/src/permissioncheck.cpp new file mode 100644 index 0000000..82ee79b --- /dev/null +++ b/src/permissioncheck.cpp @@ -0,0 +1,401 @@ +#include "permissioncheck.h" +#include +#include +#include +#include +#include "common.h" + +#include "wechatauthdialog.h" + +VerificationWidget::VerificationWidget(QWidget *parent) : QWidget(parent) +{ + qDebug() << "PermissionCheck"; + resize(1000,355); + QHBoxLayout *mainLayout = new QHBoxLayout(this); + setLayout(mainLayout); + + WeChatAuthDialog *m_weChatWidget; + PhoneAuthWidget *m_phoneAuthWidget; + + m_weChatWidget = new WeChatAuthDialog(1,this); + mainLayout->addWidget(m_weChatWidget, 1, Qt::AlignLeft); + + mainLayout->addSpacing(400); + + m_phoneAuthWidget = new PhoneAuthWidget(this); + mainLayout->addWidget(m_phoneAuthWidget, 1, Qt::AlignRight); + + connect(m_phoneAuthWidget, &PhoneAuthWidget::pageMessage, this, [=](SwitchPage s, QList list){ + Q_EMIT pageMessage(s, list); + }); +} + +void VerificationWidget::paintEvent(QPaintEvent *) +{ + int x1 = width() / 2; + int y1 = height() / 4; + int x2 = x1; + int y2 = height() / 3 * 2 + y1; + QLinearGradient linearGra(QPoint(x1, y1), QPoint(x2, y2)); + linearGra.setColorAt(0, QColor(238, 238, 238, 0)); + linearGra.setColorAt(0.5, QColor(255, 255, 255, 138)); + linearGra.setColorAt(1, QColor(216, 216, 216, 0)); + + QPainter painter(this); + QBrush brush(linearGra); + painter.setPen(Qt::transparent); + painter.setBrush(brush); + painter.drawRoundedRect(QRect(x1, y1, 4, height() / 3 * 2), 16, 16); +} + +InputInfos::InputInfos(QWidget *parent): + QWidget(parent) +{ + initUI(); + initConnect(); + setQSS(); +} + +void InputInfos::initUI() +{ + setFixedWidth(316); + QGridLayout *mainLayout = new QGridLayout(this); + setLayout(mainLayout); + mainLayout->setColumnStretch(1, 0); + mainLayout->setColumnStretch(2, 1); + mainLayout->setColumnStretch(3, 0); + + m_pPhoneIconLB = new QLabel(this); + m_pPhoneIconLB->setPixmap(QPixmap(":/images/icon-phone.png")); + mainLayout->addWidget(m_pPhoneIconLB, 0, 1, 1, 1, Qt::AlignLeft); + + m_pPhoneLE = new QLineEdit(this); + m_pPhoneLE->setPlaceholderText("手机号"); + m_pPhoneLE->setProperty("class", "InputLine"); + m_pPhoneLE->setValidator(0); + mainLayout->addWidget(m_pPhoneLE, 0, 2, 1, 2, Qt::AlignLeft); + + m_pVerCodeIconLB = new QLabel(this); + m_pVerCodeIconLB->setPixmap(QPixmap(":/images/icon-sms.png")); + mainLayout->addWidget(m_pVerCodeIconLB, 1, 1, 1, 1, Qt::AlignLeft); + + m_pVerCodeLE = new QLineEdit(this); + m_pVerCodeLE->setPlaceholderText("短信验证码"); + m_pVerCodeLE->setProperty("class", "InputLine"); + m_pVerCodeLE->setValidator(0); + mainLayout->addWidget(m_pVerCodeLE, 1, 2, 1, 1, Qt::AlignLeft); + + m_pGetVerCodeBT = new QPushButton(this); + m_pGetVerCodeBT->setText("获取验证码"); + m_pGetVerCodeBT->setEnabled(false); + m_pGetVerCodeBT->setFocusPolicy(Qt::NoFocus); + m_pGetVerCodeBT->setProperty("class", "GetCodeBT"); + m_pGetVerCodeBT->setCursor(QCursor(Qt::PointingHandCursor)); + mainLayout->addWidget(m_pGetVerCodeBT, 1, 3, 1, 1, Qt::AlignLeft); + + m_pNextGetVerCodeQTimer = new QTimer(this); + + m_curInputState = InputState::InputWaiting; +} + +void InputInfos::initConnect() +{ + connect(m_pPhoneLE, &QLineEdit::textChanged, this, &InputInfos::onPhoneTextChanged); + + connect(m_pVerCodeLE, &QLineEdit::textChanged, this, &InputInfos::onVerCodeTextChanged); + + connect(m_pNextGetVerCodeQTimer, &QTimer::timeout, this, &InputInfos::onNextGetVerCodeTimer); + + connect(m_pGetVerCodeBT, &QPushButton::clicked, this, &InputInfos::onGetVerCode); +} + +void InputInfos::setQSS() +{ + QString style_sheet = ".InputLine{" + "padding:10px 2px 10px 2px;" + "}" + ".GetCodeBT{" + "background:rgba(0,0,0,0);" + "color:rgba(38,38,38,115);" + "font-size:16px;" + "}"; + setStyleSheet(style_sheet); + adjustSize(); +} + +void InputInfos::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(Qt::white); + painter.setBrush(Qt::white); + painter.drawRoundedRect(rect(), 16, 16); + painter.setPen(QColor(226, 226, 226)); + painter.drawLine(QLineF(0, m_pPhoneIconLB->y() + m_pPhoneIconLB->height() + 1, + width(), m_pPhoneIconLB->y() + m_pPhoneIconLB->height() + 1)); +} + +void InputInfos::onPhoneTextChanged(const QString &text) +{ + if(text.length() == 11){ + m_pGetVerCodeBT->setEnabled(true); + m_pGetVerCodeBT->setFocusPolicy(Qt::NoFocus); + m_pGetVerCodeBT->setStyleSheet("color:#2FB3E8;"); + + if(m_pVerCodeLE->text().length() == 6){ + Q_EMIT InputStateChanged(InputState::InputFinish); + m_curInputState = InputState::InputFinish; + } + } + else + { + m_pGetVerCodeBT->setEnabled(false); + m_pGetVerCodeBT->setStyleSheet("color:rgba(38, 38, 38, 115);"); + if(InputState::InputFinish == m_curInputState) + { + m_curInputState = InputState::InputWaiting; + Q_EMIT InputStateChanged(InputState::InputWaiting); + } + } +} + +void InputInfos::onVerCodeTextChanged(const QString &text) +{ + if(text.length() == 6 && m_pPhoneLE->text().length() == 11) + { + Q_EMIT InputStateChanged(InputState::InputFinish); + m_curInputState = InputState::InputFinish; + } + else if(m_curInputState == InputState::InputFinish) + { + Q_EMIT InputStateChanged(InputState::InputWaiting); + m_curInputState = InputState::InputWaiting; + } +} + +void InputInfos::clearInfos() +{ + m_pPhoneLE->clear(); + m_pVerCodeLE->clear(); + if(m_curInputState == InputState::InputFinish) + { + m_curInputState = InputState::InputWaiting; + Q_EMIT InputStateChanged(m_curInputState); + } +} + +QString InputInfos::getVerificationCode() +{ + return m_pVerCodeLE->text(); +} + +QString InputInfos::getPhoneNumer() +{ + return m_pPhoneLE->text(); +} + +void InputInfos::onGetVerCode() +{ + m_pGetVerCodeBT->setEnabled(false); + m_pGetVerCodeBT->setStyleSheet("color:rgba(38, 38, 38, 115);"); + m_nextGetVerCodeTime = 60; + m_pGetVerCodeBT->setText("重新获取(60s)"); + m_pNextGetVerCodeQTimer->start(1000); +} + + +void InputInfos::onNextGetVerCodeTimer() +{ + --m_nextGetVerCodeTime; + m_pGetVerCodeBT->setText("重新获取(" + QString::number(m_nextGetVerCodeTime) + "s)"); + if(m_nextGetVerCodeTime == 0) + { + m_pNextGetVerCodeQTimer->stop(); + m_pGetVerCodeBT->setEnabled(true); + m_pGetVerCodeBT->setFocusPolicy(Qt::NoFocus); + m_pGetVerCodeBT->setText("获取验证码"); + m_pGetVerCodeBT->setStyleSheet("color:#2FB3E8;"); + return; + } + +} + +PhoneAuthWidget::PhoneAuthWidget(QWidget *parent) +{ + initUI(); + initConnect(); + setQSS(); +} + +void PhoneAuthWidget::initUI() +{ + QVBoxLayout *phoLayout = new QVBoxLayout(this); + phoLayout->setMargin(0); + + m_pPhoTitleLB = new QLabel(this); + m_pPhoTitleLB->setText(tr("Verification by phoneNum")); + m_pPhoTitleLB->setProperty("class", "titleLB"); + phoLayout->addWidget(m_pPhoTitleLB, 0, Qt::AlignHCenter); + + m_pPhoPromptMsgLB = new QLabel(this); + m_pPhoPromptMsgLB->setText(tr("「 Use bound Phone number to verification 」")); + m_pPhoPromptMsgLB->setProperty("class", "PromptText"); + phoLayout->addWidget(m_pPhoPromptMsgLB, 0, Qt::AlignHCenter); + + m_pPhoErrorMsgLB = new QLabel(this); + m_pPhoErrorMsgCloneLB = new QLabel(this); + m_pPhoErrorMsgLB->setProperty("class", "ErrorMsg"); + m_pPhoErrorMsgCloneLB->setProperty("class", "ErrorMsg"); + hidePhoneErrorMsg(); + phoLayout->addWidget(m_pPhoErrorMsgLB, 0, Qt::AlignHCenter); + phoLayout->addWidget(m_pPhoErrorMsgCloneLB, 0, Qt::AlignHCenter); + + + m_pPhoInputInfos = new InputInfos(this); + phoLayout->addWidget(m_pPhoInputInfos, 0, Qt::AlignHCenter); + + m_pPhoSubmitBT = new QPushButton(this); + m_pPhoSubmitBT->setFocusPolicy(Qt::NoFocus); + m_pPhoSubmitBT->setText(tr("commit")); + m_pPhoSubmitBT->setProperty("class", "BindBT"); + m_pPhoSubmitBT->setCursor(QCursor(Qt::PointingHandCursor)); + m_pPhoSubmitBT->setEnabled(false); + phoLayout->addSpacing(8); + phoLayout->addWidget(m_pPhoSubmitBT, 0, Qt::AlignHCenter); + phoLayout->addStretch(1); +} + +void PhoneAuthWidget::initConnect() +{ + connect(m_pPhoInputInfos, &InputInfos::InputStateChanged, this, &PhoneAuthWidget::onInputStateChanged); + + connect(m_pPhoSubmitBT, &QPushButton::clicked, this, &PhoneAuthWidget::onSubmitBTClick); + + connect(m_pPhoInputInfos, &InputInfos::getVerCode, this, &PhoneAuthWidget::onGetVerCode); +} + +QSize PhoneAuthWidget::sizeHint() const{ + return QWidget::sizeHint(); +} + +void PhoneAuthWidget::hidePhoneErrorMsg() +{ + m_pPhoErrorMsgCloneLB->setFixedHeight(m_pPhoErrorMsgLB->height()); + m_pPhoErrorMsgCloneLB->show(); + m_pPhoErrorMsgLB->hide(); +} + +void PhoneAuthWidget::showPhoneErrorMsg() +{ + m_pPhoErrorMsgLB->show(); + m_pPhoErrorMsgCloneLB->hide(); +} + +void PhoneAuthWidget::onInputStateChanged(InputInfos::InputState input_state) +{ + if(input_state == InputInfos::InputState::InputFinish) + { + m_pPhoSubmitBT->setEnabled(true); + m_pPhoSubmitBT->setFocusPolicy(Qt::NoFocus); + m_pPhoSubmitBT->setStyleSheet("background:#2FB3E8;"); + } + else + { + m_pPhoSubmitBT->setEnabled(false); + m_pPhoSubmitBT->setStyleSheet("background:rgba(255,255,255,115);"); + } +} + + +void PhoneAuthWidget::onSubmitBTClick() +{ + QString tel = m_pPhoInputInfos->getPhoneNumer(); + QString verCode = m_pPhoInputInfos->getVerificationCode(); + if (true) + { + //验证成功 + qDebug() << "-----------onSubmitBTClick"; + Q_EMIT pageMessage(SwitchPage::SwitchToResetPWD, QList()); + } +// DBusMsgCode msgCode = SSOP->m_pRetrievePwdInterface->CheckVerificationCode(tel, verCode); +// switch (msgCode) { +// case DBusMsgCode::No_Error: +// emit pageMessage(PageMessage::JumpToNewPswSet, QList()); +// break; +// // TODO 更新提交后的错误状态 +// default: +// break; +// } +} + +void PhoneAuthWidget::onGetVerCode() +{ +// DBusMsgCode msgCode = SSOP->m_pRetrievePwdInterface->GetVerificationCode(Cfg->getUsername(), m_pPhoInputInfos->getPhoneNumer()); +// switch (msgCode) { +// case DBusMsgCode::No_Error: +// // 验证码获取无错误 +// break; +// // TODO 更新错误状态 +// default: +// break; +// } +} + +void PhoneAuthWidget::onQRCodeStateChanged(QString username, QString password, int nState) +{ + QRCodeSwepState state = static_cast(nState); + switch (state) { + case QRCodeSwepState::WaitingSwep: + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: waiting user swep qrcode!"; + break; + case QRCodeSwepState::HaveSwep: + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: user has swep code!"; + break; + case QRCodeSwepState::CancelSwep: + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: user cancel swep code!"; + break; + case QRCodeSwepState::ConfirmSuccess: + { + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: user = [" << username << "] confirm success!"; +// if(username != Cfg->getUsername()) +// { +// resetQRCService(); +// // TODO 更新错误信息 +// } +// else +// emit pageMessage(PageMessage::JumpToNewPswSet, QList()); +// break; + } + case QRCodeSwepState::QRCodeInvalid: + { + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: qrcode invalid!"; +// resetQRCService(); + break; + } + default: + break; + } +} + +void PhoneAuthWidget::setQSS() +{ + QString style_sheet =".PromptText{" + "font-size:24px;" + "color: rgba(255,255,255,192);" + "}" + ".BindBT{" + "background:rgba(255,255,255,115);" + "width:316px;" + "height:64px;" + "border-radius:16px;" + "}" + ".ErrorMsg{" + "color:#FD625E;" + "font-size:14px;" + "}" + ".titleLB{" + "color:#FFFFFF;" + "font-size:32px;" + "}"; + setStyleSheet(style_sheet); +} diff --git a/src/permissioncheck.h b/src/permissioncheck.h new file mode 100644 index 0000000..94639e5 --- /dev/null +++ b/src/permissioncheck.h @@ -0,0 +1,108 @@ +#ifndef PERMISSIONCHECK_H +#define PERMISSIONCHECK_H + +#include +#include +#include +#include +#include "wechatauthdialog.h" +#include "common.h" + +class InputInfos; +class PhoneAuthWidget; + +class InputInfos : public QWidget +{ + Q_OBJECT +public: + enum InputState{ + InputWaiting + , InputFinish + }; + InputInfos(QWidget *parent = nullptr); + QString getPhoneNumer(); + QString getVerificationCode(); + void clearInfos(); + +Q_SIGNALS: + void getVerCode(); + void InputStateChanged(InputState input_state); + +protected: + void paintEvent(QPaintEvent *); + +private Q_SLOTS: + void onPhoneTextChanged(const QString &text); + void onVerCodeTextChanged(const QString &text); + void onGetVerCode(); + void onNextGetVerCodeTimer(); + +private: + void initUI(); + void initConnect(); + void setQSS(); + +private: + QLabel *m_pPhoneIconLB; + QLineEdit *m_pPhoneLE; + QLabel *m_pVerCodeIconLB; + QLineEdit *m_pVerCodeLE; + QPushButton *m_pGetVerCodeBT; + QTimer *m_pNextGetVerCodeQTimer; + int m_nextGetVerCodeTime; + + InputState m_curInputState; +}; + +class VerificationWidget : public QWidget +{ + Q_OBJECT +public: + explicit VerificationWidget(QWidget *parent = nullptr); + +Q_SIGNALS: + void pageMessage(SwitchPage id, QList argvs); +private: + QLabel *m_titleLB; + QLabel *m_phonePromptMsgLB; + WeChatAuthDialog *m_weChatWidget; +//public: + PhoneAuthWidget *m_phoneAuthWidget; + +protected: + void paintEvent(QPaintEvent *); +}; + +class PhoneAuthWidget : public QWidget +{ + Q_OBJECT +public: + PhoneAuthWidget(QWidget* parent = nullptr); + QSize sizeHint() const; + +private: + void initUI(); + void initConnect(); + void setQSS(); + + void showPhoneErrorMsg(); + void hidePhoneErrorMsg(); +Q_SIGNALS: + void pageMessage(SwitchPage id, QList argvs); +private Q_SLOTS: + void onInputStateChanged(InputInfos::InputState input_state); + void onSubmitBTClick(); + void onGetVerCode(); + void onQRCodeStateChanged(QString username, QString password, int nState); + +private: + // 手机号验证 + QLabel *m_pPhoTitleLB; + QLabel *m_pPhoPromptMsgLB; + QLabel *m_pPhoErrorMsgLB; + QLabel *m_pPhoErrorMsgCloneLB; // 控制格式 + QPushButton *m_pPhoSubmitBT; + InputInfos *m_pPhoInputInfos; + +}; +#endif // PERMISSIONCHECK_H diff --git a/src/powermanager.cpp b/src/powermanager.cpp new file mode 100644 index 0000000..7bc190d --- /dev/null +++ b/src/powermanager.cpp @@ -0,0 +1,801 @@ + /* + * Copyright (C) 2018 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 . + * + **/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "powermanager.h" + +const static QString login1Service = QStringLiteral("org.freedesktop.login1"); +const static QString login1Path = QStringLiteral("/org/freedesktop/login1"); +const static QString login1ManagerInterface = QStringLiteral("org.freedesktop.login1.Manager"); + +#ifdef USE_INTEL +PowerManager::PowerManager(QWidget *parent) + : QWidget(parent), + lasttime(QTime::currentTime()) +{ + resize((ITEM_WIDTH*4 + ITEM_SPACING*3), ITEM_HEIGHT); + initUI(); + setQSS(); +} +#else +PowerManager::PowerManager(QWidget *parent) + : QListWidget(parent), + lasttime(QTime::currentTime()) +{ + // resize(ITEM_WIDTH*7, ITEM_HEIGHT); + setFlow(QListWidget::LeftToRight); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setSelectionMode(QListWidget::NoSelection); + + + //QObject::connect(this,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(powerClicked(QListWidgetItem*))); +// QObject::connect(this, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this,\ +// SLOT(keyboardPressed(QListWidgetItem*,QListWidgetItem*))); + + sessionInterface = new QDBusInterface("org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + QDBusConnection::sessionBus(), + this); + + loginInterface = new QDBusInterface(login1Service, + login1Path, + login1ManagerInterface, + QDBusConnection::systemBus(), + this); + + xEventMonitor = new XEventMonitor(this); + connect(xEventMonitor, SIGNAL(keyPress(const QString &)), this, + SLOT(onGlobalKeyPress(const QString &))); + connect(xEventMonitor, SIGNAL(keyRelease(const QString &)), this, + SLOT(onGlobalkeyRelease(const QString &))); + xEventMonitor->start(); + + QDBusReply stateReply = loginInterface->call("CanSuspend"); + if(stateReply.isValid() && stateReply.value() == "yes"){ + canSuspend = true; + }else{ + canSuspend = false; + } + + QDBusReply stateReply1 = loginInterface->call("CanHibernate"); + if(stateReply1.isValid() && stateReply1.value() == "yes"){ + canHibernate = true; + }else{ + canHibernate = false; + } + + initUI(); + resize((ITEM_WIDTH+ITEM_SPACING*2)*this->count()-ITEM_SPACING*2, ITEM_HEIGHT+ITEM_SPACING*2); + //setCurrentRow(0); +} + + +void PowerManager::keyboardPressed(QListWidgetItem *item_c, QListWidgetItem *item_p) +{ +// if(item_p){ +// QString name = itemWidget(item_c)->objectName(); +// if(name == rebootWidget->objectName()){ +// rebootFace->setStyleSheet("background-color: rgba(255, 255, 255, 40%),\ +// QLabel:hover{background-color:rgb(255,255,255,40%)"); +// } else if(name == shutdownWidget->objectName()){ +// shutdownFace->setStyleSheet("background-color: rgba(255, 255, 255, 40%)"); +// } else if(suspendWidget && name == suspendWidget->objectName()){ +// suspendFace->setStyleSheet("background-color: rgba(255, 255, 255, 40%)"); +// } else if(hibernateWidget && name == hibernateWidget->objectName()){ +// hibernateFace->setStyleSheet("background-color: rgba(255, 255, 255, 40%)"); +// } +// QString name_p = itemWidget(item_p)->objectName(); +// if(name_p == rebootWidget->objectName()){ +// rebootFace->setStyleSheet("background-color: rgba(255, 255, 255, 20% QLabel:hover{background-color:rgb(255,255,255,40%))"); + +// } else if(name_p == shutdownWidget->objectName()){ +// shutdownFace->setStyleSheet("background-color: rgba(255, 255, 255, 20%\ +// QLabel:hover{background-color:rgb(255,255,255,40%))"); +// } else if(suspendWidget && name_p == suspendWidget->objectName()){ +// suspendFace->setStyleSheet("background-color: rgba(255, 255, 255, 20%\ +// QLabel:hover{background-color:rgb(255,255,255,40%))"); +// } else if(hibernateWidget && name_p == hibernateWidget->objectName()){ +// hibernateFace->setStyleSheet("background-color: rgba(255, 255, 255, 20%); QLabel:hover{background-color:rgb(255,255,255,40%))"); +// } +// } +} + + + +bool PowerManager::eventFilter(QObject *obj, QEvent *event) +{ + if(event->type() != QEvent::MouseButtonPress){ + return false; + } + + QString name = obj->objectName(); + + if(name == "switchFace") + switchWidgetClicked(); + else if(name == "logoutFace") + logoutWidgetCliced(); + else if(name == "rebootFace") + rebootWidgetClicked(); + else if(name == "shutdownFace") + shutdownWidgetClicked(); + else if(name == "suspendFace") + suspendWidgetClicked(); + else if(name == "hibernateFace") + hibernateWidgetClicked(); + + return false; +} + +void PowerManager::onGlobalKeyPress(const QString &key) +{ +} + +void PowerManager::onGlobalkeyRelease(const QString &key) +{ + if (key == "Escape") { + + } else if (key == "Left" || key == "Right" || key == "Return" || key == "KP_Enter") { + keyBdRelease(key); + } +} + +void PowerManager::keyBdRelease(QString key) +{ + QString focus = "focus"; + QString normal = "normal"; + if(key == "Right"){ + if(nowAt == -1){ + nowAt = 0; + setButtonStyle(focus); + } else if(nowAt == 0){ + setButtonStyle(normal); + nowAt = 1; + setButtonStyle(focus); + } else if(nowAt == 1){ + setButtonStyle(normal); + nowAt = 2; + setButtonStyle(focus); + } else if(nowAt == 2){ + setButtonStyle(normal); + nowAt = 3; + setButtonStyle(focus); + } else if(nowAt == 3){ + setButtonStyle(normal); + nowAt = 0; + setButtonStyle(focus); + } + } else if(key == "Left") { + if(nowAt == -1){ + nowAt = 3; + setButtonStyle(focus); + } else if(nowAt == 3){ + setButtonStyle(normal); + nowAt = 2; + setButtonStyle(focus); + } else if(nowAt == 2){ + setButtonStyle(normal); + nowAt = 1; + setButtonStyle(focus); + } else if(nowAt == 1){ + setButtonStyle(normal); + nowAt = 0; + setButtonStyle(focus); + } else if(nowAt == 0){ + setButtonStyle(normal); + nowAt = 3; + setButtonStyle(focus); + } + } else if(key == "Return" || key == "KP_Enter"){ + if(nowAt == 0 && this->isVisible()) + hibernateWidgetClicked(); + else if(nowAt == 1 && this->isVisible()) + suspendWidgetClicked(); + else if(nowAt == 2 && this->isVisible()) + rebootWidgetClicked(); + else if(nowAt == 3 && this->isVisible()) + shutdownWidgetClicked(); + } +} + + +void::PowerManager::setButtonStyle(QString Style) +{ + if(Style == "normal") + listLabel.at(nowAt)->setStyleSheet("background-color: rgba(255, 255, 255, 15%);QLabel:hover{background-color:rgb(255,255,255,40%);QLabel:pressed{background-color:rgb(255,255,255,30%))"); + else if(Style == "focus") + listLabel.at(nowAt)->setStyleSheet("background-color: rgba(255, 255, 255, 20%);border: 1px solid #296CD9; border-radius: 64px;"); +} + +QStringList PowerManager::getLoginedUsers() +{ + QStringList m_loginedUser; + QDBusMessage result = loginInterface->call("ListUsers"); + QList outArgs = result.arguments(); + QVariant first = outArgs.at(0); + QDBusArgument dbvFirst = first.value(); + QVariant vFirst = dbvFirst.asVariant(); + const QDBusArgument &dbusArgs = vFirst.value(); + + + QVector loginedUsers; + + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + usersInfo user; + dbusArgs >> user; + loginedUsers.push_back(user); + } + + for (usersInfo user: loginedUsers) { + + QDBusInterface userPertyInterface("org.freedesktop.login1", user.usersPath.path(), + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + + QDBusReply reply = + userPertyInterface.call("Get", "org.freedesktop.login1.User", "State"); + if (reply.isValid()) { + QString status = reply.value().toString(); + if ("closing" != status) { + m_loginedUser.append(user.usersName); + } + } + } + return m_loginedUser; +} + +QDBusArgument &operator <<(QDBusArgument &arg, const usersInfo &userInfo) +{ + arg.beginStructure(); + arg << userInfo.usersId + << userInfo.usersName + << userInfo.usersPath; + arg.endStructure(); + return arg; +} +const QDBusArgument &operator >>(const QDBusArgument &arg, usersInfo &userInfo) +{ + arg.beginStructure(); + arg >> userInfo.usersId + >> userInfo.usersName + >> userInfo.usersPath; + arg.endStructure(); + return arg; +} + +void PowerManager::powerClicked(QListWidgetItem *item) +{ + int interval = lasttime.msecsTo(QTime::currentTime()); + if(interval < 200 && interval > -200) + return ; + lasttime = QTime::currentTime(); + + QString name = itemWidget(item)->objectName(); + printf("111111111111111111111111111 name = %s\n",name.toLatin1().data()); +// if(name == lockWidget->objectName()) +// lockWidgetClicked(); + if(switchWidget && name == switchWidget->objectName()) + switchWidgetClicked(); + else if(name == logoutWidget->objectName()) + logoutWidgetCliced(); + else if(name == rebootWidget->objectName()) + rebootWidgetClicked(); + else if(name == shutdownWidget->objectName()) + shutdownWidgetClicked(); + else if(suspendWidget && name == suspendWidget->objectName()) + suspendWidgetClicked(); + else if(hibernateWidget && name == hibernateWidget->objectName()) + hibernateWidgetClicked(); +} +#endif + +void PowerManager::lockWidgetClicked() +{ + emit lock(); +} + +void PowerManager::switchWidgetClicked() +{ + emit switchToUser(); +} + +#ifdef USE_INTEL +void PowerManager::shutdownWidgetClicked() +{ + QDBusInterface *interface = new QDBusInterface("org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + QDBusConnection::sessionBus(), + this); + + QDBusMessage msg = interface->call("powerOff"); + qDebug() << "[PowerManager] [shutdownWidgetClicked]" << msg.errorMessage(); +} + +void PowerManager::rebootWidgetClicked() +{ + QDBusInterface *interface = new QDBusInterface("org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + QDBusConnection::sessionBus(), + this); + + QDBusMessage msg = interface->call("reboot"); + qDebug() << "[PowerManager] [rebootWidgetClicked]" << msg.errorMessage(); +} + +void PowerManager::logoutWidgetCliced() +{ + QDBusInterface *interface = new QDBusInterface("org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + QDBusConnection::sessionBus(), + this); + + QDBusMessage msg = interface->call("logout"); + qDebug() << "[PowerManager] [logoutWidgetCliced]" << msg.errorMessage(); +} + +void PowerManager::initUI() +{ + this->setContentsMargins(0,0,0,0); + QHBoxLayout *main_layout = new QHBoxLayout(this); + main_layout->setContentsMargins(0,0,0,0); + main_layout->setSpacing(0); + + lockWidget = new QWidget(this); + lockWidget->setContentsMargins(0,0,0,0); + lockWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + QPushButton *lockPB = new QPushButton(lockWidget); + QLabel *lockLabel = new QLabel(lockWidget); + lockPB->setProperty("class", "PowerManagerPB"); + lockPB->setIcon(QIcon(QPixmap(":/image/assets/intel/lock.png").scaled(40,40))); + lockLabel->setAlignment(Qt::AlignBottom | Qt::AlignHCenter); + lockLabel->setText(tr("lock")); + QVBoxLayout *locklayout = new QVBoxLayout(lockWidget); + locklayout->setContentsMargins(0,0,0,0); + locklayout->addWidget(lockPB); + locklayout->addWidget(lockLabel); + connect(lockPB, &QPushButton::clicked, this, [=]{ + qDebug() << "PowerManager lock clicked"; + Q_EMIT lock(); + }); + + logoutWidget = new QWidget(this); + logoutWidget->setContentsMargins(0,0,0,0); + logoutWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + QPushButton *logoutPB = new QPushButton(logoutWidget); + QLabel *logoutLabel = new QLabel(this); + logoutPB->setProperty("class", "PowerManagerPB"); + logoutPB->setIcon(QIcon(QPixmap(":/image/assets/intel/logout.png").scaled(40,40))); + logoutLabel->setText(tr("Log Out")); + logoutLabel->setAlignment(Qt::AlignBottom | Qt::AlignHCenter); + QVBoxLayout *logoutlayout = new QVBoxLayout(logoutWidget); + logoutlayout->setContentsMargins(0,0,0,0); + logoutlayout->addWidget(logoutPB); + logoutlayout->addWidget(logoutLabel); + connect(logoutPB, &QPushButton::clicked, this, [=]{ + qDebug() << "PowerManager logout clicked"; + logoutWidgetCliced();; + }); + + rebootWidget = new QWidget(this); + rebootWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + rebootWidget->setContentsMargins(0,0,0,0); + QPushButton *rebootPB = new QPushButton(rebootWidget); + QLabel *rebootLabel = new QLabel(this); + rebootPB->setProperty("class", "PowerManagerPB"); + rebootPB->setIcon(QIcon(QPixmap(":/image/assets/intel/reboot.png").scaled(40,40))); + rebootLabel->setText(tr("Restart")); + rebootLabel->setAlignment(Qt::AlignBottom | Qt::AlignHCenter); + + QVBoxLayout *rebootlayout = new QVBoxLayout(rebootWidget); + rebootlayout->setContentsMargins(0,0,0,0); + rebootlayout->addWidget(rebootPB); + rebootlayout->addWidget(rebootLabel); + connect(rebootPB, &QPushButton::clicked, this, [=]{ + qDebug() << "PowerManager reboot clicked"; + //rebootWidgetClicked(); + reboot(); + }); + + shutdownWidget = new QWidget(this); + shutdownWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + shutdownWidget->setObjectName("shutdownWidget"); + QPushButton *shutdownPB = new QPushButton(shutdownWidget); + QLabel *shutdownLabel = new QLabel(shutdownWidget); + shutdownPB->setProperty("class", "PowerManagerPB"); + shutdownPB->setIcon(QIcon(QPixmap(":/image/assets/intel/shutdown.png").scaled(40,40))); + shutdownLabel->setText(tr("Power Off")); + shutdownLabel->setAlignment(Qt::AlignBottom | Qt::AlignHCenter); + QVBoxLayout *shutdownlayout = new QVBoxLayout(shutdownWidget); + shutdownlayout->setContentsMargins(0,0,0,0); + shutdownlayout->addWidget(shutdownPB); + shutdownlayout->addWidget(shutdownLabel); + connect(shutdownPB, &QPushButton::clicked, this, [=]{ + qDebug() << "PowerManager shutdown clicked"; + //shutdownWidgetClicked(); + powerOff(); + }); + + main_layout->addWidget(lockWidget); + main_layout->addSpacing(ITEM_SPACING); + main_layout->addWidget(logoutWidget); + main_layout->addSpacing(ITEM_SPACING); + main_layout->addWidget(rebootWidget); + main_layout->addSpacing(ITEM_SPACING); + main_layout->addWidget(shutdownWidget); + adjustSize(); +} + +//息屏,休眠状态Hibernate/挂起Suspend +bool PowerManager::hibernate() +{ + const QString service = "org.freedesktop.login1"; + const QString path = "/org/freedesktop/login1"; + const QString interface = "org.freedesktop.login1.Manager"; + QString command = QLatin1String("Suspend"); + + QDBusInterface dbus(service, path, interface, QDBusConnection::systemBus()); + if (!dbus.isValid()) { + qWarning() << "dbusCall: QDBusInterface is invalid" << service<< path + << interface << "Suspend"; + return false; + } + QDBusMessage msg = dbus.call(command, QVariant(true)); + + if (!msg.errorName().isEmpty()) { + qWarning() << "Debus error: " << msg; + } + + if (msg.arguments().isEmpty() || msg.arguments().constFirst().isNull()) + return true; + + QString response = msg.arguments().constFirst().toString(); + qDebug() << "systemd:" << QLatin1String("Suspend") << "=" << response; + return response == QLatin1String("yes") || response == QLatin1String("challenge"); +} + +bool PowerManager::reboot() +{ + const QString service = "org.freedesktop.login1"; + const QString path = "/org/freedesktop/login1"; + const QString interface = "org.freedesktop.login1.Manager"; + QString command = QLatin1String("Reboot"); + + QDBusInterface dbus(service, path, interface, QDBusConnection::systemBus()); + if (!dbus.isValid()) { + qWarning() << "dbusCall: QDBusInterface is invalid" << service<< path + << interface << "Reboot"; + return false; + } + QDBusMessage msg = dbus.call(command, QVariant(true)); + + if (!msg.errorName().isEmpty()) { + qWarning() << "Debus error: " << msg; + } + + if (msg.arguments().isEmpty() || msg.arguments().constFirst().isNull()) + return true; + + QString response = msg.arguments().constFirst().toString(); + qDebug() << "systemd:" << QLatin1String("Reboot") << "=" << response; + return response == QLatin1String("yes") || response == QLatin1String("challenge"); +} + +bool PowerManager::powerOff() +{ + const QString service = "org.freedesktop.login1"; + const QString path = "/org/freedesktop/login1"; + const QString interface = "org.freedesktop.login1.Manager"; + QString command = QLatin1String("PowerOff"); + + QDBusInterface dbus(service, path, interface, QDBusConnection::systemBus()); + if (!dbus.isValid()) { + qWarning() << "dbusCall: QDBusInterface is invalid" << service<< path + << interface << "PowerOff"; + return false; + } + QDBusMessage msg = dbus.call(command, QVariant(true)); + + if (!msg.errorName().isEmpty()) { + qWarning() << "Debus error: " << msg; + } + + if (msg.arguments().isEmpty() || msg.arguments().constFirst().isNull()) + return true; + + QString response = msg.arguments().constFirst().toString(); + qDebug() << "systemd:" << QLatin1String("PowerOff") << "=" << response; + return response == QLatin1String("yes") || response == QLatin1String("challenge"); +} + +void PowerManager::setQSS() +{ + //设置电源管理按键样式 + QString style_sheet = ".PowerManagerPB{" + "background:rgba(255,255,255,38);" + "min-width: 128px;" + "max-width: 128px;" + "min-height: 128px;" + "max-height: 128px;" + "border-radius: 64px;" + "icon-size: 40px;" + "font-family: NotoSansCJKsc-Regular, NotoSansCJKsc;" + "}" + ".PowerManagerPB:hover{" + "background:rgba(255,255,255,89);" + "}" + ".PowerManagerPB:pressed{" + "background:rgba(255,255,255,12);" + "}"; + setStyleSheet(style_sheet); +} +#else + +void PowerManager::doEvent(int type) +{ + switch (type) { + case REBOOT: + sessionInterface->call("reboot"); + break; + case SHOTDOWN: + sessionInterface->call("powerOff"); + default: + break; + } +} + +void PowerManager::suspendWidgetClicked() +{ + loginInterface->call("Suspend",true); + emit lock(); +} + +void PowerManager::hibernateWidgetClicked() +{ + loginInterface->call("Hibernate",true); + emit lock(); +} + +void PowerManager::shutdownWidgetClicked() +{ + if(getLoginedUsers().count() > 1){ + Q_EMIT mulUsersLogined(SHOTDOWN); + return; + } + sessionInterface->call("powerOff"); +} + +void PowerManager::rebootWidgetClicked() +{ + if(getLoginedUsers().count() > 1){ + Q_EMIT mulUsersLogined(REBOOT); + return; + } + sessionInterface->call("reboot"); +} + +void PowerManager::logoutWidgetCliced() +{ + sessionInterface->call("logout"); +} + +void PowerManager::showSmallSize() +{ + for(int i = 0;iitem(i); + item->setSizeHint(QSize(ITEM_WIDTH*0.8,ITEM_HEIGHT)); + itemWidget(item)->setFixedSize(ITEM_WIDTH*0.8,ITEM_HEIGHT); + } + resize(ITEM_WIDTH*this->count()*0.8,ITEM_HEIGHT); +} + +void PowerManager::showNormalSize() +{ + for(int i = 0;iitem(i); + item->setSizeHint(QSize(ITEM_WIDTH,ITEM_HEIGHT)); + itemWidget(item)->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + } + // resize(ITEM_WIDTH*this->count(),ITEM_HEIGHT); + // resize((ITEM_WIDTH+ITEM_SPACING)*this->count(), ITEM_HEIGHT+ITEM_SPACING); + resize((ITEM_WIDTH+ITEM_SPACING*2)*this->count()-ITEM_SPACING*2, ITEM_HEIGHT+ITEM_SPACING*2); +} + +void PowerManager::initUI() +{ + setSpacing(30); + +// actService = new QDBusInterface("org.freedesktop.Accounts", +// "/org/freedesktop/Accounts", +// "org.freedesktop.Accounts", +// QDBusConnection::systemBus()); + +// QDBusMessage ret = actService->call("ListCachedUsers"); +// QList outArgs = ret.arguments(); +// QVariant first = outArgs.at(0); +// const QDBusArgument &dbusArgs = first.value(); +// dbusArgs.beginArray(); +// QDBusObjectPath path; +// int userCount =0; +// while (!dbusArgs.atEnd()) +// { +// userCount++; +// dbusArgs >> path; +// } +// dbusArgs.endArray(); +// switchWidget=nullptr; +// if(userCount>1){ +// switchWidget = new QWidget(this); +// switchWidget->setObjectName("switchWidget"); +// QLabel *switchFace = new QLabel(switchWidget); +// QLabel *switchLabel = new QLabel(switchWidget); +// switchFace->setAlignment(Qt::AlignCenter); +// switchFace->setObjectName("switchFace"); +// switchFace->installEventFilter(this); +// switchLabel->setAlignment(Qt::AlignCenter); +// switchFace->setPixmap(QPixmap(":/image/assets/switchGreeter.png").scaled(58,58)); +// switchLabel->setText(tr("Switch User")); +// switchWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); +// QVBoxLayout *switchlayout = new QVBoxLayout(switchWidget); +// switchlayout->addWidget(switchFace); +// switchlayout->addWidget(switchLabel); +// // switchWidget->installEventFilter(this); +// } +// logoutWidget = new QWidget(this); +// logoutWidget->setObjectName("logoutWidget"); +// QLabel *logoutFace = new QLabel(this); +// QLabel *logoutLabel = new QLabel(this); +// logoutFace->setAlignment(Qt::AlignCenter); +// logoutFace->setObjectName("logoutFace"); +// logoutFace->installEventFilter(this); +// logoutLabel->setAlignment(Qt::AlignCenter); +// logoutFace->setPixmap(QPixmap(":/image/assets/logout.png").scaled(48,48)); +// logoutLabel->setText(tr("Log Out")); +// logoutWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); +// QVBoxLayout *logoutlayout = new QVBoxLayout(logoutWidget); +// logoutlayout->addWidget(logoutFace); +// logoutlayout->addWidget(logoutLabel); + //logoutWidget->installEventFilter(this); + + rebootWidget = new QWidget(this); + rebootWidget->setObjectName("rebootWidget"); + QWidget *rbLabelWidget = new QWidget(this); + rbLabelWidget->setFixedSize(130, 130); + rebootFace = new QLabel(rbLabelWidget); + rebootFace->setObjectName("rebootFace"); + QLabel *rebootLabel = new QLabel(this); + rebootFace->setAlignment(Qt::AlignCenter); + rebootFace->installEventFilter(this); + rebootLabel->setAlignment(Qt::AlignCenter); + rebootFace->setPixmap(QPixmap(":/image/assets/reboot.png").scaled(58,58)); + rebootLabel->setText(tr("Restart")); + rebootWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + QVBoxLayout *rebootlayout = new QVBoxLayout(rebootWidget); + rebootlayout->addWidget(rbLabelWidget); + rebootlayout->addWidget(rebootLabel); + //rebootWidget->installEventFilter(this); + + shutdownWidget = new QWidget(this); + shutdownWidget->setObjectName("shutdownWidget"); + QWidget *shLabelWidget = new QWidget(this); + shLabelWidget->setFixedSize(130, 130); + shutdownFace = new QLabel(shLabelWidget); + shutdownFace->setObjectName("shutdownFace"); + QLabel *shutdownLabel = new QLabel(this); + shutdownLabel->setAlignment(Qt::AlignCenter); + shutdownFace->setAlignment(Qt::AlignCenter); + shutdownFace->installEventFilter(this); + shutdownFace->setPixmap(QPixmap(":/image/assets/shutdown.png").scaled(58,58)); + shutdownLabel->setText(tr("Shut Down")); + shutdownWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + QVBoxLayout *shutdownlayout = new QVBoxLayout(shutdownWidget); + shutdownlayout->addWidget(shLabelWidget); + shutdownlayout->addWidget(shutdownLabel); + //shutdownWidget->installEventFilter(this); + +// if(userCount>1){ +// QListWidgetItem *item1 = new QListWidgetItem(); +// item1->setSizeHint(QSize(ITEM_WIDTH, ITEM_HEIGHT)); +// insertItem(this->count(), item1); +// setItemWidget(item1, switchWidget); +// } + hibernateWidget = nullptr; + if(canHibernate){ + hibernateWidget = new QWidget(this); + hibernateWidget->setObjectName("hibernateWidget"); + QWidget *hbLabelWidget = new QWidget(this); + hbLabelWidget->setFixedSize(130, 130); + hibernateFace = new QLabel(hbLabelWidget); + hibernateFace->setObjectName("hibernateFace"); + QLabel *hibernateLabel = new QLabel(this); + hibernateLabel->setAlignment(Qt::AlignCenter); + hibernateFace->setAlignment(Qt::AlignCenter); + hibernateFace->installEventFilter(this); + hibernateFace->setPixmap(QPixmap(":/image/assets/hibernate.png").scaled(48,48)); + hibernateLabel->setText(tr("Hibernate")); + hibernateWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + QVBoxLayout *hibernatelayout = new QVBoxLayout(hibernateWidget); + hibernatelayout->addWidget(hbLabelWidget); + hibernatelayout->addWidget(hibernateLabel); + //hibernateWidget->installEventFilter(this); + + QListWidgetItem *item5 = new QListWidgetItem(); + item5->setSizeHint(QSize(ITEM_WIDTH, ITEM_HEIGHT)); + insertItem(this->count(), item5); + setItemWidget(item5, hibernateWidget); + listLabel.append(hibernateFace); + } + + suspendWidget = nullptr; + if(canSuspend){ + suspendWidget = new QWidget(this); + suspendWidget->setObjectName("suspendWidget"); + QWidget *spLabelWidget = new QWidget(this); + spLabelWidget->setFixedSize(130, 130); + suspendFace = new QLabel(spLabelWidget); + suspendFace->setObjectName("suspendFace"); + QLabel *suspendLabel = new QLabel(this); + suspendLabel->setAlignment(Qt::AlignCenter); + suspendFace->setAlignment(Qt::AlignCenter); + suspendFace->installEventFilter(this); + suspendFace->setPixmap(QPixmap(":/image/assets/suspend.png").scaled(48,48)); + suspendLabel->setText(tr("Suspend")); + suspendWidget->setFixedSize(ITEM_WIDTH,ITEM_HEIGHT); + QVBoxLayout *suspendlayout = new QVBoxLayout(suspendWidget); + suspendlayout->addWidget(spLabelWidget); + suspendlayout->addWidget(suspendLabel); + //suspendWidget->installEventFilter(this); + + QListWidgetItem *item4 = new QListWidgetItem(); + item4->setSizeHint(QSize(ITEM_WIDTH, ITEM_HEIGHT)); + insertItem(this->count(), item4); + setItemWidget(item4, suspendWidget); + listLabel.append(suspendFace); + } + +// QListWidgetItem *item1 = new QListWidgetItem(); +// item1->setSizeHint(QSize(ITEM_WIDTH, ITEM_HEIGHT)); +// insertItem(this->count(), item1); +// setItemWidget(item1, logoutWidget); + + QListWidgetItem *item2 = new QListWidgetItem(); + item2->setSizeHint(QSize(ITEM_WIDTH, ITEM_HEIGHT)); + insertItem(this->count(), item2); + setItemWidget(item2, rebootWidget); + listLabel.append(rebootFace); + + QListWidgetItem *item3 = new QListWidgetItem(); + item3->setSizeHint(QSize(ITEM_WIDTH, ITEM_HEIGHT)); + insertItem(this->count(), item3); + setItemWidget(item3, shutdownWidget); + listLabel.append(shutdownFace); +} +#endif diff --git a/src/powermanager.h b/src/powermanager.h new file mode 100644 index 0000000..3a4a1ee --- /dev/null +++ b/src/powermanager.h @@ -0,0 +1,135 @@ + /* + * Copyright (C) 2018 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 . + * + **/ + +#ifndef POWERMANAGER_H +#define POWERMANAGER_H +#include +#include +#include +#include +#include "config.h" +#include "xeventmonitor.h" +#ifdef USE_INTEL +#define ITEM_WIDTH 128 +#define ITEM_HEIGHT (ITEM_WIDTH + 40) +#define ITEM_SPACING 72 + +class QWidget; +class PowerManager:public QWidget +#else +#define ITEM_WIDTH 144 +#define ITEM_HEIGHT 200 +#define ITEM_SPACING 30 + +enum stateType { + REBOOT, + SHOTDOWN, + NOTHING +}; + +struct usersInfo { + int usersId; + QString usersName; + QDBusObjectPath usersPath; +}; + +QDBusArgument &operator <<(QDBusArgument &arg, const usersInfo &userInfo); +const QDBusArgument &operator >>(const QDBusArgument &arg, usersInfo &userInfo); + +class QLabel; +class QListWidget; +class QListWidgetItem; +class QDBusInterface; +class PowerManager:public QListWidget +#endif +{ + Q_OBJECT + +public: + PowerManager(QWidget *parent = 0); +#ifdef USE_INTEL + bool hibernate(); +#else + void showNormalSize(); + void showSmallSize(); + void doEvent(int type); +#endif +private: + void initUI(); + +#ifdef USE_INTEL + void setQSS(); + QWidget *list; +#else + QList listLabel; + int nowAt = -1; + QListWidget *list; + QWidget *suspendWidget; + QWidget *hibernateWidget; + QDBusInterface *sessionInterface; + QDBusInterface *loginInterface; + QDBusInterface *actService; + int login_Num; + + bool canSuspend; + bool canHibernate; + int m_count; +#endif + QWidget *lockWidget; + QWidget *switchWidget; + QWidget *logoutWidget; + QWidget *rebootWidget; + QWidget *shutdownWidget; + QTime lasttime; + XEventMonitor *xEventMonitor; + QLabel *rebootFace; + QLabel *shutdownFace; + QLabel *hibernateFace; + QLabel *suspendFace; + +private: + void lockWidgetClicked(); + void switchWidgetClicked(); + void logoutWidgetCliced(); + void rebootWidgetClicked(); + QStringList getLoginedUsers(); + void shutdownWidgetClicked(); + void keyBdRelease(QString key); + void setButtonStyle(QString Style); +#ifdef USE_INTEL + bool reboot(); + bool powerOff(); +#else + void suspendWidgetClicked(); + void hibernateWidgetClicked(); +#endif +private Q_SLOTS: +#ifndef USE_INTEL + void powerClicked(QListWidgetItem *item); + bool eventFilter(QObject *obj, QEvent *event); + void onGlobalKeyPress(const QString &key); + void onGlobalkeyRelease(const QString &key); + void keyboardPressed(QListWidgetItem *item,QListWidgetItem*); +#endif +Q_SIGNALS: + void switchToUser(); + void lock(); + void mulUsersLogined(int type); +}; + +#endif // POWERMANAGER_H diff --git a/src/screensaver.cpp b/src/screensaver.cpp new file mode 100644 index 0000000..744d33b --- /dev/null +++ b/src/screensaver.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "screensaver.h" +#include +#include +#include + +ScreenSaver::ScreenSaver(QObject *parent) + : QObject(parent), + imageIndex(0), + timer(nullptr) +{ + +} + +ScreenSaver::ScreenSaver(const ScreenSaver &screensaver) + : mode(screensaver.mode), + path(screensaver.path), + effect(screensaver.effect), + interval(screensaver.interval), + imageIndex(screensaver.imageIndex), + timer(screensaver.timer), + imagePaths(screensaver.imagePaths) +{ +} + + +ScreenSaver::ScreenSaver(ScreenSaver &&screensaver) noexcept + : mode(screensaver.mode), + path(screensaver.path), + effect(screensaver.effect), + interval(screensaver.interval), + imageIndex(screensaver.imageIndex), + timer(screensaver.timer), + imagePaths(screensaver.imagePaths) +{ +} + +bool ScreenSaver::exists() +{ + switch(mode) + { + case SAVER_BLANK_ONLY: + return true; + case SAVER_RANDOM: + case SAVER_SINGLE: + return QFile(path).exists(); + case SAVER_IMAGE: + return QDir(path).exists(); + case SAVER_DEFAULT: + return QDir(path).exists(); + case SAVER_DEFAULT_CUSTOM: + return QDir(path).exists(); + default: + return false; + } + return false; +} + +void ScreenSaver::startSwitchImages() +{ + qDebug() << "ScreenSaver::startSwitchImages"; + if(mode != SAVER_IMAGE) + return; + QFileInfo fileInfo(path); + if(fileInfo.isFile()) + return; + QList formats = QImageReader::supportedImageFormats(); + if(fileInfo.isDir()) { + QDir dir(path); + QStringList files = dir.entryList(QDir::Files | QDir::Readable); + for(QString file : files) { + fileInfo.setFile(file); + QString suffix = fileInfo.suffix(); + if(formats.contains(suffix.toUtf8())) + imagePaths.push_back(path + "/" + file); + } + if(!imagePaths.empty()) { + path = imagePaths[0]; + timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, [&]{ + imageIndex = (imageIndex + 1) % imagePaths.size(); + path = imagePaths[imageIndex]; + lastPath = imagePaths[imageIndex - 1 < 0 ? imagePaths.size() - 1 : imageIndex - 1]; + Q_EMIT imagePathChanged(path); + }); + timer->start(interval * 1000); + Q_EMIT imagePathChanged(path); + } + } +} + +void ScreenSaver::stopSwitchImages() +{ + if(timer && timer->isActive()) + timer->stop(); +} + +bool ScreenSaver::timerStatus() +{ + return timer->isActive(); +} + +QDebug &operator<<(QDebug debug, const ScreenSaver &screensaver) +{ + QString modes[] = {"blank-only", "random", "single", "image","default-ukui","default-ukui-custom"}; + QString effects[] = {"none", "fade-in-out"}; + debug.nospace()<< "screensaver: "<< modes[screensaver.mode]; + switch(screensaver.mode) { + case SAVER_BLANK_ONLY: + break; + case SAVER_RANDOM: + case SAVER_SINGLE: + debug.nospace() << screensaver.path; + break; + case SAVER_IMAGE: + debug.nospace() << screensaver.path << effects[screensaver.effect] << screensaver.interval; + case SAVER_DEFAULT: + debug.nospace() << screensaver.path << effects[screensaver.effect] << screensaver.interval; + case SAVER_DEFAULT_CUSTOM: + debug.nospace() << screensaver.path << effects[screensaver.effect] << screensaver.interval; + default: + debug.nospace() <<"screensaver path not exists"; + } + + return debug.maybeSpace(); +} + diff --git a/src/screensaver.h b/src/screensaver.h new file mode 100644 index 0000000..d3f2ad3 --- /dev/null +++ b/src/screensaver.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef SCREENSAVER_H +#define SCREENSAVER_H + +#include +#include +#include + +enum SaverMode +{ + SAVER_BLANK_ONLY = 0, + SAVER_RANDOM, + SAVER_SINGLE, + SAVER_IMAGE, + SAVER_DEFAULT, + SAVER_DEFAULT_CUSTOM +}; + +enum TransitionEffect +{ + TRANSITION_NONE, + TRANSITION_FADE_IN_OUT +}; + +class ScreenSaver : public QObject +{ + Q_OBJECT +public: + SaverMode mode; + //path is a directory or a file path if mode is SAVER_IMAGE + QString path; + QString lastPath; + + //for images saver + TransitionEffect effect; + int interval; + +private: + int imageIndex; + QTimer *timer; + QStringList imagePaths; + +Q_SIGNALS: + void imagePathChanged(const QString &path); + +public: + explicit ScreenSaver( QObject *parent=nullptr); + explicit ScreenSaver(const ScreenSaver &screensaver); + ScreenSaver(ScreenSaver &&screensaver) noexcept; + bool exists(); + void startSwitchImages(); + void stopSwitchImages(); + bool timerStatus(); + friend QDebug &operator<<(QDebug stream, const ScreenSaver &screensaver); +}; + +Q_DECLARE_METATYPE(ScreenSaver) + +QDebug &operator<<(QDebug stream, const ScreenSaver &screensaver); + +#endif // SCREENSAVER_H diff --git a/src/screensaverwidget.cpp b/src/screensaverwidget.cpp new file mode 100644 index 0000000..e194c54 --- /dev/null +++ b/src/screensaverwidget.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "screensaverwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +ScreenSaverWidget::ScreenSaverWidget(ScreenSaver *screensaver, QWidget *parent) + : QWidget(parent), + timer(nullptr), + screensaver(screensaver), + closing(false) +{ + qDebug() << "ScreenSaverWidget::ScreenSaverWidget"; + setMouseTracking(true); + setFocus(); + this->installEventFilter(this); + + QPalette pal(palette()); + pal.setColor(QPalette::Background, Qt::black); //设置背景黑色 + setAutoFillBackground(true); + setPalette(pal); + + switch(screensaver->mode) { + case SAVER_RANDOM: + case SAVER_SINGLE: + embedXScreensaver(screensaver->path); + break; + case SAVER_BLANK_ONLY: + break; + case SAVER_IMAGE: + { + setAutoFillBackground(true); + screensaver->startSwitchImages(); + + QPalette plt; + plt.setBrush(QPalette::Background, Qt::black); + setPalette(plt); + + connect(screensaver, &ScreenSaver::imagePathChanged, + this, &ScreenSaverWidget::onBackgroundChanged); + break; + } + case SAVER_DEFAULT: + embedXScreensaver(screensaver->path); + break; + case SAVER_DEFAULT_CUSTOM: + embedXScreensaver(screensaver->path); + break; + default: + break; + } + + show(); +} + +ScreenSaverWidget::~ScreenSaverWidget() +{ + +} + +void ScreenSaverWidget::closeEvent(QCloseEvent *event) +{ + qDebug() << "ScreenSaverWidget::closeEvent---beginStop"; + if(process.state() != QProcess::NotRunning) + process.kill(); + + if(!closing){ + closing = true; + screensaver->stopSwitchImages(); + delete screensaver; + if(timer && timer->isActive()) + timer->stop(); + } + qDebug() << "ScreenSaverWidget::closeEvent---endStop"; + return QWidget::closeEvent(event); +} + +void ScreenSaverWidget::paintEvent(QPaintEvent *event) +{ + if(!screensaver->exists()) + { + QPainter painter(this); + painter.fillRect(geometry(), Qt::black); + } + if(screensaver->mode == SAVER_IMAGE) { + switch(screensaver->effect) { + case TRANSITION_NONE: + { + QPixmap pixmap(screensaver->path); + pixmap.scaled(size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + QPainter painter(this); + painter.drawPixmap(geometry(), pixmap); + break; + } + case TRANSITION_FADE_IN_OUT: + { + QPainter painter(this); + QPixmap pixmap1(screensaver->lastPath); + pixmap1.scaled(size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + painter.setOpacity(opacity); + painter.drawPixmap(geometry(), pixmap1); + + QPixmap pixmap(screensaver->path); + pixmap.scaled(size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + painter.setOpacity(1 - opacity); + painter.drawPixmap(geometry(), pixmap); + break; + } + } + + + } + return QWidget::paintEvent(event); +} + +bool ScreenSaverWidget::eventFilter(QObject *obj, QEvent *event) +{ + if(event->type() == 23) + { + XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + } + return false; +} + +/* Embed xscreensavers */ +void ScreenSaverWidget::embedXScreensaver(const QString &path) +{ + QString cmd = path + " -window-id " + QString::number(winId()); + if(process.state() == QProcess::NotRunning) + process.start(cmd); +} + + + +void ScreenSaverWidget::onBackgroundChanged(const QString &/*path*/) +{ + switch(screensaver->effect) { + case TRANSITION_NONE: + repaint(); + break; + case TRANSITION_FADE_IN_OUT: + opacity = 1.0; + timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, [&]{ + opacity -= 0.1; + if(opacity <= 0) + timer->stop(); + else + repaint(); + + }); + timer->start(50); + break; + } +} + diff --git a/src/screensaverwidget.h b/src/screensaverwidget.h new file mode 100644 index 0000000..a76d428 --- /dev/null +++ b/src/screensaverwidget.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef SCREENSAVERWIDGET_H +#define SCREENSAVERWIDGET_H + +#include +#include +#include "screensaver.h" + +class ScreenSaverWidget : public QWidget +{ + Q_OBJECT +public: + ScreenSaverWidget(ScreenSaver *screensaver, + QWidget *parent = nullptr); + ~ScreenSaverWidget() ; + +protected: + void closeEvent(QCloseEvent *); + void paintEvent(QPaintEvent *event); + bool eventFilter(QObject *obj, QEvent *event); +private: + void embedXScreensaver(const QString &path); + +private Q_SLOTS: + void onBackgroundChanged(const QString &path); + +private: + QTimer *timer; + ScreenSaver *screensaver; + bool closing; + float opacity; + QProcess process; +}; + +#endif // SCREENSAVERWIDGET_H diff --git a/src/sessionwatcher.cpp b/src/sessionwatcher.cpp new file mode 100644 index 0000000..c97d7b8 --- /dev/null +++ b/src/sessionwatcher.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "sessionwatcher.h" +#include +#include +#include +#include "types.h" + +#define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" +#define KEY_IDLE_DELAY "idleDelay" +#define KEY_IDLE_LOCK "idleLock" +#define KEY_IDLE_ACTIVATION_ENABLED "idleActivationEnabled" +#define KEY_IDLE_LOCK_ENABLED "idleLockEnabled" +#define TIME_TYPE_SCHEMA "org.ukui.control-center.panel.plugins" + +SessionWatcher::SessionWatcher(QObject *parent) : QObject(parent) +{ + sessionPath = qgetenv("XDG_SESSION_PATH"); + + QDBusInterface *interface = new QDBusInterface( + SM_DBUS_SERVICE, + SM_DBUS_PATH, + SM_DBUS_INTERFACE, + QDBusConnection::sessionBus()); + + connect(interface, SIGNAL(StatusChanged(unsigned int)), + this, SLOT(onStatusChanged(unsigned int))); + + QDBusInterface *displayManagerInterface = new QDBusInterface( + DM_DBUS_SERVICE, + DM_DBUS_PATH, + DM_DBUS_INTERFACE, + QDBusConnection::systemBus()); + connect(displayManagerInterface, SIGNAL(SessionRemoved(QDBusObjectPath)), + this, SLOT(onSessionRemoved(QDBusObjectPath))); + + settings_delay = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); + connect(settings_delay, &QGSettings::changed, + this, &SessionWatcher::onConfigurationDelayChanged); + idleDelay = settings_delay->get("idle-delay").toInt(); + + settings_lock = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); + connect(settings_lock, &QGSettings::changed, + this, &SessionWatcher::onConfigurationLockChanged); + idleLock = settings_lock->get("idle-lock").toInt(); + + QString userName = getenv("USER"); + QString configPath; + configPath = QString("/var/lib/lightdm-data/%1/ukui-greeter.conf").arg(userName); + QFile fileConf(configPath); + if (!fileConf.exists()) { + QFile file(configPath); + file.setPermissions(QFile::WriteUser | QFile::ReadUser | QFile::WriteOther | QFile::ReadOther); + } + configSettings = new QSettings(configPath, QSettings::IniFormat, this); + if(QGSettings::isSchemaInstalled(TIME_TYPE_SCHEMA)) + timegsettings = new QGSettings(TIME_TYPE_SCHEMA,"",this); + int timeType = timegsettings->get("hoursystem").toInt(); + setValue("timeType",timeType); + QString dateType = timegsettings->get("date").toString(); + setValue("dateType",dateType); + connect(timegsettings, &QGSettings::changed, + this, &SessionWatcher::onConfigurationTimeTpChanged); + +// activationEnabled_Key = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); +// connect(activationEnabled_Key, &QGSettings::changed, +// this, &SessionWatcher::activationEnabledChanged); +// idleActivationEnabled = activationEnabled_Key->get("idle-activation-enabled").toBool(); + +// lockEnabled_Key = new QGSettings(GSETTINGS_SCHEMA_SCREENSAVER, "", this); +// connect(lockEnabled_Key, &QGSettings::changed, +// this, &SessionWatcher::lockEnabledChanged); +// lockEnabled = lockEnabled_Key->get("idle-lock-enabled").toBool(); +// qDebug()<get("idle-delay").toInt(); + } +} + +void SessionWatcher::onConfigurationLockChanged(QString key) +{ + if(key == KEY_IDLE_LOCK){ + idleLock = settings_lock->get("idle-lock").toInt(); + } +} + +void SessionWatcher::onConfigurationTimeTpChanged(QString key) +{ + if(key == "hoursystem"){ + int timeType = timegsettings->get("hoursystem").toInt(); + setValue("timeType",timeType); + } + if(key == "date"){ + qDebug()<<"jinlaile~~~~~~~~~~~~~~key="<get("date").toString(); + qDebug()<<"lsadjfldsa"<beginGroup("Greeter"); + configSettings->setValue(key, value); + configSettings->endGroup(); +} + +//void SessionWatcher::activationEnabledChanged(QString key) +//{ +// if(key == KEY_IDLE_ACTIVATION_ENABLED){ +// idleActivationEnabled = activationEnabled_Key->get("idle-activation-enabled").toBool(); +// } +//} + +//void SessionWatcher::lockEnabledChanged(QString key) +//{ +// if(key == KEY_IDLE_LOCK_ENABLED){ +// lockEnabled = lockEnabled_Key->get("idle-lock-enabled").toBool(); +// } +//} + +void SessionWatcher::onStatusChanged(unsigned int status) +{ + if(status == SESSION_IDLE) { + if(idleDelay != -1){ + if(!m_timer){ + m_timer = new QTimer(this); + connect(m_timer, &QTimer::timeout, this, [&]{ + Q_EMIT sessionIdle(); + m_timer->stop(); + }); + } + int time = (idleDelay - 1)*60000; + if(time<0) + time = 0; + + m_timer->start(time); + } + + if(idleLock != -1){ + if(!m_timer2){ + m_timer2 = new QTimer(this); + connect(m_timer2, &QTimer::timeout, this, [&]{ + Q_EMIT sessionLockIdle(); + m_timer2->stop(); + }); + } + int lockTime = (idleLock - 1)*60000; + if(lockTime<0) + lockTime = 0; + + m_timer2->start(lockTime); + } + + + }else if(status == SESSION_AVAILABLE){ + if(m_timer && m_timer->isActive()){ + m_timer->stop(); + } + if(m_timer2 && m_timer2->isActive()){ + m_timer2->stop(); + } + } +} + +void SessionWatcher::onSessionRemoved(const QDBusObjectPath &objectPath) +{ + //如果session注销了,则结束进程 + if(objectPath.path() == sessionPath) + exit(0); +} diff --git a/src/sessionwatcher.h b/src/sessionwatcher.h new file mode 100644 index 0000000..9b202d1 --- /dev/null +++ b/src/sessionwatcher.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef SESSIONWATCHER_H +#define SESSIONWATCHER_H + +#include +#include +#include +#include +#include +#include + +class SessionWatcher : public QObject +{ + Q_OBJECT +public: + explicit SessionWatcher(QObject *parent = nullptr); + void setValue(const QString &key, const QVariant &value); +Q_SIGNALS: + void sessionIdle(); + void sessionLockIdle(); + +private Q_SLOTS: + void onStatusChanged(unsigned int status); + void onSessionRemoved(const QDBusObjectPath &objectPath); + void onConfigurationDelayChanged(QString key); + void onConfigurationLockChanged(QString key); + void onConfigurationTimeTpChanged(QString key); +// void activationEnabledChanged(QString key); +// void lockEnabledChanged(QString key); +private: + QString sessionPath; + QGSettings *settings_delay; + QGSettings *settings_lock; + QGSettings *activationEnabled_Key; + QGSettings *lockEnabled_Key; + QGSettings *timegsettings; + QSettings *configSettings; + bool idleActivationEnabled; + bool lockEnabled; + int idleDelay; + int idleLock; + QTimer *m_timer = nullptr; + QTimer *m_timer2 = nullptr; +}; + +#endif // SESSIONWATCHER_H diff --git a/src/surewindow.cpp b/src/surewindow.cpp new file mode 100644 index 0000000..7633f15 --- /dev/null +++ b/src/surewindow.cpp @@ -0,0 +1,32 @@ +#include "surewindow.h" +#include "ui_surewindow.h" +#include +SureWindow::SureWindow(QWidget *parent) : + QWidget(parent), + ui(new Ui::SureWindow) +{ + ui->setupUi(this); + ui->tipLabel->setText(tr("Multiple users are logged in at the same time.Are you sure " + "you want to reboot this system?")); + ui->tipLabel->setStyleSheet("color:white;font:14pt;"); + ui->cancelBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0.2);border-radius: 8px;}" + "QPushButton:hover{background: rgba(255, 255, 255, 0.4);border-radius: 8px;}" + "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 8px;}"); + ui->confirmBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0.2);border-radius: 8px;}" + "QPushButton:hover{background: rgba(255, 255, 255, 0.25);border-radius: 8px;}" + "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 8px;}"); + connect(ui->cancelBtn, &QPushButton::clicked, this, [&]() { emit cantelButtonclicked(); }); + connect(ui->confirmBtn, &QPushButton::clicked, this, [&]() { emit confirmButtonclicked(); }); +} + +SureWindow::~SureWindow() +{ + delete ui; + + +} + +void SureWindow::setText(const QString tips) +{ + ui->tipLabel->setText(tips); +} diff --git a/src/surewindow.h b/src/surewindow.h new file mode 100644 index 0000000..89871ff --- /dev/null +++ b/src/surewindow.h @@ -0,0 +1,28 @@ +#ifndef SUREWINDOW_H +#define SUREWINDOW_H + +#include + +namespace Ui { +class SureWindow; +} + +class SureWindow : public QWidget +{ + Q_OBJECT + +public: + explicit SureWindow(QWidget *parent = nullptr); + ~SureWindow(); + void setText(const QString tips); + +private: + Ui::SureWindow *ui; + void on_cancelBtn_Clicked(); + +Q_SIGNALS: + void cantelButtonclicked(); + void confirmButtonclicked(); +}; + +#endif // SUREWINDOW_H diff --git a/src/surewindow.ui b/src/surewindow.ui new file mode 100644 index 0000000..0f921d5 --- /dev/null +++ b/src/surewindow.ui @@ -0,0 +1,163 @@ + + + SureWindow + + + + 0 + 0 + 821 + 631 + + + + Form + + + + 46 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + Noto Sans CJK SC + + + + TextLabel + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 24 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 96 + 36 + + + + + 96 + 36 + + + + Cancel + + + + + + + + 96 + 36 + + + + + 96 + 36 + + + + Confirm + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/src/switchbuttongroup.cpp b/src/switchbuttongroup.cpp new file mode 100644 index 0000000..dcb085d --- /dev/null +++ b/src/switchbuttongroup.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#include "switchbuttongroup.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +SwitchButtonGroup::SwitchButtonGroup(QWidget *parent) : QWidget(parent), + m_checkedId(0) +{ + this->resize(264, 48); + m_bg_switch = new QButtonGroup(this); + m_pb_password = new QPushButton(tr("uEduPWD"), this); + m_pb_qrCode = new QPushButton(tr("Wechat"), this); + m_pb_password->setIcon(QIcon(":/image/assets/intel/pin.png")); + m_pb_qrCode->setIcon(QIcon(":/image/assets/intel/wechat.png")); + + m_pb_password->setCheckable(true); + m_pb_qrCode->setCheckable(true); + + m_pb_password->setStyleSheet("font-size:16px;color:#ffffff"); + m_pb_qrCode->setStyleSheet("font-size:16px;color:#ffffff"); + + m_bg_switch->addButton(m_pb_password, 0); + m_bg_switch->addButton(m_pb_qrCode, 1); + + QObject::connect(m_pb_password, &QPushButton::clicked, this, &SwitchButtonGroup::parseButtonStatus); + QObject::connect(m_pb_qrCode, &QPushButton::clicked, this, &SwitchButtonGroup::parseButtonStatus); + + initUI(); +} + +void SwitchButtonGroup::initUI() +{ + QHBoxLayout *hbLayout = new QHBoxLayout(this); + hbLayout->setContentsMargins(0, 0, 0, 0); + hbLayout->addSpacerItem(new QSpacerItem(40,20,QSizePolicy::Expanding, QSizePolicy::Maximum)); + hbLayout->addWidget(m_pb_password); + hbLayout->addSpacerItem(new QSpacerItem(64,20,QSizePolicy::Expanding, QSizePolicy::Maximum)); + + QLine *s = new QLine(this->width()/2, 0, this->width(), this->height()/2); +// hbLayout->addChildWidget(s); + + hbLayout->addWidget(m_pb_qrCode); + hbLayout->addSpacerItem(new QSpacerItem(40,20,QSizePolicy::Expanding, QSizePolicy::Maximum)); +} + +void SwitchButtonGroup::parseButtonStatus() +{ +// qDebug() << "---------------------------parseButtonStatus check id=" << m_bg_switch->checkedId(); + if (m_checkedId == m_bg_switch->checkedId()) + return; + m_checkedId = m_bg_switch->checkedId(); +// switch (m_checkedId) { +// case 0: +// m_pb_password->setStyleSheet("font-size:16px;color:#2fb4e8"); +// m_pb_qrCode->setStyleSheet("font-size:16px;color:#ffffff"); +// break; +// case 1: +// m_pb_qrCode->setStyleSheet("font-size:16px;color:#2fb4e8"); +// m_pb_password->setStyleSheet("font-size:16px;color:#ffffff"); +// break; +// default: +// break; +// } + repaint(); + emit onSwitch(m_checkedId); +} + +void SwitchButtonGroup::paintEvent(QPaintEvent *event) +{ +// Q_UNUSED(event); +// QPainter painter(this); //QWidget为绘图设备,创建一个画刷对象,主要用到设置颜色和填充模式,brush,setBrush +// int width=this->width(); //获取QWidget 窗口的宽度 +// int height=this->height();//获取QWidget 窗口的高度 + +// painter.setPen(QColor("#ffffff")); +// painter.drawLine(this->width()/2, 0, this->width()/2, this->height()/2); + +// QPainterPath drawtriangle; //单独画三角形 + +// QPushButton *checkedButton; +// if (m_checkedId == 0) +// { +// checkedButton = m_pb_password; +// } else { +// checkedButton = m_pb_qrCode; +// } + +// drawtriangle.moveTo(checkedButton->x() + checkedButton->geometry().width()/2 -6, height);//左下角,第一点坐标为(0,height); +// drawtriangle.lineTo(checkedButton->x() + checkedButton->geometry().width()/2, height -12);//第二点坐标为(width/4,height/2) +// drawtriangle.lineTo(checkedButton->x() + checkedButton->geometry().width()/2 + 6, height);//第三点坐标为(width/2,height) +// painter.setPen(Qt::NoPen); +// painter.setBrush(QColor("#2fb4e8")); //填充绿色 +// painter.drawPath(drawtriangle); //绘制出图形 + + //设计稿变化重新做界面 + QPainter painter(this); + QColor color("#ffffff"); + color.setAlphaF(0.15); + painter.setRenderHint(QPainter::Antialiasing); + QPen pen(color); + painter.setPen(pen); + painter.setBrush(color); + + if(m_checkedId == 0) { + QRect rect1(4, 0, 120, 48); + painter.drawRoundedRect(rect1, 24, 24); + } else { + QRect rect2(140, 0, 120, 48); + painter.drawRoundedRect(rect2, 24, 24); + } +} diff --git a/src/switchbuttongroup.h b/src/switchbuttongroup.h new file mode 100644 index 0000000..1a2ace7 --- /dev/null +++ b/src/switchbuttongroup.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#ifndef SWITCHBUTTONGROUP_H +#define SWITCHBUTTONGROUP_H + +#include +#include +#include + +class SwitchButtonGroup : public QWidget +{ + Q_OBJECT +public: + explicit SwitchButtonGroup(QWidget *parent = nullptr); + +Q_SIGNALS: + void onSwitch(int id); + +private Q_SLOTS: + void parseButtonStatus(); + +private: + void initUI(); + + int m_checkedId;//上一次选中的按钮id + QButtonGroup *m_bg_switch; + QPushButton *m_pb_password; + QPushButton *m_pb_qrCode; + +protected: + void paintEvent(QPaintEvent *event) override; +}; + +#endif // SWITCHBUTTONGROUP_H diff --git a/src/tabletlockwidget.cpp b/src/tabletlockwidget.cpp new file mode 100644 index 0000000..82e4932 --- /dev/null +++ b/src/tabletlockwidget.cpp @@ -0,0 +1,634 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#include +#include +#include +#include +//#include +//#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tabletlockwidget.h" +#include "authdialog.h" +#include "virtualkeyboard.h" +#include "users.h" +#include "displaymanager.h" +#include "weathermanager.h" +#include "powermanager.h" +#include "digitalauthdialog.h" +#include "switchbuttongroup.h" +#include "wechatauthdialog.h" +#include "verificationwidget.h" +#include "verticalVerificationwidget.h" +#include "common.h" +#include "eduplatforminterface.h" +#include "accountsinterface.h" +#include "kylinnm.h" + +#include + +float tablescale; +TabletLockWidget::TabletLockWidget(QWidget *parent) : + QWidget(parent), + displayManager(new DisplayManager(this)), + m_switchButtonGroup(new SwitchButtonGroup(this)), + m_digitalAuthDialog(new DigitalAuthDialog(this)), + m_weChatAuthDialog(new WeChatAuthDialog(this)), + m_pb_powerManager(new QPushButton(this)), + m_pb_networkManager(new QPushButton(this)), + m_vKeyboardPB(new QPushButton(this)), + m_vKeyboard(new VirtualKeyboard(this)), + m_cancelOrBack(new QPushButton(this)), + m_pb_skip(new QPushButton(this)), + m_verificationWidget(new VerificationWidget(this)), + m_verticalVerificationWidget(new VerticalVerificationWidget(this)), + m_authType(0), + m_eduPlatformInterface(nullptr), + m_kylinNM(new KylinNM(this)) +{ + tablescale = 1.0; + m_kylinNM->installEventFilter(this); + m_digitalAuthDialog->installEventFilter(this); + m_switchButtonGroup->installEventFilter(this); + m_vKeyboard->installEventFilter(this); + this->installEventFilter(this); + + powermanager = new PowerManager(this); + powermanager->hide(); + + initUI(); + initConnect(); + onSwitchPage(); +} + +TabletLockWidget::~TabletLockWidget() +{ +} + +void TabletLockWidget::closeEvent(QCloseEvent *event) +{ + qDebug() << "TabletLockWidget::closeEvent"; + m_digitalAuthDialog->close(); + m_weChatAuthDialog->close(); + m_switchButtonGroup->close(); + m_verificationWidget->close(); + m_verticalVerificationWidget->close(); + m_kylinNM->close(); + return QWidget::closeEvent(event); +} + + +bool TabletLockWidget::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == m_vKeyboard || obj == m_kylinNM) + return true; + + if (event->type() == QEvent::MouseButtonPress && m_kylinNM->isVisible()) + { + m_kylinNM->hide(); + if(powermanager->isHidden()) //非电源会话界面则刷新,否则只网络弹窗 + onSwitchPage(); + } + + return QWidget::eventFilter(obj, event); +} + +void TabletLockWidget::startAuth() +{ + m_digitalAuthDialog->startAuth(); +} + +void TabletLockWidget::stopAuth() +{ + +} + +void TabletLockWidget::initUI() +{ + //电源管理 + m_pb_powerManager->setIcon(QIcon(":/image/assets/intel/powerManager.png")); + m_pb_powerManager->setFixedSize(48,48); + m_pb_powerManager->setIconSize(QSize(24,24)); + m_pb_powerManager->setFocusPolicy(Qt::NoFocus); + m_pb_powerManager->setStyleSheet("QPushButton:Hover{border-radius:24px;background-color:rgba(255, 255, 255, 0.15);}" + "QPushButton:Pressed{border-radius:24px;background-color:rgba(255, 255, 255, 0.05);}"); + m_pb_powerManager->installEventFilter(this); + + connect(m_pb_powerManager,&QPushButton::clicked + ,this,&TabletLockWidget::showPowerManager); + + //网络设置 + updateNetIcon(m_kylinNM->getConnectStatus()); + m_pb_networkManager->setFixedSize(48,48); + m_pb_networkManager->setIconSize(QSize(24,24)); + m_pb_networkManager->setFocusPolicy(Qt::NoFocus); + m_pb_networkManager->setStyleSheet("QPushButton:Hover{border-radius:24px;background-color:rgba(255, 255, 255, 0.15);}" + "QPushButton:Pressed{border-radius:24px;background-color:rgba(255, 255, 255, 0.05);}"); + m_pb_networkManager->installEventFilter(this); + + connect(m_pb_networkManager,&QPushButton::clicked + ,this,&TabletLockWidget::showNetManager); + + //虚拟键盘 + m_vKeyboard->hide(); + + connect(m_vKeyboard, &VirtualKeyboard::aboutToClose, + m_vKeyboard, &VirtualKeyboard::hide); + + m_vKeyboardPB->setIcon(QIcon(":/image/assets/intel/keyboard.png")); + m_vKeyboardPB->setFixedSize(48,48); + m_vKeyboardPB->setIconSize(QSize(24,24)); + m_vKeyboardPB->setFocusPolicy(Qt::NoFocus); + m_vKeyboardPB->installEventFilter(this); + m_vKeyboardPB->setStyleSheet("QPushButton:Hover{border-radius:24px;background-color:rgba(255, 255, 255, 0.15);}" + "QPushButton:Pressed{border-radius:24px;background-color:rgba(255, 255, 255, 0.05);}"); + + connect(m_vKeyboardPB,&QPushButton::clicked + ,this,&TabletLockWidget::showVirtualKeyboard); + + //取消或返回 + m_cancelOrBack->resize(88, 48); + m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/cancel.png")); + m_cancelOrBack->setStyleSheet("QPushButton{font-size:16px;color:#ffffff;}" + "QPushButton:Hover{border-radius:24px;background-color:rgba(255, 255, 255, 0.15);}" + "QPushButton:Pressed{border-radius:24px;background-color:rgba(255, 255, 255, 0.05);}"); + m_cancelOrBack->setText(tr("Cancel")); + m_cancelOrBack->setIconSize(QSize(24,24)); + m_cancelOrBack->setFocusPolicy(Qt::NoFocus); + m_cancelOrBack->installEventFilter(this); + connect(m_digitalAuthDialog, &DigitalAuthDialog::requestPasswordReset, this, [=]{ + m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/back.png")); + m_cancelOrBack->setText(tr("Back")); + m_pageType = pageType::check; + m_pb_skip->hide(); + onSwitchPage(); + }); + connect(m_cancelOrBack, &QPushButton::clicked, this, [=]{ + if(powermanager->isVisible()) + { + powermanager->hide(); + onSwitchPage(); + // m_digitalAuthDialog->reset(); + if(m_pageType != pageType::check) + { + m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/cancel.png")); + m_cancelOrBack->setText(tr("Cancel")); + } + return; + } + + if(m_pageType == pageType::pinLogin && + m_digitalAuthDialog->getStatus() == DigitalAuthDialog::LoginType::SECONDCONFIRMATION) + { + // 二次确认页返回,则显示重置密码页 + m_digitalAuthDialog->showResetPasswordPage(); + return; + } + + if(m_pageType == pageType::check) { + m_pageType = pageType::pinLogin; + m_digitalAuthDialog->reset(); + + onSwitchPage(); + m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/cancel.png")); + m_cancelOrBack->setText(tr("Cancel")); + return; + } + + if(m_digitalAuthDialog->getStatus() == 0) + { + //Todo 1、锁屏 -》息屏 + m_digitalAuthDialog->reset(); + Q_EMIT blackSaver(); +#ifdef USE_INTEL + powermanager->hibernate(); +#endif + } else { + m_digitalAuthDialog->reset(); + m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/cancel.png")); + m_cancelOrBack->setText(tr("Cancel")); + } + }); + + // 重置密码时跳过按钮 + m_pb_skip->setText(tr("Skip")); + m_pb_skip->resize(88, 48); + m_pb_skip->setStyleSheet("QPushButton{font-size:16px;color:#ffffff;}" + "QPushButton:Hover{border-radius:24px;background-color:rgba(255, 255, 255, 0.15);}" + "QPushButton:Pressed{border-radius:24px;background-color:rgba(255, 255, 255, 0.05);}"); + m_pb_skip->hide(); + + //网络模块 + m_kylinNM->hide(); +} + +/** + * @brief TabletLockWidget::initConnect + * 建立信号与槽的绑定 + */ +void TabletLockWidget::initConnect() +{ + connect(m_digitalAuthDialog, &DigitalAuthDialog::authenticateCompete, + this, &TabletLockWidget::closed); + connect(m_digitalAuthDialog, &DigitalAuthDialog::setPinCode, this, [=](QString pinCode){ + //Todo + QString currentPinCode; + AccountsInterface::getInstance()->GetAccountPincode(getenv("USER"), currentPinCode); + qDebug() << "currentPinCode:" << currentPinCode << "--old pinCode:" << pinCode; + if(!currentPinCode.isEmpty() && currentPinCode == pinCode) + { + //与原密码相同 + m_digitalAuthDialog->showErrorMessage(tr("New password is the same as old")); + m_digitalAuthDialog->showResetPasswordPage(); + return; + } + + DBusMsgCode code = AccountsInterface::getInstance()->SetAccountPincode(getenv("USER"), pinCode); + if (code == DBusMsgCode::No_Error) { + qDebug() << "set pincode success"; + Q_EMIT closed(); + } else { + qWarning() << "设置失败" << code; + m_digitalAuthDialog->showErrorMessage(tr("Reset password error:%1").arg(code)); + } + }); + connect(m_weChatAuthDialog, &WeChatAuthDialog::authenticateCompete, this, &TabletLockWidget::closed); + connect(m_weChatAuthDialog, &WeChatAuthDialog::qRStatusChange, this, [=] (QString loginname, QString loginpwd, int curstatus){ + //QString loginname, QString loginpwd, int curstatus + if(getenv("USER") == loginname && m_pageType == pageType::wecharLogin) + { + Q_EMIT closed(); + } else { + qWarning() << "[error] Username does not match wechat<" << loginname << ">" << " local<" << getenv("USER")<<">"; + if (!loginname.isEmpty()){ + m_weChatAuthDialog->showErrorMessage(tr("Please scan by correct WeChat")); + m_weChatAuthDialog->onReset(); + } + } + }); + connect(m_switchButtonGroup, &SwitchButtonGroup::onSwitch, this, &TabletLockWidget::switchLoginType); + connect(m_verificationWidget, &VerificationWidget::pageMessage, this, [=](SwitchPage type, QList args) + { + m_pageType = pageType::pinLogin; + onSwitchPage(); + m_pb_skip->show(); + }); + connect(m_verticalVerificationWidget, &VerticalVerificationWidget::pageMessage, this, [=](SwitchPage type, QList args) + { + m_pageType = pageType::pinLogin; + onSwitchPage(); + m_pb_skip->show(); + }); + + connect(powermanager,SIGNAL(lock()) + ,this,SLOT(showPowerManager())); + + if(QGSettings::isSchemaInstalled("org.ukui.SettingsDaemon.plugins.tablet-mode")) + { + QGSettings *tm = new QGSettings("org.ukui.SettingsDaemon.plugins.tablet-mode", "", this); + //判断是否是平板模式 + if(tm->get("tablet-mode").toBool()){ + connect(m_kylinNM, &KylinNM::onLineEditClicked, this, [=](){ + //点击了输入密码的框框,需要弹出软键盘 + showVirtualKeyboard(true); + m_kylinNM->move(m_kylinNM->x(), height() - m_vKeyboard->height() - m_kylinNM->height() - 20); + }); + } + + //监听平板模式变化 + connect(tm, &QGSettings::changed, this, [=](QString key){ + if(key == "tablet-mode" || key == "tabletMode") { + disconnect(m_kylinNM, &KylinNM::onLineEditClicked, this, nullptr); + if(tm->get("tablet-mode").toBool()){ + connect(m_kylinNM, &KylinNM::onLineEditClicked, this, [=](){ + //点击了输入密码的框框,需要弹出软键盘 + showVirtualKeyboard(true); + m_kylinNM->move(m_kylinNM->x(), height() - m_vKeyboard->height() - m_kylinNM->height()); + }); + } + } + }); + } + + connect(m_kylinNM, &KylinNM::onConnectChanged, this,[=](){ + updateNetIcon(m_kylinNM->getConnectStatus()); + }); + + connect(m_vKeyboard, &VirtualKeyboard::aboutToClose, m_vKeyboard, [=](){ + if(m_vKeyboard->isHidden() && m_kylinNM->isVisible()) { + m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - 100, + m_kylinNM->width(), + m_kylinNM->height()); + } + }); + + connect(m_pb_skip, &QPushButton::clicked, this, &TabletLockWidget::closed); + connect(m_digitalAuthDialog, &DigitalAuthDialog::switchToReset, this, [=](bool isReset){ + if(isReset){ + m_pb_skip->show(); + } else { + m_pb_skip->hide(); + } + }); +} + +void TabletLockWidget::switchLoginType(int position) +{ + if(position == 0) + { + //锁屏密码登录 + m_pageType = pageType::pinLogin; + } else if (position == 1) + { + m_pageType = pageType::wecharLogin; + //微信登录 + m_digitalAuthDialog->reset(); + m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/cancel.png")); + m_cancelOrBack->setText(tr("Cancel")); + } + + onSwitchPage(); +} + +void TabletLockWidget::showPowerManager() +{ + if (powermanager->isVisible()) + { + powermanager->hide(); + onSwitchPage(); + if(m_pageType != pageType::check) + { + m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/cancel.png")); + m_cancelOrBack->setText(tr("Cancel")); + } + Q_EMIT screenSaver(); + } else { + m_digitalAuthDialog->hide(); + m_weChatAuthDialog->hide(); + m_switchButtonGroup->hide(); + m_verificationWidget->hide(); + m_verticalVerificationWidget->hide(); + m_cancelOrBack->setIcon(QIcon(":/image/assets/intel/back.png")); + m_cancelOrBack->setText(tr("Back")); + m_pb_networkManager->hide(); + m_pb_powerManager->hide(); + m_vKeyboardPB->hide(); + m_vKeyboard->hide(); + powermanager->show(); + powermanager->setGeometry((width()-ITEM_WIDTH*4 - ITEM_SPACING*3)/2, + (height()-ITEM_HEIGHT)/2, + (ITEM_WIDTH*4 + ITEM_SPACING*3),ITEM_HEIGHT); + } +} + +void TabletLockWidget::showNetManager() +{ + if(m_kylinNM->isVisible()) + { + m_kylinNM->hide(); + } else { + m_digitalAuthDialog->releaseKeyboard(); + m_kylinNM->show(); + m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - 100, + m_kylinNM->width(), + m_kylinNM->height()); + m_kylinNM->updateWifiList(); + } +} + +/* lockscreen follows cursor */ +void TabletLockWidget::resizeEvent(QResizeEvent *event) +{ + QSize size = event->size(); + //重新计算缩放比例 + tablescale = QString::number(size.width() / 1920.0, 'f', 1).toFloat(); + + if(tablescale > 1) + tablescale = 1; + + m_cancelOrBack->setGeometry(32, 40, m_cancelOrBack->width(), m_cancelOrBack->height()); + m_pb_skip->setGeometry(this->width() - m_pb_skip->width() - 32, 40, m_pb_skip->width(), m_pb_skip->height()); + + m_digitalAuthDialog->setGeometry((this->width()-m_digitalAuthDialog->width())/2, (this->height()-m_digitalAuthDialog->height())/2 + 40, + m_digitalAuthDialog->width(), m_digitalAuthDialog->height()); + m_weChatAuthDialog->setGeometry((this->width()-m_weChatAuthDialog->width())/2, (this->height()-m_digitalAuthDialog->height())/2 + 40, + m_weChatAuthDialog->width(), m_weChatAuthDialog->height()); + + m_switchButtonGroup->setGeometry((this->width()-m_switchButtonGroup->width())/2, this->height()-80, + m_switchButtonGroup->width(), m_switchButtonGroup->height()); + + if(isOrientation()) + m_verticalVerificationWidget->setGeometry((this->width()-m_verticalVerificationWidget->width())/2, (this->height()-m_verticalVerificationWidget->height())/2, + m_verticalVerificationWidget->width(), m_verticalVerificationWidget->height()); + else + m_verificationWidget->setGeometry((this->width()-m_verificationWidget->width())/2, (this->height()-m_verificationWidget->height())/2 - 65, + m_verificationWidget->width(), m_verificationWidget->height()); + if(m_verificationWidget->isVisible() || m_verticalVerificationWidget->isVisible()) + showVerificationPage(); + // XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime); + //右下角按钮,x,y的初始值代表距离右下角的距离。 + int x=19,y=76; + x = x + m_pb_powerManager->width(); + m_pb_powerManager->setGeometry(this->width() - x,this->height() - y, m_pb_powerManager->width(), m_pb_powerManager->height()); + m_pb_networkManager->setGeometry(this->width() - x - 64 * tablescale, this->height() - y, + m_pb_networkManager->width(),m_pb_networkManager->height()); + m_vKeyboardPB->setGeometry(this->width() - x - 128 * tablescale, this->height() - y, + m_vKeyboardPB->width(), m_vKeyboardPB->height()); + m_kylinNM->setGeometry(this->width() - m_kylinNM->width() - 20, + this->height() - m_kylinNM->height() - 100, + m_kylinNM->width(), + m_kylinNM->height()); + //更新软键盘位置 + setVirkeyboardPos(); + if(powermanager && powermanager->isVisible()) + { + powermanager->setGeometry((width()-ITEM_WIDTH*4 - ITEM_SPACING*3)/2, + (height()-ITEM_HEIGHT)/2, + (ITEM_WIDTH*4 + ITEM_SPACING*3),ITEM_HEIGHT); + } +} + +//重写重绘事件,比如动态更新文本位置等 +void TabletLockWidget::paintEvent(QPaintEvent *event) +{ +} + +void TabletLockWidget::onSwitchPage() +{ + bool isOnlyWeChatLogin = false; + EduPlatformInterface::getInstance()->CheckPincodeSet(getenv("USER"), isOnlyWeChatLogin); + if(isOnlyWeChatLogin && m_pageType == pageType::pinLogin) + { + m_pageType = pageType::wecharLogin; + } + + if(!m_pb_networkManager->isVisible()) + m_pb_networkManager->show(); + + if(!m_pb_powerManager->isVisible()) + m_pb_powerManager->show(); + + switch (m_pageType) { + case pageType::pinLogin: + m_digitalAuthDialog->show(); + m_digitalAuthDialog->grabKeyboard(); + m_switchButtonGroup->show(); + m_weChatAuthDialog->hide(); + m_verificationWidget->hide(); + m_verticalVerificationWidget->hide(); + m_vKeyboardPB->hide(); + m_vKeyboard->hide(); + break; + case pageType::wecharLogin: + m_digitalAuthDialog->hide(); + m_digitalAuthDialog->releaseKeyboard(); + m_weChatAuthDialog->show(); + if(isOnlyWeChatLogin) + { + m_switchButtonGroup->hide(); + } else { + m_switchButtonGroup->show(); + } + m_verificationWidget->hide(); + m_verticalVerificationWidget->hide(); + m_vKeyboardPB->hide(); + m_vKeyboard->hide(); + break; + case pageType::check: + m_digitalAuthDialog->hide(); + m_digitalAuthDialog->releaseKeyboard(); + m_weChatAuthDialog->hide(); + m_switchButtonGroup->hide(); + showVerificationPage(); + m_vKeyboardPB->show(); + break; + default: + break; + } +} + +QWidget* TabletLockWidget::getCurrentWidget() +{ + switch (m_pageType) { + case pageType::pinLogin: + return m_digitalAuthDialog; + case pageType::wecharLogin: + return m_weChatAuthDialog; + case pageType::check: + return m_verificationWidget; + default: + return m_digitalAuthDialog; + } +} + +void TabletLockWidget::showVirtualKeyboard(bool isShow) +{ + m_vKeyboard->setVisible(isShow || m_vKeyboard->isHidden()); + setVirkeyboardPos(); +} + +void TabletLockWidget::setVirkeyboardPos() +{ + if(m_vKeyboard) + { + m_vKeyboard->setGeometry(0 + 20, + height() - height()/3 + 10, + width() - 40 , height()/3 - 20); + m_vKeyboard->raise(); + m_vKeyboard->repaint(); + } +} + +bool TabletLockWidget::isOrientation() +{ + QRect wRect = QApplication::primaryScreen()->geometry(); + if(wRect.height() > wRect.width()) + return true; + return false; +} + +void TabletLockWidget::showVerificationPage() +{ + if(isOrientation()) + { + m_verificationWidget->hide(); + m_verticalVerificationWidget->show(); + } + else + { + m_verificationWidget->show(); + m_verticalVerificationWidget->hide(); + } +} + +//void TabletLockWidget::RecieveKey(int key) +//{ +// if(m_pageType == pageType::pinLogin ||m_pageType == pageType::check) +// m_digitalAuthDialog->RecieveKey(key); +//} + +void TabletLockWidget::updateNetIcon(int status) +{ + switch(status) { + case 0: + //有线 + m_pb_networkManager->setIcon(QIcon(":/image/assets/intel/icon-wired.png")); + break; + case 1: + //无线 + m_pb_networkManager->setIcon(QIcon(":/image/assets/intel/icon-wifi.png")); + break; + case 2: + //有线+无线 + m_pb_networkManager->setIcon(QIcon(":/image/assets/intel/icon-wired.png")); + break; + default: + //无连接 + m_pb_networkManager->setIcon(QIcon(":/image/assets/intel/icon-no-signal.png")); + } +} + +/** + * @Destoryed + * @brief TabletLockWidget::getEduPlatformInterface + * @return + */ +EduPlatformInterface* TabletLockWidget::getEduPlatformInterface() +{ + if(m_eduPlatformInterface == nullptr) + { + m_eduPlatformInterface = new EduPlatformInterface("cn.kylinos.SSOBackend", + "/cn/kylinos/SSOBackend", + QDBusConnection::systemBus(), + this); + } + + return m_eduPlatformInterface; +} diff --git a/src/tabletlockwidget.h b/src/tabletlockwidget.h new file mode 100644 index 0000000..12be613 --- /dev/null +++ b/src/tabletlockwidget.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#ifndef TABLETLOCKWIDGET_H +#define TABLETLOCKWIDGET_H + +#ifndef QT_NO_KEYWORDS +#define QT_NO_KEYWORDS +#endif + +#include +#include +#include +#include +#include +#include + +class VirtualKeyboard; +class PowerManager; +class AuthDialog; +class Users; +class UserItem; +class DisplayManager; +class QMenu; +class DigitalAuthDialog; +class SwitchButtonGroup; +class WeChatAuthDialog; +class VerificationWidget; +class VerticalVerificationWidget; +class EduPlatformInterface; +class KylinNM; + +class TabletLockWidget : public QWidget +{ + Q_OBJECT +public: + explicit TabletLockWidget(QWidget *parent = nullptr); + ~TabletLockWidget(); + + enum pageType{ + pinLogin = 0, + wecharLogin, + check + }; + + void closeEvent(QCloseEvent *event); + void startAuth(); + void stopAuth(); + bool exitSubWidget() { + return true; + }; +// void RecieveKey(int key); + +Q_SIGNALS: + void closed(); + void capsLockChanged(); + void screenSaver(); + void blackSaver(); + +private: + void initUI(); + void initConnect(); + + void onSwitchPage(); + QWidget* getCurrentWidget(); + EduPlatformInterface* getEduPlatformInterface(); + void updateNetIcon(int status); + + void paintEvent(QPaintEvent *event) override; + + bool isOrientation(); + void showVerificationPage(); + +private Q_SLOTS: + void showPowerManager(); + void showNetManager(); + void showVirtualKeyboard(bool isShow = false); + void setVirkeyboardPos(); + void switchLoginType(int position); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + void resizeEvent(QResizeEvent *event); + +private: + AuthDialog *authDialog; + VirtualKeyboard *m_vKeyboard; + PowerManager *powermanager; + QTimer *timer; + QMenu *usersMenu; + Users *users; + DisplayManager *displayManager; + DigitalAuthDialog *m_digitalAuthDialog; + WeChatAuthDialog *m_weChatAuthDialog; + SwitchButtonGroup *m_switchButtonGroup; + QPushButton *m_pb_powerManager; + QPushButton *m_pb_networkManager; + QPushButton *m_cancelOrBack; + QPushButton *m_pb_skip; + QPushButton *m_vKeyboardPB; + VerificationWidget *m_verificationWidget; + VerticalVerificationWidget *m_verticalVerificationWidget; + EduPlatformInterface *m_eduPlatformInterface; + + KylinNM *m_kylinNM; + QWidget *m_NetManagerWidget; + + int m_authType; + int m_pageType = 0; +}; + +#endif // TABLETLOCKWIDGET_H diff --git a/src/test-accounts.cpp b/src/test-accounts.cpp new file mode 100644 index 0000000..4da700b --- /dev/null +++ b/src/test-accounts.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include +#include "users.h" +#include + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + Users users; + + qDebug() << users.getUserByName("kylin"); + + return 0; +} diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000..42d5522 --- /dev/null +++ b/src/types.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef TYPES_H +#define TYPES_H + +/* https://www.narf.ssji.net/~shtrom/wiki/projets/gnomescreensavernosession */ +enum SessionStatus +{ + SESSION_AVAILABLE = 0, + SESSION_INVISIBLE = 1, + SESSION_BUSY = 2, + SESSION_IDLE = 3 +}; + +enum ScreenStatus +{ + UNDEFINED = 0x00, + SCREEN_SAVER = 0x01, + SCREEN_LOCK = 0x02, + SCREEN_LOCK_AND_SAVER = 0x03, + SCREEN_BLACK = 0x04, +}; + +#define SM_DBUS_SERVICE "org.gnome.SessionManager" +#define SM_DBUS_PATH "/org/gnome/SessionManager/Presence" +#define SM_DBUS_INTERFACE "org.gnome.SessionManager.Presence" + +#define DM_DBUS_SERVICE "org.freedesktop.DisplayManager" +#define DM_DBUS_PATH "/org/freedesktop/DisplayManager" +#define DM_DBUS_INTERFACE "org.freedesktop.DisplayManager" +#define DM_SEAT_INTERFACE "org.freedesktop.DisplayManager.Seat" + +#define ACT_DBUS_SERVICE "org.freedesktop.Accounts" +#define ACT_DBUS_PATH "/org/freedesktop/Accounts" +#define ACT_DBUS_INTERFACE "org.freedesktop.Accounts" +#define ACT_USER_INTERFACE "org.freedesktop.Accounts.User" + +#define DBUS_PROP_INTERFACE "org.freedesktop.DBus.Properties" + +#define SS_DBUS_SERVICE "org.ukui.ScreenSaver" +#define SS_DBUS_PATH "/" +#define SS_DBUS_INTERFACE "org.ukui.ScreenSaver" + +#define BIO_ERROR -1 +#define BIO_FAILED 0 +#define BIO_SUCCESS 1 +#define BIO_IGNORE 2 + +#define BIOMETRIC_PAM "BIOMETRIC_PAM" +#define BIOMETRIC_IGNORE "BIOMETRIC_IGNORE" +#define BIOMETRIC_SUCCESS "BIOMETRIC_SUCCESS" +#define BIOMETRIC_FAILED "BIOMETRIC_FAILED" + +#define LG_DBUS_SERVICE "org.freedesktop.login1" +#define LG_DBUS_PATH "/org/freedesktop/login1" +#define LG_DBUS_INTERFACE "org.freedesktop.login1.Manager" + + + +#endif // TYPES_H diff --git a/src/ukui-screensaver-backend.cpp b/src/ukui-screensaver-backend.cpp new file mode 100644 index 0000000..63f6351 --- /dev/null +++ b/src/ukui-screensaver-backend.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include +#include +#include +#include + +#include "interface.h" +#include "sessionwatcher.h" +#include "screensaveradaptor.h" +#include "types.h" + +#include +#include +#include +#include +#include + +#define POWER_TYPE_SCHENA "org.ukui.power-manager" + +void sig_chld(int /*signo*/) +{ + pid_t pid; + while( (pid = waitpid(-1, NULL, WNOHANG)) > 0) + qDebug() << "child" << pid << "terminated"; + return; +} + +int main(int argc, char *argv[]) +{ +// if(signal(SIGCHLD, sig_chld) == SIG_ERR) { +// perror("signal error"); +// exit(EXIT_FAILURE); +// } + initUkuiLog4qt("ukui-screensaver-backend"); + // 重启或关机时不被session关掉 + qunsetenv("SESSION_MANAGER"); + QCoreApplication a(argc, argv); + + // 检查该程序是否已经有实例在运行 + QDBusInterface *checkInterface = + new QDBusInterface("org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + QDBusConnection::sessionBus()); + QDBusReply ret = checkInterface->call("NameHasOwner", + "cn.kylinos.ScreenSaver"); + if(ret.value()) { + qDebug() << "There is an instance running"; + exit(EXIT_FAILURE); + } + + FILE *fp; + + // for PowerManager + fp = popen("xset s 0 0", "r"); + fclose(fp); +// Q_UNUSED(fp) + + QGSettings *powerSettings; + if(QGSettings::isSchemaInstalled(POWER_TYPE_SCHENA)){ + powerSettings = new QGSettings(POWER_TYPE_SCHENA,"",NULL); + QStringList keys = powerSettings->keys(); + if (keys.contains("lockSuspend")) { + bool ret = powerSettings->get("lockSuspend").toBool(); + if(ret){ + powerSettings->set("lock-suspend",false); + } + } + if (keys.contains("lockHibernate")) { + bool ret = powerSettings->get("lockHibernate").toBool(); + if(ret){ + powerSettings->set("lock-hibernate",false); + } + } + } + + // 注册DBus + Interface *interface = new Interface(); + ScreenSaverAdaptor adaptor(interface); + + QDBusConnection service = QDBusConnection::sessionBus(); + if(!service.registerService(SS_DBUS_SERVICE)) { + qDebug() << service.lastError().message(); + exit(EXIT_FAILURE); + } + if(!service.registerObject(SS_DBUS_PATH, SS_DBUS_SERVICE, &adaptor, + QDBusConnection::ExportAllSlots | + QDBusConnection::ExportAllSignals)) { + qDebug() << service.lastError().message(); + exit(EXIT_FAILURE); + } + qDebug() << service.baseService(); + + // 发送DBus信号 + SessionWatcher *watcher = new SessionWatcher; + QObject::connect(watcher, &SessionWatcher::sessionIdle, + interface, &Interface::onSessionIdleReceived); + + QObject::connect(watcher, &SessionWatcher::sessionLockIdle, + interface, &Interface::Lock); + + QObject::connect(watcher, &SessionWatcher::sessionIdle, + &a, [&]{ + QDBusMessage message = QDBusMessage::createSignal(SS_DBUS_PATH, + SS_DBUS_INTERFACE, + "SessionIdle"); + service.send(message); + //qDebug()<<"message="<start(3000); + + QObject::connect(checkInterface, SIGNAL(NameLost(QString)), + interface, SLOT(onNameLost(QString))); + + return a.exec(); +} diff --git a/src/ukui-screensaver-checkpass.cpp b/src/ukui-screensaver-checkpass.cpp new file mode 100644 index 0000000..6f48647 --- /dev/null +++ b/src/ukui-screensaver-checkpass.cpp @@ -0,0 +1,166 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +static int toParent = 0; +static int fromChild = 0; + +typedef struct pam_message PAM_MESSAGE; +typedef struct pam_response PAM_RESPONSE; + +static void +writeData(int fd, const void *buf, ssize_t count) +{ + if(write(fd, buf, count) != count) + printf("write to parent failed: %s\n",strerror(errno)); +} + +static void +writeString(int fd, const char *data) +{ + int length = data ? strlen(data) : -1; + writeData(fd, &length, sizeof(length)); + if(data) + writeData(fd, data, sizeof(char) * length); +} + +static int +readData(int fd, void *buf, size_t count) +{ + ssize_t nRead = read(fd, buf, count); + if(nRead < 0) + printf("read data failed: %s\n",strerror(errno)); + return nRead; +} + +static char * +readString(int fd) +{ + int length; + + if(readData(fd, &length, sizeof(length)) <= 0) + return NULL; + if(length <= 0) + length = 0; + char *value = (char *)malloc(sizeof(char) * (length + 1)); + readData(fd, value, length); + value[length] = '\0'; + + return value; +} + +static int +pam_conversation(int msgLength, const struct pam_message **msg, + PAM_RESPONSE **resp, void */*appData*/) +{ + PAM_RESPONSE *response = (PAM_RESPONSE*)calloc(msgLength,sizeof(PAM_RESPONSE)); + + int authComplete = 0; + writeData(toParent, (const void*)&authComplete, sizeof(authComplete)); + writeData(toParent, (const void*)&msgLength, sizeof(msgLength)); + //发送pam消息 + for(int i = 0; i < msgLength; i++) + { + const struct pam_message *m = msg[i]; + writeData(toParent, (const void *)&m->msg_style, sizeof(m->msg_style)); + writeString(toParent, m->msg); + } + //读取响应 + for(int i = 0; i < msgLength; i++) + { + PAM_RESPONSE *r = &response[i]; + readData(fromChild, &r->resp_retcode, sizeof(r->resp_retcode)); + r->resp = readString(fromChild); + } + *resp = response; + return PAM_SUCCESS; +} + +static void +_authenticate(const char *userName) +{ + printf("authenticate %s\n",userName); + + pam_handle_t *pamh = NULL; + char *newUser; + int ret; + int authRet; + struct pam_conv conv; + + conv.conv = pam_conversation; + conv.appdata_ptr = NULL; + + ret = pam_start("ukui-screensaver-qt", userName, &conv, &pamh); + if(ret != PAM_SUCCESS) + { + printf("failed to start PAM: = %s\n", pam_strerror(NULL, ret)); + } + + authRet = pam_authenticate(pamh, 0); + + ret = pam_get_item(pamh, PAM_USER, (const void **)&newUser); + if(ret != PAM_SUCCESS) + { + pam_end(pamh, 0); + printf("failed to get username\n"); + _exit(EXIT_FAILURE); + return ; + } + if(authRet == PAM_SUCCESS) + authRet = pam_acct_mgmt(pamh, 0); + if (authRet == PAM_NEW_AUTHTOK_REQD) + authRet = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); + if(authRet != PAM_SUCCESS) + { + + } + + fprintf(stderr, "authentication result: %d\n", authRet); + + // 发送认证结果 + int authComplete = 1; + writeData(toParent, (const void*)&authComplete, sizeof(authComplete)); + writeData(toParent, (const void *)&authRet, sizeof(authRet)); + printf("--- 认证完成\n"); + + /* Stop if we didn't authenticated */ + if (authRet != PAM_SUCCESS) + { + pam_end(pamh, 0); + _exit(EXIT_FAILURE); + return ; + } + pam_end(pamh, 0); + pamh = NULL; + _exit(EXIT_SUCCESS); +} + +int main(int argc, char **argv) +{ + if (argc != 4) + { + return EXIT_FAILURE; + } + toParent = atoi (argv[1]); + fromChild = atoi (argv[2]); + if (toParent == 0 || fromChild == 0) + { + printf ("Invalid file descriptors %s %s\n", argv[2], argv[3]); + return EXIT_FAILURE; + } + + //mlockall (MCL_CURRENT | MCL_FUTURE); + fcntl (toParent, F_SETFD, FD_CLOEXEC); + fcntl (fromChild, F_SETFD, FD_CLOEXEC); + + + _authenticate(argv[3]); + + +} + diff --git a/src/ukui-screensaver-command.cpp b/src/ukui-screensaver-command.cpp new file mode 100644 index 0000000..1ce2d54 --- /dev/null +++ b/src/ukui-screensaver-command.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include +#include +#include +#include +#include +#include +#include +#include "types.h" +#include + +#define WORKING_DIRECTORY "/usr/share/ukui-screensaver" + +int main(int argc, char **argv) +{ + initUkuiLog4qt("ukui-screensaver-command"); + QCoreApplication a(argc, argv); + + QString locale = QLocale::system().name(); + QTranslator translator; + QString qmFile = QString(WORKING_DIRECTORY"/i18n_qm/%1.qm").arg(locale); + translator.load(qmFile); + a.installTranslator(&translator); + + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::translate("main", "Start command for the ukui ScreenSaver.")); + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption lockOption({"l", QStringLiteral("lock")}, + QCoreApplication::translate("main", "lock the screen immediately")); + + QCommandLineOption queryOption({"q", QStringLiteral("query")}, + QCoreApplication::translate("main", "query the status of the screen saver")); + + QCommandLineOption unlockOption({"u", QStringLiteral("unlock")}, + QCoreApplication::translate("main", "unlock the screen saver")); + QCommandLineOption screensaverOption({"s", QStringLiteral("screensaver")}, + QCoreApplication::translate("main", "show the screensaver")); + + parser.addOption(lockOption); + parser.addOption(queryOption); + parser.addOption(unlockOption); + parser.addOption(screensaverOption); + parser.process(a); + + if(!parser.isSet(lockOption) && !parser.isSet(queryOption) && !parser.isSet(unlockOption) && !parser.isSet(screensaverOption)) + return -1; + + QDBusInterface *interface = new QDBusInterface(SS_DBUS_SERVICE, + SS_DBUS_PATH, + SS_DBUS_INTERFACE); + + QDBusReply stateReply = interface->call("GetLockState"); + if(!stateReply.isValid()){ + qWarning()<< "Get state error:" << stateReply.error(); + return 0; + } + qInfo()<<"Command:"<call("Lock"); + if(msg.type() == QDBusMessage::ErrorMessage) + qDebug() << msg.errorMessage(); + }else if(parser.isSet(unlockOption)){ + QDBusMessage msg = interface->call("UnLock"); + if(msg.type() == QDBusMessage::ErrorMessage) + qDebug() << msg.errorMessage(); + }else if(parser.isSet(screensaverOption)){ + QDBusMessage msg = interface->call("ShowScreensaver"); + if(msg.type() == QDBusMessage::ErrorMessage) + qDebug() << msg.errorMessage(); + } + return 0; +} + diff --git a/src/ukui-screensaver-dialog.cpp b/src/ukui-screensaver-dialog.cpp new file mode 100644 index 0000000..bd7bb1e --- /dev/null +++ b/src/ukui-screensaver-dialog.cpp @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fullbackgroundwidget.h" +#include "configuration.h" +#define CACHE_DIR "/.cache/ukui-screensaver/" +#define DOUBLE 2 +#define MAX_FILE_SIZE 1024 * 1024 +#define LOG_FILE0 "screensaver_0.log" +#define LOG_FILE1 "screensaver_1.log" + +#define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver" +#define KEY_LOCK_ENABLED "lock-enabled" + +FullBackgroundWidget *window = NULL; +static void +messageOutput(QtMsgType type, const QMessageLogContext &context,const QString &msg); + +void checkIslivecd() +{ + char cmd[128] = {0}; + char str[1024]; + FILE *fp; + + int n = sprintf(cmd, "cat /proc/cmdline"); + Q_UNUSED(n) + + fp = popen(cmd, "r"); + while(fgets(str, sizeof(str)-1, fp)) { + if(strstr(str,"boot=casper")) + { + printf("is livecd\n"); + exit(0); + } + } + pclose(fp); + + QString filepath = QDir::homePath() + "/Desktop" + "/kylin-os-installer.desktop"; + QFileInfo file(filepath); + if(!file.exists()) + return; + if(getuid() != 999) + return; + exit(0); +} + +void checkIsRunning() +{ + int fd, len; + char buf[32]; + struct flock lock; + + const QString PID_DIR = QString("/var/run/user/%1").arg(QString::number(getuid())); + QString env = qgetenv("DISPLAY"); + const QString PID_FILE = PID_DIR + QString("/ukui-screensaver%1.pid").arg(env); + + qDebug() << PID_DIR; + QDir dir(PID_DIR); + if(!dir.exists()) { + if(!dir.mkdir(PID_DIR.toLocal8Bit().data())) { + perror("create pid directory failed"); + exit(1); + } + } + if( (fd = open(PID_FILE.toLocal8Bit().data(), + O_RDWR | O_CREAT, 0666)) == -1){ + perror("open pid file failed"); + exit(1); + } + + memset(&lock, 0, sizeof(struct flock)); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + + if(fcntl(fd, F_SETLK, &lock) < 0) { +// perror("fcntl F_SETLK failed"); + printf("There is already an instance running\n"); + exit(1); + } + + len = snprintf(buf, sizeof(buf), "%d", getpid()); + ftruncate(fd, 0); + if(write(fd, buf, len) != len) { + perror("write pid to lock file failed"); + exit(1); + } +} + +void handler(int signum) +{ + window->closeScreensaver(); +} + +#define WORKING_DIRECTORY "/usr/share/ukui-screensaver" +int main(int argc, char *argv[]) +{ + if(argc < 2) + return 0; + + initUkuiLog4qt("ukui-screensaver-dialog"); + // 重启或关机时不被session关掉 + qunsetenv("SESSION_MANAGER"); + checkIsRunning(); + checkIslivecd(); + + qputenv("QT_QPA_PLATFORMTHEME",QByteArray("ukui")); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); +#endif +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); +#endif + + qunsetenv("QT_IM_MODULE"); + //signal(SIGTERM,handler); + QApplication a(argc, argv); + QApplication::setSetuidAllowed(true); + + + //命令行参数解析 + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::translate("main", "Dialog for the ukui ScreenSaver.")); + parser.addHelpOption(); + parser.addVersionOption(); + + QCommandLineOption lockOption(QStringLiteral("lock"), + QCoreApplication::translate("main", "lock the screen immediately")); + QCommandLineOption lstOption(QStringLiteral("lock-startup"), + QCoreApplication::translate("main", "lock the screen immediately")); + QCommandLineOption sessionIdleOption(QStringLiteral("session-idle"), + QCoreApplication::translate("main", "activated by session idle signal")); + QCommandLineOption lscreensaverOption(QStringLiteral("lock-screensaver"), + QCoreApplication::translate("main", "lock the screen and show screensaver immediately")); + QCommandLineOption screensaverOption(QStringLiteral("screensaver"), + QCoreApplication::translate("main", "show screensaver immediately")); + QCommandLineOption blankOption(QStringLiteral("blank"), + QCoreApplication::translate("main", "lock the screen and show screensaver immediately")); + parser.addOptions({lockOption, lstOption,sessionIdleOption , screensaverOption,blankOption,lscreensaverOption}); + parser.process(a); + + if(!parser.isSet(sessionIdleOption) + && !parser.isSet(lockOption) + && !parser.isSet(lstOption) + && !parser.isSet(screensaverOption) + && !parser.isSet(lscreensaverOption) + && !parser.isSet(blankOption)) + { + return 0; + } + + //qInstallMessageHandler(messageOutput); + + //加载翻译文件 + QString locale = QLocale::system().name(); + QTranslator translator; + QString qmFile = QString(WORKING_DIRECTORY"/i18n_qm/%1.qm").arg(locale); + translator.load(qmFile); + a.installTranslator(&translator); + qDebug() << "load translation file " << qmFile; + + window = new FullBackgroundWidget(); + + QFile qssFile(":/qss/assets/authdialog.qss"); + if(qssFile.open(QIODevice::ReadOnly)) { + a.setStyleSheet(qssFile.readAll()); + } + qssFile.close(); + + if(parser.isSet(blankOption)) + { + window->onBlankScreensaver(); + } + +#ifndef USE_INTEL + window->show(); + window->activateWindow(); +#endif + if(parser.isSet(lockOption)) + { + window->lock(); + } + + if(parser.isSet(lstOption)) + { + window->lock(); + window->setIsStartup(true); + } + + if(parser.isSet(sessionIdleOption)) + { + if(window->onSessionStatusChanged(SESSION_IDLE) == -1) + return 0; + } + + if(parser.isSet(lscreensaverOption)) + { + window->onScreensaver(); + } +/* + if(parser.isSet(blankOption)) + { + window->onBlankScreensaver(); + } +*/ + if(parser.isSet(screensaverOption)) + { + window->showScreensaver(); + } + +#ifdef USE_INTEL + window->show(); + window->activateWindow(); +#endif + + QString username = getenv("USER"); + int uid = getuid(); + QDBusInterface *interface = new QDBusInterface("cn.kylinos.Kydroid2", + "/cn/kylinos/Kydroid2", + "cn.kylinos.Kydroid2", + QDBusConnection::systemBus(), + window); + + QDBusMessage msg = interface->call(QStringLiteral("SetPropOfContainer"),username, uid, "is_kydroid_on_focus", "0"); + return a.exec(); +} + +static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + Q_UNUSED(context) + QDateTime dateTime = QDateTime::currentDateTime(); + QByteArray time = QString("[%1] ").arg(dateTime.toString("MM-dd hh:mm:ss.zzz")).toLocal8Bit(); + QByteArray localMsg = msg.toLocal8Bit(); + + QString name[DOUBLE] = {LOG_FILE0, LOG_FILE1}; + FILE *log_file = nullptr; + QString logFilePath; + int fileSize; + static int i = 0; + QDir dir; + + if (dir.mkpath(QDir::homePath() + CACHE_DIR)) { + logFilePath = QDir::homePath() + CACHE_DIR + "/" + name[i]; + log_file = fopen(logFilePath.toLocal8Bit().constData(), "a+"); + } + + QString filePath(context.file); + int separator = filePath.lastIndexOf('/'); + QString fileName = filePath.right(filePath.length() - separator - 1); + const char *file = fileName.toLocal8Bit().data(); + + switch(type) { + case QtDebugMsg: + fprintf(log_file? log_file:stderr, "%s Debug: %s:%u: %s\n", time.constData(), file, context.line, localMsg.constData()); + break; + case QtInfoMsg: + fprintf(log_file? log_file:stderr, "%s Info: %s:%u: %s\n", time.constData(), file, context.line, localMsg.constData()); + break; + case QtWarningMsg: + fprintf(log_file? log_file:stderr, "%s Warnning: %s:%u: %s\n", time.constData(), file, context.line, localMsg.constData()); + break; + case QtCriticalMsg: + fprintf(log_file? log_file:stderr, "%s Critical: %s:%u: %s\n", time.constData(), file, context.line, localMsg.constData()); + break; + case QtFatalMsg: + fprintf(log_file? log_file:stderr, "%s Fatal: %s:%u: %s\n", time.constData(), file, context.line, localMsg.constData()); + abort(); + } + fflush(stderr); + + if (log_file) { + fileSize = ftell(log_file); + if (fileSize >= MAX_FILE_SIZE) { + i = (i + 1) % DOUBLE; + logFilePath = QDir::homePath() + logFilePath + "/" + name[i]; + if (QFile::exists(logFilePath)) { + QFile temp(logFilePath); + temp.remove(); + } + } + fclose(log_file); + } +} diff --git a/src/ukui-screensaver.pro b/src/ukui-screensaver.pro new file mode 100644 index 0000000..f8b4b43 --- /dev/null +++ b/src/ukui-screensaver.pro @@ -0,0 +1,80 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2018-04-09T11:40:40 +# +#------------------------------------------------- +QT += core gui dbus x11extras + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +include(BioAuth/bioauth.pri) +include(VirtualKeyboard/VirtualKeyboard.pri) + +TARGET = ukui-screensaver-dialog +TEMPLATE = app + +# 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 \ + QT_MESSAGELOGCONTEXT + +LIBS += -lpam -lpam_misc -lX11 -lXext -lXtst + +CONFIG += link_pkgconfig +PKGCONFIG += gio-2.0 x11 xcb xtst + +# 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 + +INCLUDEPATH += \ + VirtualKeyboard/src/ + BioAuth/include/ + +SOURCES += \ + ukui-screensaver-dialog.cpp \ + mainwindow.cpp \ + unixsignallistener.cpp \ + auth-pam.cpp \ + authdialog.cpp \ + gsettings.cpp \ + auxiliary.cpp \ + configuration.cpp \ + screensaverwidget.cpp \ + screensaver.cpp \ + event_monitor.cpp \ + monitorwatcher.cpp + +HEADERS += \ + mainwindow.h \ + unixsignallistener.h \ + auth-pam.h \ + auth.h \ + authdialog.h \ + gsettings.h \ + auxiliary.h \ + configuration.h \ + screensaverwidget.h \ + screensaver.h \ + event_monitor.h \ + monitorwatcher.h + +FORMS += \ + mainwindow.ui \ + authdialog.ui + +RESOURCES += \ + assets.qrc + +TRANSLATIONS = ../i18n_ts/zh_CN.ts \ + ../i18n_ts/ru.ts \ + ../i18n_ts/fr.ts \ + ../i18n_ts/pt.ts \ + ../i18n_ts/es.ts + +target.path = /usr/bin/ + +INSTALLS += target diff --git a/src/unixsignallistener.cpp b/src/unixsignallistener.cpp new file mode 100644 index 0000000..6cb1583 --- /dev/null +++ b/src/unixsignallistener.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "unixsignallistener.h" +#include +#include +#include +#include +#include + +int UnixSignalListener::sigusr1Fd[2]; + +UnixSignalListener::UnixSignalListener(QObject *parent) : QObject(parent) +{ + if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigusr1Fd)) + qFatal("Couldn't create SIGUSR1 socketpair"); + snUsr1 = new QSocketNotifier(sigusr1Fd[1], QSocketNotifier::Read, this); + connect(snUsr1, &QSocketNotifier::activated, this, &UnixSignalListener::handleSigUsr1); +} + +void UnixSignalListener::usr1SignalAction(int sig, siginfo_t *siginfo, void *ucontext) +{ + (void)sig; + (void)ucontext; + char buffer[16]; + sprintf(buffer, "%d", siginfo->si_pid); + int ignore = ::write(sigusr1Fd[0], buffer, strlen(buffer) + 1); + (void)ignore; +} + +void UnixSignalListener::chldSignalAction(int /*sig*/, siginfo_t */*siginfo*/, void */*ucontext*/) +{ + ::waitpid(-1, NULL, 0); +} + +void UnixSignalListener::handleSigUsr1() +{ + snUsr1->setEnabled(false); + char buffer[16]; + int pid; + int ignore = ::read(sigusr1Fd[1], buffer, sizeof(buffer)); + sscanf(buffer, "%d", &pid); + (void)ignore; + + /* Do Qt stuff */ + Q_EMIT transition(pid); + + snUsr1->setEnabled(true); +} diff --git a/src/unixsignallistener.h b/src/unixsignallistener.h new file mode 100644 index 0000000..2a1da96 --- /dev/null +++ b/src/unixsignallistener.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#ifndef UNIXSIGNALLISTENER_H +#define UNIXSIGNALLISTENER_H + +#ifndef QT_NO_KEYWORDS +#define QT_NO_KEYWORDS +#endif + +#include +#include +#include + +class UnixSignalListener : public QObject +{ + Q_OBJECT +public: + explicit UnixSignalListener(QObject *parent = nullptr); + +public: + /* Unix signal handlers. */ + static void usr1SignalAction(int sig, siginfo_t *siginfo, void *ucontext); + static void chldSignalAction(int sig, siginfo_t *siginfo, void *ucontext); + +Q_SIGNALS: + /* pid is the sending process id */ + void transition(int pid); /* Finite State Machine Driven Signal */ + +public Q_SLOTS: + /* Qt signal handlers. */ + void handleSigUsr1(); + +private: + static int sigusr1Fd[2]; + QSocketNotifier *snUsr1; +}; + +#endif // UNIXSIGNALLISTENER_H diff --git a/src/users.cpp b/src/users.cpp new file mode 100644 index 0000000..03c87e6 --- /dev/null +++ b/src/users.cpp @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2018 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 . + * +**/ +#include "users.h" + +#include +#include +#include +#include +#include +#include + +#include "types.h" +#include +#include + +QDebug operator<<(QDebug stream, const UserItem &user) +{ + stream << user.name << user.realName << user.uid + << user.icon << user.path; + return stream; +} + +Users::Users(QObject *parent) : QObject(parent) +{ + if (Utils::isCommunity()) { + defaultIcon = ":/image/assets/01-default-community.png"; + } else { + defaultIcon = ":/image/assets/01-default-commercial.png"; + } + loadUsers(); +} + +QList Users::getUsers() +{ + return users; +} + +UserItem Users::getUserByName(const QString &name) +{ + for(int i = 0 ; i < users.size() ; i++) { + if(users.at(i).name == name) + { + return users.at(i); + } + } + UserItem user; + if(name == "root") + { + user.icon = "/root/.face"; + if(!QFile(user.icon).exists()) + { + user.icon = defaultIcon; + } + } + else + { + user.icon = qgetenv("HOME")+"/.face"; + if(!QFile(user.icon).exists()) + { + user.icon = defaultIcon; + } + } + user.name = name; + user.path = ""; + user.realName = name; + user.uid = getuid(); + return user; +} + +QString Users::getDefaultIcon() +{ + return defaultIcon; +} + +bool compareBarData(const UserItem &user1, const UserItem &user2) +{ + if (user1.realName < user2.realName) + { + return true; + } + return false; +} + +//https://stackoverflow.com/questions/20206376/ +//how-do-i-extract-the-returned-data-from-qdbusmessage-in-a-qt-dbus-call +void Users::loadUsers() +{ + qDebug() << "loadUsers"; + actService = new QDBusInterface(ACT_DBUS_SERVICE, + ACT_DBUS_PATH, + ACT_DBUS_INTERFACE, + QDBusConnection::systemBus()); + + connect(actService, SIGNAL(UserAdded(const QDBusObjectPath&)), + this, SLOT(onUserAdded(const QDBusObjectPath&))); + connect(actService, SIGNAL(UserDeleted(const QDBusObjectPath&)), + this, SLOT(onUserDeleted(const QDBusObjectPath&))); + QDBusMessage ret = actService->call("ListCachedUsers"); + QList outArgs = ret.arguments(); //(QVariant(QDBusArgument,)) + QVariant first = outArgs.at(0); //QVariant(QDBusArgument,) + const QDBusArgument &dbusArgs = first.value(); + QDBusObjectPath path; + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) + { + dbusArgs >> path; + getUser(path.path()); + } + dbusArgs.endArray(); + qSort(users.begin(), users.end(), compareBarData); +} + +UserItem Users::getUser(const QString &path) +{ + QDBusInterface iface(ACT_DBUS_SERVICE, + path, + DBUS_PROP_INTERFACE, + QDBusConnection::systemBus()); + QDBusMessage ret = iface.call("GetAll", ACT_USER_INTERFACE); + QList outArgs = ret.arguments(); + QVariant first = outArgs.at(0); + const QDBusArgument &dbusArgs = first.value(); + UserItem user; + user.path = path; + dbusArgs.beginMap(); + while(!dbusArgs.atEnd()) + { + QString key; + QVariant value; + dbusArgs.beginMapEntry(); + dbusArgs >> key >> value; + if(key == "UserName") + { + user.name = value.toString(); + } + else if(key == "RealName") + { + user.realName = value.toString(); + } + else if(key == "IconFile") + { + user.icon = value.toString(); + if(!QFile(user.icon).exists()) + { + user.icon = defaultIcon; + } + } + else if(key == "Uid") + { + user.uid = value.toUInt(); + } + dbusArgs.endMapEntry(); + } + dbusArgs.endMap(); + if(user.realName.isEmpty()) + { + user.realName = user.name; + } + users.push_back(user); + return user; +} + +void Users::onUserAdded(const QDBusObjectPath& path) +{ + int index = findUserByPath(path.path()); + if(index >=0 &&index= 0 && index. + * +**/ +#ifndef USERS_H +#define USERS_H + +#include + + +struct UserItem +{ + QString name; + QString realName; + QString icon; + quint64 uid; + QString path; //accounts service path + friend QDebug operator<<(QDebug stream, const UserItem &user); +}; + +class QDBusInterface; +class QDBusObjectPath; +class Users : public QObject +{ + Q_OBJECT +public: + explicit Users(QObject *parent = nullptr); + QList getUsers(); + UserItem getUserByName(const QString &name); + QString getDefaultIcon(); + +private: + void loadUsers(); + UserItem getUser(const QString &path); + int findUserByPath(const QString &path); + +private Q_SLOTS: + void onUserAdded(const QDBusObjectPath& path); + void onUserDeleted(const QDBusObjectPath& path); + +Q_SIGNALS: + void userAdded(const UserItem &user); + void userDeleted(const UserItem &user); + +private: + QDBusInterface *actService; + QList users; + QString defaultIcon; +}; + +#endif // USERS_H diff --git a/src/utils.cpp b/src/utils.cpp new file mode 100644 index 0000000..e5b7f50 --- /dev/null +++ b/src/utils.cpp @@ -0,0 +1,20 @@ +#include "utils.h" +#include + + +namespace Utils { + +bool isCommunity() +{ + QString filename = "/etc/os-release"; + QSettings osSettings(filename, QSettings::IniFormat); + + QString versionID = osSettings.value("VERSION_ID").toString(); + + if (versionID.compare("22.04", Qt::CaseSensitive)) { + return false; + } + return true; +} + +} diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..4966654 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,11 @@ +#ifndef UTILS_H +#define UTILS_H + +namespace Utils { + +// 是否为2204社区版本 +bool isCommunity(); + +} + +#endif // UTILS_H diff --git a/src/verificationwidget.cpp b/src/verificationwidget.cpp new file mode 100644 index 0000000..edbb92f --- /dev/null +++ b/src/verificationwidget.cpp @@ -0,0 +1,674 @@ +#include "verificationwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#include "wechatauthdialog.h" +#include "eduplatforminterface.h" +#include "accountsinterface.h" + +/** + * 忘记密码后,校验页面:分为二维码校验和手机号校验 + */ + +bool isDigitalString(QString s);//判断字符串是否全为数字 + +VerificationWidget::VerificationWidget(QWidget *parent) : QWidget(parent) +{ + qDebug() << "PermissionCheck"; + resize(1000,400); + QHBoxLayout *mainLayout = new QHBoxLayout(this); + setLayout(mainLayout); + + m_weChatWidget = new WeChatAuthDialog(1,this); + mainLayout->addWidget(m_weChatWidget, 1, Qt::AlignLeft); + m_weChatWidget->setFixedWidth(400); + + mainLayout->addSpacerItem(new QSpacerItem(0,200,QSizePolicy::Fixed,QSizePolicy::Expanding)); + + m_phoneAuthWidget = new PhoneAuthWidget(this); + mainLayout->addWidget(m_phoneAuthWidget, 1, Qt::AlignRight); + m_phoneAuthWidget->setFixedWidth(400); + + connect(m_phoneAuthWidget, &PhoneAuthWidget::pageMessage, this, [=](SwitchPage s, QList list){ + Q_EMIT pageMessage(s, list); + }); + + connect(m_weChatWidget, &WeChatAuthDialog::qRStatusChange, this, [=] (QString loginname, QString loginpwd, int curstatus){ + //QString loginname, QString loginpwd, int curstatus + if (loginname.isEmpty()) + { + // Todo?正在登陆???? + qDebug() << "wechar name is null"; + } else if(getenv("USER") == loginname) + { + Q_EMIT pageMessage(SwitchPage::SwitchToResetPWD, QList());; + } else { + qWarning() << "[error] Username does not match wechat<" << loginname << ">" << " local<" << getenv("USER")<<">"; + m_weChatWidget->showErrorMessage(tr("Please scan by bound WeChat")); + m_weChatWidget->onReset(); + } + }); +} + +VerificationWidget::~VerificationWidget() +{ + m_phoneAuthWidget->close(); + m_weChatWidget->close(); +} + +void VerificationWidget::paintEvent(QPaintEvent *) +{ + int x1 = width() / 2; + int y1 = height() / 4; + int x2 = x1; + int y2 = height() / 3 * 2 + y1; + QLinearGradient linearGra(QPoint(x1, y1), QPoint(x2, y2)); + linearGra.setColorAt(0, QColor(238, 238, 238, 0)); + linearGra.setColorAt(0.5, QColor(255, 255, 255, 138)); + linearGra.setColorAt(1, QColor(216, 216, 216, 0)); + + QPainter painter(this); + QBrush brush(linearGra); + painter.setPen(Qt::transparent); + painter.setBrush(brush); + painter.drawRoundedRect(QRect(x1, y1, 4, height() / 3 * 2), 16, 16); +} + +void VerificationWidget::reloadQR() +{ + m_weChatWidget->reloadQR(); +} + +InputInfos::InputInfos(QWidget *parent): + QWidget(parent) +{ + initUI(); + initConnect(); + setQSS(); +} + +void InputInfos::initUI() +{ + setFixedSize(316, 129); + QGridLayout *mainLayout = new QGridLayout(this); + setLayout(mainLayout); + mainLayout->setColumnStretch(1, 0); + mainLayout->setColumnStretch(2, 1); + mainLayout->setColumnStretch(3, 0); + + m_pPhoneIconLB = new QLabel(this); + m_pPhoneIconLB->setPixmap(QPixmap(":/image/assets/intel/phone.png")); + mainLayout->addWidget(m_pPhoneIconLB, 0, 1, 1, 1, Qt::AlignLeft); + + m_pPhoneLE = new QLineEdit(this); + m_pPhoneLE->setReadOnly(true); + //限制以下特殊符号在lineEdit中的输入 + /*需求变更,不需要用户输入手机号,直接获取已绑定的手机号显示给用户 + QRegExp phoneNumrx = QRegExp("^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$"); + QRegExpValidator *phoneNumValidator = new QRegExpValidator(phoneNumrx); + m_pPhoneLE->setValidator(phoneNumValidator); + */ + m_pPhoneLE->setText("正在获取手机号..."); + GetPhoneNumThread *workerThread = new GetPhoneNumThread(this); + connect(workerThread, &GetPhoneNumThread::resultReady, this, &InputInfos::onGetPhoneNum); + connect(workerThread, &GetPhoneNumThread::finished, workerThread, &QObject::deleteLater); + workerThread->start(); + + m_pPhoneLE->setPlaceholderText("手机号"); + m_pPhoneLE->setProperty("class", "InputLine"); + mainLayout->addWidget(m_pPhoneLE, 0, 2, 1, 2, Qt::AlignLeft); + + m_pVerCodeIconLB = new QLabel(this); + m_pVerCodeIconLB->setPixmap(QPixmap(":/image/assets/sms.png")); + mainLayout->addWidget(m_pVerCodeIconLB, 1, 1, 1, 1, Qt::AlignLeft); + + //限制以下特殊符号在lineEdit中的输入 + QRegExp verCoderx = QRegExp("^[0-9]{6}$"); + QRegExpValidator *verCodeValidator = new QRegExpValidator(verCoderx); + m_pVerCodeLE = new MyLineEdit(this); + m_pVerCodeLE->setValidator(verCodeValidator); + mainLayout->addWidget(m_pVerCodeLE, 1, 2, 1, 1, Qt::AlignLeft); + + m_pGetVerCodeBT = new QPushButton(this); + m_pGetVerCodeBT->setText(tr("Get code")); + m_pGetVerCodeBT->setEnabled(false); + m_pGetVerCodeBT->setFocusPolicy(Qt::NoFocus); + m_pGetVerCodeBT->setProperty("class", "GetCodeBT"); + m_pGetVerCodeBT->setCursor(QCursor(Qt::PointingHandCursor)); + mainLayout->addWidget(m_pGetVerCodeBT, 1, 3, 1, 1, Qt::AlignLeft); + + m_pNextGetVerCodeQTimer = new QTimer(this); + + m_curInputState = InputState::InputWaiting; + + m_networkWatcher = new NetWorkWatcher(this); +} + +void InputInfos::initConnect() +{ + connect(m_pPhoneLE, &QLineEdit::textChanged, this, &InputInfos::onPhoneTextChanged); + + connect(m_pVerCodeLE, &QLineEdit::textChanged, this, &InputInfos::onVerCodeTextChanged); + + connect(m_pNextGetVerCodeQTimer, &QTimer::timeout, this, &InputInfos::onNextGetVerCodeTimer); + + connect(m_pGetVerCodeBT, &QPushButton::clicked, this, &InputInfos::onGetVerCode); + + connect(m_networkWatcher, &NetWorkWatcher::NetworkStateChanged, this, &InputInfos::onNetworkStateChanged); +} + +void InputInfos::setQSS() +{ + QString style_sheet = ".InputLine{" + "padding:10px 2px 10px 2px;" + "background-color:rgb(255,255,255,0);" + "color:black;" + "}" + ".GetCodeBT{" + "background:rgba(0,0,0,0);" + "color:rgba(38,38,38,115);" + "font-size:16px;" + "}"; + setStyleSheet(style_sheet); + //adjustSize(); +} + +void InputInfos::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(Qt::white); + painter.setBrush(Qt::white); + painter.drawRoundedRect(rect(), 16, 16); + painter.setPen(QColor(226, 226, 226)); + painter.drawLine(QLineF(0, m_pPhoneIconLB->y() + m_pPhoneIconLB->height() + 1, + width(), m_pPhoneIconLB->y() + m_pPhoneIconLB->height() + 1)); +} + +void InputInfos::onPhoneTextChanged(const QString &text) +{ + if(text.length() == 11 && isDigitalString(text)){ + m_pGetVerCodeBT->setEnabled(true); + m_pGetVerCodeBT->setFocusPolicy(Qt::NoFocus); + m_pGetVerCodeBT->setStyleSheet("color:#2FB3E8;"); + + if(m_pVerCodeLE->text().length() == 6){ + Q_EMIT InputStateChanged(InputState::InputFinish); + m_curInputState = InputState::InputFinish; + } + } + else + { + m_pGetVerCodeBT->setEnabled(false); + m_pGetVerCodeBT->setStyleSheet("color:rgba(38, 38, 38, 115);"); + if(InputState::InputFinish == m_curInputState) + { + m_curInputState = InputState::InputWaiting; + Q_EMIT InputStateChanged(InputState::InputWaiting); + } + } +} + +void InputInfos::onNetworkStateChanged(uint state) +{ + if(NM_STATE_CONNECTED_LIMIT == state) + { + m_nextGetVerCodeTime = 0; + emit notGlobal(); + } + else if(NM_STATE_CONNECTED_GLOBAL != state) + { + m_nextGetVerCodeTime = 0; + emit offlineState(); + } + else + emit online(); +} + +void InputInfos::onVerCodeTextChanged(const QString &text) +{ + if(text.length() == 6 && m_pPhoneLE->text().length() == 11 && isDigitalString(m_pPhoneLE->text())) + { + Q_EMIT InputStateChanged(InputState::InputFinish); + m_curInputState = InputState::InputFinish; + } + else if(m_curInputState == InputState::InputFinish && text.length() > 0 && text.length() < 6) + { + Q_EMIT InputStateChanged(InputState::InputWaiting); + m_curInputState = InputState::InputWaiting; + } +} + +void InputInfos::clearInfos() +{ + m_pPhoneLE->clear(); + m_pVerCodeLE->clear(); + if(m_curInputState == InputState::InputFinish) + { + m_curInputState = InputState::InputWaiting; + Q_EMIT InputStateChanged(m_curInputState); + } +} + +QString InputInfos::getVerificationCode() +{ + return m_pVerCodeLE->text(); +} + +QString InputInfos::getPhoneNumer() +{ + return m_phoneNum; +} + +/** + * @brief InputInfos::onGetVerCode + * 获取手机验证码 + */ +void InputInfos::onGetVerCode() +{ + if(!m_networkWatcher->isConnect()) + { + emit offlineState(); + return; + } + + m_networkWatcher->checkOnline(); + + m_pGetVerCodeBT->setEnabled(false); + m_pGetVerCodeBT->setStyleSheet("color:rgba(38, 38, 38, 115);"); + m_nextGetVerCodeTime = 60; + m_pGetVerCodeBT->setText(tr("Recapture(60s)")); + m_pNextGetVerCodeQTimer->start(1000); + + QDBusReply reply = EduPlatformInterface::getInstance()->call("GetVerifyCode", getPhoneNumer()); + if(!reply.isValid()) + { + qDebug() << "info: [InputInfos][onGetVerCode]: DBus Connect Failed!"; + return; + } + // + if(reply.value() != 0) // 默认0为成功 + { + qDebug() << "info: [InputInfos][onGetVerCode]: DBus request failed!"; + return; + } +} + + +void InputInfos::onNextGetVerCodeTimer() +{ + if(m_nextGetVerCodeTime > 0) + --m_nextGetVerCodeTime; + if(m_nextGetVerCodeTime == 20 || m_nextGetVerCodeTime == 40) + m_networkWatcher->checkOnline(); + m_pGetVerCodeBT->setText(tr("Recapture(%1s)").arg(QString::number(m_nextGetVerCodeTime))); + if(m_nextGetVerCodeTime == 0) + { + m_pNextGetVerCodeQTimer->stop(); + m_pGetVerCodeBT->setEnabled(true); + m_pGetVerCodeBT->setFocusPolicy(Qt::NoFocus); + m_pGetVerCodeBT->setText(tr("Get code")); + m_pGetVerCodeBT->setStyleSheet("color:#2FB3E8;"); + return; + } + +} + +void InputInfos::onGetPhoneNum(int errorCode, const QString phoneNum) +{ + switch (errorCode) { + case DBusMsgCode::No_Error: + if(phoneNum != nullptr && phoneNum.size() == 11) + { + m_phoneNum = phoneNum; + m_pPhoneLE->setText(QString(phoneNum).replace(3,4,"****")); + } else { + qWarning() << "error: [InputInfos] onGetPhoneNum 获取到的手机号格式错误:" << phoneNum; + } + break; + case DBusMsgCode::Error_NoReply: + m_pPhoneLE->setText(tr("Service exception...")); + break; + case DBusMsgCode::Error_ArgCnt: + m_pPhoneLE->setText(tr("Invaild parameters...")); + break; + default: + m_pPhoneLE->setText(tr("Unknown fault:%1").arg(errorCode)); + break; + } + + if(DBusMsgCode::No_Error == errorCode && phoneNum != nullptr && phoneNum.size() == 11 && isDigitalString(phoneNum)) + { + + } else { + + qWarning() << "error: [InputInfos] onGetPhoneNum errorcode" << errorCode; + } +} + +void InputInfos::onClearInfo() +{ + m_pVerCodeLE->clear(); +} + +PhoneAuthWidget::PhoneAuthWidget(QWidget *parent) +{ + initUI(); + initConnect(); + setQSS(); +} + +void PhoneAuthWidget::initUI() +{ + QVBoxLayout *phoLayout = new QVBoxLayout(this); + phoLayout->setMargin(0); + + m_pPhoTitleLB = new QLabel(this); + m_pPhoTitleLB->setText(tr("Verification by phoneNum")); + m_pPhoTitleLB->setProperty("class", "titleLB"); + phoLayout->addWidget(m_pPhoTitleLB, 0, Qt::AlignHCenter); + + phoLayout->addSpacing(16); + m_pPhoPromptMsgLB = new QLabel(this); + m_pPhoPromptMsgLB->setText(tr("「 Use SMS to verification 」")); + m_pPhoPromptMsgLB->setProperty("class", "PromptText"); + phoLayout->addWidget(m_pPhoPromptMsgLB, 0, Qt::AlignHCenter); + + m_pPhoErrorMsgLB = new QLabel(this); + m_pPhoErrorMsgCloneLB = new QLabel(this); + m_pPhoErrorMsgLB->setProperty("class", "ErrorMsg"); + m_pPhoErrorMsgCloneLB->setProperty("class", "ErrorMsg"); + hidePhoneErrorMsg(); + phoLayout->addWidget(m_pPhoErrorMsgLB, 0, Qt::AlignHCenter); + phoLayout->addWidget(m_pPhoErrorMsgCloneLB, 0, Qt::AlignHCenter); + + + m_pPhoInputInfos = new InputInfos(this); + phoLayout->addWidget(m_pPhoInputInfos, 0, Qt::AlignHCenter); + + m_pPhoSubmitBT = new QPushButton(this); + m_pPhoSubmitBT->setFocusPolicy(Qt::NoFocus); + m_pPhoSubmitBT->setText(tr("commit")); + m_pPhoSubmitBT->setProperty("class", "BindBT"); + m_pPhoSubmitBT->setCursor(QCursor(Qt::PointingHandCursor)); + m_pPhoSubmitBT->setEnabled(false); + phoLayout->addSpacing(8); + phoLayout->addWidget(m_pPhoSubmitBT, 0, Qt::AlignHCenter); + phoLayout->addStretch(1); + + m_pPhoPromptMsgLB->setWordWrap(true); + + m_hideTimer = new QTimer(this); +} + +void PhoneAuthWidget::initConnect() +{ + connect(m_pPhoInputInfos, &InputInfos::InputStateChanged, this, &PhoneAuthWidget::onInputStateChanged); + + connect(m_pPhoSubmitBT, &QPushButton::clicked, this, &PhoneAuthWidget::onSubmitBTClick); + + connect(m_pPhoInputInfos, &InputInfos::getVerCode, this, &PhoneAuthWidget::onGetVerCode); + + connect(m_pPhoInputInfos, &InputInfos::offlineState, this, &PhoneAuthWidget::onOfflineState); + + connect(m_pPhoInputInfos, &InputInfos::notGlobal, this, &PhoneAuthWidget::onNotGlobal); + + connect(m_pPhoInputInfos, &InputInfos::online, this, &PhoneAuthWidget::hidePhoneErrorMsg); + + connect(m_hideTimer, &QTimer::timeout, this, &PhoneAuthWidget::hidePhoneErrorMsg); + + connect(this, &PhoneAuthWidget::clearInfo, m_pPhoInputInfos, &InputInfos::onClearInfo); +} + +QSize PhoneAuthWidget::sizeHint() const{ + return QWidget::sizeHint(); +} + +void PhoneAuthWidget::hidePhoneErrorMsg() +{ + m_pPhoErrorMsgCloneLB->setFixedHeight(m_pPhoErrorMsgLB->height()); + m_pPhoErrorMsgCloneLB->show(); + m_pPhoErrorMsgLB->hide(); +} + +void PhoneAuthWidget::showPhoneErrorMsg() +{ + if(m_hideTimer->isActive()) + m_hideTimer->stop(); + + m_pPhoErrorMsgLB->show(); + m_pPhoErrorMsgCloneLB->hide(); + + //QTimer::singleShot(5*1000, this,&PhoneAuthWidget::hidePhoneErrorMsg); + m_hideTimer->setSingleShot(true); + m_hideTimer->start(5*1000); +} + +void PhoneAuthWidget::onInputStateChanged(InputInfos::InputState input_state) +{ + if(m_pPhoErrorMsgLB->isVisible()) + hidePhoneErrorMsg(); + if(input_state == InputInfos::InputState::InputFinish) + { + m_pPhoSubmitBT->setEnabled(true); + m_pPhoSubmitBT->setFocusPolicy(Qt::NoFocus); + m_pPhoSubmitBT->setStyleSheet("background:#2FB3E8;"); + } + else + { + m_pPhoSubmitBT->setEnabled(false); + m_pPhoSubmitBT->setStyleSheet("background:rgba(255,255,255,115);"); + } +} + +void PhoneAuthWidget::onSubmitBTClick() +{ + QString tel = m_pPhoInputInfos->getPhoneNumer(); + QString verCode = m_pPhoInputInfos->getVerificationCode(); + + DBusMsgCode code = EduPlatformInterface::getInstance()->CheckUserByPhone(getenv("USER"), tel, verCode); + + switch (code) { + case DBusMsgCode::No_Error: + Q_EMIT pageMessage(SwitchPage::SwitchToResetPWD, QList()); + break; + case DBusMsgCode::Error_NetWork: + m_pPhoErrorMsgLB->setText(tr("Network not connected~")); + break; + case DBusMsgCode::Error_VerifyCode_Timeout: + m_pPhoErrorMsgLB->setText(tr("Verification Code invalid!")); + break; + case DBusMsgCode::Error_VerifyCodeDiff: + m_pPhoErrorMsgLB->setText(tr("Verification Code incorrect.Please retry!")); + break; + case Error_ErrTimesOverMax: + m_pPhoErrorMsgLB->setText(tr("Failed time over limit!Retry after 1 hour!")); + break; + default: + qWarning() << "[ERROR] verification error code is" << code; + m_pPhoErrorMsgLB->setText(tr("verifaction failed!")); + break; + } + if( code != DBusMsgCode::No_Error) + { + showPhoneErrorMsg(); + emit clearInfo(); + m_pPhoSubmitBT->setEnabled(false); + m_pPhoSubmitBT->setStyleSheet("background:rgba(255,255,255,115);"); + } +} + +void PhoneAuthWidget::onGetVerCode() +{ +// DBusMsgCode msgCode = SSOP->m_pRetrievePwdInterface->GetVerificationCode(Cfg->getUsername(), m_pPhoInputInfos->getPhoneNumer()); +// switch (msgCode) { +// case DBusMsgCode::No_Error: +// // 验证码获取无错误 +// break; +// // TODO 更新错误状态 +// default: +// break; +// } +} + +void PhoneAuthWidget::onOfflineState() +{ + m_pPhoErrorMsgLB->setText(tr("Network not connected~")); + showPhoneErrorMsg(); +} + +void PhoneAuthWidget::onNotGlobal() +{ + m_pPhoErrorMsgLB->setText(tr("Network unavailable~")); + showPhoneErrorMsg(); +} + +void PhoneAuthWidget::onQRCodeStateChanged(QString username, QString password, int nState) +{ + QRCodeSwepState state = static_cast(nState); + switch (state) { + case QRCodeSwepState::WaitingSwep: + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: waiting user swep qrcode!"; + break; + case QRCodeSwepState::HaveSwep: + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: user has swep code!"; + break; + case QRCodeSwepState::CancelSwep: + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: user cancel swep code!"; + break; + case QRCodeSwepState::ConfirmSuccess: + { + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: user = [" << username << "] confirm success!"; +// if(username != Cfg->getUsername()) +// { +// resetQRCService(); +// // TODO 更新错误信息 +// } +// else +// emit pageMessage(PageMessage::JumpToNewPswSet, QList()); +// break; + } + case QRCodeSwepState::QRCodeInvalid: + { + qDebug() << "info: [QRCodePhoneAuthWidget][onQRCodeStateChanged]: qrcode invalid!"; +// resetQRCService(); + break; + } + default: + break; + } +} + +void PhoneAuthWidget::setQSS() +{ + QString style_sheet =".PromptText{" + "font-size:24px;" + "color: rgba(255,255,255,192);" + "}" + ".BindBT{" + "background:rgba(255,255,255,115);" + "width:316px;" + "height:64px;" + "border-radius:16px;" + "}" + ".ErrorMsg{" + "color:#FD625E;" + "font-size:14px;" + "}" + ".titleLB{" + "color:#FFFFFF;" + "font-size:32px;" + "}"; + setStyleSheet(style_sheet); +} + +MyLineEdit::MyLineEdit(QWidget *parent) +{ + this->setStyleSheet("padding:10px 2px 10px 2px;" + "background-color:rgb(255,255,255,0);" + "color:grey;" + "font-size:16px"); + setText(tr("Verification code")); +} + +void MyLineEdit::focusInEvent(QFocusEvent *e) +{ + QLineEdit::focusInEvent(e); + if(text() == tr("Verification code")) + this->clear(); + this->setStyleSheet("padding:10px 2px 10px 2px;" + "background-color:rgb(255,255,255,0);" + "color:black;" + "font-size:16px"); +} + +void MyLineEdit::focusOutEvent(QFocusEvent *e) +{ + QLineEdit::focusOutEvent(e); + if(text().isEmpty()) + { + this->setStyleSheet("padding:10px 2px 10px 2px;" + "background-color:rgb(255,255,255,0);" + "color:grey;" + "font-size:16px"); + setText(tr("Verification code")); + } + +} + + + +GetPhoneNumThread::GetPhoneNumThread(QObject *parent) : QThread(parent) +{ + //获取手机号的dbus理论上也是耗时操作,故放到线程里面去请求 +} + +void GetPhoneNumThread::run() +{ + QString phoneNum = ""; + DBusMsgCode ret = DBusMsgCode::Error_UnknownReason; + /**极其不良的重试策略,如果没有服务或者网络问题,会导致不停地重试,应该做优化 + * 1、需要后台服务支持,如果不存在dbus服务,应该直接报错,当前绑定失败不意味着服务不存在,判断逻辑需要研究 + * 2、监听网络变化,网络状态变化时,断网时及时提醒用户网络未连接;联网时,如未获取到已绑定的手机号,需要重新获取; + * 网络异常时,固定次数的重试,都失败后提示用户网络请求异常,并提供可手动刷新的策略 + * */ + while (DBusMsgCode::No_Error != ret) + { + ret = AccountsInterface::getInstance()->GetUserPhone(getenv("USER"), phoneNum); + Q_EMIT resultReady(ret, phoneNum); + sleep(5); + } +} + + +bool isDigitalString(QString s) +{ + for(int i = 0; i< s.length(); i++) + { + if(s.at(i) > '9' || s.at(i) < '0') + { + qDebug() << "phoneNum error at" << i+1 << "position"; + return false; + } + if(i == 2) + i += 4; + } + + for(int i = 3; i< 7; i++) + { + if(s.at(i) != '*') + { + qDebug() << "phoneNum error at" << i+1 << "position unencrypted"; + return false; + } + } + return true; +} diff --git a/src/verificationwidget.h b/src/verificationwidget.h new file mode 100644 index 0000000..cbc13e7 --- /dev/null +++ b/src/verificationwidget.h @@ -0,0 +1,155 @@ +#ifndef VERIFICATIONWIDGET_H +#define VERIFICATIONWIDGET_H + +#include +#include +#include +#include +#include +#include "wechatauthdialog.h" +#include "common.h" +#include "networkwatcher.h" + +class InputInfos; +class PhoneAuthWidget; +class MyLineEdit; + +class InputInfos : public QWidget +{ + Q_OBJECT +public: + enum InputState{ + InputWaiting + , InputFinish + }; + InputInfos(QWidget *parent = nullptr); + QString getPhoneNumer(); + QString getVerificationCode(); + void clearInfos(); + +Q_SIGNALS: + void getVerCode(); + void InputStateChanged(InputState input_state); + void offlineState(); + void notGlobal(); + void online(); + +protected: + void paintEvent(QPaintEvent *); + +private Q_SLOTS: + void onPhoneTextChanged(const QString &text); + void onVerCodeTextChanged(const QString &text); + void onGetVerCode(); + void onNextGetVerCodeTimer(); + void onGetPhoneNum(int errorCode, const QString phoneNum); + void onNetworkStateChanged(uint state); + +public Q_SLOTS: + void onClearInfo(); + +private: + void initUI(); + void initConnect(); + void setQSS(); + +private: + QLabel *m_pPhoneIconLB; + QLineEdit *m_pPhoneLE; + QLabel *m_pVerCodeIconLB; + MyLineEdit *m_pVerCodeLE; + QPushButton *m_pGetVerCodeBT; + QTimer *m_pNextGetVerCodeQTimer; + int m_nextGetVerCodeTime; + QString m_phoneNum = nullptr; + + InputState m_curInputState; + NetWorkWatcher *m_networkWatcher; +}; + +class VerificationWidget : public QWidget +{ + Q_OBJECT +public: + explicit VerificationWidget(QWidget *parent = nullptr); + ~VerificationWidget(); + + void reloadQR(); + +Q_SIGNALS: + void pageMessage(SwitchPage id, QList argvs); +private: + QLabel *m_titleLB; + QLabel *m_phonePromptMsgLB; + WeChatAuthDialog *m_weChatWidget; +//public: + PhoneAuthWidget *m_phoneAuthWidget; + +protected: + void paintEvent(QPaintEvent *); +}; + +class PhoneAuthWidget : public QWidget +{ + Q_OBJECT +public: + PhoneAuthWidget(QWidget* parent = nullptr); + QSize sizeHint() const; + +private: + void initUI(); + void initConnect(); + void setQSS(); + + void showPhoneErrorMsg(); + void hidePhoneErrorMsg(); +Q_SIGNALS: + void pageMessage(SwitchPage id, QList argvs); + void clearInfo(); +private Q_SLOTS: + void onInputStateChanged(InputInfos::InputState input_state); + void onSubmitBTClick(); + void onGetVerCode(); + void onQRCodeStateChanged(QString username, QString password, int nState); + void onOfflineState(); + void onNotGlobal(); + + +private: + // 手机号验证 + QLabel *m_pPhoTitleLB; + QLabel *m_pPhoPromptMsgLB; + QLabel *m_pPhoErrorMsgLB; + QLabel *m_pPhoErrorMsgCloneLB; // 控制格式 + QPushButton *m_pPhoSubmitBT; + InputInfos *m_pPhoInputInfos; + QTimer *m_hideTimer; +}; + +class MyLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit MyLineEdit(QWidget *parent = nullptr); + +/*public Q_SLOTS: + void onTextChanged(const QString &text);*/ + +protected: + void focusInEvent(QFocusEvent *) override; + void focusOutEvent(QFocusEvent *) override; +}; + +class GetPhoneNumThread : public QThread +{ + Q_OBJECT +public: + GetPhoneNumThread(QObject *parent); + +protected: + void run() override; + +Q_SIGNALS: + void resultReady(int errorCode, const QString phoneNum); +}; +#endif // VERIFICATIONWIDGET_H diff --git a/src/verticalVerificationwidget.cpp b/src/verticalVerificationwidget.cpp new file mode 100644 index 0000000..1dd912a --- /dev/null +++ b/src/verticalVerificationwidget.cpp @@ -0,0 +1,87 @@ +#include "verticalVerificationwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#include "wechatauthdialog.h" +#include "eduplatforminterface.h" +#include "accountsinterface.h" + +/** + * 忘记密码后,校验页面:分为二维码校验和手机号校验 + */ + +VerticalVerificationWidget::VerticalVerificationWidget(QWidget *parent) : QWidget(parent) +{ + qDebug() << "PermissionCheck"; + resize(600,1000); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + setLayout(mainLayout); + + m_weChatWidget = new WeChatAuthDialog(1,this); + mainLayout->addWidget(m_weChatWidget, 1, Qt::AlignCenter); + + mainLayout->addSpacerItem(new QSpacerItem(0, 250, QSizePolicy::Fixed, QSizePolicy::Expanding)); + + m_phoneAuthWidget = new PhoneAuthWidget(this); + mainLayout->addWidget(m_phoneAuthWidget, 1, Qt::AlignCenter); + + connect(m_phoneAuthWidget, &PhoneAuthWidget::pageMessage, this, [=](SwitchPage s, QList list){ + Q_EMIT pageMessage(s, list); + }); + + connect(m_weChatWidget, &WeChatAuthDialog::qRStatusChange, this, [=] (QString loginname, QString loginpwd, int curstatus){ + //QString loginname, QString loginpwd, int curstatus + if (loginname.isEmpty()) + { + // Todo?正在登陆???? + qDebug() << "wechar name is null"; + } else if(getenv("USER") == loginname) + { + Q_EMIT pageMessage(SwitchPage::SwitchToResetPWD, QList());; + } else { + qWarning() << "[error] Username does not match wechat<" << loginname << ">" << " local<" << getenv("USER")<<">"; + m_weChatWidget->showErrorMessage(tr("Please scan by bound WeChat")); + m_weChatWidget->onReset(); + } + }); +} + +VerticalVerificationWidget::~VerticalVerificationWidget() +{ + m_phoneAuthWidget->close(); + m_weChatWidget->close(); +} + +void VerticalVerificationWidget::paintEvent(QPaintEvent *) +{ + int x1 = width() / 3; + int y1 = height() / 2; + int x2 = width() / 3 * 2 ; + int y2 = y1; + QLinearGradient linearGra(QPoint(x1, y1), QPoint(x2, y2)); + linearGra.setColorAt(0, QColor(238, 238, 238, 0)); + linearGra.setColorAt(0.5, QColor(255, 255, 255, 138)); + linearGra.setColorAt(1, QColor(216, 216, 216, 0)); + + QPainter painter(this); + QBrush brush(linearGra); + painter.setPen(Qt::transparent); + painter.setBrush(brush); + painter.drawRoundedRect(QRect(x1, y1, width() / 3 * 2, 4), 16, 16); +} + +void VerticalVerificationWidget::reloadQR() +{ + m_weChatWidget->reloadQR(); +} + + diff --git a/src/verticalVerificationwidget.h b/src/verticalVerificationwidget.h new file mode 100644 index 0000000..749dadc --- /dev/null +++ b/src/verticalVerificationwidget.h @@ -0,0 +1,34 @@ +#ifndef VERTICALVERIFICATIONWIDGET_H +#define VERTICALVERIFICATIONWIDGET_H + +#include +#include +#include +#include +#include + +#include "common.h" + +class VerticalVerificationWidget : public QWidget +{ + Q_OBJECT +public: + explicit VerticalVerificationWidget(QWidget *parent = nullptr); + ~VerticalVerificationWidget(); + + void reloadQR(); + +Q_SIGNALS: + void pageMessage(SwitchPage id, QList argvs); +private: + QLabel *m_titleLB; + QLabel *m_phonePromptMsgLB; + WeChatAuthDialog *m_weChatWidget; +//public: + PhoneAuthWidget *m_phoneAuthWidget; + +protected: + void paintEvent(QPaintEvent *); +}; + +#endif // VERTICALVERIFICATIONWIDGET_H diff --git a/src/weathermanager.cpp b/src/weathermanager.cpp new file mode 100644 index 0000000..e1738f2 --- /dev/null +++ b/src/weathermanager.cpp @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#include "weathermanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const QString weatherServerAddr = "http://service.ubuntukylin.com:8001/weather/api/3.0/heweather_data_s6/"; +const QString defaultCityId = "101030100"; //"101030100" 默认天津 +const int weatherReqInterval = 1000 * 60 * 20; //定时更新天气,和麒麟天气保持一致 + +const QByteArray schemaWeather = "org.china-weather-data.settings"; + +static const QMap weatherMap { + {"NA", "55"}, + {"晴", "0"}, + {"多云", "1"}, + {"阴", "2"}, + {"阵雨", "3"}, + {"雷阵雨", "4"}, + {"小雨", "7"}, + {"中雨", "8"}, + {"大雨", "9"}, + {"中到大雨", "9"}, + {"雪", "13"}, +}; + +WeatherManager::WeatherManager(QObject *parent) : QObject(parent) +{ + //初始化m_net_manager请求天气 + m_net_manager = new QNetworkAccessManager(this); + QObject::connect(m_net_manager, SIGNAL(finished(QNetworkReply*)), + this, SLOT(replyFinished(QNetworkReply*))); + + m_timer = new QTimer(this); + m_timer->setInterval(weatherReqInterval); + + m_local_weather_info = new LocalWeatherInfo(this); + + connect(m_timer, &QTimer::timeout, this, &WeatherManager::weatherRequest); +} + +void WeatherManager::getWeather() +{ + weatherRequest(); + if (m_timer != NULL) + { + m_timer->start(); + } + return; +} + +void WeatherManager::weatherRequest() +{ + if (updateLocation()) + return; + QNetworkRequest request(QUrl(weatherServerAddr + m_city_id + "/")); + m_net_manager->get(request); +} + +bool WeatherManager::updateLocation() +{ + //更新城市信息 未实现 麒麟天气提供gsettings,完成后对接 + if (QGSettings::isSchemaInstalled(schemaWeather)) { + m_settings = new QGSettings(schemaWeather,"",this); //org/ukui/indicator-china-weather path + if(getLogcalWeather()) + { + emit onWeatherUpdate(m_local_weather_info->getCityName(), + m_local_weather_info->getCondText(), + m_local_weather_info->getTemperature()); + return true; + } + m_city_id = getLogcalCityId(); + } + + if (m_city_id.isEmpty()) + m_city_id = defaultCityId; + + return false; +} + +bool WeatherManager::getLogcalWeather() +{ + if (m_settings != nullptr) + { + //"1920-08-27 10:17:42,101310204,澄迈,小雨,95%,25℃,北风,1级," 时间,城市编码,城市名称,天气,湿度,温度,风向,风力 + QString weather = m_settings->get("weather").toString(); + QStringList weatherInfoList = weather.split(","); + if (weatherInfoList.size() < 9) + return false; + m_local_weather_info->setTime(weatherInfoList.at(0)); + if(!m_local_weather_info->isTimeValid()) + return false; + + m_local_weather_info->setCityId(weatherInfoList.at(1)); + m_local_weather_info->setCityName(weatherInfoList.at(2)); + m_local_weather_info->setCondText(weatherInfoList.at(3)); + m_local_weather_info->setAirHumidity(weatherInfoList.at(4)); + m_local_weather_info->setTemperature(weatherInfoList.at(5)); + m_local_weather_info->setWindDirection(weatherInfoList.at(6)); + m_local_weather_info->setWindForce(weatherInfoList.at(7)); + return true; + } + + return false; +} + +QString WeatherManager::getLogcalCityId() +{ + if (m_settings != nullptr) { + QString citys = m_settings->get("citylist").toString();//"101010100," + if (citys.isEmpty()) + return ""; + + QStringList cityList = citys.split(","); + if (cityList.size() >= 1) + { + QString s = cityList.at(0); + qDebug() << "local city id = " << s; + return s; + } + } + return ""; +} + +void WeatherManager::replyFinished(QNetworkReply *reply) +{ + //注:天气信息只解析了锁屏需要展示的部分 + QByteArray BA; + QJsonDocument JD; + QJsonParseError JPE; + + BA = reply->readAll(); + // QTextCodec *codec = QTextCodec::codecForName("UTF-8"); + // QString all = codec->toUnicode(BA); + // qDebug() << "reply is:" << all; + + JD = QJsonDocument::fromJson(BA, &JPE); + if (JPE.error == QJsonParseError::NoError) + { + if (JD.isObject()) + { + QJsonObject kylinWeatherObj = JD.object().value("KylinWeather").toObject(); + + QString nowWeather = kylinWeatherObj.value("weather").toObject().value("now").toString(); + m_city_name = kylinWeatherObj.value("weather").toObject().value("location").toString(); + QStringList nowList = nowWeather.split(","); + for(QString now : nowList) + { + if(now.contains("cond_txt")) { + m_cond_txt = now.mid(9); + } + + if (now.contains("tmp")){ + m_temperature = now.mid(4); + } + } + emit onWeatherUpdate(m_city_name, m_cond_txt, m_temperature); + } + } else { + qWarning() << "get weather info error : " << JPE.errorString(); + } + + reply->deleteLater(); +} + +QPixmap WeatherManager::getWeatherIcon() +{ + return getWeatherIcon(m_cond_txt); +} + +QPixmap WeatherManager::getWeatherIcon(QString cond) +{ + if (cond.isEmpty()) + { + qWarning() << "cond info is unknown"; + return QPixmap(":/image/assets/weather/55.png").scaled(32,32); + } + + //根据m_cond_txt + QString numStr = weatherMap.value(cond); + if (!numStr.isEmpty()) { + qDebug() << "----------------numStr=" + numStr; + return QPixmap(":/image/assets/weather/" + numStr +".png").scaled(32,32); + } + + return QPixmap(":/image/assets/weather/55.png").scaled(32,32); +} + +LocalWeatherInfo::LocalWeatherInfo(QObject *parent) +{ +} + +bool LocalWeatherInfo::isTimeValid() +{ + if (m_update_time != nullptr && !m_update_time.isEmpty()) + { + QString strBuffer; + QDateTime time = QDateTime::fromString(m_update_time, "yyyy-MM-dd hh:mm:ss"); + QDateTime currentTime = QDateTime::currentDateTime(); + + if (!time.isValid()) + return false; + + uint timeInterval = currentTime.toTime_t() - time.toTime_t(); + + if((timeInterval <= 21 * 60) + && (timeInterval > 0)) + { + //麒麟天气更新时间为20分钟,加入1分钟容错机制 + return true; + } + } + return false; +} + +void LocalWeatherInfo::setTime(QString time) +{ + m_update_time = time; +} + +QString LocalWeatherInfo::getTime() +{ + return m_update_time; +} + +void LocalWeatherInfo::setCityId(QString cityId) +{ + m_city_id = cityId; +} + +QString LocalWeatherInfo::getCityId() +{ + return m_city_id; +} + +void LocalWeatherInfo::setCityName(QString cityName) +{ + m_city_name = cityName; +} + +QString LocalWeatherInfo::getCityName() +{ + return m_city_name; +} + +void LocalWeatherInfo::setCondText(QString condText) +{ + m_cond_text = condText; +} + +QString LocalWeatherInfo::getCondText() +{ + return m_cond_text; +} + +void LocalWeatherInfo::setAirHumidity(QString airHumidity) +{ + m_air_humidity = airHumidity; +} + +QString LocalWeatherInfo::getAirHumidity() +{ + return m_air_humidity; +} + +void LocalWeatherInfo::setTemperature(QString temperature) +{ + m_temperature = temperature; +} + +QString LocalWeatherInfo::getTemperature() +{ + return m_temperature; +} + +void LocalWeatherInfo::setWindDirection(QString windDirection) +{ + m_wind_direction = windDirection; +} + +QString LocalWeatherInfo::getWindDirection() +{ + return m_wind_direction; +} + +void LocalWeatherInfo::setWindForce(QString windForce) +{ + m_wind_force = windForce; +} + +QString LocalWeatherInfo::getWindForce() +{ + return m_wind_force; +} diff --git a/src/weathermanager.h b/src/weathermanager.h new file mode 100644 index 0000000..b1d2783 --- /dev/null +++ b/src/weathermanager.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#ifndef WEATHERMANAGER_H +#define WEATHERMANAGER_H + +#include +#include +#include +#include + +class QNetworkAccessManager; +class QNetworkReply; +class LocalWeatherInfo; + +class WeatherManager : public QObject +{ + Q_OBJECT +public: + explicit WeatherManager(QObject *parent = nullptr); + +Q_SIGNALS: + void onWeatherUpdate(QString city, QString cond, QString temperature); + +private Q_SLOTS: + void replyFinished(QNetworkReply *); + +public: + void getWeather(); + QPixmap getWeatherIcon(); + QPixmap getWeatherIcon(QString cond); + +private: + bool updateLocation();//更新位置,从用户设置获取城市信息,如有多个,只取第一个,未对接 + void weatherRequest(); + + bool getLogcalWeather(); + QString getLogcalCityId(); + +private: + QString m_city_id; // "101030100" 默认天津 + QString m_city_name; + QString m_cond_txt; //天气条件 晴、阴等 + QString m_temperature;//温度 10、20等 + + QNetworkAccessManager *m_net_manager; + QTimer *m_timer; + QGSettings *m_settings; + + LocalWeatherInfo *m_local_weather_info; +}; + +class LocalWeatherInfo : QObject +{ + //"1920-08-27 10:17:42,101310204,澄迈,小雨,95%,25℃,北风,1级," 时间,城市编码,城市名称,天气,湿度,温度,风向,风力 + Q_OBJECT +public: + explicit LocalWeatherInfo(QObject *parent = nullptr); + +private: + QString m_update_time; + QString m_city_id; + QString m_city_name; + QString m_cond_text; + QString m_air_humidity; + QString m_temperature; + QString m_wind_direction; + QString m_wind_force; +public: + bool isTimeValid(); + + void setTime(QString time); + QString getTime(); + + void setCityId(QString cityId); + QString getCityId(); + + void setCityName(QString cityName); + QString getCityName(); + + void setCondText(QString condText); + QString getCondText(); + + void setAirHumidity(QString airHumidity); + QString getAirHumidity(); + + void setTemperature(QString temperature); + QString getTemperature(); + + void setWindDirection(QString windDirection); + QString getWindDirection(); + + void setWindForce(QString windForce); + QString getWindForce(); +}; + +#endif // WEATHERMANAGER_H diff --git a/src/wechatauthdialog.cpp b/src/wechatauthdialog.cpp new file mode 100644 index 0000000..8deb3ed --- /dev/null +++ b/src/wechatauthdialog.cpp @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#include "wechatauthdialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "eduplatforminterface.h" + +WeChatAuthDialog::WeChatAuthDialog(QWidget *parent) : QWidget(parent), + m_networkManager(new QNetworkAccessManager(this)), + m_loginQR(new QRLabel(this)), + m_title(new QLabel(this)), + m_guide(new QLabel(this)), + m_errorMsg(new QLabel(this)), + m_networkWatcher(new NetWorkWatcher(this)), + m_timer(new QTimer(this)) +{ + initUI(); +} + +WeChatAuthDialog::WeChatAuthDialog(int type, QWidget *parent) : QWidget(parent), + m_networkManager(new QNetworkAccessManager(this)), + m_loginQR(new QRLabel(this)), + m_title(new QLabel(this)), + m_guide(new QLabel(this)), + m_errorMsg(new QLabel(this)), + m_networkWatcher(new NetWorkWatcher(this)), + m_timer(new QTimer(this)) +{ + m_authType = type; + initUI(); +} + +void WeChatAuthDialog::initUI() +{ + /** + * ************标题*************** + * **********提示信息************** + * **********二维码**************** + * **********错误信息*************** + */ + + this->setContentsMargins(0, 0, 0, 0); + QVBoxLayout *vbLayout = new QVBoxLayout(this); + vbLayout->setContentsMargins(0, 0, 0, 0); + + if (m_authType == authType::login) + { + m_title->setText(tr("Login by wechat")); + m_guide->setText(tr("「 Use registered WeChat account to login 」")); + } else if (m_authType == authType::check) + { + m_title->setText(tr("Verification by wechat")); + m_guide->setText(tr("「 Use bound WeChat account to verification 」")); + } + + m_errorMsg->setText(""); + m_title->setStyleSheet("font-size:32px;color:#ffffff"); + m_guide->setStyleSheet("font-size:24px;color: rgba(255,255,255,192);"); + m_errorMsg->setStyleSheet("font-size:14px;color:#FD625E;"); + m_guide->setWordWrap(true); + m_title->adjustSize(); + m_guide->adjustSize(); + + QPixmap pixmap(":/image/assets/intel/icon-wechat-noqrcode.png"); + m_loginQR->setPixmap(pixmap.scaled(188, 188, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + m_loginQR->setStyleSheet("QLabel{border-radius: 16px;background:rgb(255,255,255);color:white}"); + //m_loginQR->resize(208,208); + + vbLayout->addWidget(m_title, 0, Qt::AlignCenter); + vbLayout->addSpacerItem(new QSpacerItem(0,16,QSizePolicy::Fixed,QSizePolicy::Preferred)); + vbLayout->addWidget(m_guide, 0, Qt::AlignCenter); + vbLayout->addSpacerItem(new QSpacerItem(0,30,QSizePolicy::Fixed,QSizePolicy::Preferred)); + vbLayout->addWidget(m_loginQR, 0, Qt::AlignCenter); + vbLayout->addWidget(m_errorMsg, 0 ,Qt::AlignCenter); + vbLayout->addStretch(1); + this->adjustSize(); + + + +// //监听网络状态变化 +// QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), +// QString("/org/freedesktop/NetworkManager"), +// QString("org.freedesktop.NetworkManager"), +// QString("StateChanged"), this, SLOT(onNetworkStateChanged(uint))); + + connect(m_networkWatcher, &NetWorkWatcher::NetworkStateChanged, this, &WeChatAuthDialog::onNetworkStateChanged); + + connect(m_timer, &QTimer::timeout, this, [=]{ + m_errorMsg->clear(); + }); + +} + +void WeChatAuthDialog::onNetworkStateChanged(uint state) +{ + if(isHidden()) + return; + + if(NM_STATE_CONNECTED_GLOBAL == state) + showErrorMessage(" ", true); + else + showErrorMessage(tr("Network not connected~"), true); + +} + +void WeChatAuthDialog::onReset() +{ + if (m_authType == authType::login) + { + m_title->setText(tr("Login by wechat")); + m_guide->setText(tr("「 Use registered WeChat account to login 」")); + } else if (m_authType == authType::check) + { + m_title->setText(tr("Verification by wechat")); + m_guide->setText(tr("「 Use bound WeChat account to verification 」")); + } + m_guide->show(); + + QPixmap pixmap(":/image/assets/intel/icon-wechat-noqrcode.png"); + m_loginQR->setPixmap(pixmap.scaled(188, 188, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + m_loginQR->setStyleSheet("QLabel{border-radius: 16px;background:rgb(255,255,255);color:white}"); + //m_loginQR->resize(208,208); + reloadQR(); +} + +void WeChatAuthDialog::initConnect() +{ + QObject::connect(m_networkManager, &QNetworkAccessManager::finished, + this, &WeChatAuthDialog::replyFinished); +} + +void WeChatAuthDialog::getLoginQR() +{ + if(!m_requestQRThread) + { + qDebug() << "[WeChatAuthDialog] getLoginQR create new requestQRThread"; + m_requestQRThread = new RequestQRThread(this); + connect(m_requestQRThread, &RequestQRThread::resultReady, this, &WeChatAuthDialog::onQRUrlReady); + } + + if(!m_isThreadWorking){ + qDebug() << "[WeChatAuthDialog] getLoginQR requestQRThread is not running"; + m_requestQRThread->start(); + m_isThreadWorking = true; + } else { + qDebug() << "[WeChatAuthDialog] getLoginQR requestQRThread is running"; + } +} + +void WeChatAuthDialog::replyFinished(QNetworkReply *reply) +{ + if(!reply->isFinished()) + { + //超时 + reply->abort(); + qWarning() << "error: [WeChatAuthDialog][replyFinished]: network timeout"; + showErrorMessage(tr("Network not connected~")); + reloadQR(); + return; + } + + if (reply->error() == QNetworkReply::NoError) + { + QByteArray bytes = reply->readAll(); + + QSize size(188, 188); + QBitmap mask(size); + QPainter painter(&mask); + painter.setRenderHint(QPainter::Antialiasing); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.fillRect(0, 0, size.width(), size.height(), Qt::white); + painter.setBrush(QColor(0, 0, 0)); + painter.drawRoundedRect(0, 0, size.width(), size.height(), 16, 16); + + QPixmap pixmap; + pixmap.loadFromData(bytes); + QPixmap pixmap_ = pixmap.scaled(188, 188, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + + pixmap_.setMask(mask); + m_loginQR->setPixmap(pixmap_); + //m_loginQR->resize(208,208); + } + else + { + qWarning() << "网络错误" << reply->error(); + reloadQR(); + // 错误处理-显示错误信息,或显示上一次缓存的图片或叉图。 + } +} + +void WeChatAuthDialog::qRStatusChangeSolt(QString loginname, QString loginpwd, int curstatus) +{ + qDebug() << "---loginname:" << loginname << "---loginpwd:" << loginpwd << "---curstatus:" << curstatus; + QRCodeSwepState state = static_cast(curstatus); + switch (state) { + case QRCodeSwepState::WaitingSwep: + qDebug() << "info: [WeChatAuthDialog][qRStatusChangeSolt]: waiting user swep qrcode!"; + break; + case QRCodeSwepState::HaveSwep: + qDebug() << "info: [WeChatAuthDialog][qRStatusChangeSolt]: user has swep code!"; + m_title->setText(tr("Scan code successfully")); + m_guide->setText(" "); + m_errorMsg->setText(""); + break; + case QRCodeSwepState::CancelSwep: + qDebug() << "info: [WeChatAuthDialog][qRStatusChangeSolt]: user cancel swep code!"; + onReset(); + m_errorMsg->setText(""); + break; + case QRCodeSwepState::ConfirmSuccess: + { + //Todo 判断是否是该用户 + qDebug() << "info: [WeChatAuthDialog][qRStatusChangeSolt]: user = [" << loginname << "] confirm success!"; + Q_EMIT qRStatusChange(loginname, loginpwd, curstatus); + } + case QRCodeSwepState::QRCodeInvalid: + { + qDebug() << "info: [WeChatAuthDialog][onQRCodeStateChanged]: qrcode invalid!"; + onReset(); + break; + }case QRCodeSwepState::QRCodeTimeout: + { + qDebug() << "info: [UserSecondQRCodeLogin][onQRCodeState]: qrcode timeout!"; + onReset(); + // 更新错误信息 + showErrorMessage(tr("Timeout!Try again!")); + break; + } + default: + break; + } +} + + +void WeChatAuthDialog::reloadQR() +{ + if(this->parentWidget()->isHidden() || isHidden()) + return; + qDebug() << "info: [WeChatAuthDialog] [reloadQR] reloadQR"; + getLoginQR(); +} + +void WeChatAuthDialog::showErrorMessage(QString message, bool isLong) +{ + if (m_timer->isActive()) + m_timer->stop(); + onReset(); + m_errorMsg->setText(message); + m_errorMsg->adjustSize(); + m_errorMsg->setGeometry((this->width() - m_errorMsg->width())/2, + this->height() - m_errorMsg->height(), + m_errorMsg->width(), + m_errorMsg->height()); +// if(isLong) +// return; +// QTimer *timer = new QTimer(this); +// connect(timer, &QTimer::timeout, this, [=]{ +// m_errorMsg->setText(" "); +// }); +// timer->start(3000); + m_timer->setSingleShot(true); + m_timer->start(10000); +} + +void WeChatAuthDialog::onQRUrlReady(int errorCode, const QString url) +{ + m_isThreadWorking = false; + if (DBusMsgCode(errorCode) == DBusMsgCode::No_Error) + { + // 从网络上下载二维码 并加载到qrcode + QNetworkRequest request; + request.setUrl(url); + QNetworkReply *reply = m_networkManager->get(request); + QTimer::singleShot(2*1000, this, [=](){ + replyFinished(reply); + }); + } else if(DBusMsgCode(errorCode) == DBusMsgCode::Error_NetWork) + { + qWarning() << "[error] [WeChatAuthDialog] DBus(cn.kylinos.SSOBackend.eduplatform) get url network error"; + QTimer::singleShot(2 * 1000, this, [=]{ + if(this->isVisible() && !m_requestQRThread->isRunning()) + reloadQR(); + }); + } + else { + qWarning() << "[error] connect form DBus(cn.kylinos.SSOBackend.eduplatform)"; + QTimer::singleShot(2 * 1000, this, [=](){ reloadQR(); }); + } +} + +void WeChatAuthDialog::closeEvent(QCloseEvent *event) +{ + if(m_requestQRThread) { + qDebug() << "[WeChatAuthDialog] requestQRThread delete"; + m_requestQRThread->quit(); + m_requestQRThread->wait(); + m_requestQRThread->deleteLater(); + } +} + +void WeChatAuthDialog::showEvent(QShowEvent *event) +{ + m_networkWatcher->checkOnline(); + + onReset(); + connect(EduPlatformInterface::getInstance(),&EduPlatformInterface::QRStatusChange, + this, &WeChatAuthDialog::qRStatusChangeSolt); +} + +void WeChatAuthDialog::hideEvent(QHideEvent *event) +{ + disconnect(EduPlatformInterface::getInstance(),&EduPlatformInterface::QRStatusChange, + this, &WeChatAuthDialog::qRStatusChangeSolt); +} + +QRLabel::QRLabel(QWidget *parent) : QLabel(parent) +{ +} + +void QRLabel::mousePressEvent(QMouseEvent *event) +{ + if(event->button()== Qt::LeftButton) + { + Q_EMIT clicked(); + } +} + +RequestQRThread::RequestQRThread(QObject *parent) : QThread(parent) +{ + // +} + +void RequestQRThread::run() +{ + QString url; + DBusMsgCode ret = EduPlatformInterface::getInstance()->CheckUserByQR(url); + Q_EMIT resultReady(ret, url.toLocal8Bit()); +} diff --git a/src/wechatauthdialog.h b/src/wechatauthdialog.h new file mode 100644 index 0000000..57b183a --- /dev/null +++ b/src/wechatauthdialog.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2018 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 . + * + * Authors: ZHAI Kang-ning +**/ +#ifndef WECHATAUTHDIALOG_H +#define WECHATAUTHDIALOG_H + +#include +#include +#include +#include +#include + +#include +#include "networkwatcher.h" + +class QRLabel; +class RequestQRThread; + +/** + * @brief The WeChatAuthDialog class + * 微信登录、校验界面 + * 一、标题状态改变: + * 成功 事例: 1、微信登录->扫描成功->正在登录··· + * 微信不相符: 2、微信登录->登录失败 + */ +class WeChatAuthDialog : public QWidget +{ + Q_OBJECT +public: + explicit WeChatAuthDialog(QWidget *parent = nullptr); + explicit WeChatAuthDialog(int type, QWidget *parent = nullptr); + enum authType{ + login = 0, + check, + }; + + void reloadQR(); + void showErrorMessage(QString message, bool isLong = false); +// void updateStatus(int status); + void onReset(); + +protected: + void closeEvent(QCloseEvent *event) override; + void hideEvent(QHideEvent *event) override; + void showEvent(QShowEvent *event) override; + +Q_SIGNALS: + void authenticateCompete(bool result); + void qRStatusChange(QString loginname, QString loginpwd, int curstatus); + +private: + void initUI(); + void initConnect(); + + int m_authType = 0; + QNetworkAccessManager *m_networkManager; + QRLabel *m_loginQR; + QLabel *m_title; //标题 + QLabel *m_guide; //提示 + QLabel *m_errorMsg; //错误信息 + RequestQRThread *m_requestQRThread = nullptr; + bool m_isThreadWorking = false; + NetWorkWatcher *m_networkWatcher; + QTimer *m_timer; + + void getLoginQR(); + +private Q_SLOTS: + void replyFinished(QNetworkReply *); + void qRStatusChangeSolt(QString loginname, QString loginpwd, int curstatus); + void onQRUrlReady(int errorCode, const QString url); + void onNetworkStateChanged(uint state); +}; + +class QRLabel : public QLabel +{ + Q_OBJECT +public: + explicit QRLabel(QWidget *parent = nullptr); + +Q_SIGNALS: + void clicked(); + +protected: + void mousePressEvent(QMouseEvent *event) override; +}; + +class RequestQRThread : public QThread +{ + Q_OBJECT +public: + RequestQRThread(QObject *parent); + +protected: + void run() override; + +Q_SIGNALS: + void resultReady(int errorCode, const QString url); +}; + +#endif // WECHATAUTHDIALOG_H diff --git a/src/xeventmonitor.cpp b/src/xeventmonitor.cpp new file mode 100644 index 0000000..3d2feb4 --- /dev/null +++ b/src/xeventmonitor.cpp @@ -0,0 +1,208 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2011 ~ 2017 Deepin, Inc. + * 2011 ~ 2017 Wang Yong + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * Author: Wang Yong + * Maintainer: Wang Yong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * 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 . + */ + +#include +#include "xeventmonitor.h" +#include +#include +#include +#include +#include + +// Virtual button codes that are not defined by X11. +#define Button1 1 +#define Button2 2 +#define Button3 3 +#define WheelUp 4 +#define WheelDown 5 +#define WheelLeft 6 +#define WheelRight 7 +#define XButton1 8 +#define XButton2 9 + +class XEventMonitorPrivate +{ +public: + XEventMonitorPrivate(XEventMonitor *parent); + virtual ~XEventMonitorPrivate(); + void run(); + +protected: + XEventMonitor *q_ptr; + + bool filterWheelEvent(int detail); + static void callback(XPointer trash, XRecordInterceptData* data); + void handleRecordEvent(XRecordInterceptData *); + void emitButtonSignal(const char *member, xEvent *event); + void emitKeySignal(const char *member, xEvent *event); + +private: + Q_DECLARE_PUBLIC(XEventMonitor) +}; + +XEventMonitorPrivate::XEventMonitorPrivate(XEventMonitor *parent) + : q_ptr(parent) +{ + +} + +XEventMonitorPrivate::~XEventMonitorPrivate() +{ + +} + +void XEventMonitorPrivate::emitButtonSignal(const char *member, xEvent *event) +{ + int x = event->u.keyButtonPointer.rootX; + int y = event->u.keyButtonPointer.rootY; + QMetaObject::invokeMethod(q_ptr, member, + Qt::DirectConnection, + Q_ARG(int, x), + Q_ARG(int, y)); +} + +void XEventMonitorPrivate::emitKeySignal(const char *member, xEvent *event) +{ + if(QX11Info::display()){ + int keyCode = event->u.u.detail; + KeySym keySym = XkbKeycodeToKeysym(QX11Info::display(), event->u.u.detail, 0, 0); + char *keyStr = XKeysymToString(keySym); + QMetaObject::invokeMethod(q_ptr, member, + Qt::AutoConnection, + Q_ARG(int, keyCode)); + QMetaObject::invokeMethod(q_ptr, member, + Qt::AutoConnection, + Q_ARG(QString, keyStr)); + } +} + +void XEventMonitorPrivate::run() +{ + Display* display = XOpenDisplay(0); + if (display == 0) { + fprintf(stderr, "unable to open display\n"); + return; + } + + // Receive from ALL clients, including future clients. + XRecordClientSpec clients = XRecordAllClients; + XRecordRange* range = XRecordAllocRange(); + if (range == 0) { + fprintf(stderr, "unable to allocate XRecordRange\n"); + return; + } + + // Receive KeyPress, KeyRelease, ButtonPress, ButtonRelease and MotionNotify events. + memset(range, 0, sizeof(XRecordRange)); + range->device_events.first = KeyPress; + range->device_events.last = MotionNotify; + + // And create the XRECORD context. + XRecordContext context = XRecordCreateContext(display, 0, &clients, 1, &range, 1); + if (context == 0) { + fprintf(stderr, "XRecordCreateContext failed\n"); + return; + } + XFree(range); + + XSync(display, True); + + Display* display_datalink = XOpenDisplay(0); + if (display_datalink == 0) { + fprintf(stderr, "unable to open second display\n"); + return; + } + if (!XRecordEnableContext(display_datalink, context, callback, (XPointer) this)) { + fprintf(stderr, "XRecordEnableContext() failed\n"); + return; + } + +} + +void XEventMonitorPrivate::callback(XPointer ptr, XRecordInterceptData* data) +{ + ((XEventMonitorPrivate *) ptr)->handleRecordEvent(data); +} + +void XEventMonitorPrivate::handleRecordEvent(XRecordInterceptData* data) +{ + + if (data->category == XRecordFromServer) { + xEvent * event = (xEvent *)data->data; + switch (event->u.u.type) + { + case ButtonPress: + if (filterWheelEvent(event->u.u.detail)) { + emitButtonSignal("buttonPress", event); + } + break; + case MotionNotify: + emitButtonSignal("buttonDrag", event); + break; + case ButtonRelease: + if (filterWheelEvent(event->u.u.detail)) { + emitButtonSignal("buttonRelease", event); + } + break; + case KeyPress: + emitKeySignal("keyPress", event); + break; + case KeyRelease: + emitKeySignal("keyRelease", event); + break; + default: + break; + } + } + fflush(stdout); + XRecordFreeData(data); +} + +bool XEventMonitorPrivate::filterWheelEvent(int detail) +{ + return detail != WheelUp && detail != WheelDown && detail != WheelLeft && detail != WheelRight; +} + + +XEventMonitor::XEventMonitor(QObject *parent) + : QThread(parent), + d_ptr(new XEventMonitorPrivate(this)) +{ + Q_D(XEventMonitor); +} + +XEventMonitor::~XEventMonitor() +{ + requestInterruption(); + quit(); + wait(); +} + +void XEventMonitor::run() +{ + if(!isInterruptionRequested()) + { + d_ptr->run(); + } +} diff --git a/src/xeventmonitor.h b/src/xeventmonitor.h new file mode 100644 index 0000000..b30099d --- /dev/null +++ b/src/xeventmonitor.h @@ -0,0 +1,58 @@ +/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- + * -*- coding: utf-8 -*- + * + * Copyright (C) 2011 ~ 2017 Deepin, Inc. + * 2011 ~ 2017 Wang Yong + * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd. + * + * Author: Wang Yong + * Maintainer: Wang Yong + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * 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 . + */ + +#ifndef XEVENTMONITOR_H +#define XEVENTMONITOR_H + +#include +#include +#include + +class XEventMonitorPrivate; +class XEventMonitor : public QThread +{ + Q_OBJECT + +public: + XEventMonitor(QObject *parent = 0); + ~XEventMonitor(); + +Q_SIGNALS: + void buttonPress(int x, int y); + void buttonDrag(int x, int y); + void buttonRelease(int x, int y); + void keyPress(int keyCode); + void keyRelease(int keyCode); + void keyPress(const QString &key); + void keyRelease(const QString &key); + +protected: + void run(); + +private: + XEventMonitorPrivate *d_ptr; + Q_DECLARE_PRIVATE(XEventMonitor) +}; + +#endif