diff -Nru ukui-control-center-2.0.3/checkUserPwd/checkUserPwd.pro ukui-control-center-3.0.3/checkUserPwd/checkUserPwd.pro --- ukui-control-center-2.0.3/checkUserPwd/checkUserPwd.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwd/checkUserPwd.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,37 @@ +QT += core + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = checkuserpwd +#DESTDIR = .. +TEMPLATE = app + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked 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 it uses 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 += -L/usr/lib/ -lcrypt + +target.source += $$TARGET +target.path = /usr/bin +INSTALLS += \ + target \ + +SOURCES += \ + main.cpp + +HEADERS += + +# Default rules for deployment. +#qnx: target.path = /tmp/$${TARGET}/bin +#else: unix:!android: target.path = /opt/$${TARGET}/bin +#!isEmpty(target.path): INSTALLS += target diff -Nru ukui-control-center-2.0.3/checkUserPwd/main.cpp ukui-control-center-3.0.3/checkUserPwd/main.cpp --- ukui-control-center-2.0.3/checkUserPwd/main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwd/main.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,95 @@ +/* -*- 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. + * + */ + +extern "C" { + +#include +#include +#include + +#include + +} + +#define SHADOW_FILE "/etc/shadow" +#define BUFF_SIZE 256 +#define SIZE 256 + +static bool checkpwd(char * name, char * currentPwd); + +int main(int argc, char *argv[]) +{ +// QApplication a(argc, argv); +// Widget w; +// w.show(); +// return a.exec(); + if (3 == argc){ + if (checkpwd(argv[1], argv[2])) + printf("Success\n"); + } + + return 0; +} + +static bool checkpwd(char * username, char * currentPwd){ + + char buf[BUFF_SIZE+1] = {0}; /*缓冲区*/ + FILE *fp = NULL/*,*fd = NULL,*fp_check_shadow = NULL*/; /*文件指针*/ + int len = 0; /*行字符个数*/ + int line_len = 0; + char name[SIZE]={0}; + char pwd[SIZE]={0}; + char tmp_1[SIZE]={0}; + char tmp_2[SIZE]={0}; + char tmp_3[SIZE]={0}; + char tmp_4[SIZE]={0}; + char tmp_5[SIZE]={0}; + char tmp_6[SIZE]={0}; + char tmp_7[SIZE]={0}; + + if((fp = fopen(SHADOW_FILE,"r")) == NULL){ + perror("/etc/shadow fail to read\n"); + return false; + } + + while(fgets(buf,BUFF_SIZE,fp) != NULL){ + buf[BUFF_SIZE] = '\0'; + line_len = strlen(buf); + len += line_len; + sscanf(buf,"%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]", + name,pwd,tmp_1,tmp_2,tmp_3,tmp_4,tmp_5,tmp_6,tmp_7); + //printf("line_name:%s username:%s pwd:%s\n",name,username,pwd); + + if(0 == strcmp(name,username)){ + char * encrypted = NULL; + encrypted = crypt(currentPwd, pwd); + if ( encrypted && strcmp(encrypted, pwd) == 0){ + fclose(fp); + return true; + } else { + fclose(fp); + return false; + } + } + } + + fclose(fp); + return false; +} diff -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/auth.h ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/auth.h --- ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/auth.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/auth.h 2021-04-14 01:27:20.000000000 +0000 @@ -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, const QString &userPwd) = 0; + virtual void stopAuth() = 0; + virtual void respond(const QString &response) = 0; + virtual bool isAuthenticating() = 0; + virtual bool isAuthenticated() = 0; +}; + +#endif // AUTH_H diff -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/auth-pam.cpp ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/auth-pam.cpp --- ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/auth-pam.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/auth-pam.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,343 @@ +/* + * 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 +#include + +#include + + +#define PAM_SERVICE_NAME "control-center" + +//通信管道的文件描述符 +int toParent[2], toChild[2]; + +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); +static 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, const QString &userPwd) +{ + 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) + { + int arg1_int = toParent[1]; + int arg2_int = toChild[0]; + char arg1[128]; + char arg2[128]; + snprintf(arg1,128,"%d",arg1_int); + snprintf(arg2,128,"%d",arg2_int); + //_authenticate(userName.toLocal8Bit().data()); + prctl(PR_SET_PDEATHSIG,SIGHUP); + execlp ("childCheckpwdwithPAM", + "childCheckpwdwithPAM", + arg1, arg2,userName.toLocal8Bit().data(), NULL); + _exit (EXIT_FAILURE); + } + else + { + _isAuthenticating = true; + notifier = new QSocketNotifier(toParent[0], QSocketNotifier::Read); + connect(notifier, &QSocketNotifier::activated, this, &AuthPAM::onSockRead); + } + + QTimer::singleShot(100, this, [=]{respond(userPwd);}); + +} + +void AuthPAM::stopAuth() +{ +// qDebug()<<"pppppppppppppppppid = "<resp = (char *)malloc(sizeof(char) * respLength); + memcpy(r->resp, responseList[j].toLocal8Bit().data(), respLength); + j++; + } + } + _respond(resp); + free(resp); + resp = NULL; + messageList.clear(); + responseList.clear(); + } +} + +bool AuthPAM::isAuthenticated() +{ + return _isAuthenticated; +} + +bool AuthPAM::isAuthenticating() +{ + return _isAuthenticating; +} + + +void AuthPAM::onSockRead() +{ +// qDebug() << "has message"; + int msgLength; + int authComplete; + readData(toParent[0], &authComplete, sizeof(authComplete)); + + if(authComplete) + { + int authRet; + 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; + 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); + response = NULL; + 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) + return NULL; + + 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"; + } + free(newUser); + newUser = NULL; +// 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 -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/auth-pam.h ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/auth-pam.h --- ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/auth-pam.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/auth-pam.h 2021-04-14 01:27:20.000000000 +0000 @@ -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, const QString &userPwd); + 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 -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/checkUserPwd.pro ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/checkUserPwd.pro --- ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/checkUserPwd.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/checkUserPwd.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,38 @@ +QT += core + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = checkUserPwd +TEMPLATE = app + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked 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 it uses 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 += -lpam + +SOURCES += \ + auth-pam.cpp \ + main.cpp \ + widget.cpp + +HEADERS += \ + auth-pam.h \ + auth.h \ + widget.h + +target.source += $$TARGET +target.path = /usr/bin + + +INSTALLS += \ + target \ diff -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/main.cpp ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/main.cpp --- ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/main.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,18 @@ +#include "widget.h" + +#include + +#include + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + + Widget w; + if (argc == 3){ + w.pwdCheck(argv[1], argv[2]); + } + + return a.exec(); +} diff -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/widget.cpp ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/widget.cpp --- ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/widget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/widget.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,56 @@ +#include "widget.h" + +#include "auth-pam.h" + +#include + + +Widget::Widget() +{ + + auth = new AuthPAM(this); + + connect(auth, &Auth::showMessage, this, &Widget::onShowMessage); + connect(auth, &Auth::showPrompt, this, &Widget::onShowPrompt); + connect(auth, &Auth::authenticateComplete, this, &Widget::onAuthComplete); + +} + +Widget::~Widget() +{ + + auth->stopAuth(); + + delete auth; +} + +void Widget::pwdCheck(QString userName, QString userPwd){ + auth->authenticate(userName, userPwd); +} + +void Widget::onShowMessage(const QString &message, Auth::MessageType type) +{ +// qDebug() << "showMessage" << message; + +} + +void Widget::onShowPrompt(const QString &prompt, Auth::PromptType type) +{ +// qDebug() << "prompt: " << prompt; +} + +void Widget::onAuthComplete() +{ + + if(auth->isAuthenticated()){ +// qDebug() << "Succes!\n"; + printf("Succes!\n"); + } else { + printf("Failed!\n"); +// qDebug() << "Failed!"; + } + + exit(0); + +} + diff -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/widget.h ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/widget.h --- ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwd/widget.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwd/widget.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,27 @@ +#ifndef WIDGET_H +#define WIDGET_H + + +#include "auth-pam.h" + + +class Widget : public QObject +{ + Q_OBJECT + +public: + Widget(); + ~Widget(); + +public: + void pwdCheck(QString userName, QString userPwd); + +private: + Auth * auth; + +private Q_SLOTS: + void onShowMessage(const QString &message, Auth::MessageType type); + void onShowPrompt(const QString &prompt, Auth::PromptType type); + void onAuthComplete(); +}; +#endif // WIDGET_H diff -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwdWithPAM.pro ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwdWithPAM.pro --- ukui-control-center-2.0.3/checkUserPwdWithPAM/checkUserPwdWithPAM.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/checkUserPwdWithPAM.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,7 @@ +TEMPLATE = subdirs + +CONFIG += ordered + +SUBDIRS = \ + childCheckPwdWithPAM \ + checkUserPwd \ diff -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/childCheckPwdWithPAM/childCheckPwdWithPAM.pro ukui-control-center-3.0.3/checkUserPwdWithPAM/childCheckPwdWithPAM/childCheckPwdWithPAM.pro --- ukui-control-center-2.0.3/checkUserPwdWithPAM/childCheckPwdWithPAM/childCheckPwdWithPAM.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/childCheckPwdWithPAM/childCheckPwdWithPAM.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,38 @@ +QT += core + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = childCheckpwdwithPAM +TEMPLATE = app + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked 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 it uses 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 += -lpam + +SOURCES += \ + main.cpp + +HEADERS += + + +cf.files += ../conf/control-center +cf.path = /etc/pam.d/ + +target.source += $$TARGET +target.path = /usr/bin + + +INSTALLS += \ + cf \ + target \ diff -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/childCheckPwdWithPAM/main.cpp ukui-control-center-3.0.3/checkUserPwdWithPAM/childCheckPwdWithPAM/main.cpp --- ukui-control-center-2.0.3/checkUserPwdWithPAM/childCheckPwdWithPAM/main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/childCheckPwdWithPAM/main.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,166 @@ +/* -*- 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 +#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) + return NULL; + + 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("control-center", 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"); + } + free(newUser); + newUser = NULL; +// fprintf(stderr, "authentication result: %d\n", authRet); + + // 发送认证结果 + int authComplete = 1; + writeData(toParent, (const void*)&authComplete, sizeof(authComplete)); + writeData(toParent, (const void *)&authRet, sizeof(authRet)); + + /* ---认证完成\n*/ + _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 -Nru ukui-control-center-2.0.3/checkUserPwdWithPAM/conf/control-center ukui-control-center-3.0.3/checkUserPwdWithPAM/conf/control-center --- ukui-control-center-2.0.3/checkUserPwdWithPAM/conf/control-center 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/checkUserPwdWithPAM/conf/control-center 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,11 @@ +@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 -Nru ukui-control-center-2.0.3/commonComponent/CloseButton/closebutton.cpp ukui-control-center-3.0.3/commonComponent/CloseButton/closebutton.cpp --- ukui-control-center-2.0.3/commonComponent/CloseButton/closebutton.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/CloseButton/closebutton.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,265 @@ +/* CloseButton by David Peng + * 2020 10.20 + * Version Beta 1.0 + * 介绍:该控件是用于对话框的关闭按钮,只需指定父对象即可可自动回收。 + * 使用方法: + * 1、new CloseButton(this); //这样会直接调用主题的关闭按钮。 + * 2、new CloseButton(黑色图标路径,this); //这样会用一个黑色的'X'图标SVG,hover时会渲染成白色。 + * 3、new CloseButton(黑色图标路径,白色图标路径,this) //这样会用两张图片来实现图标显示。 +*/ + +#include "closebutton.h" +#include +#include + +#define THEME_QT_SCHEMA "org.ukui.style" +#define THEME_GTK_SCHEMA "org.mate.interface" + +CloseButton::CloseButton(QWidget *parent, const QString &filePath, const QString &hoverPath) : QLabel(parent) +{ + + //Allocation + + if(filePath != "" && filePath != "window-close-symbolic") + m_icon = new QIcon(filePath); + else if(filePath == "window-close-symbolic"){ + QIcon icon = QIcon::fromTheme("window-close-symbolic"); + m_icon = new QIcon(icon); + } else { + m_icon = nullptr; + } + if(hoverPath != "") + m_hoverIcon = new QIcon(hoverPath); + else + m_hoverIcon = nullptr; + + //Properties + //setProperty("useIconHighlightEffect", true); + //setProperty("iconHighlightEffectMode", 1); + setFocusPolicy(Qt::NoFocus); + + //Initial componentss + m_bIsChecked = false; + m_bIsPressed = false; + m_settedBkg = false; + m_szHoverIn = "white"; + m_szHoverOut = "default"; + m_cSize = 16; + m_colorBkg = palette().color(QPalette::Base); + setAlignment(Qt::AlignCenter); + + if(m_icon != nullptr) { + setPixmap(renderSvg(*m_icon,m_szHoverOut)); + } + if(QGSettings::isSchemaInstalled(THEME_GTK_SCHEMA) && QGSettings::isSchemaInstalled(THEME_QT_SCHEMA)) { + QByteArray qtThemeID(THEME_QT_SCHEMA); + QByteArray gtkThemeID(THEME_GTK_SCHEMA); + + m_gtkThemeSetting = new QGSettings(gtkThemeID,QByteArray(),this); + m_qtThemeSetting = new QGSettings(qtThemeID,QByteArray(),this); + + QString style = m_qtThemeSetting->get("styleName").toString(); + if(style == "ukui-black" || style == "ukui-dark") { + m_szHoverOut = "white"; + } else { + m_szHoverOut = "default"; + } + + connect(m_qtThemeSetting,&QGSettings::changed, [this] (const QString &key) { + QString style = m_qtThemeSetting->get("styleName").toString(); + if(key == "styleName") { + if(style == "ukui-black" || style == "ukui-dark") { + m_szHoverOut = "white"; + } else { + m_szHoverOut = "default"; + } + } + }); + } +} + +const QPixmap CloseButton::renderSvg(const QIcon &icon, QString cgColor) { + int size = m_cSize; + const auto ratio = qApp->devicePixelRatio(); + if ( 2 == ratio) { + size = m_cSize * 2; + } else if (3 == ratio) { + size = m_cSize * 3; + } + QPixmap iconPixmap = icon.pixmap(size,size); + iconPixmap.setDevicePixelRatio(ratio); + QImage img = iconPixmap.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); + // color.setAlpha(0.1); + color.setAlphaF(0.12); + 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 iconPixmap; + } + } + } + } + return QPixmap::fromImage(img); +} + +QPixmap CloseButton::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); + color.setAlphaF(0.9); + 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); +} + +void CloseButton::enterEvent(QEvent *event) { + Q_UNUSED(event); + if(m_hoverIcon == nullptr && m_icon != nullptr) + setPixmap(renderSvg(*m_icon,m_szHoverIn)); + else if(m_hoverIcon != nullptr && m_icon != nullptr) + setPixmap(m_hoverIcon->pixmap(m_cSize,m_cSize)); + else if(m_customIcon != nullptr) + setPixmap(renderSvg(*m_customIcon,m_szHoverIn)); + m_colorBkg = QColor("#FA6056"); +} + +void CloseButton::mousePressEvent(QMouseEvent *event) { + if(event->button() == Qt::LeftButton) + { + m_colorBkg = QColor("#E54A50"); + m_bIsPressed = true; + update(); + } +} + +void CloseButton::mouseReleaseEvent(QMouseEvent *event) { + Q_UNUSED(event); + if(m_bIsPressed && this->rect().contains(event->pos())) + { + m_bIsChecked = !m_bIsChecked; + emit clicked(m_bIsChecked); + m_bIsPressed = false; + } +} + +void CloseButton::leaveEvent(QEvent *event) { + Q_UNUSED(event); + m_colorBkg = m_customBkg.isValid() ? m_customBkg : palette().color(QPalette::Base); + if(m_icon != nullptr) + setPixmap(renderSvg(*m_icon,m_szHoverOut)); + else if(m_customIcon != nullptr) + setPixmap(renderSvg(*m_customIcon,m_szHoverOut)); + +} + +void CloseButton::paintEvent(QPaintEvent *event) { + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); // 反锯齿; + painter.setPen(Qt::transparent); + painter.setBrush(QBrush(m_colorBkg)); + painter.drawRoundedRect(rect(), 4, 4); + painter.end(); + return QLabel::paintEvent(event); +} + +void CloseButton::setIconSize(int size) { + m_cSize = size; + update(); +} + +void CloseButton::setIcon(const QIcon &icon) { + m_customIcon = new QIcon(icon); + setPixmap(renderSvg(*m_customIcon,m_szHoverOut)); +} + +void CloseButton::setBkg(const QColor &color) { + m_settedBkg = true; + m_customBkg = color; + m_colorBkg = m_customBkg; + if(m_icon != nullptr) { + setPixmap(renderSvg(*m_icon,m_szHoverOut)); + } else if(m_customIcon != nullptr) { + setPixmap(renderSvg(*m_customIcon,m_szHoverOut)); + } +} + +void CloseButton::setHoverIn(const QString &hoverIn) { + m_szHoverIn = hoverIn; + update(); +} + +void CloseButton::setHoverOut(const QString &hoverOut) { + m_szHoverOut = hoverOut; + if(m_icon != nullptr) { + setPixmap(renderSvg(*m_icon,m_szHoverOut)); + } else if(m_customIcon != nullptr) { + setPixmap(renderSvg(*m_customIcon,m_szHoverOut)); + } + update(); +} + +CloseButton::~CloseButton() { + if(m_icon != nullptr) { + delete m_icon; + m_icon = nullptr; + } + if(m_hoverIcon != nullptr) { + delete m_hoverIcon; + m_hoverIcon = nullptr; + } + if(m_customIcon != nullptr) { + delete m_customIcon; + m_customIcon = nullptr; + } +} + + diff -Nru ukui-control-center-2.0.3/commonComponent/CloseButton/closebutton.h ukui-control-center-3.0.3/commonComponent/CloseButton/closebutton.h --- ukui-control-center-2.0.3/commonComponent/CloseButton/closebutton.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/CloseButton/closebutton.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,54 @@ +#ifndef CLOSEBUTTON_H +#define CLOSEBUTTON_H + +#include +#include +#include +#include +#include +#include +#include + +class CloseButton : public QLabel +{ + Q_OBJECT +public: + explicit CloseButton(QWidget *parent = nullptr,const QString &filePath = "",const QString &hoverPath = ""); + + //Render icon from theme + const QPixmap renderSvg(const QIcon &icon, QString color); + // change svg picture's color + QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString color); + void setIcon(const QIcon &icon); + void setIconSize(int size); + void setBkg(const QColor &color); + void setHoverIn(const QString &hoverIn); + void setHoverOut(const QString &hoverOut); + + ~CloseButton(); +protected: + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); +private: + QIcon *m_icon; + QIcon *m_customIcon; + QIcon *m_hoverIcon; + bool m_bIsChecked; + bool m_bIsPressed; + QColor m_colorBkg; + int m_cSize; + bool m_settedBkg; + QColor m_customBkg; + QString m_szHoverOut; + QString m_szHoverIn; + QGSettings *m_qtThemeSetting; + QGSettings *m_gtkThemeSetting; + +Q_SIGNALS: + void clicked(bool checked = true); +}; + +#endif // CLOSEBUTTON_H diff -Nru ukui-control-center-2.0.3/commonComponent/closebutton.pri ukui-control-center-3.0.3/commonComponent/closebutton.pri --- ukui-control-center-2.0.3/commonComponent/closebutton.pri 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/closebutton.pri 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,8 @@ + +#LIBINTERFACE_NAME = $$qtLibraryTarget(switchbutton) + +SOURCES += \ + $$PWD/CloseButton/closebutton.cpp \ + +HEADERS += \ + $$PWD/CloseButton/closebutton.h \ diff -Nru ukui-control-center-2.0.3/commonComponent/ComboBox/combobox.cpp ukui-control-center-3.0.3/commonComponent/ComboBox/combobox.cpp --- ukui-control-center-2.0.3/commonComponent/ComboBox/combobox.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/ComboBox/combobox.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -73,6 +73,7 @@ QListWidgetItem * item = partListWidget->item(i); partListWidget->removeItemWidget(item); delete item; + item = nullptr; } } diff -Nru ukui-control-center-2.0.3/commonComponent/ComboxFrame/comboxframe.cpp ukui-control-center-3.0.3/commonComponent/ComboxFrame/comboxframe.cpp --- ukui-control-center-2.0.3/commonComponent/ComboxFrame/comboxframe.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/ComboxFrame/comboxframe.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,40 @@ +#include "comboxframe.h" + +ComboxFrame:: ComboxFrame(QString labelStr, QWidget *parent) : QFrame(parent), mTitleName(labelStr) { + + this->setMinimumSize(550, 50); + this->setMaximumSize(16777215, 50); + this->setFrameShape(QFrame::Shape::Box); + + mTitleLabel = new QLabel(mTitleName, this); + mCombox = new QComboBox(this); + + mHLayout = new QHBoxLayout(this); + mHLayout->addWidget(mTitleLabel); + mHLayout->addWidget(mCombox); + + this->setLayout(mHLayout); +} + +ComboxFrame::ComboxFrame(bool isNum, QString labelStr, QWidget *parent) : QFrame(parent), mTitleName(labelStr) +{ + Q_UNUSED(isNum) + this->setMinimumSize(550, 50); + this->setMaximumSize(16777215, 50); + this->setFrameShape(QFrame::Shape::Box); + + mTitleLabel = new QLabel(mTitleName, this); + mNumCombox = new QComboBox(this); + mCombox = new QComboBox(this); + + mHLayout = new QHBoxLayout(this); + mHLayout->addWidget(mTitleLabel); + mHLayout->addWidget(mNumCombox); + mHLayout->addWidget(mCombox); + + this->setLayout(mHLayout); +} + +ComboxFrame::~ComboxFrame() { + +} diff -Nru ukui-control-center-2.0.3/commonComponent/ComboxFrame/comboxframe.h ukui-control-center-3.0.3/commonComponent/ComboxFrame/comboxframe.h --- ukui-control-center-2.0.3/commonComponent/ComboxFrame/comboxframe.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/ComboxFrame/comboxframe.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,31 @@ +#ifndef COMBOXFRAME_H +#define COMBOXFRAME_H + +#include +#include +#include +#include +#include +#include + +class ComboxFrame : public QFrame +{ + Q_OBJECT +public: + ComboxFrame(QString labelStr, QWidget *parent = nullptr); + ComboxFrame(bool isNum, QString labelStr, QWidget *parent = nullptr); + ~ComboxFrame(); + +public: + QComboBox *mCombox; + QComboBox *mNumCombox; + QLabel *mTitleLabel; + QHBoxLayout *mHLayout; + +private: + QString mTitleName; + +signals: +}; + +#endif // COMBOXFRAME_H diff -Nru ukui-control-center-2.0.3/commonComponent/comboxframe.pri ukui-control-center-3.0.3/commonComponent/comboxframe.pri --- ukui-control-center-2.0.3/commonComponent/comboxframe.pri 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/comboxframe.pri 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,7 @@ +#LIBINTERFACE_NAME = $$qtLibraryTarget(comboxframe) + +SOURCES += \ + $$PWD/ComboxFrame/comboxframe.cpp \ + +HEADERS += \ + $$PWD/ComboxFrame/comboxframe.h \ \ No newline at end of file diff -Nru ukui-control-center-2.0.3/commonComponent/HoverBtn/hoverbtn.cpp ukui-control-center-3.0.3/commonComponent/HoverBtn/hoverbtn.cpp --- ukui-control-center-2.0.3/commonComponent/HoverBtn/hoverbtn.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/HoverBtn/hoverbtn.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,108 @@ +#include "hoverbtn.h" + +#include + +HoverBtn::HoverBtn(QString mname, bool isHide, QWidget *parent) : + mName(mname), mIsHide(isHide), QWidget(parent) +{ + this->setMaximumSize(960, 50); + this->setMinimumSize(550, 50); + initUI(); +} + +HoverBtn::HoverBtn(QString mname, QString detailName, QWidget *parent) : + mName(mname), mDetailName(detailName), QWidget(parent) +{ + this->setMaximumSize(960, 50); + this->setMinimumSize(550, 50); + initUI(); +} + +HoverBtn::~HoverBtn() { + +} + +void HoverBtn::initUI() { + + mIsHide ? (mHideWidth = 0) : (mHideWidth = 102); + + mInfoItem = new QFrame(this); + mInfoItem->setFrameShape(QFrame::Shape::Box); + mInfoItem->setGeometry(0, 0, this->width(), this->height()); + + mHLayout = new QHBoxLayout(mInfoItem); + mHLayout->setSpacing(8); + + mPitIcon = new QLabel(mInfoItem); + mHLayout->addWidget(mPitIcon); + + mPitLabel = new QLabel(mInfoItem); + mHLayout->addWidget(mPitLabel); + + mDetailLabel = new QLabel(mInfoItem); + mHLayout->addWidget(mDetailLabel); + + mHLayout->addStretch(); + + mAbtBtn = new QPushButton(this); + mAbtBtn->setVisible(false); + + initAnimation(); +} + +void HoverBtn::initAnimation() { + mMouseTimer = new QTimer(this); + mMouseTimer->setInterval(1); + + connect(mMouseTimer, &QTimer::timeout, this, [=] { + if (mAnimationFlag) { + if(mLeaveAction->state() != QAbstractAnimation::Running){ + mEnterAction->setStartValue(QRect(0, 0, mInfoItem->width(), mInfoItem->height())); + mEnterAction->setEndValue(QRect(0, 0, mInfoItem->width() - mHideWidth, mInfoItem->height())); + mEnterAction->start(); + } + } + mMouseTimer->stop(); + }); + + mEnterAction = new QPropertyAnimation(mInfoItem, "geometry"); + mEnterAction->setDuration(1); + mEnterAction->setEasingCurve(QEasingCurve::OutQuad); + + connect(mEnterAction, &QPropertyAnimation::finished, this, [=] { + mAbtBtn->setGeometry(this->width()-100, 2, 80, 45); + mAbtBtn->setVisible(!mIsHide); + }); + + mLeaveAction = new QPropertyAnimation(mInfoItem,"geometry"); + mLeaveAction->setDuration(1); + mLeaveAction->setEasingCurve(QEasingCurve::InQuad); +} + +void HoverBtn::resizeEvent(QResizeEvent *event) { + mInfoItem->resize(event->size()); +} + +void HoverBtn::enterEvent(QEvent *event) { + Q_UNUSED(event); + mAnimationFlag = true; + mMouseTimer->start(); +} + +void HoverBtn::leaveEvent(QEvent *event) { + Q_UNUSED(event); + + mAnimationFlag = false; + + mAbtBtn->setVisible(false); + + mLeaveAction->setStartValue(QRect(0, 0, mInfoItem->width(), mInfoItem->height())); + mLeaveAction->setEndValue(QRect(0, 0, this->width(), mInfoItem->height())); + mLeaveAction->start(); +} + +void HoverBtn::mousePressEvent(QMouseEvent *event) { + + emit widgetClicked(mName); + QWidget::mousePressEvent(event); +} diff -Nru ukui-control-center-2.0.3/commonComponent/HoverBtn/hoverbtn.h ukui-control-center-3.0.3/commonComponent/HoverBtn/hoverbtn.h --- ukui-control-center-2.0.3/commonComponent/HoverBtn/hoverbtn.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/HoverBtn/hoverbtn.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,62 @@ +#ifndef HOVERBTN_H +#define HOVERBTN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class HoverBtn : public QWidget +{ + Q_OBJECT +public: + HoverBtn(QString mname, bool isHide, QWidget *parent = nullptr); + HoverBtn(QString mname, QString detailName, QWidget *parent = nullptr); + ~HoverBtn(); + +public: + QString mName; + QString mDetailName; + QPushButton *mAbtBtn; + + QFrame *mInfoItem; + + QLabel *mPitIcon; + QLabel *mPitLabel; + QLabel *mDetailLabel; + + QHBoxLayout *mHLayout; + + QTimer *mMouseTimer; + + bool mAnimationFlag = false; + bool mIsHide; + + int mHideWidth; + + QPropertyAnimation *mEnterAction = nullptr; + QPropertyAnimation *mLeaveAction = nullptr; + +private: + void initUI(); + void initAnimation(); + +protected: + virtual void resizeEvent(QResizeEvent *event); + virtual void enterEvent(QEvent * event); + virtual void leaveEvent(QEvent * event); + virtual void mousePressEvent(QMouseEvent * event); + +Q_SIGNALS: + void widgetClicked(QString name); + void enterWidget(QString name); + void leaveWidget(QString name); +}; + +#endif // HOVERBTN_H diff -Nru ukui-control-center-2.0.3/commonComponent/hoverbtn.pri ukui-control-center-3.0.3/commonComponent/hoverbtn.pri --- ukui-control-center-2.0.3/commonComponent/hoverbtn.pri 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/hoverbtn.pri 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,8 @@ + +#LIBINTERFACE_NAME = $$qtLibraryTarget(hoverbtn) + +SOURCES += \ + $$PWD/HoverBtn/hoverbtn.cpp \ + +HEADERS += \ + $$PWD/HoverBtn/hoverbtn.h \ diff -Nru ukui-control-center-2.0.3/commonComponent/ImageUtil/imageutil.h ukui-control-center-3.0.3/commonComponent/ImageUtil/imageutil.h --- ukui-control-center-2.0.3/commonComponent/ImageUtil/imageutil.h 2020-06-18 07:43:39.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/ImageUtil/imageutil.h 2021-04-14 01:27:20.000000000 +0000 @@ -28,7 +28,7 @@ class ImageUtil { public: - static const QPixmap loadSvg(const QString &path, const QString color, int size = 48); + static const QPixmap loadSvg(const QString &path, const QString color, int size = 16); static QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor); }; diff -Nru ukui-control-center-2.0.3/commonComponent/listDelegate/listdelegate.cpp ukui-control-center-3.0.3/commonComponent/listDelegate/listdelegate.cpp --- ukui-control-center-2.0.3/commonComponent/listDelegate/listdelegate.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/listDelegate/listdelegate.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,40 @@ +/* -*- 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 "listdelegate.h" + +ListDelegate::ListDelegate(QObject *parent):QStyledItemDelegate(parent) +{ + +} + +ListDelegate::~ListDelegate() +{ + +} + +void ListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem optionVI = option; + if (option.state & QStyle::State_MouseOver) { + optionVI.state &= (~QStyle::State_MouseOver); + } + QStyledItemDelegate::paint(painter, optionVI, index); +} diff -Nru ukui-control-center-2.0.3/commonComponent/listDelegate/listdelegate.h ukui-control-center-3.0.3/commonComponent/listDelegate/listdelegate.h --- ukui-control-center-2.0.3/commonComponent/listDelegate/listdelegate.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/listDelegate/listdelegate.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,38 @@ +/* -*- 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 LISTDELEGATE_H +#define LISTDELEGATE_H + + +#include +#include +#include +#include + +class ListDelegate : public QStyledItemDelegate +{ +public: + ListDelegate(QObject *parent = nullptr); + ~ListDelegate(); + + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; +}; + +#endif // LISTDELEGATE_H diff -Nru ukui-control-center-2.0.3/commonComponent/listdelegate.pri ukui-control-center-3.0.3/commonComponent/listdelegate.pri --- ukui-control-center-2.0.3/commonComponent/listdelegate.pri 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/listdelegate.pri 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,8 @@ + +#LIBINTERFACE_NAME = $$qtLibraryTarget(listdelegate) + +SOURCES += \ + $$PWD/listDelegate/listdelegate.cpp \ + +HEADERS += \ + $$PWD/listDelegate/listdelegate.h \ diff -Nru ukui-control-center-2.0.3/commonComponent/MaskWidget/maskwidget.cpp ukui-control-center-3.0.3/commonComponent/MaskWidget/maskwidget.cpp --- ukui-control-center-2.0.3/commonComponent/MaskWidget/maskwidget.cpp 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/MaskWidget/maskwidget.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -38,6 +38,7 @@ void MaskWidget::paintEvent(QPaintEvent *event){ + Q_UNUSED(event) QPainter painter(this); painter.setRenderHint(QPainter:: Antialiasing, true); //设置渲染,启动反锯齿 diff -Nru ukui-control-center-2.0.3/commonComponent/SwitchButton/switchbutton.cpp ukui-control-center-3.0.3/commonComponent/SwitchButton/switchbutton.cpp --- ukui-control-center-2.0.3/commonComponent/SwitchButton/switchbutton.cpp 2020-06-18 07:43:39.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/SwitchButton/switchbutton.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -20,22 +20,18 @@ #include "switchbutton.h" #include +#define THEME_QT_SCHEMA "org.ukui.style" +#define THEME_GTK_SCHEMA "org.mate.interface" SwitchButton::SwitchButton(QWidget *parent) : QWidget(parent) { // this->resize(QSize(52, 24)); - this->setFixedSize(QSize(48, 24)); + this->setFixedSize(QSize(50, 24)); checked = false; - - borderColorOff = QColor("#cccccc"); - - bgColorOff = QColor("#cccccc"); - bgColorOn = QColor("#3D6BE5"); - - sliderColorOff = QColor("#ffffff"); - sliderColorOn = QColor("#ffffff"); + hover = false; + disabled = false; space = 4; // rectRadius = 5; @@ -47,6 +43,23 @@ timer = new QTimer(this); timer->setInterval(5); connect(timer, SIGNAL(timeout()), this, SLOT(updatevalue())); + if (QGSettings::isSchemaInstalled(THEME_GTK_SCHEMA) && QGSettings::isSchemaInstalled(THEME_QT_SCHEMA)) { + QByteArray qtThemeID(THEME_QT_SCHEMA); + QByteArray gtkThemeID(THEME_GTK_SCHEMA); + + m_gtkThemeSetting = new QGSettings(gtkThemeID,QByteArray(),this); + m_qtThemeSetting = new QGSettings(qtThemeID,QByteArray(),this); + + QString style = m_qtThemeSetting->get("styleName").toString(); + changeColor(style); + + connect(m_qtThemeSetting,&QGSettings::changed, [this] (const QString &key) { + QString style = m_qtThemeSetting->get("styleName").toString(); + if (key == "styleName") { + changeColor(style); + } + }); + } } SwitchButton::~SwitchButton() @@ -62,23 +75,57 @@ drawSlider(&painter); } +void SwitchButton::changeColor(const QString &themes) { + if (hover) { + return ; + } + + if (themes == "ukui-dark" || themes == "ukui-black") { + bgColorOff = QColor(OFF_BG_DARK_COLOR); + bgColorOn = QColor(ON_BG_DARK_COLOR); + rectColorEnabled = QColor(ENABLE_RECT_DARK_COLOR); + rectColorDisabled = QColor(DISABLE_RECT_DARK_COLOR); + sliderColorDisabled = QColor(DISABLE_RECT_DARK_COLOR); + sliderColorEnabled = QColor(ENABLE_RECT_DARK_COLOR); + bgHoverOnColor = QColor(ON_HOVER_BG_DARK_COLOR); + bgHoverOffColor = QColor(OFF_HOVER_BG_DARK_COLOR); + bgColorDisabled = QColor(DISABLE_DARK_COLOR); + } else { + bgColorOff = QColor(OFF_BG_LIGHT_COLOR); + bgColorOn = QColor(ON_BG_LIGHT_COLOR); + rectColorEnabled = QColor(ENABLE_RECT_LIGHT_COLOR); + rectColorDisabled = QColor(DISABLE_RECT_LIGHT_COLOR); + sliderColorDisabled = QColor(DISABLE_RECT_LIGHT_COLOR); + sliderColorEnabled = QColor(ENABLE_RECT_LIGHT_COLOR); + bgHoverOnColor = QColor(ON_HOVER_BG_LIGHT_COLOR); + bgHoverOffColor = QColor(OFF_HOVER_BG_LIGHT_COLOR); + bgColorDisabled = QColor(DISABLE_LIGHT_COLOR); + } +} + void SwitchButton::drawBg(QPainter *painter){ painter->save(); // painter->setPen(Qt::NoPen); - if (!checked){ + if (disabled) { painter->setPen(Qt::NoPen); - painter->setBrush(bgColorOff); - } - else{ - painter->setPen(Qt::NoPen); - painter->setBrush(bgColorOn); + painter->setBrush(bgColorDisabled); + } else { + if (!checked){ + painter->setPen(Qt::NoPen); + painter->setBrush(bgColorOff); + } + else { + painter->setPen(Qt::NoPen); + painter->setBrush(bgColorOn); + } } //circle out // QRect rect(space, space, width() - space * 2, height() - space * 2); // painter->drawRoundedRect(rect, rectRadius, rectRadius); //circle in + QRect rect(0, 0, width(), height()); //半径为高度的一半 int radius = rect.height() / 2; @@ -101,11 +148,11 @@ painter->save(); painter->setPen(Qt::NoPen); - if (!checked){ - painter->setBrush(sliderColorOff); + if (!disabled){ + painter->setBrush(sliderColorEnabled); } else - painter->setBrush(sliderColorOn); + painter->setBrush(sliderColorDisabled); //circle out // QRect rect(0, 0, width() - space, height() - space); // int sliderwidth = rect.height(); @@ -113,6 +160,17 @@ // painter->drawEllipse(sliderRect); //circle in + + if (disabled) { + if (checked) { + QRect smallRect(8, height() / 2 - 2, 10 , 4); + painter->drawRoundedRect(smallRect,3,3); + } else { + QRect smallRect(width() - 8 * 2, height() / 2 - 2, 10 , 4); + painter->drawRoundedRect(smallRect,3,3); + } + } + QRect rect(0, 0, width(), height()); int sliderWidth = rect.height() - space * 2; QRect sliderRect(startX + space, space, sliderWidth, sliderWidth); @@ -121,22 +179,32 @@ painter->restore(); } -void SwitchButton::mousePressEvent(QMouseEvent *){ - checked = !checked; - emit checkedChanged(checked); - - step = width() / 40; +void SwitchButton::mousePressEvent(QMouseEvent *event){ + if (timer->isActive()) { + return ; + } - if (checked){ - //circle out -// endX = width() - height() + space; - //circle in - endX = width() - height(); + if (!disabled){ + checked = !checked; + Q_EMIT checkedChanged(checked); + + step = width() / 40; + + if (checked){ + //circle out + // endX = width() - height() + space; + //circle in + endX = width() - height(); + } + else { + endX = 0; + } + timer->start(); } - else{ + else { endX = 0; } - timer->start(); + return QWidget::mousePressEvent(event); } void SwitchButton::resizeEvent(QResizeEvent *){ @@ -155,20 +223,43 @@ update(); } +void SwitchButton::enterEvent(QEvent *event) { + bgColorOn = bgHoverOnColor; + bgColorOff = bgHoverOffColor; + + hover = true; + update(); + return QWidget::enterEvent(event); +} + +void SwitchButton::leaveEvent(QEvent *event) { + hover = false; + + QString style = m_qtThemeSetting->get("styleName").toString(); + changeColor(style); + + update(); + return QWidget::leaveEvent(event); +} + void SwitchButton::updatevalue(){ + if (disabled) { + return ; + } + if (checked) if (startX < endX){ startX = startX + step; } - else{ + else { startX = endX; timer->stop(); } - else{ + else { if (startX > endX){ startX = startX - step; } - else{ + else { startX = endX; timer->stop(); } @@ -179,7 +270,7 @@ void SwitchButton::setChecked(bool checked){ if (this->checked != checked){ this->checked = checked; - emit checkedChanged(checked); + Q_EMIT checkedChanged(checked); update(); } @@ -191,7 +282,7 @@ //circle in endX = width() - height(); } - else{ + else { endX = 0; } timer->start(); @@ -201,4 +292,15 @@ return this->checked; } +void SwitchButton::setDisabledFlag(bool value) +{ + disabled = value; + update(); +} + +bool SwitchButton::getDisabledFlag() +{ + return disabled; +} + diff -Nru ukui-control-center-2.0.3/commonComponent/SwitchButton/switchbutton.h ukui-control-center-3.0.3/commonComponent/SwitchButton/switchbutton.h --- ukui-control-center-2.0.3/commonComponent/SwitchButton/switchbutton.h 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/SwitchButton/switchbutton.h 2021-05-20 13:08:14.000000000 +0000 @@ -25,6 +25,24 @@ #include #include #include +#include + +#define OFF_BG_DARK_COLOR "#404040" +#define OFF_HOVER_BG_DARK_COLOR "#666666" +#define ON_BG_DARK_COLOR "#3790FA" +#define ON_HOVER_BG_DARK_COLOR "#40A9FB" +#define DISABLE_DARK_COLOR "#474747" +#define DISABLE_RECT_DARK_COLOR "#6E6E6E" +#define ENABLE_RECT_DARK_COLOR "#FFFFFF" + +#define OFF_BG_LIGHT_COLOR "#E0E0E0" +#define OFF_HOVER_BG_LIGHT_COLOR "#B3B3B3" +#define ON_BG_LIGHT_COLOR "#3790FA" +#define ON_HOVER_BG_LIGHT_COLOR "#40A9FB" +#define DISABLE_LIGHT_COLOR "#E9E9E9" +#define DISABLE_RECT_LIGHT_COLOR "#B3B3B3" +#define ENABLE_RECT_LIGHT_COLOR "#FFFFFF" + class SwitchButton : public QWidget { @@ -37,24 +55,38 @@ void setChecked(bool checked); bool isChecked(); - + void setDisabledFlag(bool); + bool getDisabledFlag(); protected: void mousePressEvent(QMouseEvent *); void resizeEvent(QResizeEvent *); void paintEvent(QPaintEvent *); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void drawBg(QPainter * painter); void drawSlider(QPainter * painter); + void changeColor(const QString &themes); private: bool checked; - - QColor borderColorOff; + bool disabled; QColor bgColorOff; QColor bgColorOn; + QColor bgHoverOnColor; + QColor bgHoverOffColor; + QColor bgColorDisabled; + + QColor sliderColorEnabled; + QColor sliderColorDisabled; + + + QColor rectColorEnabled; + QColor rectColorDisabled; - QColor sliderColorOff; - QColor sliderColorOn; + QGSettings *m_qtThemeSetting; + QGSettings *m_gtkThemeSetting; int space; //滑块离背景间隔 int rectRadius; //圆角角度 @@ -63,10 +95,11 @@ int startX; int endX; + bool hover; QTimer * timer; -private slots: +private Q_SLOTS: void updatevalue(); diff -Nru ukui-control-center-2.0.3/commonComponent/Uslider/uslider.cpp ukui-control-center-3.0.3/commonComponent/Uslider/uslider.cpp --- ukui-control-center-2.0.3/commonComponent/Uslider/uslider.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/commonComponent/Uslider/uslider.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -4,9 +4,10 @@ #include #include #include +#include -Uslider::Uslider(QStringList list) : scaleList(list), QSlider(Qt::Horizontal) +Uslider::Uslider(QStringList list) : QSlider(Qt::Horizontal), scaleList(list) { this->setMinimumHeight(50); this->setMaximumHeight(100); @@ -14,36 +15,35 @@ void Uslider::paintEvent(QPaintEvent *e) { - QSlider::paintEvent(e); auto painter = new QPainter(this); - painter->setPen(QPen(Qt::black)); + painter->setBrush(QBrush(QColor(QPalette::Base))); auto rect = this->geometry(); - - int numTicks = (maximum() - minimum())/tickInterval(); - + int numTicks = (maximum() - minimum()) / tickInterval(); + int total = 0; QFontMetrics fontMetrics = QFontMetrics(this->font()); + for (int i=0; i <= numTicks; i++) { + QRect fontRect = fontMetrics.boundingRect(scaleList.at(i)); + total += fontRect.width(); + } + const int interval = (rect.width() - total) / numTicks; + if (this->orientation() == Qt::Horizontal) { int fontHeight = fontMetrics.height(); + int tickX = 1; + int tickY = rect.height() / 2 + fontHeight + 5; + for (int i=0; i <= numTicks; i++) { + QRect fontRect = fontMetrics.boundingRect(scaleList.at(i)); - for (int i=0; i<=numTicks; i++) { - int tickNum = minimum() + (tickInterval() * i); - - int tickX = (((rect.width()/numTicks) * i) - (fontMetrics.width(QString::number(tickNum *10))/2 + 2)); - int tickY = rect.height()/2 + fontHeight + 1; - - if( 0 == i) { - tickX += 11; - } else if (numTicks == i){ - tickX -= 10; - } painter->drawText(QPoint(tickX, tickY), - this->scaleList.at(i)); - } - } + this->scaleList.at(i)); + tickX += fontRect.width(); + tickX += interval; + } + } painter->end(); } Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/10.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/10.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/11.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/11.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/12.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/12.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/13.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/13.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/14.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/14.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/15.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/15.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/16.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/16.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/17.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/17.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/18.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/18.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/19.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/19.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/1.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/1.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/20.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/20.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/21.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/21.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/22.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/22.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/23.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/23.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/24.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/24.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/25.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/25.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/26.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/26.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/27.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/27.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/28.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/28.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/29.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/29.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/2.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/2.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/30.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/30.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/31.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/31.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/32.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/32.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/33.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/33.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/34.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/34.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/35.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/35.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/36.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/36.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/37.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/37.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/38.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/38.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/39.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/39.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/3.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/3.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/40.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/40.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/41.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/41.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/42.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/42.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/43.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/43.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/44.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/44.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/45.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/45.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/46.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/46.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/47.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/47.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/4.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/4.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/5.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/5.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/6.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/6.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/7.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/7.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/8.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/8.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/9.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/9.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/about.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/about.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/account-add.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/account-add.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/account-edit.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/account-edit.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/account-face.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/account-face.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/account.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/account.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/account-pwd.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/account-pwd.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/account-type.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/account-type.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/add-autoboot.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/add-autoboot.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/add-shortcut.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/add-shortcut.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/area-format.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/area-format.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/area.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/area.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/audio.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/audio.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/autoboot.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/autoboot.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/background.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/background.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/backup.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/backup.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/blutooth.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/blutooth.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/choicewidget.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/choicewidget.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/cloudaccount.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/cloudaccount.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/datetime-change.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/datetime-change.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/datetime.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/datetime.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/datetime-zone.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/datetime-zone.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/default.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/default.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/delegate.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/delegate.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/desktop.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/desktop.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/display.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/display.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/font.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/font.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/historylog.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/historylog.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/keyboard.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/keyboard.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/mouse.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/mouse.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/netconnect.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/netconnect.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/notice.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/notice.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/notiend.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/notiend.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/notiffirst.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/notiffirst.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/power-custom.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/power-custom.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/power.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/power.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/printer.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/printer.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/screenlock.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/screenlock.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/screensaver.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/screensaver.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/security.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/security.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/shortcut.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/shortcut.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/theme-cursor.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/theme-cursor.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/theme-effect.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/theme-effect.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/theme.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/theme.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/touchpad.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/touchpad.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/touchscreen.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/touchscreen.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/tray.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/tray.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/ukcc.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/ukcc.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/update.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/update.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/vino.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/vino.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/en_US/image/vpn.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/en_US/image/vpn.png differ diff -Nru ukui-control-center-2.0.3/data/en_US/index.md ukui-control-center-3.0.3/data/en_US/index.md --- ukui-control-center-2.0.3/data/en_US/index.md 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/data/en_US/index.md 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,323 @@ +# Ukui Control Center +## Overview +Ukui Control Center provides a friendly graphic interface to set the system. As shown in Fig 1. + +![Fig 1 Ukui Control Center-big](image/1.png) +
+ +## System +### Display +As shown in Fig 2. + +![Fig 2 Display-big](image/2.png) + +- monitor:Select current monitor. + +- resolution, orientation, refresh rate, screen zoom are all for the current active monitor. + +- screen zoom to global zoom. + +- night mode has the functions of adjusting color temperature and customizing the night mode time period. + +### Touchscreen +As shown in Fig 3. + +![Fig 3 Touchscreen](image/3.png) + +- monitor: Select the screen that you want to map to. + +- device: The name of the chosen touchscreen. + +### Defaultapp +As shown in Fig 4, browser, mail, image viewer, audio player, video player, text editor can be changed. + +![Fig 4 Defaultapp-big](image/4.png) + +### Power +- Provide "Balance", "Saving", "Custom" modes. + +![Fig 5 Power-big](image/5.png) + +- "Custom" includes "PC sleep time" and "DP close time". + +![Fig 6 Custom mode](image/6.png) + +### Auto Boot +List shows the existed autoboot applications. + +![Fig 7 Auto boot-big](image/7.png) + +Click "+" can add apps. + +
+ +## Devices +### Printer +Provide an entry to add printers or scanners. + +![Fig 8 Printer-big](image/8.png) + +### Mouse +Customize the mouse key, pointer settings, and cursor settings. + +![Fig 9 Mouse-big](image/9.png) + +### Touchpad +Touchpad provides the settings as shown in Fig 10. + +![Fig 10 Touchpad-big](image/10.png) + +### Keyboard +Set the keyboard's general items, and adjust the layout by the language. + +![Fig 11 Keyboard-big](image/11.png) + +- Enable repeat key: Long press one button will be recognized to repeat input. + +- Delay: The time between press button and receive input. + +- Speed: The time between repeat input. + +- Layout: Up to 4 layouts can be added. + +### Shortcut +View all the system shortcuts and customize shortcut. + +![Fig 12 Shortcut-big](image/12.png) + +Tips: System shortcuts are not allowed to be modified. + +Click "Add custom shortcut" and the popup as shown in Fig 13. + +![Fig 13 Add shortcut](image/13.png) + +### Audio +Settings for output, input and system sound, as shown in Fig 14. + +![Fig 14 Audio-big](image/14.png) + +### Bluetooth +Provide the functions like those: open the bluetooth, rename the device, show/hide the icon of the bluetooth, find the nearby devices, etc.. As shown in Fig 15. + +![Fig 15 Bluetooth-big](image/15.png) +
+ +## Personalized +### Background +Here are "picture" and "color" can be selected. + +![Fig 16 Background-big](image/16.png) + +### Theme +- Theme Mode: + +![Fig 17 Theme mode](image/17.png) + +- Icon theme and cursor theme: + +![Fig 18 Icon&cursor theme](image/18.png) + +- Effect settings (some machines do not support this function): + +![Fig 19 Effect settings](image/19.png) + +### Screenlock +Select the background image that shows in login interface. + +![Fig 20 Screenlock-big](image/20.png) + +### Fonts +Settings for font, size, mono font. + +Click "Reset to default" to restore the settings to default status. + +![Fig 21 Fonts-big](image/21.png) + +### Screensaver +Set the screensaver program and idle time. + +![Fig 22 Screensaver-big](image/22.png) + +### Desktop +Set the icons lock on Start Menu and Tray Menu. + +![Fig 23 Desktop-big](image/23.png) +
+ +## Network +It includes "Connect", "Vpn", "Proxy", and "Vino". + +![Fig 24 Network-big](image/24.png) + +### Connect +Show the available network, open wifi, etc.. + +#### Set Wired Connection +1) Click "Networking settings" to open the setting window. + +2) Click "+" and choose "Ethernet". In the "Ethernet" tab can select device. + +![Fig 25 Select device-big](image/25.png) + +3) In the "IPv4 Settings" tab can edit the net configuration. + +![Fig 26 Configuration-big](image/26.png) + +4) Click "Save", and the system will use this connection automatically. + +### Vpn +Open the settings of VPN. + +![Fig 27 Vpn-big](image/27.png) + +### Proxy +Auto proxy, manual proxy (including HTTP, HTTPS, FTP, SOCKS). + +![Fig 28 Proxy-big](image/28.png) + +### Vino +Users can set that confirm when conect or enter specified password after checking "Allow others to view your desktop". + +![Fig 29 Vino-big](image/29.png) +
+ +## Account +Manage all the system users, create/delete users, and modify users' informations. + +![Fig 30 Account-big](image/30.png) + +### User Info +#### Current User +- Change User Face: Click user's face can change it. + +![Fig 31 Change face](image/31.png) + +- Change Password: Click "Password" to modify the current user's password. + +![Fig 32 Change password](image/32.png) + +- Change Account Type: administrator -- can elevated permission temporarily; standard user -- can't elevated permission. + +![Fig 33 Change password](image/33.png) + +#### Other Users +Administrator can modify other user's information, add new user, etc.. + +- Add new user + +![Fig 34 Add new user](image/34.png) + +- Edit + +![Fig 35 Edit user](image/35.png) + +### Cloud Account +Synchronize personalized settings and data, and this function needs to sign in. + +![Fig 36 Cloud account-big](image/36.png) + +#### Sign In +Login through Kylin ID login Center. + +#### Synchronizable Items +- Desktop wallpaper + +- Screensaver: wallpaper and idle time + +- Fonts + +- User's face + +- The settings in control center, such as start menu, taskbar, theme, etc. + +- The settings of pluma, kylin weather, peony, terminal, kylin video. + +#### Tips +1) When opening the cloud account first time, it will synchronize once by default. If the cloud exists configuration files, it will download them and sync to local; Otherwise, the local configuration files will be uploaded to the cloud. + +2) After login, if the automatic synchronization is opened, the cloud will synchronize the local configurations every 5 minutes. And they can be used by different machines, different users. + +3) If the automatic synchronization is closed, all the cloud configurations will keep the last upload status. + +4) The automatic synchronization for the single item is the similar effects. + +
+ +## Datetime +As shown in Fig 37: + +![Fig 37 Datetime-big](image/37.png) + +- Sync from network: Sync the time on the Internet NTP server. + +- Change time: Manual set the time and date. + +![Fig 38 Change time](image/38.png) + +- Change time zone: + +![Fig 39 Time zone-big](image/39.png) + +### Area + +![Fig 40 Area-big](image/40.png) + +- change format of data: Customize calendar, first day of week, date, time. + +![Fig 41 Change format of data](image/41.png) + +- first language: Language in system windows, menus and website. + +- Click "Add main language" to add others. + +
+ +## Update +### Security Center +An access of security center. + +![Fig 42 Security center-big](image/42.png) + +### Backup +- Begin backup: Back up files to other devices. + +- Begin restore: View backup list and restore the system to one of them. + +![Fig 43 Backup-big](image/43.png) + +### Upgrade +Check whether the system has available updates. + +- Update: Show the current update status and the time of the latest refresh. + +- Update List: Push system available updates. + +- Update Settings: Whether allow to renewable notice and backup before updating. + +![Fig 44 Upgrade-big](image/44.png) + +The update history can be seen here. + +![Fig 45 History-big](image/45.png) + +#### Background Update +Silent upgrade in the background, and remind users of available updates. + +- Users will receive notification information before and after the upgrade. + +- When there exists an available update, the update icon will appear in the lower right corner. + +- If users agree to update, it will pop up the control center and check the update. + +
+ +## Messages +### Notice +As shown in Fig 46. + +![Fig 46 Notice-big](image/46.png) + +### About +Show the system version, authentication, etc.. + +![Fig 47 About-big](image/47.png) Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/10.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/10.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/1.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/1.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/2.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/2.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/3.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/3.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/4.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/4.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/5.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/5.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/6.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/6.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/7.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/7.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/8.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/8.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/faces/9.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/faces/9.png differ diff -Nru ukui-control-center-2.0.3/data/org.ukui.control-center.panel.plugins.gschema.xml ukui-control-center-3.0.3/data/org.ukui.control-center.panel.plugins.gschema.xml --- ukui-control-center-2.0.3/data/org.ukui.control-center.panel.plugins.gschema.xml 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/data/org.ukui.control-center.panel.plugins.gschema.xml 2021-04-14 01:27:20.000000000 +0000 @@ -5,6 +5,11 @@ HourSystem status hoursystem used in UKUI Desktop Environment ,ontrol by ukui-panel and ukui-control-center + + true + sync time from network + + 'lunar' Lunar calendar @@ -30,5 +35,10 @@ ukui-control-center sets the night mode status so that ukui-panel can get the status + + false + ukui-control-center theme changes follow with the night mode + + diff -Nru ukui-control-center-2.0.3/data/org.ukui.control-center.personalise.gschema.xml ukui-control-center-3.0.3/data/org.ukui.control-center.personalise.gschema.xml --- ukui-control-center-2.0.3/data/org.ukui.control-center.personalise.gschema.xml 2020-06-18 07:43:39.000000000 +0000 +++ ukui-control-center-3.0.3/data/org.ukui.control-center.personalise.gschema.xml 2021-05-20 13:08:14.000000000 +0000 @@ -1,14 +1,29 @@ - 0.95 + 0.75 Control the transparency of all components Control the transparency of all components + + + 75 + Save the transparency before the special effects mode is turned off + Save the transparency before the special effects mode is turned off 3 Control the frosted glass effect of the component 1- Low effect;2-Middle effect;3-High effect + + true + Control panel special effects transmit signal + ture:Special effects open; false: Special effects off + + + false + Whether to customize the power plan + Used to determine that the control panel user has customized a power plan + Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/ukui-control-center.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/ukui-control-center.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/about.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/about.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/account-add.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/account-add.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/account-edit.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/account-edit.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/account-face.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/account-face.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/account.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/account.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/account-pwd.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/account-pwd.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/account-type.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/account-type.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/add-autoboot.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/add-autoboot.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/add-shortcut.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/add-shortcut.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/area-format.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/area-format.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/area.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/area.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/audio.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/audio.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/autoboot.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/autoboot.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/background.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/background.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/backup.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/backup.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/blutooth.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/blutooth.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/choicewidget.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/choicewidget.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/cloudaccount.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/cloudaccount.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/datetime-change.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/datetime-change.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/datetime.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/datetime.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/datetime-zone.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/datetime-zone.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/default.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/default.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/delegate.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/delegate.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/desktop.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/desktop.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/display.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/display.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/font.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/font.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/historylog.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/historylog.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/keyboard.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/keyboard.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/mouse.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/mouse.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/netconnect.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/netconnect.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/notice.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/notice.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/notiend.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/notiend.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/notiffirst.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/notiffirst.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/power-custom.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/power-custom.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/power.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/power.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/printer.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/printer.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/screenlock.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/screenlock.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/screensaver.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/screensaver.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/security.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/security.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/shortcut.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/shortcut.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/theme-cursor.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/theme-cursor.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/theme-effect.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/theme-effect.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/theme.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/theme.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/touchpad.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/touchpad.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/touchscreen.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/touchscreen.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/tray.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/tray.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/ukcc.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/ukcc.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/update.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/update.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/vino.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/vino.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN/image/vpn.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN/image/vpn.png differ diff -Nru ukui-control-center-2.0.3/data/zh_CN/index.md ukui-control-center-3.0.3/data/zh_CN/index.md --- ukui-control-center-2.0.3/data/zh_CN/index.md 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/data/zh_CN/index.md 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,457 @@ +# 设置 +## 概 述 +设置提供了一个友好的图形用户界面,用于对操作系统常用配置项进行管理。主界面如图所示。 + +![图 1 设置-big](image/ukcc.png) +
+ +## 系 统 +系统配置设置提供了显示器、触摸屏、默认应用、电源、开机启动五个模块。 + +### 显示器 +显示器可以配置显示相关的设置,上方彩色矩形代表当前屏幕,中间显示了显示器名称及接口名,通过快捷键(Ctrl+A)可以保存用户的显示配置,如图所示。 + +![图 2 显示器设置-big](image/display.png) + +- 显示器:选择当前显示器 + +- 分辨率、方向、刷新率、缩放屏幕的修改都是针对当前活动显示器 + +- 屏幕缩放为全局缩放 + +- 夜间模式具有调整色温度、夜间模式自定义时间段打开/关闭 + +### 触摸屏 +触摸屏可以进行触摸相关的设置,在触摸点位置偏移时校准触点或调整触摸映射,如图所示。 + +![触摸屏-big](image/touchscreen.png) + +- 显示器:选择要映射到的显示器 + +- 触摸屏标识:选择要映射或校准的触摸屏 + +- 触摸设备:所选触摸屏名称 + +- 点击触摸映射按钮,将选定的触摸屏映射到指定显示器 + +- 点击触摸校准按钮,启动工具对选定触摸屏进行校准 + +### 默认应用 +默认应用可以修改图中几种类型的默认打开应用: + +![图 4 默认应用-big](image/default.png) + +### 电 源 +- 提供平衡、节能、自定义模式可选 + +![图 5-1 系统电源设置-big](image/power.png) + +- 在通用设置中可以设置电源图标显示或者隐藏 + +- 在“自定义”模式下,用户可设置系统在空闲多少时间后,挂起和关闭显示器 + +![图 5-2 自定义模式](image/power-custom.png) + +### 开机启动 +列表中显示当前系统已存在的开机启动软件。 + +![图 6 开机启动-big](image/autoboot.png) + +点击“添加自启动程序”,可添加开机启动应用。 + +![图 7 开机启动添加](image/add-autoboot.png) + +1)填写“程序名”; + +2)填写“程序路径”,或者通过点击“浏览”按钮,在弹出的文件选择界面,选择以desktop为后缀的文件; + +3)“程序描述”作为可选项,可填可不填; + +4)点击“确定”按钮,新的启动项被创建并显示在列表中。 + +
+ +## 设 备 +设备设置提供了打印机、鼠标、触摸板、键盘、快捷键、声音六个设置模块。 + +### 打印机 +打印机功能提供了打印机程序入口 +![图 8 打印机-big](image/printer.png) + +### 触摸板 +触摸板提供了以下功能设置 + +1)触摸板开启/关闭 + +2)打字时触摸板开启/关闭 + +3) 触摸板鼠标点击开启/关闭 + +4)触摸滚动方式(禁用滚动,垂直滚动,水平边界滚动,垂直双指滚动,水平双指滚动) +![图 9 触摸板-big](image/touchpad.png) + +### 鼠 标 +对鼠标键、鼠标指针、光标进行个性化设置。 + +1)鼠标键: + +- 习惯用手设置(左手/右手) + +- 滚轮速度设置 + +- 双击间隔时长 + +2)指针: + +- 指针移动速度 + +- 加速开关 + +- 按Ctrl键显示位置开关 + +- 指针大小设置(小,中,大) + +3)光标: + +- 文本区域光标闪烁开关 + +- 光标速度 + +![图 10 鼠标设备-big](image/mouse.png) + +### 键 盘 +对键盘进行常规通用设置,并能够根据键盘语言调整键盘布局。 + +![图 11 键盘设备-big](image/keyboard.png) + +1)启用按键重复设置:按下某个按键不放,系统会将该行为作为重复的键盘输入。启用按键重复设置后,可对延时、速度两个选项进行设置。 + +- 延时:按下按键后,到系统开始接收键盘输入之间的间隔 + +- 速度:按下按键后,重复输入之间的间隔;间隔越长,同样时间内,重复输入的次数越少 + +2)键盘布局:设置当前系统的键盘布局,最多可以添加4个键盘布局。 + +### 快捷键 +查看所有快捷键,添加或删除自定义快捷键。 + +![图 12 快捷键-big](image/shortcut.png) + +Tips:系统快捷键不允许修改。 + +点击“添加自定义快捷键”,弹出添加窗口。 + +![图 13 添加快捷键](image/add-shortcut.png) + +1)确认添加后,该快捷键的按键会显示“无效”; + +2)点击“disable”,并按下自定义的按键组合,若快捷键未被占用,则自动写入; + +3)鼠标悬浮在该快捷键上时,会出现删除按钮,若不再需要该快捷键,可点击删除。 + +### 声 音 +对输入、输出和系统音效进行设置,如图所示。 + +![图 14 声音-big](image/audio.png) + +- 主音量大小:调节当前的输出音量,通过移动滑动条来控制系统输出音量大小 + +- 选择输出设备:输出设备是获取声卡选择的输出配置文件生成的,可以点击下拉框查看当前系统可用的输出设备,可根据需要切换的对应的输出设备 + +- 声卡:获取当前系统的声卡 + +- 连接器:列出当前输出设备的输出端口,一般有扬声器,模拟耳机,多声道输出等(检测到输出设备有对应的输出端口才会显示) + +- 配置:获取当前声卡的可用的配置文件,切换声卡可用获取到另一个声卡的配置文件,切换配置相当于设置可用的输入输出设备 + +- 声道平衡:调节输出音量的左右声道 + +- 选择输入设备:输入设备是获取声卡选择的输入配置文件生成的,可以点击下拉框查看当前系统可用的输入设备,可根据需要切换的对应的输入设备(输入设备主要用来录音视频以及通话) + +- 音量大小:调节当前的输入音量,通过移动滑动条来控制系统输入音量大小 + +- 输入等级:检测当前输入设备的输入等级(检测到有可用的输入设备时开始检测输入等级) + +- 开关机音乐:控制系统开关机时是否播放开关机音乐 + +- 报警音量:控制终端提示音,调节声音等的提示音大小 + +- 系统音效主题:系统的声音主题 + +- 提示音量大小:提示音大小即系统发出的提示声音大小,除了受系统音量控制之外还可以通过该选项来调节 + +### 蓝牙 + +蓝牙模块提供了开关蓝牙、修改蓝牙名称、显示隐藏蓝牙任务图标、发现周围蓝牙设备;与发现的蓝牙设备配对、连接、断开、移除蓝牙设备的基本功能,如图所示。 + +- 开关蓝牙:点击开启蓝牙按钮,对本机的蓝牙适配器开启和关闭 + +- 修改蓝牙名称:将鼠标在“可以被发现为xxx”上双击,在输入框输入想要的名称 + +- 显示隐藏蓝牙任务栏图标:点击按钮,可以在任务上显示或者不显示托盘上的蓝牙图标 + +- 发现周围蓝牙设备:首次进入蓝牙模块后,会进行周围蓝牙设备的扫描,结束后点击刷新,再次进行扫描 + +- 发现的蓝牙涉笔基础操作:鼠标悬浮到发现的设备上,出现配对按钮,点击配对按钮与设备配对;点击移除按钮,移除设备;设备配对后会自己连接,出现在我的设备一栏,这时鼠标再悬浮到设备上,出现断开按钮,点击断开按钮与设备断开连接 + +![图 15 背景形式选择-big](image/blutooth.png) + +
+ +## 个性化 +个性化设置提供了背景、主题、锁屏、字体、屏保、桌面六个模块。 + +### 背 景 +针对桌面背景,提供两种背景形式的选择:颜色、图片。 + +![图 16 背景-big](image/background.png) + +### 主 题 +主题包括主题模式、图标主题、光标主题。 + +- 主题模式: + +![图 17 主题模式](image/theme.png) + +- 图标主题和光标主题: + +![图 18 图标&光标主题](image/theme-cursor.png) + +- 透明度和特效模式(部分机型不支持): + +![图 19 特效模式](image/theme-effect.png) + +### 锁 屏 + +选择在登录界面显示的背景图片。 + +![图 20 锁屏设置-big](image/screenlock.png) + +### 字 体 +对字体、大小、等宽进行常规设置。 + +点击“恢复默认设置”按钮将所有字体设置还原为系统默认状态。 + +![图 21 字体设置-big](image/font.png) + +### 屏 保 +设置屏保程序、等待时间。 + +![图 22 屏保设置-big](image/screensaver.png) + +### 桌 面 +设置锁定在开始菜单和托盘上的图标。 + +![图 23 桌面设置-big](image/desktop.png) +
+ +## 网 络 +网络主要包含了网络连接、VPN、代理、桌面共享。 + +### 网络连接 +网络连接包括,可用网络显示(无线,有线),开启/关闭wifi等功能,具体网络配置可参考“桌面环境”中的“网络”部分。 +![图 24 网络-big](image/netconnect.png) + +### VPN +打开外部VPN设置程序 +![图 25 VPN-big](image/vpn.png) + +### 代理 +自动代理开启/关闭,手动代理设置(包括HTTP, HTTPS, FTP,SOCKS代理) +![图 26 代理-big](image/delegate.png) + +### 桌面共享(部分机型不支持) +勾选“允许其他人查看您的桌面”后,可设置访问时需要确认,或者要求输入指定密码。 + +![图 27 桌面共享-big](image/vino.png) +
+ +## 账 户 +对系统用户进行管理配置,允许管理员创建用户、删除用户、修改用户信息。 + +![图 28 账户信息设置-big](image/account.png) + +### 当前用户 +#### 更改用户头像 +点击用户头像,即可进行修改,图片可从本机图片中选择。 + +![图 29 更改用户头像](image/account-face.png) + +#### 更改密码 +点击“更改密码”,即可修改当前用户的密码。 + +![图 30 更改密码](image/account-pwd.png) + +#### 更改账户类型 +系统用户类型分两种:标准用户和管理员用户。 + +- 管理员用户:输入用户密码,可以临时提升root权限 + +- 标准用户:无法提升权限 + +Tips:系统至少需要存在一个管理员用户。 + +![图 31 更改用户类型](image/account-type.png) + +### 其他用户 +可编辑其他用户信息,添加新用户,删除用户等。 + +- 添加新用户:输入用户名、密码,并选择用户类型,如图所示 + +![图 32 添加新用户](image/account-add.png) + +- 编辑用户 + +![图 33 编辑用户](image/account-edit.png) +
+ +## 云账户 +云账户可用于同步设置配置选项,需要注册登录生效。 + +![图 34 云账户-big](image/cloudaccount.png) +### 登录方式 +- 通过麒麟ID登录中心登录,使用云账户只需拥有麒麟ID即可。 + + +### 可同步项 +- 桌面壁纸:同步桌面壁纸 +- 屏保:同步屏保壁纸、屏保休眠时间等 +- 字体:同步设置字体设置 +- 头像:同步系统用户头像 +- 开始菜单:开始菜单的相关设置 +- 任务栏: 同步任务栏位置、大小等 +- 快速启动项:同步任务栏插件快速启动栏相关设置 +- 主题:同步设置主题设置 +- 鼠标:同步设置鼠标设置 +- 触摸板:如果有触摸板的话,同步设置触摸板界面 +- 键盘:同步设置键盘设置 +- 快捷键:同步设置自定义快捷键 +- 语言和地区:同步语言以及地区时区,并非一一对应设置 +- 时间和日期:同步时间,并非一一对应设置 +- 默认打开方式:同步设置默认应用相关设置 +- 侧边栏:同步设置通知页面相关设置 +- 登录选项:同步设置用户信息自动登录以及免密登录 +- 电源:同步设置电源相关选项 +- 文本编辑器:同步文本编辑器Pluma的设置,需要关闭所有Pluma进程并重新打开文本编辑器才能看到效果 +- 终端:同步终端设置资料卡,需要关闭所有终端实例再打开终端才能看到效果 +- 麒麟天气:同步麒麟天气设置 +- 文件管理器:同步文件管理器的设置,不包括置顶窗口设置 +- 开机启动项:同步设置开机启动设置 +- 麒麟影音:同步麒麟影音相关设置 + + +### 使用须知 +- 使用麒麟ID登录云账户,首次打开默认会同步一次,如果云端有配置文件,则会先把云端配置下载下来同步到本地,否则把本地账户配置上传到云端。 +- 登录云账户之后,如果打开了自动同步按钮,用户无需其他操作,云账户每隔5分钟会同步一次本地配置到云端,上传的配置可供跨机器,跨用户同步。 +- 单独的同步开关关闭会导致此项停止上传到云端,如果开启,则会将之前的此项的云端配置同步到本地。 +- 如果关闭自动同步按钮,所有云端配置将会保留在关闭同步前最后一次上传到云端的本地配置。 +- 如果开启自动同步按钮,则将云端配置下载下来并同步到本地。 +- 单独的开关类似自动同步按钮效果,只是同步效果范围变成了当前项的同步效果。 + +## 时间和日期 +主界面如图所示: + +![图 35 时间和日期-big](image/datetime.png) + +- 同步系统时间:与互联网上的NTP服务器时间同步 + +- 手动更改时间:手动设置时间和年月日 + +![图 36 手动更改时间](image/datetime-change.png) + +- 时间格式分12小时和24小时,点击右侧开关立即生效 + +- 更改时区:如图所示,根据个人需求进行选择 + +![图 37 时区-big](image/datetime-zone.png) + +### 语言和地区 +主界面如图所示: + +![图 38 区域语言-big](image/area.png) + +- 更改数据格式:自定义日历、一周第一天、日期、时间 + +![图 39 更改格式数据](image/area-format.png) + +- 首选语言:系统窗口、菜单及网页的显示语言,首选推荐语言为简体中文 + +- 点击“添加首选语言”,可添加其他地区语言作为备选 + +
+ +## 更 新 +### 安全中心 +提供了安全中心的入口。 + +![图 40 安全中心-big](image/security.png) + +### 备 份 +- 开始备份:将文件备份到其他驱动器 + +- 开始还原:查看备份列表,并选择还原点进行恢复 + +![图 41 备份和还原-big](image/backup.png) + +### 更 新 + +设置的更新模块可以检测检测系统是否有可用更新,更新模块主界面有系统状态、更新列表、更新设置三部分组成。 +
+ +- 系统状态:主要显示当前系统更新状态以及上次检测更新时间; + +- 更新列表:推送系统可用更新; + +- 更新设置:设置是否允许推送可更新的应用以及是否在全部更新之前自动备份。 +
+ +![图 42 系统更新-big](image/update.png) +
+ +更新完成后,可在更新历史中查看更新情况。 + + +![图 43 历史更新-big](image/historylog.png) + +### 后台更新 + +后台更新主要是在后台进行重要更新操作,以及提醒用户可用更新内容。 +
+ +- 当有重要更新时,会在后台静默更新,在升级前后用户都会收到通知信息。 + +![图 44 后台更新-big](image/notiffirst.png) + +![图 45 后台更新-big](image/notiend.png) + +- 当有可用更新时,右下角出现更新图标,并弹出选择界面供用户选择。 + +![图 46 后台更新-big](image/tray.png) + +![图 47 后台更新-big](image/choicewidget.png) + +- 当用户选择同意更新后,会弹出设置>更新界面,进行检查更新 + +- 当用户选择暂不更新时,退出后台更新程序 + + + +## 通知和操作 +### 通 知 +如图所示: + +![图 48 通知-big](image/notice.png) + +### 关 于 +显示本机系统的版本、设备规格、授权激活信息。 +![图 49 通知-big](image/about.png) +
+ +## 常见问题 +#### 点击开始菜单上的设置按钮,无反应 +在键盘上按下 Ctrl + Alt + T 组合键打开命令行终端,输入“ukui-control-center”后按下Enter,查看错误输出。 + +#### 修改控件状态后,控件立刻还原到修改前状态 +大概率是因为权限问题。 + +在键盘上按下 Ctrl + Alt + T 组合键打开命令行终端,输入“rm ~/.config/dconf/user”后按下Enter。 Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/about.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/about.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/account-add.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/account-add.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/account-edit.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/account-edit.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/account-face.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/account-face.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/account.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/account.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/account-pwd.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/account-pwd.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/account-type.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/account-type.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/add-autoboot.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/add-autoboot.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/add-shortcut.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/add-shortcut.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/area-format.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/area-format.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/area.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/area.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/audio.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/audio.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/autoboot.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/autoboot.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/background.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/background.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/backup.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/backup.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/blutooth.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/blutooth.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/choicewidget.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/choicewidget.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/cloudaccount.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/cloudaccount.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/datetime-change.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/datetime-change.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/datetime.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/datetime.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/datetime-zone.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/datetime-zone.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/default.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/default.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/delegate.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/delegate.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/desktop.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/desktop.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/display.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/display.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/font.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/font.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/historylog.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/historylog.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/keyboard.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/keyboard.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/mouse.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/mouse.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/netconnect.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/netconnect.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/notice.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/notice.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/notiend.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/notiend.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/notiffirst.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/notiffirst.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/power-custom.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/power-custom.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/power.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/power.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/printer.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/printer.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/screenlock.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/screenlock.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/screensaver.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/screensaver.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/security.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/security.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/shortcut.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/shortcut.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/theme-cursor.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/theme-cursor.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/theme-effect.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/theme-effect.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/theme.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/theme.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/touchpad.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/touchpad.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/touchscreen.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/touchscreen.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/tray.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/tray.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/ukcc.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/ukcc.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/update.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/update.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/vino.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/vino.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/image/vpn.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/image/vpn.png differ diff -Nru ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/index.md ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/index.md --- ukui-control-center-2.0.3/data/zh_CN_SW/zh_CN/index.md 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/data/zh_CN_SW/zh_CN/index.md 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,457 @@ +# 设置 +## 概 述 +设置提供了一个友好的图形用户界面,用于对操作系统常用配置项进行管理。主界面如图所示。 + +![图 1 设置-big](image/ukcc.png) +
+ +## 系 统 +系统配置设置提供了显示器、触摸屏、默认应用、电源、开机启动五个模块。 + +### 显示器 +显示器可以配置显示相关的设置,上方彩色矩形代表当前屏幕,中间显示了显示器名称及接口名,通过快捷键(Ctrl+A)可以保存用户的显示配置,如图所示。 + +![图 2 显示器设置-big](image/display.png) + +- 显示器:选择当前显示器 + +- 分辨率、方向、刷新率、缩放屏幕的修改都是针对当前活动显示器 + +- 屏幕缩放为全局缩放 + +- 夜间模式具有调整色温度、夜间模式自定义时间段打开/关闭 + +### 触摸屏 +触摸屏可以进行触摸相关的设置,在触摸点位置偏移时校准触点或调整触摸映射,如图所示。 + +![触摸屏-big](image/touchscreen.png) + +- 显示器:选择要映射到的显示器 + +- 触摸屏标识:选择要映射或校准的触摸屏 + +- 触摸设备:所选触摸屏名称 + +- 点击触摸映射按钮,将选定的触摸屏映射到指定显示器 + +- 点击触摸校准按钮,启动工具对选定触摸屏进行校准 + +### 默认应用 +默认应用可以修改图中几种类型的默认打开应用: + +![图 4 默认应用-big](image/default.png) + +### 电 源 +- 提供平衡、节能、自定义模式可选 + +![图 5-1 系统电源设置-big](image/power.png) + +- 在通用设置中可以设置电源图标显示或者隐藏 + +- 在“自定义”模式下,用户可设置系统在空闲多少时间后,挂起和关闭显示器 + +![图 5-2 自定义模式](image/power-custom.png) + +### 开机启动 +列表中显示当前系统已存在的开机启动软件。 + +![图 6 开机启动-big](image/autoboot.png) + +点击“添加自启动程序”,可添加开机启动应用。 + +![图 7 开机启动添加](image/add-autoboot.png) + +1)填写“程序名”; + +2)填写“程序路径”,或者通过点击“浏览”按钮,在弹出的文件选择界面,选择以desktop为后缀的文件; + +3)“程序描述”作为可选项,可填可不填; + +4)点击“确定”按钮,新的启动项被创建并显示在列表中。 + +
+ +## 设 备 +设备设置提供了打印机、鼠标、触摸板、键盘、快捷键、声音六个设置模块。 + +### 打印机 +打印机功能提供了打印机程序入口 +![图 8 打印机-big](image/printer.png) + +### 触摸板 +触摸板提供了以下功能设置 + +1)触摸板开启/关闭 + +2)打字时触摸板开启/关闭 + +3) 触摸板鼠标点击开启/关闭 + +4)触摸滚动方式(禁用滚动,垂直滚动,水平边界滚动,垂直双指滚动,水平双指滚动) +![图 9 触摸板-big](image/touchpad.png) + +### 鼠 标 +对鼠标键、鼠标指针、光标进行个性化设置。 + +1)鼠标键: + +- 习惯用手设置(左手/右手) + +- 滚轮速度设置 + +- 双击间隔时长 + +2)指针: + +- 指针移动速度 + +- 加速开关 + +- 按Ctrl键显示位置开关 + +- 指针大小设置(小,中,大) + +3)光标: + +- 文本区域光标闪烁开关 + +- 光标速度 + +![图 10 鼠标设备-big](image/mouse.png) + +### 键 盘 +对键盘进行常规通用设置,并能够根据键盘语言调整键盘布局。 + +![图 11 键盘设备-big](image/keyboard.png) + +1)启用按键重复设置:按下某个按键不放,系统会将该行为作为重复的键盘输入。启用按键重复设置后,可对延时、速度两个选项进行设置。 + +- 延时:按下按键后,到系统开始接收键盘输入之间的间隔 + +- 速度:按下按键后,重复输入之间的间隔;间隔越长,同样时间内,重复输入的次数越少 + +2)键盘布局:设置当前系统的键盘布局,最多可以添加4个键盘布局。 + +### 快捷键 +查看所有快捷键,添加或删除自定义快捷键。 + +![图 12 快捷键-big](image/shortcut.png) + +Tips:系统快捷键不允许修改。 + +点击“添加自定义快捷键”,弹出添加窗口。 + +![图 13 添加快捷键](image/add-shortcut.png) + +1)确认添加后,该快捷键的按键会显示“无效”; + +2)点击“disable”,并按下自定义的按键组合,若快捷键未被占用,则自动写入; + +3)鼠标悬浮在该快捷键上时,会出现删除按钮,若不再需要该快捷键,可点击删除。 + +### 声 音 +对输入、输出和系统音效进行设置,如图所示。 + +![图 14 声音-big](image/audio.png) + +- 主音量大小:调节当前的输出音量,通过移动滑动条来控制系统输出音量大小 + +- 选择输出设备:输出设备是获取声卡选择的输出配置文件生成的,可以点击下拉框查看当前系统可用的输出设备,可根据需要切换的对应的输出设备 + +- 声卡:获取当前系统的声卡 + +- 连接器:列出当前输出设备的输出端口,一般有扬声器,模拟耳机,多声道输出等(检测到输出设备有对应的输出端口才会显示) + +- 配置:获取当前声卡的可用的配置文件,切换声卡可用获取到另一个声卡的配置文件,切换配置相当于设置可用的输入输出设备 + +- 声道平衡:调节输出音量的左右声道 + +- 选择输入设备:输入设备是获取声卡选择的输入配置文件生成的,可以点击下拉框查看当前系统可用的输入设备,可根据需要切换的对应的输入设备(输入设备主要用来录音视频以及通话) + +- 音量大小:调节当前的输入音量,通过移动滑动条来控制系统输入音量大小 + +- 输入等级:检测当前输入设备的输入等级(检测到有可用的输入设备时开始检测输入等级) + +- 开关机音乐:控制系统开关机时是否播放开关机音乐 + +- 报警音量:控制终端提示音,调节声音等的提示音大小 + +- 系统音效主题:系统的声音主题 + +- 提示音量大小:提示音大小即系统发出的提示声音大小,除了受系统音量控制之外还可以通过该选项来调节 + +### 蓝牙 + +蓝牙模块提供了开关蓝牙、修改蓝牙名称、显示隐藏蓝牙任务图标、发现周围蓝牙设备;与发现的蓝牙设备配对、连接、断开、移除蓝牙设备的基本功能,如图所示。 + +- 开关蓝牙:点击开启蓝牙按钮,对本机的蓝牙适配器开启和关闭 + +- 修改蓝牙名称:将鼠标在“可以被发现为xxx”上双击,在输入框输入想要的名称 + +- 显示隐藏蓝牙任务栏图标:点击按钮,可以在任务上显示或者不显示托盘上的蓝牙图标 + +- 发现周围蓝牙设备:首次进入蓝牙模块后,会进行周围蓝牙设备的扫描,结束后点击刷新,再次进行扫描 + +- 发现的蓝牙涉笔基础操作:鼠标悬浮到发现的设备上,出现配对按钮,点击配对按钮与设备配对;点击移除按钮,移除设备;设备配对后会自己连接,出现在我的设备一栏,这时鼠标再悬浮到设备上,出现断开按钮,点击断开按钮与设备断开连接 + +![图 15 背景形式选择-big](image/blutooth.png) + +
+ +## 个性化 +个性化设置提供了背景、主题、锁屏、字体、屏保、桌面六个模块。 + +### 背 景 +针对桌面背景,提供两种背景形式的选择:颜色、图片。 + +![图 16 背景-big](image/background.png) + +### 主 题 +主题包括主题模式、图标主题、光标主题。 + +- 主题模式: + +![图 17 主题模式](image/theme.png) + +- 图标主题和光标主题: + +![图 18 图标&光标主题](image/theme-cursor.png) + +- 透明度和特效模式(部分机型不支持): + +![图 19 特效模式](image/theme-effect.png) + +### 锁 屏 + +选择在登录界面显示的背景图片。 + +![图 20 锁屏设置-big](image/screenlock.png) + +### 字 体 +对字体、大小、等宽进行常规设置。 + +点击“恢复默认设置”按钮将所有字体设置还原为系统默认状态。 + +![图 21 字体设置-big](image/font.png) + +### 屏 保 +设置屏保程序、等待时间。 + +![图 22 屏保设置-big](image/screensaver.png) + +### 桌 面 +设置锁定在开始菜单和托盘上的图标。 + +![图 23 桌面设置-big](image/desktop.png) +
+ +## 网 络 +网络主要包含了网络连接、VPN、代理、桌面共享。 + +### 网络连接 +网络连接包括,可用网络显示(无线,有线),开启/关闭wifi等功能,具体网络配置可参考“桌面环境”中的“网络”部分。 +![图 24 网络-big](image/netconnect.png) + +### VPN +打开外部VPN设置程序 +![图 25 VPN-big](image/vpn.png) + +### 代理 +自动代理开启/关闭,手动代理设置(包括HTTP, HTTPS, FTP,SOCKS代理) +![图 26 代理-big](image/delegate.png) + +### 桌面共享(部分机型不支持) +勾选“允许其他人查看您的桌面”后,可设置访问时需要确认,或者要求输入指定密码。 + +![图 27 桌面共享-big](image/vino.png) +
+ +## 账 户 +对系统用户进行管理配置,允许管理员创建用户、删除用户、修改用户信息。 + +![图 28 账户信息设置-big](image/account.png) + +### 当前用户 +#### 更改用户头像 +点击用户头像,即可进行修改,图片可从本机图片中选择。 + +![图 29 更改用户头像](image/account-face.png) + +#### 更改密码 +点击“更改密码”,即可修改当前用户的密码。 + +![图 30 更改密码](image/account-pwd.png) + +#### 更改账户类型 +系统用户类型分两种:标准用户和管理员用户。 + +- 管理员用户:输入用户密码,可以临时提升root权限 + +- 标准用户:无法提升权限 + +Tips:系统至少需要存在一个管理员用户。 + +![图 31 更改用户类型](image/account-type.png) + +### 其他用户 +可编辑其他用户信息,添加新用户,删除用户等。 + +- 添加新用户:输入用户名、密码,并选择用户类型,如图所示 + +![图 32 添加新用户](image/account-add.png) + +- 编辑用户 + +![图 33 编辑用户](image/account-edit.png) +
+ +## 云账户 +云账户可用于同步设置配置选项,需要注册登录生效。 + +![图 34 云账户-big](image/cloudaccount.png) +### 登录方式 +- 通过麒麟ID登录中心登录,使用云账户只需拥有麒麟ID即可。 + + +### 可同步项 +- 桌面壁纸:同步桌面壁纸 +- 屏保:同步屏保壁纸、屏保休眠时间等 +- 字体:同步设置字体设置 +- 头像:同步系统用户头像 +- 开始菜单:开始菜单的相关设置 +- 任务栏: 同步任务栏位置、大小等 +- 快速启动项:同步任务栏插件快速启动栏相关设置 +- 主题:同步设置主题设置 +- 鼠标:同步设置鼠标设置 +- 触摸板:如果有触摸板的话,同步设置触摸板界面 +- 键盘:同步设置键盘设置 +- 快捷键:同步设置自定义快捷键 +- 语言和地区:同步语言以及地区时区,并非一一对应设置 +- 时间和日期:同步时间,并非一一对应设置 +- 默认打开方式:同步设置默认应用相关设置 +- 侧边栏:同步设置通知页面相关设置 +- 登录选项:同步设置用户信息自动登录以及免密登录 +- 电源:同步设置电源相关选项 +- 文本编辑器:同步文本编辑器Pluma的设置,需要关闭所有Pluma进程并重新打开文本编辑器才能看到效果 +- 终端:同步终端设置资料卡,需要关闭所有终端实例再打开终端才能看到效果 +- 麒麟天气:同步麒麟天气设置 +- 文件管理器:同步文件管理器的设置,不包括置顶窗口设置 +- 开机启动项:同步设置开机启动设置 +- 麒麟影音:同步麒麟影音相关设置 + + +### 使用须知 +- 使用麒麟ID登录云账户,首次打开默认会同步一次,如果云端有配置文件,则会先把云端配置下载下来同步到本地,否则把本地账户配置上传到云端。 +- 登录云账户之后,如果打开了自动同步按钮,用户无需其他操作,云账户每隔5分钟会同步一次本地配置到云端,上传的配置可供跨机器,跨用户同步。 +- 单独的同步开关关闭会导致此项停止上传到云端,如果开启,则会将之前的此项的云端配置同步到本地。 +- 如果关闭自动同步按钮,所有云端配置将会保留在关闭同步前最后一次上传到云端的本地配置。 +- 如果开启自动同步按钮,则将云端配置下载下来并同步到本地。 +- 单独的开关类似自动同步按钮效果,只是同步效果范围变成了当前项的同步效果。 + +## 时间和日期 +主界面如图所示: + +![图 35 时间和日期-big](image/datetime.png) + +- 同步系统时间:与互联网上的NTP服务器时间同步 + +- 手动更改时间:手动设置时间和年月日 + +![图 36 手动更改时间](image/datetime-change.png) + +- 时间格式分12小时和24小时,点击右侧开关立即生效 + +- 更改时区:如图所示,根据个人需求进行选择 + +![图 37 时区-big](image/datetime-zone.png) + +### 语言和地区 +主界面如图所示: + +![图 38 区域语言-big](image/area.png) + +- 更改数据格式:自定义日历、一周第一天、日期、时间 + +![图 39 更改格式数据](image/area-format.png) + +- 首选语言:系统窗口、菜单及网页的显示语言,首选推荐语言为简体中文 + +- 点击“添加首选语言”,可添加其他地区语言作为备选 + +
+ +## 更 新 +### 安全中心 +提供了安全中心的入口。 + +![图 40 安全中心-big](image/security.png) + +### 备 份 +- 开始备份:将文件备份到其他驱动器 + +- 开始还原:查看备份列表,并选择还原点进行恢复 + +![图 41 备份和还原-big](image/backup.png) + +### 更 新 + +设置的更新模块可以检测检测系统是否有可用更新,更新模块主界面有系统状态、更新列表、更新设置三部分组成。 +
+ +- 系统状态:主要显示当前系统更新状态以及上次检测更新时间; + +- 更新列表:推送系统可用更新; + +- 更新设置:设置是否允许推送可更新的应用以及是否在全部更新之前自动备份。 +
+ +![图 42 系统更新-big](image/update.png) +
+ +更新完成后,可在更新历史中查看更新情况。 + + +![图 43 历史更新-big](image/historylog.png) + +### 后台更新 + +后台更新主要是在后台进行重要更新操作,以及提醒用户可用更新内容。 +
+ +- 当有重要更新时,会在后台静默更新,在升级前后用户都会收到通知信息。 + +![图 44 后台更新-big](image/notiffirst.png) + +![图 45 后台更新-big](image/notiend.png) + +- 当有可用更新时,右下角出现更新图标,并弹出选择界面供用户选择。 + +![图 46 后台更新-big](image/tray.png) + +![图 47 后台更新-big](image/choicewidget.png) + +- 当用户选择同意更新后,会弹出设置>更新界面,进行检查更新 + +- 当用户选择暂不更新时,退出后台更新程序 + + + +## 通知和操作 +### 通 知 +如图所示: + +![图 48 通知-big](image/notice.png) + +### 关 于 +显示本机系统的版本、设备规格、授权激活信息。 +![图 49 通知-big](image/about.png) +
+ +## 常见问题 +#### 点击开始菜单上的设置按钮,无反应 +在键盘上按下 Ctrl + Alt + T 组合键打开命令行终端,输入“ukui-control-center”后按下Enter,查看错误输出。 + +#### 修改控件状态后,控件立刻还原到修改前状态 +大概率是因为权限问题。 + +在键盘上按下 Ctrl + Alt + T 组合键打开命令行终端,输入“rm ~/.config/dconf/user”后按下Enter。 diff -Nru ukui-control-center-2.0.3/debian/changelog ukui-control-center-3.0.3/debian/changelog --- ukui-control-center-2.0.3/debian/changelog 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/debian/changelog 2021-05-20 13:10:27.000000000 +0000 @@ -1,8 +1,412 @@ -ukui-control-center (2.0.3-1+0806) focal; urgency=medium +ukui-control-center (3.0.3-6) focal; urgency=medium - * Daily build. + * Build. - -- liuliang Wed, 15 Jul 2020 16:33:28 +0800 + -- liuliang Thu, 20 May 2021 21:10:27 +0800 + +ukui-control-center (3.0.1-1-57.2) v101; urgency=medium + + * 解决bug#50577显示亮度调整数值 + * 解决bug#43141修改分辨率后加延时,得到准确的控制面板位置 + + -- zhoubin Fri, 23 Apr 2021 18:00:29 +0800 + +ukui-control-center (3.0.1-1-57.1) v101; urgency=medium + + * 修改翻译:"自动登录"改为开机自动登录; + + -- zhoubin Thu, 22 Apr 2021 17:53:50 +0800 + +ukui-control-center (3.0.1-1-57) v101; urgency=medium + + * 990分数缩放添加 + * 解决bug#43141使用i2ctransfer写入bus数据调整台式机亮度 + * 解决bug#50120鼠标左键可以点击 + * 添加搜索插件 + * 解决bug#32085打开统一输出,点击两次应用设置,再关闭统一输出,显示器预览窗口仍然显示Unified outputs + + -- zhoubin Thu, 22 Apr 2021 15:40:18 +0800 + +ukui-control-center (3.0.1-1-56) v101; urgency=medium + + * 解决bug#34463拔掉HDMI屏再接入,控制面板中两个屏的位置不对 + * 解决bug#47830统一输出模式,调整屏幕亮度只有一个屏幕生效 + * 使用usd的dbus调用vino服务 + * 解决bug#48215打印机列表显示不一致问题 + * 解决bug#43100控制面板显示器名称显示未知 + * 解决bug#46560将笔记本设置为200%,VGA屏幕缩放也会变成200%,但是控制面板显示的100% + * 解决bug#BUG#47578,16号字体控制面板创建用户页面存在显示不全现象 + * 解决bug#45602 and bug#46710修复打开控制面板缩放自动为1的bug,修复刷新率数值重复的bug + * 解决bug#47203时间显示存在延迟 + * 解决bug#43489统一输出后恢复原来配置还是开关还是处于统一输出状态 + * 将网络监测机制迁移到dbus(彭代欣) + + -- zhoubin Tue, 20 Apr 2021 15:29:44 +0800 + +ukui-control-center (3.0.1-1-55) v101; urgency=medium + + * 解决bug#42212旧密码可与新密码相同 + * 解决bug#44081同步win+p更改 + * 解决bug#选择非默认光标主题后点击恢复默认设置,拉伸窗体光标显示为“白”光标 + * 解决bug#43275 + * 解决bug#43635,bug#43632,bug#43141 + + -- zhoubin Fri, 02 Apr 2021 09:58:44 +0800 + +ukui-control-center (3.0.1-1-54) v101; urgency=medium + + * 解决bug#45596 恢复原来配置主屏幕更改问题 + * 解决bug#45235可用网络列表中,“网络连接”的按钮和灰色背景有部分重叠 + * 解决bug#45233更改用户部分UI + + -- zhoubin Tue, 30 Mar 2021 16:01:44 +0800 + +ukui-control-center (3.0.1-1-53) v101; urgency=medium + + * 解决bug#43244 【双屏】【VGA+HDMI】更改HDMI屏分辨率为1024*768,刷新率为60,重新打开控制面板,分辨率自动变为1280*720 + + -- zhoubin Sat, 27 Mar 2021 11:37:15 +0800 + +ukui-control-center (3.0.1-1-52.1) v101; urgency=medium + + * 解决输入设备未及时更新以及深色主题下未反白的问题(封昭翔) + + -- zhoubin Thu, 25 Mar 2021 17:07:22 +0800 + +ukui-control-center (3.0.1-1-52) v101; urgency=medium + + * 解决bug#43058显示预览没有切换 + * 解决bug#44293mode id为空导致的闪退出问题 + * 解决bug#44472屏幕位置错误导致任务错位问题 + + -- zhoubin Wed, 24 Mar 2021 19:01:31 +0800 + +ukui-control-center (3.0.1-1-51.3) v101; urgency=medium + + * 版权符号错误 + + -- zhoubin Tue, 23 Mar 2021 17:15:11 +0800 + +ukui-control-center (3.0.1-1-51.2) v101; urgency=medium + + * 版本英文描述更改判断 + + -- zhoubin Tue, 23 Mar 2021 16:24:48 +0800 + +ukui-control-center (3.0.1-1-51.1) v101; urgency=medium + + * 版本描述增加一个空格 + + -- zhoubin Tue, 23 Mar 2021 13:56:49 +0800 + +ukui-control-center (3.0.1-1-51) v101; urgency=medium + + * 更新版权信息 + + -- zhoubin Tue, 23 Mar 2021 11:18:59 +0800 + +ukui-control-center (3.0.1-1-50) v101; urgency=medium + + * 解决bug#43396去掉夜间模式,但搜索框中仍然可以搜索到 + * 解决bug#42412控制面板”的显示器名称和“系统投屏”的第一屏幕名称不一致 + * 解决bug#42752【个性化】更改光标主题不生效 + * 解决bug#43073主副屏幕更改问题 + * 备份还原dbus接口添加参数(锁定系统更新时的备份操作) + + -- zhoubin Fri, 19 Mar 2021 18:59:43 +0800 + +ukui-control-center (3.0.1-1-49) v101; urgency=medium + + * 公司内部bug#42078键盘输入测试字符,有些字符没有显示完全 + * 解决bug#4229dbus接口造成的超时卡顿问题 + * 解决bug#37713镜像模式恢复以前配置显示错误 + * 解决bug#39697modeid錯誤引起的黑屏 + * 解决bug#42066主副屏幕记录错误 + + -- zhoubin Thu, 18 Mar 2021 16:43:32 +0800 + +ukui-control-center (3.0.1-1-48) v101; urgency=medium + + * 使用左右键快捷键调整亮度 + * 解决BUG#41698【控制面板】输入正确的当前密码,按tab键后,概率性提示密码错误 + * 解决BUG#37381 【控制面板】【用户头像】更改用户头像,选择头像图片时,选择框异常 + * 解决BUG#39995【账户信息】更改用户头像,未选择图像,点击确认,头像恢复到默认状态 + * 解决bug#21438通过控制面板的显示器设置夜间模式后,不生效 + * 解决bug39116#打开控制面板,控制面板显示黑屏三秒 + + -- zhoubin Fri, 12 Mar 2021 09:32:23 +0800 + +ukui-control-center (3.0.1-1-47.2) v101; urgency=medium + + * 取消modeid是否相等判断 + + -- zhoubin Tue, 09 Mar 2021 09:02:44 +0800 + +ukui-control-center (3.0.1-1-47.1) v101; urgency=medium + + * 取消modeid是否相等判断 + + -- zhoubin Mon, 08 Mar 2021 20:57:24 +0800 + +ukui-control-center (3.0.1-1-47) v101; urgency=medium + + * wayland添加缩放判断 + * 添加搜索词过滤(bug#40243) + + -- zhoubin Mon, 08 Mar 2021 16:05:52 +0800 + +ukui-control-center (3.0.1-1-46.2) v101; urgency=medium + + * 平台问题chroot problem,重新上传 + + -- zhoubin Thu, 04 Mar 2021 16:26:44 +0800 + +ukui-control-center (3.0.1-1-46.1) v101; urgency=medium + + * 还原插拔屏幕修改 + + -- zhoubin Thu, 04 Mar 2021 14:51:38 +0800 + +ukui-control-center (3.0.1-1-46) v101; urgency=medium + + * 解决禅道bug40205 39709 + * 亮度范围错误值(bug#41208) + * 控制面板-网络链接中,出现没有图标的wifi(bug#41011) + * 控制面板的网络状态在连接有线网络时会显示无网络连接(bug#39788) + + -- zhoubin Thu, 04 Mar 2021 11:47:13 +0800 + +ukui-control-center (3.0.1-1-45) v101; urgency=medium + + * 左侧以及导航栏改版 + * 接入4k屏的情况下,win+p切换模式后,点击控制面板-显示器-显示器区域里的显示器图标,控制面板闪退(bug#39978) + * 低分辨率下屏幕抖动(bug#39432) + + -- zhoubin Mon, 01 Mar 2021 10:29:35 +0800 + +ukui-control-center (3.0.1-1-44) v101; urgency=medium + + * 更改安全中心搜索关键字 + * wayland上面隐藏夜间模式(bug#39271) + * 修改英文用户手册 + * 内核,cpu,内存,硬盘等显示空白;对比麒麟助手显示正常(bug#38847) + * 获取屏幕大小错误(bug#34098) + + -- zhoubin Thu, 25 Feb 2021 09:57:09 +0800 + +ukui-control-center (3.0.1-1-43.20) v101; urgency=medium + + * 解决指定Qt Quick场景图形后端(bug#28609) + + -- zhoubin Sun, 21 Feb 2021 15:15:23 +0800 + +ukui-control-center (3.0.1-1-41.2) v101; urgency=medium + + * 解决平台编译失败问题 + + -- zhoubin Fri, 19 Feb 2021 09:45:38 +0800 + +ukui-control-center (3.0.1-1-40.1) v101; urgency=medium + + * 任务栏WiFi列表显示已经连接,但是控制面板的WiFi列表依然显示无网络连接(bug#38090) + * 不带安全性的WiFi,仍显示上锁(bug#38361) + * 搜索字体显示不全(bug#34565) + * 屏蔽1920x1080且50hz以下分辨率(bug#32123) + + -- zhoubin Sun, 07 Feb 2021 15:27:51 +0800 + +ukui-control-center (3.0.1-1-40) v101; urgency=medium + + * 修复用户手册错别字(bug#38116) + * 夜间模式在loongson上无效(bug#32814) + * 恢复默认透明度(bug#35990) + * 设置副屏在主屏右边(bug#27025) + * 添加自启动程序,设置程序名,添加一个程序后,设置好的程序名被更改(bug#19188) + * 用户手册图片显示不全(bug#35424) + * 在控制面板任务栏搜索安全中心搜索不到设置项(bug#37349) + * 无法添加biometri-manager.desktop文件(bug#37606) + * 解决无法设置镜像模式方向问题(#bug22989) + * 更改夜间模式描述(bug#22278i) + * 更改字体大小为16后,控制面板-安全中心字体没有加粗(bug#35704) + * 英文字体显示不全(bug#30701) + * 更新版本信息(bug#37030) + + -- zhoubin Fri, 05 Feb 2021 15:23:21 +0800 + +ukui-control-center (3.0.1-1-39.4) v101; urgency=medium + + * 云账户信号槽更改 + + -- zhoubin Fri, 29 Jan 2021 19:53:10 +0800 + +ukui-control-center (3.0.1-1-39.3) v101; urgency=medium + + * 更改亮度gsettings + + -- zhoubin Fri, 29 Jan 2021 14:46:17 +0800 + +ukui-control-center (3.0.1-1-39.2) v101; urgency=medium + + * 更新翻译 + + -- zhoubin Thu, 28 Jan 2021 14:47:30 +0800 + +ukui-control-center (3.0.1-1-39.1) v101; urgency=medium + + * 解决跳转编译失败问题 + + -- zhoubin Thu, 28 Jan 2021 14:30:15 +0800 + +ukui-control-center (3.0.1-1-39) v101; urgency=medium + + * 补充通知中心缺失的图标与汉化 + + -- zhoubin Thu, 28 Jan 2021 09:35:08 +0800 + +ukui-control-center (3.0.1-1-38.1) v101; urgency=medium + + * 解决插入耳机时调节不了输出音量的问题(bug#33827) + * 点击主题,关闭再打开透明度的设置,透明度界面先后显示不一致(bug#36029) + * 调节字体大小,个性化和字体两个标题字体大小不变(bug#35705) + * 【控制面板】网络-WiFi图标右下角无“密码”标识(bug#33339) + * 搜索框内搜索更新,出现搜索结果后,无法打出中文(bug#31887) + * 网络连接】点击打开wifi无提示信息(bug#33663) + * 屏蔽低分辨率(bug#35611) + * 输入密码框不输入密码时,通过VNC连接时密码框不输入密码连接失败(bug#32623) + * 【控制面板|时间与日期】设置日期年份为1970年前不生效(bug#29138) + * 点击“打开显示器”后再点击别的选项仍弹出“请确保至少一个屏幕开启(bug#32807) + * 深色主题下对图标反白处理(bug#33945) + * 双屏限制显示器紧靠(bug#32126) + * 亮度未同步变化(bug#28499) + + -- zhoubin Wed, 27 Jan 2021 14:17:40 +0800 + +ukui-control-center (3.0.1-1-38) v101; urgency=medium + + * 修复用户手册控制面板图标缺失 + + -- zhoubin Tue, 19 Jan 2021 10:05:18 +0800 + +ukui-control-center (3.0.1-1-37) v101; urgency=medium + + * 补充用户手册控制面板图标 + + -- zhoubin Mon, 18 Jan 2021 20:59:40 +0800 + +ukui-control-center (3.0.1-1-36) v101; urgency=medium + + * 增加蓝牙gsettings判断 + * 补充用户手册控制面板图标 + + -- zhoubin Mon, 18 Jan 2021 15:31:29 +0800 + +ukui-control-center (3.0.1-1-35) v101; urgency=medium + + * 连接投影仪,点击统一输出,控制面板闪退(bug#32309) + * 属性-网络-桌面共享-安全-要求输入此密码类项置灰(bug#33665) + * 密码最大长度为8(bug#32624) + * 托盘图标设置,显示和其他样式不一致(bug#23520) + * 切换当前区域后,区域格式的日期显示与任务栏的不一致(bug#33732) + * 特效模式关闭的情况下,点击恢复默认设置按钮,无法恢复到默认设置(bug#33871) + * 任务栏切换到夜间模式,打开控制面板主题,系统主题勾选已无(bug#33854) + * 更新界面中,关于安全中心的相关模块没有更新(bug#33465) + * 语言显示错误(bug#33697) + * 提示应用显示分辨率弹出内容文字显示错误(bug#33630) + * 系统进入空闲时间达到时间关闭显示器,设置位30分钟,重启控制面板设置变为平衡模式(bug#31101) + * 更改内存描述单位GIB为GB(bug#28848) + * QLabel更改为QTextEdit控件避免显示不全(bug#28170) + * 添加跳转到用户手册跳转到控制面板参数(bug#33341) + * 右键桌面中间部分选择设置壁纸,大概率会闪出一个半透明的右键菜单(bug#21586) + * 显示设置界面更改配置,点击应用后,弹出的提示窗口上下高度会动态收缩一次(bug#31405) + * 控制面板无法打开,top查看CPU占用率100%(bug#32164) + * 可用大小内存显示错误(bug#30880) + + -- zhoubin Sat, 16 Jan 2021 17:31:36 +0800 + +ukui-control-center (3.0.1-1-34) v101; urgency=medium + + * 首次打开控制面板-电源统计开关,控制面板闪退(bug#31081) + * 控制面板点击备份和还原无法打开备份还原工具(bug#31398) + * 增加标题栏关于入口 + * 个性化中的桌面的麒麟截图和蓝牙没有图标(bug#30918) + * 显示托盘上图标设置,电源管理和蓝牙设置与实际显示相反(bug#30913) + * 【控制面板】控制面板搜索“升级”无结果(bug#31090) + * 由高到低排序wifi强度(bug#31277) + * 时间未到进入夜间模式(bug#22276) + + -- zhoubin Fri, 08 Jan 2021 14:03:51 +0800 + +ukui-control-center (3.0.1-1-31) v101; urgency=medium + + * 退出更新管理器段错误问题 + * 修改其他用户的头像后,当前用户的头像也被修改 + * 被vnc远程连接后,断开连接,杀掉vncserver进程,打开控制面板->显示器,控制面板闪退 + + -- zhoubin Wed, 30 Dec 2020 17:47:26 +0800 + +ukui-control-center (3.0.1-1-30) v101; urgency=medium + + * 解决important为空奔溃问题 + + -- lijiang (rain) Mon, 28 Dec 2020 20:16:39 +0800 + +ukui-control-center (3.0.1-1-29) v101; urgency=medium + + * 添加升级跳转 + + -- zhoubin Mon, 28 Dec 2020 20:16:39 +0800 + +ukui-control-center (3.0.1-1-28) v101; urgency=medium + + * 添加触摸屏功能 + + -- zhoubin Mon, 28 Dec 2020 18:30:40 +0800 + +ukui-control-center (3.0.1-1-27) v101; urgency=medium + + * 首次打开控制面板-设备-声音,将提示音开关打开,调节提示音后控制面板闪 + * 设置夜间模式成功后再次点击应用,系统恢复正常模式,回到桌面后变回夜间模式 + * 设置要求用户输入此密码不生效,vnc不输入密码即可访问 + * 增加第一次是否为镜像模式判断 + * 安装系统后,首次添加自启动程序无反应 + * 关闭主屏幕再打开时候闪退问题 + * 标题水平对齐 + * 同步win+p镜像模式 && 屏幕设置无法保存 + * 密码输入框置灰色 + * 添加蓝牙不存在时隐藏判断 + + -- zhoubin Mon, 28 Dec 2020 15:40:46 +0800 + +ukui-control-center (3.0.1-1-26) v101; urgency=medium + + * 添加应用窗口图标 + * 修复云账户搜索无法跳转 + * 修复切换字体为华文新魏,字体大小界面出现重叠 + * 修复主题图标只有一套问题 + * 添加低电量执行操作行为 + * 修复系统亮度剩余20%,控制面板亮度显示为0% + * 修复首次登录打开侧面通知拦,点击顶部设置按钮,打开控制面板,关闭通知按钮,控制面板闪退 + * 修复切换到1152*864分辨率后应用,系统黑屏并显示NO SUPPORT,无法进去系统桌面,重启后也无法进入 + * 添加电源按键功能 + * 修复开始菜单-控制面板-通知和操作,多次点击后电源统计图标出现蓝色框 + + + -- zhoubin Mon, 21 Dec 2020 16:52:24 +0800 + +ukui-control-center (3.0.1-1-25) v101; urgency=medium + + * 修复电源管理布局异常问题 + + -- zhoubin Fri, 11 Dec 2020 10:52:56 +0800 + +ukui-control-center (3.0.1-1-24) v101; urgency=medium + + * 修复密码校验未生效(包含用户名、相似性) + * 修复开始菜单-控制面板-个性化-背景,在背景没加载完成的时候通过鼠标下拉,会出现大量空白 + * 修复mouse whee事件无法调整透明度 + * 修复双屏接入4k屏后,关闭4k屏后再打开,概率性出现屏幕重叠 + + -- zhoubin Thu, 10 Dec 2020 15:00:32 +0800 ukui-control-center (3.0.0-1) unstable; urgency=medium diff -Nru ukui-control-center-2.0.3/debian/control ukui-control-center-3.0.3/debian/control --- ukui-control-center-2.0.3/debian/control 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/debian/control 2021-05-20 13:10:27.000000000 +0000 @@ -16,6 +16,12 @@ libkf5configwidgets-dev, libkf5screen-dev, libkf5screen-bin, + libkf5i18n-dev, + libkf5windowsystem-dev, + libkf5guiaddons-dev, + libkf5coreaddons-dev, + libkf5xmlgui-dev, + libkf5globalaccel-dev, qtdeclarative5-dev, libdconf-dev, libmatemixer-dev, @@ -25,9 +31,19 @@ libcanberra-dev, libmate-desktop-dev, libx11-dev, - libxkbcommon-dev, libxkbfile-dev, + libboost-dev, qttools5-dev-tools, + libxcb-xkb-dev, + libpolkit-qt5-1-dev, + libpulse-dev, + libkf5bluezqt-dev, + libpwquality-dev, + libudev-dev, + xserver-xorg-dev, + libupower-glib-dev, + libpam0g-dev, + libukui-log4qt-dev[!sw64] Standards-Version: 4.5.0 Rules-Requires-Root: no Homepage: https://github.com/ukui/ukui-control-center @@ -40,7 +56,10 @@ ${misc:Depends}, qml-module-qtgraphicaleffects, qml-module-qtquick-controls, -Recommends: redshift + qt5-image-formats-plugins, + dconf-cli, + language-selector-gnome, + ukui-bluetooth, Suggests: gsettings-desktop-schemas, mate-desktop-common, ukui-power-manager, diff -Nru ukui-control-center-2.0.3/debian/rules ukui-control-center-3.0.3/debian/rules --- ukui-control-center-2.0.3/debian/rules 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/debian/rules 2021-05-20 13:08:14.000000000 +0000 @@ -11,8 +11,9 @@ dh $@ # fix private dynamic library not found when debuild -#override_dh_shlibdeps: +override_dh_shlibdeps: # dh_shlibdeps -l "${CURDIR}/cclibs" + dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info # fix private dynamic library lintian warning #override_dh_makeshlibs: diff -Nru ukui-control-center-2.0.3/debian/ukui-control-center.manpages ukui-control-center-3.0.3/debian/ukui-control-center.manpages --- ukui-control-center-2.0.3/debian/ukui-control-center.manpages 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/debian/ukui-control-center.manpages 2021-04-14 01:27:20.000000000 +0000 @@ -1,2 +1,5 @@ +man/checkuserpwd.1 +man/group-manager-server.1 man/ukui-control-center.1 man/launchSysDbus.1 +man/ukui-control-center-session.1 diff -Nru ukui-control-center-2.0.3/debian/ukui-control-center.postinst ukui-control-center-3.0.3/debian/ukui-control-center.postinst --- ukui-control-center-2.0.3/debian/ukui-control-center.postinst 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/debian/ukui-control-center.postinst 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,14 @@ +#!/bin/sh + +set -e + +glib-compile-schemas /usr/share/glib-2.0/schemas/ + +# 启动服务 +#systemctl enable ukui-group-manager.service +#systemctl start ukui-group-manager.service + +chown root:root /usr/bin/checkuserpwd +chmod u+s /usr/bin/checkuserpwd + +#DEBHELPER# diff -Nru ukui-control-center-2.0.3/.github/workflows/build.yml ukui-control-center-3.0.3/.github/workflows/build.yml --- ukui-control-center-2.0.3/.github/workflows/build.yml 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/.github/workflows/build.yml 2021-05-20 13:08:14.000000000 +0000 @@ -3,87 +3,103 @@ on: push: branches: - - master + - dev-stable pull_request: branches: - - master - - schedule: - - cron: '0 0 * * *' + - dev-stable jobs: - archlinux-latest: - name: on Archlinux Latest - runs-on: ubuntu-20.04 - container: docker.io/library/archlinux:latest - steps: - - name: Checkout ukui-control-center source code - uses: actions/checkout@v2 - - name: Refresh pacman repository - run: pacman -Sy - - name: Install build dependencies - run: pacman -S --noconfirm base-devel qt5-base gsettings-qt kwindowsystem poppler-qt5 qt5-x11extras glib2 qt5-tools pkg-config kwidgetsaddons kconfig kconfigwidgets kscreen qt5-svg libmatekbd qt5-x11extras libxklavier qt5-declarative libmatemixer libqtxdg qt5-multimedia libxml2 libcanberra mate-desktop libxkbcommon libxkbfile - - name: QMake configure & Make - run: | - mkdir build; - cd build; - qmake-qt5 ..; - make -j$(nproc); - - debian-sid: - name: on Debian Sid - runs-on: ubuntu-20.04 - container: docker.io/library/debian:sid - env: - DEBIAN_FRONTEND: noninteractive - steps: - - name: Checkout ukui-control-center source code - uses: actions/checkout@v2 - - name: Update apt repository - run: apt-get update -y - - name: Install build dependcies - run: apt-get install -y build-essential qt5-default qttools5-dev-tools pkg-kde-tools pkg-config libkf5widgetsaddons-dev libkf5config-dev libkf5configwidgets-dev libkf5screen-dev debhelper-compat libqt5svg5-dev libgsettings-qt-dev libglib2.0-dev libmatekbd-dev libqt5x11extras5-dev libxklavier-dev qtdeclarative5-dev libdconf-dev libmatemixer-dev libqt5xdg-dev qtmultimedia5-dev libxml2-dev libcanberra-dev libmate-desktop-dev libxkbcommon-dev libxkbfile-dev - - name: QMake configure & Make - run: | - mkdir build; - cd build; - qmake ..; - make -j$(nproc); + # archlinux-latest: + # name: on Archlinux Latest + # runs-on: ubuntu-20.04 + # container: docker.io/library/archlinux:latest + # steps: + # - name: Checkout ukui-control-center source code + # uses: actions/checkout@v2 + # - name: Refresh pacman repository and force upgrade + # run: pacman -Syyu --noconfirm + # - name: Install build dependencies + # run: pacman -S --noconfirm base-devel qt5-base gsettings-qt kwindowsystem poppler-qt5 qt5-x11extras glib2 qt5-tools pkg-config kwidgetsaddons kconfig kconfigwidgets kscreen qt5-svg libmatekbd qt5-x11extras libxklavier qt5-declarative libmatemixer libqtxdg qt5-multimedia libxml2 libcanberra mate-desktop libxkbcommon libxkbfile ki18n kguiaddons kcoreaddons boost glibc bluez-qt + # - name: QMake configure & Make + # run: | + # mkdir build; + # cd build; + # qmake-qt5 ..; + # make -j$(nproc); + + # debian-sid: + # name: on Debian Sid + # runs-on: ubuntu-20.04 + # container: docker.io/library/debian:sid + # env: + # DEBIAN_FRONTEND: noninteractive + # steps: + # - name: Checkout ukui-control-center source code + # uses: actions/checkout@v2 + # - name: Update apt repository + # run: apt-get update -y + # - name: Install build dependencies + # run: apt-get install -y build-essential qt5-qmake qttools5-dev-tools pkg-kde-tools pkg-config libkf5widgetsaddons-dev libkf5config-dev libkf5configwidgets-dev libkf5screen-dev debhelper-compat libqt5svg5-dev libgsettings-qt-dev libglib2.0-dev libmatekbd-dev libqt5x11extras5-dev libxklavier-dev qtdeclarative5-dev libdconf-dev libmatemixer-dev libqt5xdg-dev qtmultimedia5-dev libxml2-dev libcanberra-dev libmate-desktop-dev libxkbcommon-dev libxkbfile-dev libkf5i18n-dev libkf5windowsystem-dev libkf5guiaddons-dev libkf5coreaddons-dev libboost-dev libxcb-xkb-dev libpolkit-qt5-1-dev libpulse-dev libkf5bluezqt-dev + # - name: QMake configure & Make + # run: | + # mkdir build; + # cd build; + # qmake ..; + # make -j$(nproc); - fedora-latest: - name: on Fedora Latest - runs-on: ubuntu-20.04 - container: docker.io/library/fedora:latest - steps: - - name: Checkout ukui-control-center source code - uses: actions/checkout@v2 - - name: Install build dependencies - run: dnf install --refresh -y which gcc gcc-c++ make cmake cmake-rpm-macros autoconf automake intltool rpm-build qt5-rpm-macros qt5-qtbase-devel qt5-qtsvg-devel gsettings-qt-devel glib2-devel qt5-qtx11extras-devel libmatekbd-devel libxklavier-devel kf5-kconfigwidgets-devel kf5-kconfig-devel qt5-qtdeclarative-devel dconf-devel redshift edid-decode libmatemixer-devel libqtxdg-devel qt5-qtmultimedia-devel libxml2-devel libkscreen-qt5-devel kf5-ki18n-devel libcanberra-devel libXi-devel mate-desktop-devel libxkbcommon-devel libxkbfile-devel qt5-linguist - - name: QMake configure & Make - run: | - ln -s /usr/bin/lrelease-qt5 /usr/bin/lrelease; - mkdir build; - cd build; - qmake-qt5 ..; - make -j$(nproc); - - fedora-rawhide: - name: on Fedora Rawhide - runs-on: ubuntu-20.04 - container: docker.io/library/fedora:rawhide - steps: - - name: Checkout ukui-control-center source code - uses: actions/checkout@v2 - - name: Install build dependencies - run: dnf install --refresh -y which gcc gcc-c++ make cmake cmake-rpm-macros autoconf automake intltool rpm-build qt5-rpm-macros qt5-qtbase-devel qt5-qtsvg-devel gsettings-qt-devel glib2-devel qt5-qtx11extras-devel libmatekbd-devel libxklavier-devel kf5-kconfigwidgets-devel kf5-kconfig-devel qt5-qtdeclarative-devel dconf-devel redshift edid-decode libmatemixer-devel libqtxdg-devel qt5-qtmultimedia-devel libxml2-devel libkscreen-qt5-devel kf5-ki18n-devel libcanberra-devel libXi-devel mate-desktop-devel libxkbcommon-devel libxkbfile-devel qt5-linguist - - name: QMake configure & Make - run: | - ln -s /usr/bin/lrelease-qt5 /usr/bin/lrelease; - mkdir build; - cd build; - qmake-qt5 ..; - make -j$(nproc); + # fedora-latest: + # name: on Fedora Latest + # runs-on: ubuntu-20.04 + # container: docker.io/library/fedora:latest + # steps: + # - name: Checkout ukui-control-center source code + # uses: actions/checkout@v2 + # - name: Install build dependencies + # run: dnf install --refresh -y which gcc gcc-c++ make cmake cmake-rpm-macros autoconf automake intltool rpm-build qt5-rpm-macros qt5-qtbase-devel qt5-qtsvg-devel gsettings-qt-devel glib2-devel qt5-qtx11extras-devel libmatekbd-devel libxklavier-devel kf5-kconfigwidgets-devel kf5-kconfig-devel qt5-qtdeclarative-devel dconf-devel redshift edid-decode libmatemixer-devel libqtxdg-devel qt5-qtmultimedia-devel libxml2-devel libkscreen-qt5-devel kf5-ki18n-devel libcanberra-devel libXi-devel mate-desktop-devel libxkbcommon-devel libxkbfile-devel qt5-linguist kf5-kwindowsystem-devel kf5-kguiaddons-devel kf5-kcoreaddons-devel boost-devel libxcb-devel xcb-util-devel polkit-qt5-1-devel kf5-bluez-qt-devel + # - name: QMake configure & Make + # run: | + # ln -s /usr/bin/lrelease-qt5 /usr/bin/lrelease; + # mkdir build; + # cd build; + # qmake-qt5 ..; + # make -j$(nproc); + + # fedora-rawhide: + # name: on Fedora Rawhide + # runs-on: ubuntu-20.04 + # container: docker.io/library/fedora:rawhide + # steps: + # - name: Checkout ukui-control-center source code + # uses: actions/checkout@v2 + # - name: Install build dependencies + # run: dnf install --refresh --nogpg -y which gcc gcc-c++ make cmake cmake-rpm-macros autoconf automake intltool rpm-build qt5-rpm-macros qt5-qtbase-devel qt5-qtsvg-devel gsettings-qt-devel glib2-devel qt5-qtx11extras-devel libmatekbd-devel libxklavier-devel kf5-kconfigwidgets-devel kf5-kconfig-devel qt5-qtdeclarative-devel dconf-devel redshift edid-decode libmatemixer-devel libqtxdg-devel qt5-qtmultimedia-devel libxml2-devel libkscreen-qt5-devel kf5-ki18n-devel libcanberra-devel libXi-devel mate-desktop-devel libxkbcommon-devel libxkbfile-devel qt5-linguist kf5-kwindowsystem-devel kf5-kguiaddons-devel kf5-kcoreaddons-devel boost-devel libxcb-devel xcb-util-devel polkit-qt5-1-devel kf5-bluez-qt-devel + # - name: QMake configure & Make + # run: | + # ln -s /usr/bin/lrelease-qt5 /usr/bin/lrelease; + # mkdir build; + # cd build; + # qmake-qt5 ..; + # make -j$(nproc); + + # opensuse-tumbleweed: + # name: on openSUSE Tumbleweed + # runs-on: ubuntu-20.04 + # container: opensuse/tumbleweed:latest + # steps: + # - name: Install source checkout utils + # run: zypper -n install tar git + # - name: Checkout ukui-control-center source code + # uses: actions/checkout@v2 + # - name: Install build dependencies + # run: zypper -n install atk-devel at-spi2-atk-devel at-spi2-core-devel cairo-devel cmake cmake-full cmake-man dbus-1-devel dconf-devel extra-cmake-modules extra-cmake-modules-doc fontconfig-devel freetype2-devel fribidi-devel gcc10-c++ gcc-c++ gdk-pixbuf-devel gettext-its-gtk4 glib2-devel graphite2-devel gsettings-qt-devel gtk3-devel harfbuzz-devel kauth-devel kcodecs-devel kconfig-devel kconfigwidgets-devel kcoreaddons-devel kf5-filesystem ki18n-devel kwidgetsaddons-devel kwindowsystem-devel libblkid-devel libbrotli-devel libbz2-devel libcairo-script-interpreter2 libcanberra-devel libdatrie-devel libdrm-devel libepoxy-devel libexpat-devel libffi-devel libglvnd-devel libharfbuzz-gobject0 libharfbuzz-subset0 libicu-devel libjsoncpp24 libkscreen2-devel libmatekbd-devel libmatemixer-devel libmount-devel libpcre16-0 libpcrecpp0 libpcreposix0 libpixman-1-0-devel libpng16-compat-devel libpng16-devel libpulse-devel libQt5Concurrent-devel libQt5Core-devel libQt5DBus-devel libQt5Gui-devel libqt5-linguist libQt5Network-devel libQt5PrintSupport-devel libqt5-qtbase-common-devel libqt5-qtdeclarative-devel libqt5-qtdeclarative-tools libqt5-qtmultimedia-devel libqt5-qtsvg-devel libqt5-qtx11extras-devel libQt5Sql-devel libQt5Test-devel libQt5Widgets-devel libQt5Xml-devel librhash0 libselinux-devel libsepol-devel libstdc++6-devel-gcc10 libstdc++-devel libthai-devel libuuid-devel libX11-devel libXau-devel libxcb-devel libxcb-screensaver0 libxcb-xf86dri0 libxcb-xtest0 libxcb-xvmc0 libXcomposite-devel libXcursor-devel libXdamage-devel libXext-devel libXfixes-devel libXft-devel libXi-devel libXinerama-devel libxkbcommon-devel libxklavier-devel libxml2-devel libXrandr-devel libXrender-devel libXtst-devel mate-desktop-devel Mesa-KHR-devel Mesa-libEGL-devel Mesa-libGL-devel ncurses-devel pango-devel pcre-devel readline-devel startup-notification-devel tack typelib-1_0-Atk-1_0 typelib-1_0-Atspi-2_0 typelib-1_0-GdkPixbuf-2_0 typelib-1_0-GdkPixdata-2_0 typelib-1_0-Gtk-3_0 typelib-1_0-HarfBuzz-0_0 typelib-1_0-Pango-1_0 typelib-1_0-Xkl-1_0 vulkan-devel vulkan-headers wayland-devel wayland-protocols-devel xorgproto-devel xz-devel zlib-devel libKF5Screen7 libkscreen2-plugin libpulse0 libpulse-mainloop-glib0 pulseaudio pulseaudio-bash-completion pulseaudio-module-bluetooth pulseaudio-module-gsettings pulseaudio-module-x11 pulseaudio-module-zeroconf pulseaudio-utils extra-cmake-modules-doc libpng16-compat-devel kguiaddons-devel libpwquality1 libxkbcommon-devel libxkbfile-devel libpolkit-qt5-1-devel 'libboost*-devel' bluez-qt-devel + # - name: QMake configure & Make + # run: | + # ln -s /usr/bin/lrelease-qt5 /usr/bin/lrelease; + # mkdir build; + # cd build; + # qmake-qt5 ..; + # make -j$(nproc); ubuntu-latest: name: on Ubuntu Latest @@ -96,11 +112,31 @@ uses: actions/checkout@v2 - name: Update apt repository run: apt-get update -y - - name: Install build dependcies - run: apt-get install -y build-essential qt5-default qttools5-dev-tools pkg-kde-tools pkg-config libkf5widgetsaddons-dev libkf5config-dev libkf5configwidgets-dev libkf5screen-dev debhelper-compat libqt5svg5-dev libgsettings-qt-dev libglib2.0-dev libmatekbd-dev libqt5x11extras5-dev libxklavier-dev qtdeclarative5-dev libdconf-dev libmatemixer-dev libqt5xdg-dev qtmultimedia5-dev libxml2-dev libcanberra-dev libmate-desktop-dev libxkbcommon-dev libxkbfile-dev + - name: Install build dependencies + run: apt-get install -y build-essential qt5-default qttools5-dev-tools pkg-kde-tools pkg-config libkf5widgetsaddons-dev libkf5config-dev libkf5configwidgets-dev libkf5screen-dev debhelper-compat libqt5svg5-dev libgsettings-qt-dev libglib2.0-dev libmatekbd-dev libqt5x11extras5-dev libxklavier-dev qtdeclarative5-dev libdconf-dev libmatemixer-dev libqt5xdg-dev qtmultimedia5-dev libxml2-dev libcanberra-dev libmate-desktop-dev libxkbcommon-dev libxkbfile-dev libkf5i18n-dev libkf5windowsystem-dev libkf5guiaddons-dev libkf5coreaddons-dev libboost-dev libxcb-xkb-dev libpolkit-qt5-1-dev libkf5bluezqt-dev libudev-dev xserver-xorg-dev libupower-glib-dev libpam0g-dev libkf5xmlgui-dev libkf5globalaccel-dev - name: QMake configure & Make run: | mkdir build; cd build; qmake ..; make -j$(nproc); + + # ubuntu-rolling: + # name: on Ubuntu Rolling + # runs-on: ubuntu-20.04 + # container: docker.io/library/ubuntu:rolling + # env: + # DEBIAN_FRONTEND: noninteractive + # steps: + # - name: Checkout ukui-control-center source code + # uses: actions/checkout@v2 + # - name: Update apt repository + # run: apt-get update -y + # - name: Install build dependencies + # run: apt-get install -y build-essential qttools5-dev-tools pkg-kde-tools pkg-config libkf5widgetsaddons-dev libkf5config-dev libkf5configwidgets-dev libkf5screen-dev debhelper-compat libqt5svg5-dev libgsettings-qt-dev libglib2.0-dev libmatekbd-dev libqt5x11extras5-dev libxklavier-dev qtdeclarative5-dev libdconf-dev libmatemixer-dev libqt5xdg-dev qtmultimedia5-dev libxml2-dev libcanberra-dev libmate-desktop-dev libxkbcommon-dev libxkbfile-dev libkf5i18n-dev libkf5windowsystem-dev libkf5guiaddons-dev libkf5coreaddons-dev libboost-dev libxcb-xkb-dev libpolkit-qt5-1-dev libpulse-dev libkf5bluezqt-dev libudev-dev xserver-xorg-dev libupower-glib-dev libpam0g-dev libkf5xmlgui-dev libkf5globalaccel-dev + # - name: QMake configure & Make + # run: | + # mkdir build; + # cd build; + # qmake ..; + # make -j$(nproc); diff -Nru ukui-control-center-2.0.3/group-manager-server/conf/org.ukui.groupmanager.conf ukui-control-center-3.0.3/group-manager-server/conf/org.ukui.groupmanager.conf --- ukui-control-center-2.0.3/group-manager-server/conf/org.ukui.groupmanager.conf 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/group-manager-server/conf/org.ukui.groupmanager.conf 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/group-manager-server/conf/org.ukui.groupmanager.policy ukui-control-center-3.0.3/group-manager-server/conf/org.ukui.groupmanager.policy --- ukui-control-center-2.0.3/group-manager-server/conf/org.ukui.groupmanager.policy 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/group-manager-server/conf/org.ukui.groupmanager.policy 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,44 @@ + + + + KYLINOS + http://www.kylinos.cn + ues + + + group tools + 用户组 + To add the group, you need to authenticate. + 添加用户组需要认证 + + auth_admin + auth_admin + auth_admin + + + + group tools + 用户组 + To edit the group, you need to authenticate. + 修改用户组需要认证 + + auth_admin + auth_admin + auth_admin + + + + group tools + 用户组 + To delete the group, you need to authenticate. + 删除用户组需要认证 + + auth_admin + auth_admin + auth_admin + + + + diff -Nru ukui-control-center-2.0.3/group-manager-server/conf/ukui-group-manager.service ukui-control-center-3.0.3/group-manager-server/conf/ukui-group-manager.service --- ukui-control-center-2.0.3/group-manager-server/conf/ukui-group-manager.service 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/group-manager-server/conf/ukui-group-manager.service 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,9 @@ +[Unit] +Description=group-manager-server + +[Service] +User=root +ExecStart=/usr/bin/group-manager-server + +[Install] +WantedBy=multi-user.target diff -Nru ukui-control-center-2.0.3/group-manager-server/custom_struct.h ukui-control-center-3.0.3/group-manager-server/custom_struct.h --- ukui-control-center-2.0.3/group-manager-server/custom_struct.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/group-manager-server/custom_struct.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,50 @@ +/* +* 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 + +#ifndef CUSTOM_STRUCT +#define CUSTOM_STRUCT +struct custom_struct +{ + QString groupname; + QString passphrase; + QString groupid; + QString usergroup; + + friend QDBusArgument &operator<<(QDBusArgument &argument, const custom_struct&mystruct) + { + argument.beginStructure(); + argument << mystruct.groupname << mystruct.passphrase << mystruct.groupid << mystruct.usergroup; + argument.endStructure(); + return argument; + } + + friend const QDBusArgument &operator>>(const QDBusArgument &argument, custom_struct&mystruct) + { + argument.beginStructure(); + argument >> mystruct.groupname >> mystruct.passphrase >> mystruct.groupid >> mystruct.usergroup; + argument.endStructure(); + return argument; + } + +}; + +Q_DECLARE_METATYPE(custom_struct) +#endif diff -Nru ukui-control-center-2.0.3/group-manager-server/group_manager_server.cpp ukui-control-center-3.0.3/group-manager-server/group_manager_server.cpp --- ukui-control-center-2.0.3/group-manager-server/group_manager_server.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/group-manager-server/group_manager_server.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,235 @@ +/* +* 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 + +group_manager_server::group_manager_server() +{ + +} + +// 解析组文件 +QVariantList group_manager_server::getGroup() +{ + const QString fileName = "/etc/group"; + QFile groupFile(fileName); + + QVariantList value; + QVariant cnt; + int lineCount = 1; + + if(!groupFile.exists()){ + printf("/etc/group file not exist \n"); + } + if(!groupFile.open(QIODevice::ReadOnly | QIODevice::Text)){ + printf("open /etc/group fail \n"); + } + + QTextStream in(&groupFile); + QString line = in.readLine(); + struct custom_struct demo[200]; + + while(!line.isNull()){ + QStringList lineList = line.split(":"); + line = in.readLine(); + demo[lineCount].groupname = lineList.at(0); + demo[lineCount].passphrase = lineList.at(1); + demo[lineCount].groupid = lineList.at(2); + demo[lineCount].usergroup = lineList.at(3); + cnt = QVariant::fromValue(demo[lineCount]); + value << cnt; + lineCount ++; + } + return value; +} + +// 解析passwd文件 +QVariantList group_manager_server::getPasswd() +{ + const QString fileName = "/etc/passwd"; + QFile passwdFile(fileName); + + QVariantList value; + QVariant cnt; + int lineCount = 1; + + if(!passwdFile.exists()){ + printf("/etc/passwd file not exist \n"); + } + if(!passwdFile.open(QIODevice::ReadOnly | QIODevice::Text)){ + printf("open /etc/passwd fail \n"); + } + + QTextStream in(&passwdFile); + QString line = in.readLine(); + struct custom_struct demo[200]; + + while(!line.isNull()){ + QStringList lineList = line.split(":"); + line = in.readLine(); + demo[lineCount].groupname = lineList.at(0); + demo[lineCount].passphrase = lineList.at(1); + demo[lineCount].groupid = lineList.at(3); + cnt = QVariant::fromValue(demo[lineCount]); + value << cnt; + lineCount ++; + } + return value; +} + +// 添加组 +bool group_manager_server::add(QString groupName, QString groupId) +{ + QString groupadd = "/usr/sbin/groupadd"; + QString addgroup = "/usr/sbin/addgroup"; + QString command; + QFile groupaddFile("/usr/sbin/addgroup"); + QFile addgroupFile("/usr/sbin/groupadd"); + + QProcess p(0); + QStringList args; + + if(!addgroupFile.exists()){ + printf("/usr/sbin/addgroup file not exist \n"); + if(!groupaddFile.exists()){ + return false; + } + command = groupadd; + args.append("-g"); + args.append(groupId); + args.append(groupName); + }else{ + command = addgroup; + args.append("-gid"); + args.append(groupId); + args.append(groupName); + } + + + p.execute(command,args);//command是要执行的命令,args是参数 + p.waitForFinished(-1); +// qDebug()< +#include +#include +#include +#include +#include + +#include "custom_struct.h" + +class group_manager_server : public QObject +{ + Q_OBJECT + //定义Interface名称 + Q_CLASSINFO("D-Bus Interface", "org.ukui.groupmanager.interface") +public: + explicit group_manager_server(); + +public slots: + QVariantList getGroup(); + QVariantList getPasswd(); + bool add(QString groupName, QString groupId); + bool set(QString groupName, QString groupId); + bool del(QString groupName); + bool addUserToGroup(QString groupName, QString userName); + bool delUserFromGroup(QString groupName, QString userName); + +private: + QList value; + +signals: + void message(); +}; diff -Nru ukui-control-center-2.0.3/group-manager-server/group-manager-server.pro ukui-control-center-3.0.3/group-manager-server/group-manager-server.pro --- ukui-control-center-2.0.3/group-manager-server/group-manager-server.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/group-manager-server/group-manager-server.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,48 @@ +TEMPLATE = app +TARGET = group-manager-server +INCLUDEPATH += . + +QT += dbus core +# The following define makes your compiler warn you 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 + +# Input +DBUS_ADAPTORS += org.ukui.groupmanager.xml +DBUS_INTERFACES += org.ukui.groupmanager.xml + +HEADERS += \ + custom_struct.h \ + group_manager_server.h +SOURCES += \ + group_manager_server.cpp \ + main.cpp + +target.path = /usr/bin/ +!isEmpty(target.path): INSTALLS += target + +dbus_conf.path = /etc/dbus-1/system.d +dbus_conf.files += conf/org.ukui.groupmanager.conf +INSTALLS += dbus_conf + +systemd_service.path = /lib/systemd/system +systemd_service.files += conf/ukui-group-manager.service +INSTALLS += systemd_service + +polkit.path = /usr/share/polkit-1/actions/ +polkit.files += conf/org.ukui.groupmanager.policy +INSTALLS += polkit + + + + + + + diff -Nru ukui-control-center-2.0.3/group-manager-server/main.cpp ukui-control-center-3.0.3/group-manager-server/main.cpp --- ukui-control-center-2.0.3/group-manager-server/main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/group-manager-server/main.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,47 @@ +/* +* 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 "group_manager_server.h" +#include "custom_struct.h" +#include "groupmanager_adaptor.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + + qRegisterMetaType("custom_struct"); + qDBusRegisterMetaType(); + QDBusConnection connection = QDBusConnection::systemBus(); + + if (!connection.registerService("org.ukui.groupmanager")) { + qDebug() << "error:" << connection.lastError().message(); +// exit(-1); + } + group_manager_server *dbus_demo = new group_manager_server(); + new InterfaceAdaptor(dbus_demo); + connection.registerObject("/org/ukui/groupmanager", dbus_demo); + QDBusMessage msg = QDBusMessage::createSignal("/org/ukui/groupmanager", "org.ukui.groupmanager.interface", "message"); + QDBusConnection::systemBus().send(msg); + return a.exec(); +} diff -Nru ukui-control-center-2.0.3/group-manager-server/org.ukui.groupmanager.xml ukui-control-center-3.0.3/group-manager-server/org.ukui.groupmanager.xml --- ukui-control-center-2.0.3/group-manager-server/org.ukui.groupmanager.xml 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/group-manager-server/org.ukui.groupmanager.xml 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/man/checkuserpwd.1 ukui-control-center-3.0.3/man/checkuserpwd.1 --- ukui-control-center-2.0.3/man/checkuserpwd.1 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/man/checkuserpwd.1 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,19 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH CHECKUSERPWD 1 "20 SEP 2019" +.\" Please adjust this date whenever revising the manpage. +.SH NAME +checkuserpwd \- launch ukui-control-center program +.SH SYNOPSIS +.B checkuserpwd +.SH DESCRIPTION +.B checkuserpwd +It is used to launch program of checkuserpwd. +.PP +.SH SEE ALSO +.BR checkuserpwd (1), +.br +.SH AUTHOR +checkuserpwd was written by hebing . +.PP +This manual page was written by hebing . + diff -Nru ukui-control-center-2.0.3/man/group-manager-server.1 ukui-control-center-3.0.3/man/group-manager-server.1 --- ukui-control-center-2.0.3/man/group-manager-server.1 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/man/group-manager-server.1 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,19 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH GROUP-MANAGER-SERVER 1 "20 SEP 2019" +.\" Please adjust this date whenever revising the manpage. +.SH NAME +group-manager-server \- launch ukui-control-center program +.SH SYNOPSIS +.B group-manager-server +.SH DESCRIPTION +.B group-manager-server +It is used to launch program of group-manager-server. +.PP +.SH SEE ALSO +.BR group-manager-server (1), +.br +.SH AUTHOR +group-manager-server was written by hebing . +.PP +This manual page was written by hebing . + diff -Nru ukui-control-center-2.0.3/man/ukui-control-center-session.1 ukui-control-center-3.0.3/man/ukui-control-center-session.1 --- ukui-control-center-2.0.3/man/ukui-control-center-session.1 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/man/ukui-control-center-session.1 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,19 @@ +.\" Hey, EMACS: -*- nroff -*- +.TH UKUI-CONTROL-CENTER-SESSION 1 "20 SEP 2019" +.\" Please adjust this date whenever revising the manpage. +.SH NAME +ukui-control-center-session \- launch ukui-control-center-session program +.SH SYNOPSIS +.B ukui-control-center-session +.SH DESCRIPTION +.B ukui-control-center-session +It is used to launch program of ukui-control-center-session. +.PP +.SH SEE ALSO +.BR ukui-control-center-session (1), +.br +.SH AUTHOR +ukui-control-center-session was written by hebing . +.PP +This manual page was written by hebing . + diff -Nru ukui-control-center-2.0.3/plugins/account/loginoptions/loginoptions.cpp ukui-control-center-3.0.3/plugins/account/loginoptions/loginoptions.cpp --- ukui-control-center-2.0.3/plugins/account/loginoptions/loginoptions.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/loginoptions/loginoptions.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -34,6 +34,7 @@ LoginOptions::~LoginOptions() { delete ui; + ui = nullptr; } QString LoginOptions::get_plugin_name(){ diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/areacodelineedit.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/areacodelineedit.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/areacodelineedit.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/areacodelineedit.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ -/* -*- 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 "areacodelineedit.h" - - -/* 读取国家代码JSon文件并写入ComboBox */ -void AreaCodeLineEdit::InittoCountrycode() { - m_loadFile = new QFile(":/country.json",this); - if(!m_loadFile->open(QIODevice::ReadOnly)) { - qDebug() <<"Open fail!"; - return ; - } - QByteArray Data = m_loadFile->readAll(); - m_loadFile->close(); - QJsonParseError json_error; - m_jsonFile = new QJsonDocument(QJsonDocument::fromJson(Data,&json_error)); - - if(json_error.error != QJsonParseError::NoError) { - qDebug() << "Json Error!"; - return ; - } - - m_jsonCode = m_jsonFile->array(); - for(int itempos = 0;itempos < m_jsonCode.count();itempos ++) { - QJsonObject json = m_jsonCode.at(itempos).toObject(); - QJsonArray jar = json.value("items").toArray(); - for(int country = 0;country < jar.count();country ++) { - QString c_code = jar.at(country).toObject().value("label").toString(); - QString code = jar.at(country).toObject().value("code").toString(); - QString c_en = jar.at(country).toObject().value("label_en").toString(); - m_countryCode.insert(c_en,QPair(c_code,code)); - } - } -} - -AreaCodeLineEdit::AreaCodeLineEdit(QWidget *parent) : QLineEdit(parent) -{ - //Allocate the memories - m_countryComboBox = new ComboBox(this); - m_verticalLine = new QFrame(this); - m_hboxLayout = new QHBoxLayout; - - //Resize - resize(338,36); - setMinimumSize(338,36); - m_verticalLine->setParent(this); - setMaximumSize(338,36); - // setMaximumSize(82,36); - m_verticalLine->setMaximumSize(2,14); - m_verticalLine->setMinimumSize(2,14); - m_verticalLine->resize(2,14); - setTextMargins(98,0,0,0); - //Configuration - InittoCountrycode(); - QMapIterator> Iter(m_countryCode); - while(Iter.hasNext()) - { - Iter.next(); - m_countryComboBox->addItem(Iter.value().second,Iter.value().first); - } - m_verticalLine->setFrameShape(QFrame::VLine); - m_verticalLine->setFrameShadow(QFrame::Plain); - m_verticalLine->setLineWidth(1); - m_verticalLine->setFixedHeight(14); - m_verticalLine->setStyleSheet("color:#CCCCCC"); - setPlaceholderText(tr("Sign up by Phone")); - - //Set Layout - - m_hboxLayout->setContentsMargins(2,0,0,0); - m_hboxLayout->addWidget(m_countryComboBox); - m_hboxLayout->addSpacing(8); - m_hboxLayout->addWidget(m_verticalLine); - m_hboxLayout->setAlignment(Qt::AlignLeft); - setLayout(m_hboxLayout); - setContentsMargins(0,0,0,0); - -} - -AreaCodeLineEdit::~AreaCodeLineEdit() { - delete m_jsonFile; -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/areacodelineedit.h ukui-control-center-3.0.3/plugins/account/networkaccount/areacodelineedit.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/areacodelineedit.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/areacodelineedit.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* -*- 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 AREA_CODE_LINEEDIT_H -#define AREA_CODE_LINEEDIT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "combobox.h" - -class AreaCodeLineEdit : public QLineEdit -{ - Q_OBJECT -public: - explicit AreaCodeLineEdit(QWidget *parent = nullptr); - void InittoCountrycode(); - ~AreaCodeLineEdit(); -private: - ComboBox *m_countryComboBox; - QJsonArray m_jsonCode; - QJsonArray m_jsonArray; - QJsonDocument *m_jsonFile; - QFrame *m_verticalLine; - QFile *m_loadFile; - QMap>m_countryCode; - QStandardItemModel *m_stardardModel; - QHBoxLayout *m_hboxLayout; -signals: - -}; - -#endif // AREA_CODE_LINEEDIT_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/bindphonedialog.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/bindphonedialog.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/bindphonedialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/bindphonedialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,124 +0,0 @@ -/* -*- 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 "bindphonedialog.h" - -BindPhoneDialog::BindPhoneDialog(QWidget *parent) : QWidget(parent) -{ - setContentsMargins(0,0,0,0); - this->setFixedWidth(338); - m_phoneLineEdit = new AreaCodeLineEdit(this); - m_mCodeLineEdit = new QLineEdit(this); - m_sendCode_btn = new QPushButton(this); - - m_tips = new Tips(this); - m_svgHandler = new SVGHandler(this); - m_vboxLayout = new QVBoxLayout; - m_subHBoxLayout = new QHBoxLayout; - - QString str = ("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3D6BE5;font-size: 14px;color: rgba(0,0,0,0.85);lineedit-password-character: 42;}" - "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}" - "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}"); - //valid_code->setStyleSheet(str); - //phone->setStyleSheet(str); - m_mCodeLineEdit->setPlaceholderText(tr("Your code here")); - m_sendCode_btn->setText(tr("Get phone code")); - //send_code->setStyleSheet("QPushButton{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(0,0,0,0.85);} " - // "QPushButton:hover{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(61,107,229,0.85);}" - // "QPushButton:click{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(61,107,229,0.85);}"); - - - m_phoneLineEdit->setFixedSize(QSize(338,36)); - m_mCodeLineEdit->setFixedSize(120,36); - m_sendCode_btn->setFixedSize(198,36); - m_vboxLayout->setMargin(0); - m_vboxLayout->setSpacing(8); - m_vboxLayout->setAlignment(Qt::AlignTop); - m_subHBoxLayout->setMargin(0); - m_subHBoxLayout->setSpacing(16); - - m_mCodeLineEdit->setTextMargins(12,0,0,0); - - m_vboxLayout->addWidget(m_phoneLineEdit); - m_subHBoxLayout->addWidget(m_mCodeLineEdit,0,Qt::AlignLeft); - m_subHBoxLayout->addWidget(m_sendCode_btn,0,Qt::AlignRight); - m_vboxLayout->addLayout(m_subHBoxLayout); - m_vboxLayout->addWidget(m_tips); - m_vboxLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - setLayout(m_vboxLayout); - - m_tips->hide(); - m_phoneLineEdit->setFocus(); - adjustSize(); -} - -void BindPhoneDialog::set_staus(bool ok) { - m_phoneLineEdit->setEnabled(ok); - m_mCodeLineEdit->setEnabled(ok); - m_sendCode_btn->setEnabled(ok); -} - -/* 设置错误代码,并发出错误代码更换信号,传给主框,让主框完成错误代码更新 */ -void BindPhoneDialog::set_code(QString codenum) { - m_countryCode = codenum; - emit code_changed(); -} - -/* 富文本处理错误提示消息 */ -void BindPhoneDialog::setstyleline() { - m_tips->set_text(m_countryCode); -} - -/* 清理绑定手机号码框 */ -void BindPhoneDialog::setclear() { - m_phoneLineEdit->setText(""); - m_mCodeLineEdit->setText(""); -} - -/* 获取验证码发送按钮 */ -QPushButton* BindPhoneDialog::get_send_code() { - return m_sendCode_btn; -} - -/* 获取密码输入提示文本 */ -Tips* BindPhoneDialog::get_tips() { - return m_tips; -} - -/* 获取验证码字符串 */ -QString BindPhoneDialog::get_code() { - return m_mCodeLineEdit->text(); -} - - -/* 获取手机号码字符串 */ -QString BindPhoneDialog::get_phone() { - return m_phoneLineEdit->text(); -} - -/* 获取验证码输入框 */ -QLineEdit* BindPhoneDialog::get_code_lineedit() { - return m_mCodeLineEdit; -} - - -/* 获取手机号码输入框 */ -AreaCodeLineEdit* BindPhoneDialog::get_phone_lineedit() { - return m_phoneLineEdit; -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/bindphonedialog.h ukui-control-center-3.0.3/plugins/account/networkaccount/bindphonedialog.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/bindphonedialog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/bindphonedialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* -*- 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 BINDPHONEDIALOG_H -#define BINDPHONEDIALOG_H - -#include -#include -#include -#include "passwordlineedit.h" -#include -#include -#include -#include "areacodelineedit.h" -#include -#include "tips.h" -#include "svghandler.h" - -class BindPhoneDialog : public QWidget -{ - Q_OBJECT -public: - explicit BindPhoneDialog(QWidget *parent = nullptr); - void setclear(); - void set_code(QString m_countryCode); - QPushButton *get_send_code(); - Tips *get_tips(); - QString get_phone(); - QString get_code(); - AreaCodeLineEdit* get_phone_lineedit(); - QLineEdit* get_code_lineedit(); - void set_staus(bool ok); -public slots: - void setstyleline(); -signals: - void code_changed(); -private: - QString m_countryCode; - AreaCodeLineEdit *m_phoneLineEdit; - QLineEdit *m_mCodeLineEdit; - QPushButton *m_sendCode_btn; - QVBoxLayout *m_vboxLayout; - QHBoxLayout *m_subHBoxLayout; - Tips *m_tips; - SVGHandler *m_svgHandler; - -}; - -#endif // BINDPHONEDIALOG_H - diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/blueeffect.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/blueeffect.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/blueeffect.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/blueeffect.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -8,8 +8,8 @@ m_svgHandler = new SVGHandler(this); m_workLayout = new QHBoxLayout; - this->setStyleSheet("ql_animation_label{background-color:#3D6BE5;border-radius:4px;}"); - m_textLabel->setStyleSheet("font-size:14px;color:#ffffff;background:transparent;"); + this->setStyleSheet("Blueeffect{background-color:#3790FA;border-radius:4px;}"); + m_textLabel->setStyleSheet("color:#ffffff;background:transparent;"); m_iconLabel->setStyleSheet("background:transparent;"); m_iconLabel->setFixedSize(24,24); m_workLayout->setSpacing(8); @@ -19,7 +19,7 @@ m_workLayout->addWidget(m_iconLabel); setLayout(m_workLayout); m_cTimer->stop(); - connect(m_cTimer,&QTimer::timeout, [this] () { + connect(m_cTimer,&QTimer::timeout, this,[=] () { QPixmap pixmap = m_svgHandler->loadSvgColor(QString(":/new/image/loading1%1.svg").arg(m_cCnt),"white",16); m_iconLabel->setPixmap(pixmap); m_cCnt = (m_cCnt + 9) % 8; @@ -27,7 +27,11 @@ hide(); } -void Blueeffect::settext(QString t) { +Blueeffect::~Blueeffect(){ + m_cTimer->stop(); +} + +void Blueeffect::settext(const QString &t) { m_textLabel->setText(t); } @@ -40,7 +44,7 @@ void Blueeffect::stop() { m_cCnt = 1; m_iconLabel->setPixmap(m_svgHandler->loadSvg(":/new/image/loading11.svg")); - if(m_cTimer->isActive()) + if (m_cTimer->isActive()) m_cTimer->stop(); hide(); } diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/blueeffect.h ukui-control-center-3.0.3/plugins/account/networkaccount/blueeffect.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/blueeffect.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/blueeffect.h 2021-04-14 01:27:20.000000000 +0000 @@ -13,9 +13,10 @@ Q_OBJECT public: explicit Blueeffect(QWidget *parent = nullptr); + ~ Blueeffect(); QLabel *m_textLabel; QLabel *m_iconLabel; - void settext(QString t); + void settext(const QString &t); void startmoive(); void stop(); QTimer *m_cTimer; diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/boxitem.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/boxitem.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/boxitem.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/boxitem.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -23,10 +23,10 @@ { m_countryCode= new QLabel(this); m_countryName = new QLabel(this); - m_countryCode->setStyleSheet("QLabel{color:rgba(0,0,0,0.85);font-size:14px}" - "QLabel:hover{color:#FFFFFF;font-size:14px}"); - m_countryName->setStyleSheet("QLabel{color:rgba(0,0,0,0.65);font-size:14px}" - "QLabel:hover{color:#FFFFFF;font-size:14px}"); + m_countryCode->setStyleSheet("QLabel{color:rgba(0,0,0,0.85);}" + "QLabel:hover{color:#FFFFFF}"); + m_countryName->setStyleSheet("QLabel{color:rgba(0,0,0,0.65);}" + "QLabel:hover{color:#FFFFFF;}"); QHBoxLayout *layout = new QHBoxLayout; m_countryCode->setObjectName("code"); m_countryName->setObjectName("country"); @@ -40,12 +40,12 @@ } /* 设置国家名字 */ -void BoxItem::set_code(QString str) { +void BoxItem::set_code(const QString &str) { m_countryCode->setText(str); } /* 设置国家代码 */ -void BoxItem::set_country_code(QString str) { +void BoxItem::set_country_code(const QString &str) { m_countryName->setText(str); } diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/boxitem.h ukui-control-center-3.0.3/plugins/account/networkaccount/boxitem.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/boxitem.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/boxitem.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* -*- 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 QL_BOX_ITEM_H -#define QL_BOX_ITEM_H - -#include -#include -#include -#include - - -class BoxItem : public QWidget -{ - Q_OBJECT -public: - explicit BoxItem(QWidget *parent = nullptr); - void set_country_code(QString str); - void set_code(QString str); -protected: - virtual void enterEvent(QEvent * event); - virtual void leaveEvent(QEvent * event); -private: - QLabel *m_countryCode; - QLabel *m_countryName; -signals: - -}; - -#endif // QL_BOX_ITEM_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/combobox.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/combobox.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/combobox.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/combobox.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/* -*- 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 "combobox.h" - -ComboBox::ComboBox(QWidget *parent) : QWidget(parent) -{ - //Allocate the memory - m_mainLineEdit = new QLineEdit(this); - m_pushButton = new QPushButton(this); - m_popupWidget = new PopupWidget(this); - m_listWidget = new QListWidget(this); - m_lineeditLayout = new QHBoxLayout; - m_popupLayout = new QVBoxLayout; - m_comboboxLayout = new QVBoxLayout; - m_svgHandler = new SVGHandler(this); - - //Size - m_mainLineEdit->setFixedSize(66,34); - m_pushButton->setFixedSize(14,14); - m_listWidget->setMinimumSize(188,36); - m_listWidget->resize(188,36); - m_popupWidget->setFixedSize(216,196); - setMaximumSize(66,34); - resize(66,34); - idx = 0; - setContentsMargins(0,0,0,0); - - //Configuration - m_listWidget->setContentsMargins(0,0,0,0); - m_mainLineEdit->setTextMargins(16,0,0,0); - m_mainLineEdit->setFocusPolicy(Qt::NoFocus); - m_pushButton->setFocusPolicy(Qt::NoFocus); - - //Style - //lineedit->setStyleSheet("QLineEdit{border:none;font-size:14px;}"); - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/arrow_down.svg"); - m_pushButton->setIcon(pixmap); - m_pushButton->setStyleSheet("QPushButton{" - "background-repeat:no-repeat;background-position :center;font-size:14px;background-color:transparent;border:none}"); - m_listWidget->setStyleSheet("QListView{border:1px solid #CFCFCF;border-color:#F4F4F4;border-radius:4px;}" - "QListView::item{background: #FFF;border-radius:4px;}" - "QListView::item:selected{background: #ffffffff;}" - "QListView::item:hover {background: #3D6BE5;}"); - - //Layout - m_lineeditLayout->setMargin(0); - m_lineeditLayout->setSpacing(0); - m_lineeditLayout->addWidget(m_pushButton,0,Qt::AlignRight); - m_mainLineEdit->setLayout(m_lineeditLayout); - - m_popupLayout->setMargin(0); - m_popupLayout->setSpacing(0); - m_popupLayout->addWidget(m_listWidget); - m_popupWidget->setLayout(m_popupLayout); - m_popupWidget->setContentsMargins(6,6,6,6); - m_popupWidget->hide(); - - m_comboboxLayout->setMargin(0); - m_comboboxLayout->setSpacing(0); - m_comboboxLayout->addWidget(m_mainLineEdit); - m_comboboxLayout->addWidget(m_popupWidget); - m_comboboxLayout->setAlignment(Qt::AlignLeft); - setLayout(m_comboboxLayout); - m_mainLineEdit->setText("+86"); - m_pushButton->setEnabled(false); - - //Connect slots - connect(m_listWidget,SIGNAL(itemClicked(QListWidgetItem *)),this,SLOT(closepopup(QListWidgetItem *))); - connect(m_pushButton, SIGNAL(clicked()),this,SLOT(showpopup())); -} - -/* 显示下拉框 */ -void ComboBox::showpopup() { - if (m_popupWidget->isHidden()) { - QPoint pos; - pos.setX(this->mapToGlobal(QPoint(0, 0)).x() - 6); - pos.setY(this->mapToGlobal(QPoint(0, 0)).y() + this->height()); - m_popupWidget->move(pos); - m_popupWidget->show(); - } else { - m_popupWidget->hide(); - } -} - -/* 关闭下拉框,并记录鼠标点击的位置相对应的国家代码输入到代码框 */ -void ComboBox::closepopup(QListWidgetItem *item) { - m_popupWidget->hide(); - QWidget *wgt = m_listWidget->itemWidget(item); - if(wgt != NULL) { - QLabel *code = wgt->findChild("code"); - m_mainLineEdit->setText(code->text()); - } -} - -/* 增加新的国家以及代码,不常用 */ -void ComboBox::addItem(QString country, QString code) { - QListWidgetItem* widgetItem = new QListWidgetItem(m_listWidget); - BoxItem *wgt = new BoxItem(this); - - wgt->set_code(country); - wgt->set_country_code(code); - m_listWidget->insertItem(idx ++,widgetItem); - widgetItem->setSizeHint(QSize(188,36)); - widgetItem->setHidden(false); - m_listWidget->setItemWidget(widgetItem, wgt); -} - - diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/combobox.h ukui-control-center-3.0.3/plugins/account/networkaccount/combobox.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/combobox.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/combobox.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -/* -*- 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 QL_COMBOBOBX_H -#define QL_COMBOBOBX_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "boxitem.h" -#include "popupwidget.h" -#include -#include "svghandler.h" - -class ComboBox : public QWidget -{ - Q_OBJECT -public: - explicit ComboBox(QWidget *parent = nullptr); - void addItem(QString country,QString code); -public slots: - void showpopup(); - void closepopup(QListWidgetItem *item); -protected: - int idx; -private: - QLineEdit *m_mainLineEdit; - QPushButton *m_pushButton; - QListWidget *m_listWidget; - QWidget *m_popupWidget; - QHBoxLayout *m_lineeditLayout; - QVBoxLayout *m_popupLayout; - QVBoxLayout *m_comboboxLayout; - SVGHandler *m_svgHandler; -signals: - void currentIndexChanged(int index); -}; - -#endif // QL_COMBOBOBX_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/configfile.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/configfile.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/configfile.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/configfile.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -19,35 +19,48 @@ */ #include "configfile.h" #include +#include +#include +#include -ConfigFile::ConfigFile(QString qstrfilename) +ConfigFile::ConfigFile( QString qstrfilename) { if (qstrfilename.isEmpty()) { - m_qstrFileName = "/kylinssoclient/All.conf"; + QProcess proc; + QStringList option; + option << "-c" << "lsb_release -r | awk -F'\t' '{print $2}'"; + proc.start("/bin/bash",option); + proc.waitForFinished(); + QByteArray ar = proc.readAll().toStdString().c_str(); + QString m_confName = "All-" + ar.replace("\n","") + ".conf"; + m_qstrFileName =QDir::homePath() + "/.cache/kylinId/" + m_confName; } else { m_qstrFileName = qstrfilename; } - m_psetting = new QSettings(m_qstrFileName, QSettings::IniFormat); } ConfigFile::~ConfigFile() { delete m_psetting; - m_psetting = 0; + m_psetting = nullptr; +} + +QString ConfigFile::GetPath() const { + return m_qstrFileName; } -void ConfigFile::Set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue) +void ConfigFile::Set(const QString &qstrnodename,const QString &qstrkeyname,const QVariant &qvarvalue) { m_psetting->setValue(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname), qvarvalue); m_psetting->sync(); } -QVariant ConfigFile::Get(QString qstrnodename,QString qstrkeyname) +QVariant ConfigFile::Get(const QString &qstrnodename,const QString &qstrkeyname) const { QVariant qvar = m_psetting->value(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname)); return qvar; diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/configfile.h ukui-control-center-3.0.3/plugins/account/networkaccount/configfile.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/configfile.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/configfile.h 2021-04-14 01:27:20.000000000 +0000 @@ -28,8 +28,9 @@ public: ConfigFile(QString qstrfilename = ""); virtual ~ConfigFile(void); - void Set(QString,QString,QVariant); - QVariant Get(QString,QString); + void Set(const QString &group,const QString &key,const QVariant &value); + QVariant Get(const QString &group, const QString &key) const; + QString GetPath() const; private: QString m_qstrFileName; QSettings *m_psetting; diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/dbushandleclient.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/dbushandleclient.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/dbushandleclient.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/dbushandleclient.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,363 +0,0 @@ -#include "dbushandleclient.h" - -DbusHandleClient::DbusHandleClient(QObject *parent) : QObject(parent) -{ - -} - -/* DBUS接口之注册 */ -int DbusHandleClient::registered(QString username, QString pwd, QString phonenumb, QString mcode,QString uuid) { - int re = -1; - //构造一个method_call消息,服务名称为:org.kylinssoclient.dbus,对象路径为:/org/kylinssoclient/path - //接口名称为org.freedesktop.kylinssoclient.interface,method名称为check_login - QDBusMessage message = QDBusMessage::createMethodCall("org.kylinssoclient.dbus", - "/org/kylinssoclient/path", - "org.freedesktop.kylinssoclient.interface", - "registered"); - message< -#include - -class DbusHandleClient : public QObject -{ - Q_OBJECT -public: - bool m_bFirstAttempt = false; - explicit DbusHandleClient(QObject *parent = nullptr); -public slots: - int registered(QString username, QString pwd, QString phonenumb, QString mcode,QString uuid); // 注册接口 - int login(QString username, QString pwd,QString uuid); // 登录接口 - int get_mcode_by_phone(QString phonenumb,QString uuid); // 手机获取验证码 - int get_mcode_by_username(QString username,QString uuid); // 用户名获取验证码 - int user_resetpwd(QString username, QString newpwd, QString mCode,QString uuid); // 重置密码 - int user_phone_login(QString phone, QString mCode,QString uuid); // 手机登录 - char * check_login(); //检测登录状态 - int logout(); // 注销 - int init_conf(); // 登录后,调用init_oss后再初始化conf - int change_conf_value(QString name, int flag); // 应用配置开关 - int bindPhone(QString username, QString pwd, QString phone, QString mCode,QString uuid); - - - // ----------- 云相关 ----------------- - int init_oss(QString uuid); // 登录后,初始化云服务 - int manual_sync(); // 手动同步 -private: - -signals: - void login_ok(); - void reg_ok(); - void mcode_phone_ok(); - void mcode_username_ok(); - void restpwd_ok(); - void bind_ok(); - void init_ok(); - void changeret(int mode); - - void finished_ret_log(int ret); - void finished_ret_reg(int ret); - void finished_ret_phonelogin(int ret); - void finished_ret_rest(int ret); - void finished_ret_bind(int ret); - void finished_ret_code_log(int ret); - void finished_ret_code_reg(int ret); - void finished_ret_code_pass(int ret); - void finished_ret_code_bind(int ret); - void finished_ret_check_edit(QString ret); - void finished_ret_reset_edit(int ret); - void finished_ret_code_edit(int ret); - void finished_oss(int ret); - void finished_check_oss(QString ret); - void finished_check(QString ret); - void finished_conf(int ret); - void finished_man(int ret); - void finished_change(int ret); - void finished_logout(int ret); - -}; - -#endif // DBUSHANDLECLIENT_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/dbusutils.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/dbusutils.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/dbusutils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/dbusutils.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,92 @@ +#include "dbusutils.h" + +DBusUtils::DBusUtils(QObject *parent) : QObject(parent) +{ + +} + +QString DBusUtils::callMethod(const QString &methodName, const QList &argList) { + QVariant ret; + QDBusMessage message = QDBusMessage::createMethodCall(QString(DBUSNAME), + QString(PATH), + QString(INTERFACE), + methodName); + if (argList.isEmpty() == false) { + message.setArguments(argList); + } + QDBusMessage response = QDBusConnection::sessionBus().call(message); + if (response.type() == QDBusMessage::ReplyMessage) + { + if (response.arguments().isEmpty() == false) { + ret = response.arguments().takeFirst();; + } + } else { + qDebug()<(response.arguments().takeFirst()); + variant = value.variant(); + } + } else { + qDebug() < &argList) { + QVariant variant = "qwer"; + QDBusMessage message = QDBusMessage::createMethodCall(dbusname,path, + interface, + method); + QList list ; + if (value != "") + list << value; + if (argList.isEmpty() == false) { + list.append(argList); + } + if (list.isEmpty() == false) { + message.setArguments(list); + } + //qDebug() << dbusname <(response.arguments().takeFirst()); + variant = value.variant(); + if (variant.isValid() == false) { + variant = response.arguments().takeFirst(); + } + } + } else { + qDebug() << "call failed"; + } + //qDebug()< +#include +#include + +#define PATH "/org/kylinssoclient/path" +#define INTERFACE "org.freedesktop.kylinssoclient.interface" +#define DBUSNAME "org.kylinssoclient.dbus" +#define PROPERTYINTERFACE "org.freedesktop.DBus.Properties" +#define GETMETHOD "Get" +#define SETMETHOD "Set" + +class DBusUtils : public QObject +{ + Q_OBJECT +public: + explicit DBusUtils(QObject *parent = nullptr); + QString callMethod(const QString &methodName,const QList &argList); + int connectSignal(const QString &signal, QObject *obejct,const char *slot); + QVariant GetProperty(const QString &dbusname,const QString &interface,const QString &path,const QString &property,const int &flag); + QVariant ValueRet(const QString &dbusname, const QString &interface, const QString &path, const QString &method, + const int &flag, const QString &value, const QList &argList); + +Q_SIGNALS: + void taskFinished(const QString &taskName,int ret); + void infoFinished(const QString &ret); + void querryFinished(const QStringList &list); +}; + +#endif // DBUSUTILS_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/editpassdialog.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/editpassdialog.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/editpassdialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/editpassdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,550 +0,0 @@ -/* -*- 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 "editpassdialog.h" -#include -#include - -EditPassDialog::EditPassDialog(QWidget *parent) : QWidget(parent) -{ - m_szUuid = QUuid::createUuid().toString(); - //内存分配 - m_stackedWidget = new QStackedWidget(this); //切换成功页面与业务逻辑页面 - m_title = new QLabel(this); //标题 - m_delBtn = new QPushButton(this); //关闭按钮,定点摆放 - //account = new ql_lineedit_pass(this); - m_newPassLineEdit = new PasswordLineEdit(this); //新密码框 - m_passConfirm = new PasswordLineEdit(this); //确认密码框 - m_passTips = new QLabel(this); //密码提示 - m_mcodeLineEdit = new QLineEdit(this); //验证码框 - m_mcodeBtn = new QPushButton(this); //发送验证码按钮 - m_cancelBtn = new QPushButton(this); //取消按钮 - m_confirmBtn = new QPushButton(this); //确认按钮 - m_successDialog = new SuccessDiaolog(this); //成功页面 - m_workWidget = new QWidget(this); //业务逻辑页面 - - m_wokrLayout = new QVBoxLayout; //输入框布局 - m_hboxLayout = new QHBoxLayout; //验证码布局 - m_btnLayout = new QHBoxLayout; //按钮布局 - m_cMcodeTimer = new QTimer(this); //验证码计时器 - m_Tips = new Tips(this); //错误提示 - m_vboxLayout = new QVBoxLayout; //主窗口界面布局 - m_svgHandler = new SVGHandler(this); //SVG控制器 - - - - //控件初始化设置 - m_stackedWidget->addWidget(m_workWidget); - m_stackedWidget->addWidget(m_successDialog); - m_cMcodeTimer->stop(); - m_title->setText(tr("Edit Password")); - //account->setPlaceholderText(tr("Your password here")); - m_newPassLineEdit->setPlaceholderText(tr("Your new password here")); - m_mcodeLineEdit->setPlaceholderText(tr("Your code")); - m_mcodeBtn->setText(tr("Get phone code")); - m_cancelBtn->setText(tr("Cancel")); - m_confirmBtn->setText(tr("Confirm")); - m_passConfirm->setPlaceholderText(tr("Confirm your new password")); - m_passTips->setText(tr("At least 6 bit, include letters and digt")); - m_passTips->setStyleSheet("font-size:14px;"); - m_passTips->setFixedHeight(16); - m_mcodeLineEdit->setMaxLength(4); - m_stackedWidget->setCurrentWidget(m_workWidget); - - //控件尺寸大小设置 - m_delBtn->setMaximumSize(30,30); - m_delBtn->setMinimumSize(30,30); - m_title->adjustSize(); - m_delBtn->setFixedSize(30,30); - //account->setFixedSize(338,36); - m_newPassLineEdit->setFixedSize(338,36); - m_passConfirm->setFixedSize(338,36); - m_mcodeLineEdit->setFixedSize(120,34); - m_mcodeBtn->setFixedSize(198,34); - m_cancelBtn->setFixedSize(120,36); - m_confirmBtn->setFixedSize(120,36); - setFixedSize(420,446); - m_workWidget->setFixedSize(420,446); - m_successDialog->setFixedSize(420,446); - - m_delBtn->setGeometry(this->width() - 46,14,30,30); - m_delBtn->setFlat(true); - //设置样式表 - QString liness = "QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3D6BE5;font-size: 14px;color: rgba(0,0,0,0.85);lineedit-password-character: 42;}" - "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}" - "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}"; - QString labelss = "font-size: 24px;"; - QString confirmbtnss = "QPushButton {font-size:14px;background-color: #3D6BE5;border-radius: 4px;color:rgba(255,255,255,0.85);}" - "QPushButton:hover {font-size:14px;background-color: #415FC4;border-radius: 4px;position:relative;color:rgba(255,255,255,0.85);}" - "QPushButton:click {font-size:14px;background-color: #415FC4;border-radius: 4px;postion:realative;color:rgba(255,255,255,0.85);}"; - QString btnss = "QPushButton {font-size:14px;background: #F4F4F4;color:rgba(0,0,0,0.85);border-radius: 4px;}" - "QPushButton:hover{font-size:14px;color:rgba(61,107,229,0.85);position:relative;border-radius: 4px;}" - "QPushButton:click{font-size:14px;color:rgba(61,107,229,0.85);position:relative;border-radius: 4px;}"; - QString btns = "QPushButton {font-size:14px;background: #E7E7E7;color:rgba(0,0,0,0.85);border-radius: 4px;}" - "QPushButton:hover{font-size:14px;color:rgba(61,107,229,0.85);position:relative;border-radius: 4px;}" - "QPushButton:click{font-size:14px;color:rgba(61,107,229,0.85);position:relative;border-radius: 4px;}"; - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete.svg"); - m_delBtn->setIcon(pixmap); - m_delBtn->setStyleSheet("QPushButton{background:transparent;border-radius:4px;}" - "QPushButton:hover{background:transparent;background-color:#F86457;" - "border-radius:4px}" - "QPushButton:click{background:transparent;background-color:#E44C50;border-radius:4px}"); - m_delBtn->installEventFilter(this); - m_title->setStyleSheet(labelss); - //account->setStyleSheet(liness); - //newpass->setStyleSheet(liness); - //valid_code->setStyleSheet(liness); - //confirm_pass->setStyleSheet(liness); - //get_code->setStyleSheet(btnss); - //cancel->setStyleSheet(btns); - m_confirmBtn->setStyleSheet(confirmbtnss); - m_delBtn->setFocusPolicy(Qt::NoFocus); - - m_mcodeLineEdit->setMaxLength(4); - m_successDialog->set_mode_text(1); - QRegExp regx_code("[0-9]+$"); - QValidator *validator_code = new QRegExpValidator(regx_code, m_mcodeLineEdit ); - m_mcodeLineEdit->setValidator( validator_code ); - - //布局设置 - //account->setTextMargins(16,0,0,0); - m_newPassLineEdit->setTextMargins(12,0,0,0); - m_mcodeLineEdit->setTextMargins(12,0,0,0); - m_passConfirm->setTextMargins(12,0,0,0); - m_wokrLayout->addWidget(m_title,0,Qt::AlignLeft); - m_wokrLayout->setContentsMargins(41,55,41,36); - m_wokrLayout->addSpacing(20); - m_wokrLayout->setSpacing(8); - //vlayout->addWidget(account); - m_wokrLayout->addWidget(m_newPassLineEdit); - m_wokrLayout->addWidget(m_passTips); - m_wokrLayout->addWidget(m_passConfirm); - m_hboxLayout->addWidget(m_mcodeLineEdit); - m_hboxLayout->setMargin(0); - m_hboxLayout->setSpacing(16); - m_hboxLayout->addWidget(m_mcodeBtn); - m_hboxLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - m_wokrLayout->addLayout(m_hboxLayout); - m_wokrLayout->addWidget(m_Tips); - m_wokrLayout->addStretch(); - m_wokrLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - m_btnLayout->addStretch(); - m_btnLayout->setMargin(0); - m_btnLayout->setSpacing(16); - m_btnLayout->addWidget(m_cancelBtn); - m_btnLayout->addWidget(m_confirmBtn); - m_btnLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - m_wokrLayout->addLayout(m_btnLayout,0); - m_workWidget->setLayout(m_wokrLayout); - - m_vboxLayout->setMargin(0); - m_vboxLayout->setAlignment(Qt::AlignCenter); - m_vboxLayout->setSpacing(0); - m_vboxLayout->addWidget(m_stackedWidget); - setLayout(m_vboxLayout); - - m_passTips->setContentsMargins(16,0,0,0); - m_Tips->hide(); - m_Tips->setAttribute(Qt::WA_DontShowOnScreen); - m_passTips->hide(); - m_passTips->setAttribute(Qt::WA_DontShowOnScreen); - - //account->installEventFilter(this); - m_passConfirm->installEventFilter(this); - m_newPassLineEdit->installEventFilter(this); - m_mcodeLineEdit->installEventFilter(this); - - //控件逻辑信号连接 - connect(m_delBtn,SIGNAL(clicked()),this,SLOT(on_close())); - connect(m_mcodeBtn,SIGNAL(clicked()),this,SLOT(on_send_code())); - connect(m_confirmBtn,SIGNAL(clicked()),this,SLOT(on_edit_submit())); - connect(m_cMcodeTimer,SIGNAL(timeout()),this,SLOT(on_timer_start())); - connect(m_cancelBtn,SIGNAL(clicked()),this,SLOT(on_close())); - connect(this,SIGNAL(code_changed()),this,SLOT(setstyleline())); - connect(m_successDialog->m_backloginBtn,SIGNAL(clicked()),this,SLOT(on_close())); - connect(m_successDialog->m_backloginBtn,&QPushButton::clicked,[this] () { - emit account_changed(); - }); - connect(m_newPassLineEdit,&PasswordLineEdit::verify_text,[this] () { - m_passTips->setText(tr("Your password is valid!")); - }); - connect(m_newPassLineEdit,&PasswordLineEdit::false_text,[this] () { - m_passTips->setText(tr("At least 6 bit, include letters and digt")); - }); - - // setStyleSheet("EditPassDialog{border-radius:6px;}"); - setAttribute(Qt::WA_TranslucentBackground, true); - setWindowFlags(Qt::FramelessWindowHint); - setWindowModality(Qt::ApplicationModal); - m_delBtn->raise(); - m_cancelBtn->setFocusPolicy(Qt::NoFocus); - m_mcodeBtn->setFocusPolicy(Qt::NoFocus); - m_confirmBtn->setFocusPolicy(Qt::NoFocus); - m_confirmBtn->setShortcut(QKeySequence::InsertParagraphSeparator); - m_confirmBtn->setShortcut(Qt::Key_Enter); - m_confirmBtn->setShortcut(Qt::Key_Return); - //account->setFocus(); - - //设置第一个输入框为聚焦 - m_newPassLineEdit->setFocus(); - - //窗口显示在屏幕中央 - QDesktopWidget* desktop = QApplication::desktop(); - move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2); -} - -/* 设置DBUS客户端 */ -void EditPassDialog::set_client(DbusHandleClient *c,QThread *t) { - m_dbusClient = c; - m_workThread = t; - - connect(this,SIGNAL(docode(QString,QString)),m_dbusClient,SLOT(get_mcode_by_username(QString,QString))); - connect(m_dbusClient,SIGNAL(finished_ret_code_edit(int)),this,SLOT(setret_code(int))); - connect(this,SIGNAL(doreset(QString,QString,QString,QString)),m_dbusClient,SLOT(user_resetpwd(QString,QString,QString,QString))); - connect(m_dbusClient,SIGNAL(finished_ret_reset_edit(int)),this,SLOT(setret_edit(int))); - connect(this,SIGNAL(docheck()),m_dbusClient,SLOT(check_login())); - connect(m_dbusClient,SIGNAL(finished_ret_check_edit(QString)),this,SLOT(setret_check(QString))); - - //connect(client,SIGNAL(finished_mcode_by_username(int)),this,SLOT(on_edit_code_finished(int))); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_mcode_by_username",this,SLOT(on_edit_code_finished(int,QString))); - //connect(client,SIGNAL(finished_user_resetpwd(int)),this,SLOT(on_edit_submit_finished(int))); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_user_resetpwd",this,SLOT(on_edit_submit_finished(int,QString))); -} - -/* DBUS客户端回调函数处理,处理异常 */ -void EditPassDialog::setret_code(int ret) { - if(ret != 0) { - m_mcodeLineEdit->setText(""); - set_code(messagebox(ret)); - m_Tips->show(); - setshow(m_workWidget); - return ; - } else { - } -} - -void EditPassDialog::setret_check(QString ret) { - if (ret == "401" || ret == "201" || ret == "203" || ret == "") { - close(); - emit dologout(); - } -} - -void EditPassDialog::setret_edit(int ret) { - if(ret == 0) { - } else { - set_code(messagebox(ret)); - m_mcodeLineEdit->setText(""); - m_Tips->show(); - setshow(m_workWidget); - } -} - -/* 设置错误提示代码 */ -void EditPassDialog::set_code(QString codenum) { - m_codeStatus = codenum; - emit code_changed(); -} - -/* 设置提示错误消息 */ -void EditPassDialog::setstyleline() { - m_Tips->set_text(m_codeStatus); -} - -/* 验证码发送按钮处理 */ -void EditPassDialog::on_send_code() { - char phone[32]; - emit docheck(); - m_mcodeBtn->setEnabled(false); - if(m_newPassLineEdit->check() == false){ - m_mcodeBtn->setEnabled(true); - m_mcodeLineEdit->setText(""); - set_code(tr("At least 6 bit, include letters and digt")); - m_Tips->show(); - setshow(m_workWidget); - return ; - } - //qDebug()<text()!="") { - qstrcpy(phone,m_szCode.toStdString().c_str()); - emit docode(phone,m_szUuid); - }else { - m_mcodeBtn->setEnabled(true); - m_mcodeLineEdit->setText(""); - set_code(messagebox(-1)); - m_Tips->show(); - return ; - } -} - -/* 修改密码按钮处理 */ -void EditPassDialog::on_edit_submit() { - QString new_pass,mcode,confirm_password,acco; - //bool ok_cur = account->text().isNull(); - bool ok_new = m_newPassLineEdit->text().isNull(); - bool ok_code = m_mcodeLineEdit->text().isNull(); - bool ok_confirm = m_passConfirm->text().isNull(); - bool ok_acc = m_szCode.isNull(); - m_workWidget->setEnabled(false); //防止用户乱点 - if( !ok_new && !ok_code && !ok_confirm && !ok_acc) { - //qstrcpy(cur_acc,account->text().toStdString().c_str()); - //cur_acc = account->text(); - // qstrcpy(new_pass,newpass->text().toStdString().c_str()); - new_pass = m_newPassLineEdit->text(); - //qstrcpy(mcode,valid_code->text().toStdString().c_str()); - mcode = m_mcodeLineEdit->text(); - //qstrcpy(confirm_password,confirm_pass->text().toStdString().c_str()); - confirm_password = m_passConfirm->text(); - acco = m_szCode; - if(m_newPassLineEdit->check() == false) { - m_workWidget->setEnabled(true); - set_code(tr("At least 6 bit, include letters and digt")); - m_Tips->show(); - setshow(m_workWidget); - return ; - } - if(new_pass != confirm_password ) { - m_workWidget->setEnabled(true); - set_code(tr("Please check your password!")); - m_Tips->show(); - setshow(m_workWidget); - return ; - } - emit doreset(acco,new_pass,mcode,m_szUuid); - } -} - -/* 计时开始 */ -void EditPassDialog::on_timer_start() { - if(m_szTimerNum > 0) { - QString str = tr("Resend(") + QString::number(m_szTimerNum,10) + tr(")"); - m_mcodeBtn->setText(tr(str.toStdString().c_str())); - m_szTimerNum --; - }else if(m_szTimerNum == 0) { - m_szTimerNum = 60; - m_mcodeBtn->setEnabled(true); - m_mcodeBtn->setText(tr("Send")); - m_cMcodeTimer->stop(); - } -} - -/* 修改密码成功后进行回调处理 */ -void EditPassDialog::on_edit_submit_finished(int req,QString uuid) { - if(uuid != this->m_szUuid) { - return ; - } - if(m_bIsUsed == false) { - return ; - } - - m_workWidget->setEnabled(true); - if(req == 0) { - //qDebug()<<"wb888"; - m_delBtn->hide(); - m_stackedWidget->setCurrentWidget(m_successDialog); - m_successDialog->m_backloginBtn->setText(tr("Reback sign in")); - } else { - set_code(messagebox(req)); - m_Tips->show(); - setshow(m_stackedWidget); - } -} - -/* 消息盒子 */ -QString EditPassDialog::messagebox(int code) { - QString ret = tr("Error code:") + QString::number(code,10)+ tr("!"); - switch(code) { - case 101:ret = tr("Internal error occurring!");break; - case 102:ret = tr("Failed to sign up!");break; - case 103:ret = tr("Failed attempt to return value!");break; - case 104:ret = tr("Check your connection!");break; - case 105:ret = tr("Failed to get by phone!");break; - case 106:ret = tr("Failed to get by user!");break; - case 107:ret = tr("Failed to reset password!");break; - case 110:ret = tr("Please check your information!");break; - case 401:ret = tr("Please check your account!");break; - case 500:ret = tr("Failed due to server error!");break; - case 501:ret = tr("Please check your information!");break; - case 502:ret = tr("User existing!");break; - case 610:ret = tr("Phone number already in used!");break; - case 611:ret = tr("Please check your format!");break; - case 612:ret = tr("Your are reach the limit!");break; - case 613:ret = tr("Please check your phone number!");break; - case 614:ret = tr("Please check your code!");break; - case 615:ret = tr("Account doesn't exist!");break; - case 619:ret = tr("Sending code error occurring!");break; - case -1:ret = tr("Please check your information!");break; - - } - return ret; -} - -/* 动态显示布局处理 */ -void EditPassDialog::setshow(QWidget *widget) { - widget->hide(); - widget->setAttribute(Qt::WA_DontShowOnScreen); - widget->setAttribute(Qt::WA_DontShowOnScreen, false); - widget->show(); - widget->adjustSize(); -} - -/* 验证码获取回调 */ -void EditPassDialog::on_edit_code_finished(int req,QString uuid) { - if(this->m_szUuid != uuid) { - return ; - } - - if(m_bIsUsed == false) { - return ; - } - m_mcodeBtn->setEnabled(true); - if(req != 0) { - set_code(messagebox(req)); - m_Tips->show(); - setshow(m_stackedWidget); - } else if(req == 0) { - m_cMcodeTimer->start(); - m_cMcodeTimer->setInterval(1000); - m_mcodeBtn->setEnabled(false); - } -} - -/* 窗口重绘,阴影设置 */ -void EditPassDialog::paintEvent(QPaintEvent *event) -{ - - QPainter painter(this); - QColor m_defaultBackgroundColor = qRgb(0, 0, 0); - QPainterPath path1; - path1.setFillRule(Qt::WindingFill); - path1.addRoundedRect(10, 10, this->width() - 20, this->height() - 20, 6, 6); - - painter.setRenderHint(QPainter::Antialiasing, true); - painter.fillPath(path1, QBrush(QColor(m_defaultBackgroundColor.red(), - m_defaultBackgroundColor.green(), - m_defaultBackgroundColor.blue()))); - - QColor color(0, 0, 0, 15); - for (int i = 0; i < 6; i++) - { - QPainterPath path; - path.setFillRule(Qt::WindingFill); - path.addRoundedRect(10 - i, 10 - i, this->width() - (10 - i) * 2, this->height() - (10 - i) * 2, 6, 6); - color.setAlpha(120 - qSqrt(i) * 50); - painter.setPen(color); - painter.drawPath(path); - } - - painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(QBrush(palette().color(QPalette::Base))); - painter.setPen(Qt::transparent); - QRect rect = this->rect(); - rect.setX(10); - rect.setY(10); - rect.setWidth(rect.width() - 10); - rect.setHeight(rect.height() - 10); - // rect: 绘制区域 10 圆角弧度 6 - painter.drawRoundedRect(rect, 6, 6); -} - -/* 控件聚焦失去焦点事件处理 */ -bool EditPassDialog::eventFilter(QObject *w, QEvent *e) { -// if(w == account) { -// if (e->type() == QEvent::FocusIn && !tips->isHidden()) { -// tips->hide(); - -// setshow(content); - -// } -// } - if(w == m_delBtn) { - if(e->type() == QEvent::Enter) { - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete_click.svg"); - m_delBtn->setIcon(pixmap); - } - if(e->type() == QEvent::Leave) { - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete.svg"); - m_delBtn->setIcon(pixmap); - } - } - if(w == m_newPassLineEdit) { - if (e->type() == QEvent::FocusIn && !m_Tips->isHidden()) { - m_Tips->hide(); - - setshow(m_workWidget); - - } - if (e->type() == QEvent::FocusIn && m_passTips->isHidden()) { - m_passTips->show(); - - setshow(m_workWidget); - - } else if (e->type() == QEvent::FocusOut && !m_passTips->isHidden()) { - m_passTips->hide(); - - setshow(m_workWidget); - } - } - if(w == m_passConfirm) { - if (e->type() == QEvent::FocusIn && !m_Tips->isHidden()) { - m_Tips->hide(); - - setshow(m_workWidget); - - } - } - if(w == m_mcodeLineEdit) { - if (e->type() == QEvent::FocusIn && !m_Tips->isHidden()) { - m_Tips->hide(); - - setshow(m_workWidget); - - } - } - return QWidget::eventFilter(w,e); -} - -/* 清理窗口 */ -void EditPassDialog::set_clear() { - if(!m_Tips->isHidden()) { - m_Tips->hide(); - } - // account->setText(""); - m_newPassLineEdit->setText(""); - m_passConfirm->setText(""); - m_mcodeLineEdit->setText(""); - m_szTimerNum = 60; - m_mcodeBtn->setEnabled(true); - m_mcodeBtn->setText(tr("Send")); - m_cMcodeTimer->stop(); -} - -/* 关闭窗口处理函数 */ -void EditPassDialog::on_close() { - if(m_delBtn->isHidden()) { - m_delBtn->show(); - m_delBtn->raise(); - } - m_newPassLineEdit->get_visble()->setChecked(false); - //account->get_visble()->setChecked(false); - m_passConfirm->get_visble()->setChecked(false); - m_stackedWidget->setCurrentIndex(0); - set_clear(); - close(); -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/editpassdialog.h ukui-control-center-3.0.3/plugins/account/networkaccount/editpassdialog.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/editpassdialog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/editpassdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* -*- 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 EDITPASSDIALOG_H -#define EDITPASSDIALOG_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "successdiaolog.h" -#include -#include "passwordlineedit.h" -#include "dbushandleclient.h" -#include -#include "tips.h" -#include "svghandler.h" - -class EditPassDialog : public QWidget -{ - Q_OBJECT -public: - explicit EditPassDialog(QWidget *parent = nullptr); - int m_szTimerNum = 60; - void set_code(QString codenum); - void set_client(DbusHandleClient *c,QThread *t); - void set_clear(); - Tips* get_tips(); - QString messagebox(int codenum); - void setshow(QWidget *w); - QString m_szCode; - bool m_bIsUsed = false; -public slots: - void on_edit_submit(); - void on_edit_submit_finished(int req,QString m_szUuid); - void on_edit_code_finished(int req,QString m_szUuid); - void on_timer_start(); - void on_send_code(); - void setstyleline(); - void on_close(); - void setret_code(int ret); - void setret_check(QString ret); - void setret_edit(int ret); -protected: - void paintEvent(QPaintEvent *event); - bool eventFilter(QObject *w,QEvent *e); -private: - QLabel *m_title; - QPushButton *m_delBtn; - PasswordLineEdit *m_newPassLineEdit; - QLineEdit *m_mcodeLineEdit; - QPushButton *m_mcodeBtn; - QPushButton *m_cancelBtn; - QPushButton *m_confirmBtn; - QVBoxLayout *m_wokrLayout; - PasswordLineEdit *m_passConfirm; - QHBoxLayout *m_hboxLayout; - QHBoxLayout *m_btnLayout; - QPoint m_startPoint; - DbusHandleClient *m_dbusClient; - QTimer *m_cMcodeTimer; - Tips *m_Tips; - QString m_codeStatus; - QStackedWidget *m_stackedWidget; - QWidget *m_workWidget; - SuccessDiaolog *m_successDialog; - QVBoxLayout *m_vboxLayout; - QLabel *m_passTips; - QThread *m_workThread; - QString m_szUuid; - SVGHandler *m_svgHandler; -signals: - void code_changed(); - void account_changed(); - void docode(QString m_szCode,QString m_szUuid); - void doreset(QString a,QString b,QString c,QString m_szUuid); - void docheck(); - void dologout(); -}; - -#endif // EDITPASSDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/editpushbutton.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/editpushbutton.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/editpushbutton.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/editpushbutton.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* -*- 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 "editpushbutton.h" - -EditPushButton::EditPushButton(QWidget *parent) : QPushButton(parent) -{ - m_toolTips = new Tooltips(this); - m_resetLabel = new QLabel(m_toolTips); - m_workLayout = new QHBoxLayout; - - m_toolTips->setFixedSize(86,44); - m_toolTips->setStyleSheet("QWidget{border-radius:4px;}"); - - m_resetLabel->setText(tr("Reset")); - m_resetLabel->setStyleSheet("QLabel{font-size:14px;}"); - - m_workLayout->addWidget(m_resetLabel,0,Qt::AlignCenter); - m_workLayout->setMargin(0); - m_workLayout->setSpacing(0); - m_toolTips->setLayout(m_workLayout); - m_toolTips->hide(); - m_toolTips->setFocusPolicy(Qt::NoFocus); - setFocusPolicy(Qt::NoFocus); - m_resetLabel->setFocusPolicy(Qt::NoFocus); -} - -/* 鼠标进入,弹出提示框 */ -void EditPushButton::enterEvent(QEvent *e) { - - QPoint pos; - pos.setX(this->mapToGlobal(QPoint(0, 0)).x() + 26); - pos.setY(this->mapToGlobal(QPoint(0, 0)).y() + 26); - m_toolTips->move(pos); - m_toolTips->show(); - return QPushButton::enterEvent(e); -} - -/* 鼠标离开,提示框消失 */ -void EditPushButton::leaveEvent(QEvent *e) { - m_toolTips->hide(); - - return QPushButton::leaveEvent(e); -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/editpushbutton.h ukui-control-center-3.0.3/plugins/account/networkaccount/editpushbutton.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/editpushbutton.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/editpushbutton.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* -*- 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 QL_PUSHBUTTON_EDIT_H -#define QL_PUSHBUTTON_EDIT_H - -#include -#include -#include -#include "tooltips.h" -#include -#include -#include -#include -#include - -class EditPushButton : public QPushButton -{ - Q_OBJECT -public: - explicit EditPushButton(QWidget *parent = nullptr); - void enterEvent(QEvent *e); - void leaveEvent(QEvent *e); -protected: - Tooltips *m_toolTips; - QLabel *m_resetLabel; - QHBoxLayout *m_workLayout; - QTimer *m_cTimer; -public slots: -signals: - -}; - -#endif // QL_PUSHBUTTON_EDIT_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/frameitem.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/frameitem.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/frameitem.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/frameitem.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -27,15 +27,14 @@ this->setFrameShape(QFrame::Shape::Box); m_itemName = new QLabel(this); - m_itemName->setStyleSheet("font-size: 14px;"); m_switchBtn = new SwitchButton(this); m_workLayout = new QHBoxLayout; m_workLayout->addWidget(m_itemName); m_hboxLayout = new QHBoxLayout; m_run = new QLabel(this); - m_errorStatusLabel = new InfoLabel(this); + m_errorStatusLabel = new QLabel(this); m_cTimer = new QTimer(this); - m_svgHandler = new SVGHandler(this); + m_svgHandler = new SVGHandler(this,true); m_stackedWidget = new QStackedWidget(this); m_nullWidget = new QWidget(this); @@ -47,23 +46,29 @@ m_nullWidget->setStyleSheet("background:transparent;"); m_stackedWidget->setCurrentWidget(m_nullWidget); + m_errorStatusLabel->setPixmap(m_svgHandler->loadSvg(":/new/image/_.svg",16)); m_cTimer->stop(); + m_errorStatusLabel->setFixedHeight(50); + m_errorStatusLabel->setAlignment(Qt::AlignVCenter); m_workLayout->addStretch(); m_hboxLayout->setMargin(0); m_hboxLayout->setSpacing(16); m_hboxLayout->addWidget(m_stackedWidget,0,Qt::AlignRight); m_hboxLayout->addWidget(m_switchBtn,0,Qt::AlignRight); m_workLayout->addLayout(m_hboxLayout); - m_workLayout->setMargin(16); + m_workLayout->setAlignment(Qt::AlignVCenter); + m_workLayout->setContentsMargins(16,0,16,0); this->setAttribute(Qt::WA_StyledBackground,true); //widget->setStyleSheet("background-color: rgba(244,244,244,85%);border-radius:4px;"); this->setLayout(m_workLayout); - + m_stackedWidget->setFixedHeight(50); m_stackedWidget->adjustSize(); - + connect(m_switchBtn, &SwitchButton::checkedChanged,this, [=] (bool checked) { + emit itemChanged(m_itemName->text(),checked); + }); connect(m_cTimer,&QTimer::timeout, [this] () { QPixmap pixmap = m_svgHandler->loadSvgColor(QString(":/new/image/loading1%1.svg").arg(m_cCnt),"black",16); m_run->setPixmap(pixmap); @@ -82,7 +87,7 @@ } /* 获取项目名字 */ -QString FrameItem::get_itemname() { +QString FrameItem::get_itemname() const { return m_itemName->text(); } @@ -92,12 +97,12 @@ } /* 设置项目名字 */ -void FrameItem::set_itemname(QString name) { +void FrameItem::set_itemname(const QString &name) { m_itemName->setText(name); } -void FrameItem::set_change(int status,QString code) { - if(status == 1) { +void FrameItem::set_change(const int &status,const QString &code) { + if (status == 1) { m_stackedWidget->setCurrentWidget(m_run); bIsStart = true; m_cTimer->start(140); @@ -108,23 +113,23 @@ } else { m_cTimer->stop(); bIsStart = false; - if(code == "Failed!") { - m_errorStatusLabel->setTipText(tr("Sync failed, please login out to retry!")); + if (code == "Failed!") { + m_errorStatusLabel->setToolTip(tr("Sync failed,please relogin!")); } - if(code == "Change conf file failed!") { - m_errorStatusLabel->setTipText(tr("Change configuration file failed, please login out to retry!")); + if (code == "Change conf file failed!") { + m_errorStatusLabel->setToolTip(tr("Change configuration file failed,please relogin!")); } - if(code == "Config file not exist!") { - m_errorStatusLabel->setTipText(tr("Configuration file not exist, please login out to retry!")); + if (code == "Config file not exist!") { + m_errorStatusLabel->setToolTip(tr("Configuration file not exist,please relogin!")); } - if(code == "Cloud verifyed file download failed!") { - m_errorStatusLabel->setTipText(tr("Cloud verifyed file download failed, please login out to retry!")); + if (code == "Cloud verifyed file download failed!") { + m_errorStatusLabel->setToolTip(tr("Cloud verifyed file download failed,please relogin!")); } - if(code == "OSS access failed!") { - m_errorStatusLabel->setTipText(tr("OSS access failed, please login out to retry!")); + if (code == "OSS access failed!") { + m_errorStatusLabel->setToolTip(tr("OSS access failed,please relogin!")); } - else if(code != "Upload" && code != "Download") { - m_errorStatusLabel->setTipText(tr("Sync failed, please retry or login out to get a better experience!")); + else if (code != "Upload" && code != "Download") { + m_errorStatusLabel->setToolTip(tr("Sync failed,please relogin!")); } m_stackedWidget->setCurrentWidget(m_errorStatusLabel); } @@ -133,10 +138,11 @@ /* 让SwitchButton播放打开动画 */ void FrameItem::make_itemon() { - if(m_switchBtn != nullptr) { - if(m_switchBtn->get_swichbutton_val() != 1) { - m_switchBtn->set_swichbutton_val(1); - //switch_btn->update(); + if (m_switchBtn != nullptr) { + if (m_switchBtn->isChecked() != true) { + m_switchBtn->blockSignals(true); + m_switchBtn->setChecked(true); + m_switchBtn->blockSignals(false); } } else { qDebug() <<"switch button is null ptr"; @@ -144,16 +150,17 @@ } FrameItem::~FrameItem() { - if(m_cTimer->isActive()) + if (m_cTimer->isActive()) m_cTimer->stop(); } /* 让SwitchButton播放关闭动画 */ void FrameItem::make_itemoff() { - if(m_switchBtn != nullptr) { - if(m_switchBtn->get_swichbutton_val() != 0) { - m_switchBtn->set_swichbutton_val(0); - //switch_btn->update(); + if (m_switchBtn != nullptr) { + if (m_switchBtn->isChecked() != false) { + m_switchBtn->blockSignals(true); + m_switchBtn->setChecked(false); + m_switchBtn->blockSignals(false); } } else { qDebug() <<"switch button is null ptr"; @@ -161,6 +168,6 @@ } /* 让列表的SwitchButton可用或者不可用,调用一次就是取反 */ -void FrameItem::set_active(bool ok) { - m_switchBtn->set_active(ok); +void FrameItem::set_active(const bool &ok) { + m_switchBtn->setDisabledFlag(!ok); } diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/frameitem.h ukui-control-center-3.0.3/plugins/account/networkaccount/frameitem.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/frameitem.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/frameitem.h 2021-04-14 01:27:20.000000000 +0000 @@ -25,11 +25,10 @@ #include #include #include -#include "switchbutton.h" +#include #include #include #include -#include "infolabel.h" #include "svghandler.h" class FrameItem : public QFrame @@ -37,15 +36,15 @@ Q_OBJECT public: explicit FrameItem(QWidget *parent = nullptr); - void set_itemname(QString name); - QString get_itemname(); + void set_itemname(const QString &name); + QString get_itemname() const; void make_itemoff(); void make_itemon(); - void set_change(int status,QString code); + void set_change(const int &status,const QString &code); QHBoxLayout* get_layout(); SwitchButton* get_swbtn(); QWidget* get_widget(); - void set_active(bool ok); + void set_active(const bool &ok); ~FrameItem(); private: QLabel *m_itemName; @@ -55,13 +54,14 @@ SwitchButton *m_switchBtn; QLabel *m_run; QWidget *m_nullWidget; - InfoLabel *m_errorStatusLabel; + QLabel *m_errorStatusLabel; QStackedWidget *m_stackedWidget; QTimer *m_cTimer; bool bIsStart = false; int m_cCnt = 1; SVGHandler *m_svgHandler; signals: + void itemChanged(const QString &name, bool checked); }; #endif // NETWORK_ITEM_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/infolabel.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/infolabel.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/infolabel.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/infolabel.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +0,0 @@ -#include "infolabel.h" -#include -#include - -InfoLabel::InfoLabel(QWidget *parent) : QLabel(parent) -{ - m_svgHandler = new SVGHandler(this); - m_toolTips = new Tooltips(this); - m_textLabel = new QLabel(m_toolTips); - - QHBoxLayout *worklayout = new QHBoxLayout; - QHBoxLayout *layout = new QHBoxLayout; - - - layout->addWidget(m_textLabel); - - - m_toolTips->setLayout(layout); - - worklayout->addWidget(m_toolTips); - - setPixmap(m_svgHandler->loadSvgColor(":/new/image/_.svg","default",16)); - m_toolTips->adjustSize(); - - setLayout(worklayout); -} - -void InfoLabel::enterEvent(QEvent *e) { - QPoint pos; - pos.setX(this->mapToGlobal(QPoint(0, 0)).x() + 26); - pos.setY(this->mapToGlobal(QPoint(0, 0)).y() + 26); - m_toolTips->move(pos); - m_toolTips->show(); - return QLabel::enterEvent(e); -} - -void InfoLabel::setTipText(QString text) { - m_textLabel->setText(text); - m_textLabel->adjustSize(); - m_toolTips->adjustSize(); - adjustSize(); -} - - -void InfoLabel::leaveEvent(QEvent *e) { - m_toolTips->hide(); - - return QLabel::leaveEvent(e); -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/infolabel.h ukui-control-center-3.0.3/plugins/account/networkaccount/infolabel.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/infolabel.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/infolabel.h 2021-04-14 01:27:20.000000000 +0000 @@ -5,21 +5,17 @@ #include #include #include "svghandler.h" -#include "tooltips.h" class InfoLabel : public QLabel { Q_OBJECT public: explicit InfoLabel(QWidget *parent = nullptr); - void setTipText(QString text); void leaveEvent(QEvent *e); - void enterEvent(QEvent *e); + void enterEvent(QEvent *e); private: SVGHandler *m_svgHandler; - Tooltips *m_toolTips; - QLabel *m_textLabel; signals: }; diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/itemlist.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/itemlist.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/itemlist.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/itemlist.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -26,7 +26,6 @@ for(int cur_ptr = 0; cur_ptr < m_cItemCnt; cur_ptr ++) { m_itemWidget[cur_ptr] = new FrameItem(this); m_itemWidget[cur_ptr]->set_itemname(m_szItemNameList[cur_ptr]); - m_itemWidget[cur_ptr]->get_swbtn()->set_id(cur_ptr); m_vboxLayout->addWidget(m_itemWidget[cur_ptr]); } //customize the script on/off area @@ -41,21 +40,22 @@ /* 获取列表物品,如麒麟天气、壁纸等选单列表 * Get a item of list, for example: Getting Kylin-Weather, Wallpaper etc.. */ -FrameItem* ItemList::get_item(int cur) { +FrameItem* ItemList::get_item(const int &cur) { return m_itemWidget[cur]; } -FrameItem* ItemList::get_item_by_name(QString name) { +FrameItem* ItemList::get_item_by_name(const QString &name) { m_cItemCnt = m_szItemNameList.size(); for(int cur_ptr = 0; cur_ptr < m_cItemCnt; cur_ptr ++) { - if(m_itemWidget[cur_ptr]->get_itemname() == name) { + if (m_itemWidget[cur_ptr]->get_itemname() == name) { return m_itemWidget[cur_ptr]; } } + return 0; } /* 读取列表 * Read the list */ -QStringList ItemList::get_list() { +QStringList ItemList::get_list() const { return m_szItemNameList; } diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/itemlist.h ukui-control-center-3.0.3/plugins/account/networkaccount/itemlist.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/itemlist.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/itemlist.h 2021-04-14 01:27:20.000000000 +0000 @@ -33,11 +33,14 @@ Q_OBJECT public: explicit ItemList(QWidget *parent = nullptr,int itemssize = CURSIZE); - QStringList get_list(); - FrameItem* get_item(int cur); - FrameItem* get_item_by_name(QString name); + QStringList get_list() const; + FrameItem* get_item(const int &cur); + FrameItem* get_item_by_name(const QString &name); private: - QStringList m_szItemNameList = {tr("Walpaper"),tr("ScreenSaver"),tr("Menu"),tr("Quick Start"),tr("Tab"),tr("Weather"),tr("Media")}; + QStringList m_szItemNameList = {tr("Wallpaper"),tr("ScreenSaver"),tr("Font"),tr("Avatar"),tr("Menu"),tr("Tab"),tr("Quick Start"), + tr("Themes"),tr("Mouse"),tr("TouchPad"),tr("KeyBoard"),tr("ShortCut"), + tr("Area"),tr("Date/Time"),tr("Default Open"),tr("Notice"),tr("Option"),tr("Peony"), + tr("Boot"),tr("Power"),tr("Editor"),tr("Terminal"),tr("Weather"),tr("Media")}; int m_cItemCnt = 0; FrameItem *m_itemWidget[30]; QPoint m_startPoint; diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/logindialog.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/logindialog.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/logindialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/logindialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -55,8 +55,8 @@ m_phoneTips->setFixedHeight(32); m_passTips->setFixedHeight(32); - m_phoneTips->setContentsMargins(9,0,0,0); - m_passTips->setContentsMargins(9,0,0,0); + m_phoneTips->setContentsMargins(0,0,0,0); + m_passTips->setContentsMargins(0,0,0,0); //Basic Widget Configuration @@ -74,38 +74,37 @@ m_phoneWidget->adjustSize(); m_phoneWidget->setContentsMargins(0,0,0,0); - m_accountLogin_btn->setMaximumSize(90,36); + m_accountLogin_btn->setMaximumSize(126,36); m_accountLogin_btn->setMinimumSize(90,36); //account_login_btn->setGeometry(31 + sizeoff,96 + sizeoff,90,36); - m_phoneLogin_btn->setMaximumSize(90,36); + m_phoneLogin_btn->setMaximumSize(126,36); m_phoneLogin_btn->setMinimumSize(90,36); //message_login_btn->setGeometry(161 + sizeoff,96 + sizeoff,90,36); - m_accountLogin_btn->setStyleSheet("QPushButton{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);} " - "QPushButton:hover{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}" - "QPushButton:click{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}"); - m_phoneLogin_btn->setStyleSheet("QPushButton{font-size:14px;background: transparent;border-radius: 4px;} " - "QPushButton:hover{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}" - "QPushButton:click{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}"); + m_accountLogin_btn->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);} " + "QPushButton:hover{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}" + "QPushButton:click{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}"); + m_phoneLogin_btn->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;} " + "QPushButton:hover{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}" + "QPushButton:click{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}"); m_accountLogin_btn->setFocusPolicy(Qt::NoFocus); m_phoneLogin_btn->setFocusPolicy(Qt::NoFocus); m_accountLineEdit->setMaxLength(30); - m_accountLineEdit->setMaximumSize(338,36); - m_accountLineEdit->setMinimumSize(338,36); + m_accountLineEdit->setFixedWidth(338); m_accountLineEdit->setTextMargins(12,0,0,0); m_accountLineEdit->setFocusPolicy(Qt::StrongFocus); - m_accountLineEdit->setPlaceholderText(tr("Your account here")); + m_accountLineEdit->setPlaceholderText(tr("Your account/phone here")); - //account_phone->setStyleSheet("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3D6BE5;font-size: 14px;color: rgba(0,0,0,0.85);}" - // "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}" - // "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}"); + //account_phone->setStyleSheet("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3790FA;font-size: 14px;color: rgba(0,0,0,0.85);}" + // "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3790FA;font-size: 14px;color:rgba(0,0,0,0.85)}" + // "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3790FA;font-size: 14px;color:rgba(0,0,0,0.85)}"); m_mcodeNormalLineEdit->setMaxLength(4); m_mcodeNormalLineEdit->setTextMargins(12,0,0,0); m_mcodeNormalLineEdit->setPlaceholderText(tr("Your code here")); - //mcode_lineedit->setStyleSheet("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3D6BE5;font-size: 14px;color: rgba(0,0,0,0.85);}" - // "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}" - // "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}"); + //mcode_lineedit->setStyleSheet("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3790FA;font-size: 14px;color: rgba(0,0,0,0.85);}" + // "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3790FA;font-size: 14px;color:rgba(0,0,0,0.85)}" + // "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3790FA;font-size: 14px;color:rgba(0,0,0,0.85)}"); m_accountLineEdit->setContentsMargins(0,0,0,0); QHBoxLayout *HBox_way = new QHBoxLayout; HBox_way->setMargin(0); @@ -139,7 +138,7 @@ //Subabstract Build login_account_thr_number(); login_account_thr_phone(); - QRegExp regx("^[a-zA-Z0-9_@.-]+$"); + QRegExp regx("^[^\\s]+$"); QValidator *validator = new QRegExpValidator(regx, m_accountLineEdit ); m_accountLineEdit->setValidator(validator); //Initial configuration @@ -151,26 +150,26 @@ /* 用户密码登录方式的界面设置 * * Setting the page of login that use password way. */ void LoginDialog::startaction_1() { - if(m_stackedWidget->currentIndex() == 0) { + if (m_stackedWidget->currentIndex() == 0) { set_clear(); m_accountLineEdit->setFocus(); - m_accountLineEdit->setText(""); + //m_accountLineEdit->setText(""); m_accountLineEdit->setMaxLength(11); - QRegExp regx("^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"); + QRegExp regx("^1[3-9]\\d{9}$"); QValidator *validator = new QRegExpValidator(regx, m_accountLineEdit ); m_accountLineEdit->setValidator(validator); - m_accountLogin_btn->setMaximumSize(90,36); + m_accountLogin_btn->setMaximumSize(126,36); m_accountLogin_btn->setMinimumSize(90,36); //account_login_btn->setGeometry(31 + sizeoff,96 + sizeoff,90,36); - m_phoneLogin_btn->setMaximumSize(90,36); + m_phoneLogin_btn->setMaximumSize(126,36); m_phoneLogin_btn->setMinimumSize(90,36); //message_login_btn->setGeometry(161 + sizeoff,96 + sizeoff,90,36); - m_accountLogin_btn->setStyleSheet("QPushButton{font-size:14px;background: transparent;border-radius: 4px;} " - "QPushButton:hover{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}" - "QPushButton:click{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}"); - m_phoneLogin_btn->setStyleSheet("QPushButton{font-size:14px;background: transparent;border-radius: 4px;color:#3D6BE5;} " - "QPushButton:hover{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}" - "QPushButton:click{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}"); + m_accountLogin_btn->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;} " + "QPushButton:hover{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}" + "QPushButton:click{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}"); + m_phoneLogin_btn->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;color:#3790FA;} " + "QPushButton:hover{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}" + "QPushButton:click{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}"); m_accountLogin_btn->setFocusPolicy(Qt::NoFocus); m_phoneLogin_btn->setFocusPolicy(Qt::NoFocus); @@ -188,38 +187,38 @@ startaction_2(); } -QString LoginDialog::get_user_name() { +QString LoginDialog::get_user_name() const { return this->m_accountLineEdit->text(); } -QString LoginDialog::get_user_pass() { +QString LoginDialog::get_user_pass() const { return this->m_passwordLineEdit->text(); } void LoginDialog::startaction_2() { - if(m_stackedWidget->currentIndex() == 1) { + if (m_stackedWidget->currentIndex() == 1) { set_clear(); m_accountLineEdit->setFocus(); - QRegExp regx("^[a-zA-Z0-9_@.-]+$"); + QRegExp regx("^[^\\s]+$"); m_accountLineEdit->setMaxLength(30); QValidator *validator = new QRegExpValidator(regx, m_accountLineEdit ); m_accountLineEdit->setValidator(validator); - m_accountLogin_btn->setMaximumSize(90,36); + m_accountLogin_btn->setMaximumSize(126,36); m_accountLogin_btn->setMinimumSize(90,36); //account_login_btn->setGeometry(31 + sizeoff,96 + sizeoff,90,36); - m_phoneLogin_btn->setMaximumSize(90,36); + m_phoneLogin_btn->setMaximumSize(126,36); m_phoneLogin_btn->setMinimumSize(90,36); //message_login_btn->setGeometry(161 + sizeoff,96 + sizeoff,90,36); - m_accountLogin_btn->setStyleSheet("QPushButton{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);} " - "QPushButton:hover{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}" - "QPushButton:click{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}"); - m_phoneLogin_btn->setStyleSheet("QPushButton{font-size:14px;background: transparent;border-radius: 4px;} " - "QPushButton:hover{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}" - "QPushButton:click{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}"); + m_accountLogin_btn->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);} " + "QPushButton:hover{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}" + "QPushButton:click{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}"); + m_phoneLogin_btn->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;} " + "QPushButton:hover{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}" + "QPushButton:click{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}"); m_accountLogin_btn->setFocusPolicy(Qt::NoFocus); m_phoneLogin_btn->setFocusPolicy(Qt::NoFocus); m_stackedWidget->setCurrentIndex(0); - m_accountLineEdit->setPlaceholderText(tr("Your account here")); + m_accountLineEdit->setPlaceholderText(tr("Your account/phone/email here")); } } @@ -229,29 +228,30 @@ //Congfigurate the widgets m_accountLineEdit->setFocus(); - QRegExp regx("^[a-zA-Z0-9_@.-]+$"); + QRegExp regx("^[^\\s]+$"); QValidator *validator = new QRegExpValidator(regx, m_accountLineEdit ); m_accountLineEdit->setValidator(validator); m_passwordLineEdit->setPlaceholderText(tr("Your password here")); - m_passwordLineEdit->setMaximumSize(338,36); - m_passwordLineEdit->setMinimumSize(338,36); - m_passwordLineEdit->setTextMargins(12,0,0,0); + m_passwordLineEdit->setFixedWidth(338); + //m_passwordLineEdit->setTextMargins(12,0,0,0); m_passwordLineEdit->setMaxLength(30); - //account_pass->setStyleSheet("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3D6BE5;font-size: 14px;color: rgba(0,0,0,0.85);lineedit-password-character: 42;}" - // "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}" - // "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}"); + //account_pass->setStyleSheet("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3790FA;font-size: 14px;color: rgba(0,0,0,0.85);lineedit-password-character: 42;}" + // "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3790FA;font-size: 14px;color:rgba(0,0,0,0.85)}" + // "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3790FA;font-size: 14px;color:rgba(0,0,0,0.85)}"); //account_phone->setGeometry(31 + sizeoff,148 + sizeoff,338,36); //account_pass->setGeometry(31 + sizeoff,192 + sizeoff,338,36); m_forgetPasswordBtn->setMaximumSize(80,30); m_forgetPasswordBtn->setMinimumSize(80,30); //forgot_pass_btn->setGeometry(289 + sizeoff,228 + sizeoff,80,30); - m_forgetPasswordBtn->setStyleSheet("QPushButton {font-size:14px;background: transparent;border-radius: 4px;}" - "QPushButton:hover{font-size:14px;color:rgba(61,107,229,0.85);position:relative;border-radius: 4px;}" - "QPushButton:click{font-size:14px;color:rgba(61,107,229,0.85);position:relative;border-radius: 4px;}"); + m_forgetPasswordBtn->setStyleSheet("QPushButton {background: transparent;border-radius: 4px;}" + "QPushButton:hover{color:rgba(55,144,250,0.85);position:relative;border-radius: 4px;}" + "QPushButton:click{color:rgba(55,144,250,0.85);position:relative;border-radius: 4px;}"); m_forgetPasswordBtn->setFocusPolicy(Qt::NoFocus); - m_mcodeNormalLineEdit->setFixedSize(202,36); + //m_mcodeNormalLineEdit->setFixedSize(202,36); + m_mcodeNormalLineEdit->setFixedWidth(202); + m_mcodeNormalLineEdit->setMinimumHeight(36); //login_submit->setGeometry(31 + sizeoff,350 + sizeoff,338,36); //register_account->setGeometry(134 + sizeoff,406 + sizeoff,120,36); @@ -317,13 +317,13 @@ return m_sendMsgBtn; } -void LoginDialog::set_code(QString codenum) { +void LoginDialog::set_code(const QString &codenum) { m_szCode = codenum; emit code_changed(); } void LoginDialog::setstyleline() { - if(m_stackedWidget->currentIndex() == 0) { + if (m_stackedWidget->currentIndex() == 0) { m_passTips->set_text(m_szCode); } else { m_phoneTips->set_text(m_szCode); @@ -348,28 +348,25 @@ //Congfigurate the widgets m_accountLineEdit->setFocus(); - QRegExp regx("^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"); + QRegExp regx("^1[3-9]\\d{9}$"); QValidator *validator = new QRegExpValidator(regx, m_accountLineEdit ); m_accountLineEdit->setValidator(validator); - m_mcodePhoneLineEdit->setMaximumSize(192,36); + m_mcodePhoneLineEdit->setFixedWidth(192); m_mcodePhoneLineEdit->setMaxLength(4); m_mcodePhoneLineEdit->setPlaceholderText(tr("Your code here")); QRegExp regx_code("[0-9]+$"); QValidator *validator_code = new QRegExpValidator(regx_code, m_mcodePhoneLineEdit ); m_mcodePhoneLineEdit->setValidator( validator_code ); - m_sendMsgBtn->setMaximumSize(130,36); - m_mcodePhoneLineEdit->setMinimumSize(192,36); - m_sendMsgBtn->setMinimumSize(130,36); - m_sendMsgBtn->setMaximumSize(130,36); + m_sendMsgBtn->setFixedWidth(130); m_mcodePhoneLineEdit->setTextMargins(12,0,0,0); //valid_code->setGeometry(31 + sizeoff,192 + sizeoff,192,36); //send_msg_submit->setGeometry(239 + sizeoff,192 + sizeoff,130,36); //valid_code->setStyleSheet("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #F4F4F4;font-size: 14px;color: rgba(0,0,0,0.85);}" - // "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}" - // "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}"); - //send_msg_submit->setStyleSheet("QPushButton{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(0,0,0,0.85);} " - // "QPushButton:hover{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(61,107,229,0.85);}" - // "QPushButton:click{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(61,107,229,0.85);}"); + // "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3790FA;font-size: 14px;color:rgba(0,0,0,0.85)}" + // "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3790FA;font-size: 14px;color:rgba(0,0,0,0.85)}"); + //send_msg_submit->setStyleSheet("QPushButton{background-color:#F4F4F4;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(0,0,0,0.85);} " + // "QPushButton:hover{background-color:#F4F4F4;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(55,144,250,0.85);}" + // "QPushButton:click{background-color:#F4F4F4;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(55,144,250,0.85);}"); m_sendMsgBtn->setFocusPolicy(Qt::NoFocus); QWidget::setTabOrder(m_accountLineEdit, m_mcodePhoneLineEdit); @@ -396,7 +393,7 @@ return false; } -void LoginDialog::set_staus(bool ok) { +void LoginDialog::set_staus(const bool &ok) { m_accountLogin_btn->setEnabled(ok); m_phoneLogin_btn->setEnabled(ok); m_passwordLineEdit->setEnabled(ok); @@ -408,17 +405,25 @@ } +QLineEdit *& LoginDialog::phoneLineEdit() { + return m_phoneLineEdit; +} + +QLineEdit *& LoginDialog::mCodeLineEdit() { + return m_mcodePhoneLineEdit; +} + /* 清空登录框 */ void LoginDialog::set_clear() { - if(!m_phoneTips->isHidden()) { + if (!m_phoneTips->isHidden()) { m_phoneTips->hide(); } - if(!m_passTips->isHidden()) { + if (!m_passTips->isHidden()) { m_passTips->hide(); } m_passwordLineEdit->get_visble()->setChecked(false); m_passwordLineEdit->setText(""); - m_accountLineEdit->setText(""); m_mcodePhoneLineEdit->setText(""); m_mcodeNormalLineEdit->setText(""); } + diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/logindialog.h ukui-control-center-3.0.3/plugins/account/networkaccount/logindialog.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/logindialog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/logindialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -32,7 +32,6 @@ #include #include #include -#include "areacodelineedit.h" #include "mcodewidget.h" #include "passwordlineedit.h" #include "tips.h" @@ -56,15 +55,17 @@ Tips* get_tips_pass(); Tips* get_tips_code(); QLineEdit* get_login_code(); - QString get_user_name(); - QString get_user_pass(); + QString get_user_name() const; + QString get_user_pass() const; QPushButton* get_user_mcode(); + QLineEdit *& phoneLineEdit(); + QLineEdit *& mCodeLineEdit(); QStackedWidget* get_stack_widget(); - void set_code(QString codenum); + void set_code(const QString &codenum); MCodeWidget* get_mcode_widget(); QLineEdit* get_mcode_lineedit(); void set_clear(); - void set_staus(bool ok); + void set_staus(const bool &ok); public slots: void set_window1(); void set_window2(); diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/maindialog.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/maindialog.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/maindialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/maindialog.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -18,19 +18,23 @@ * */ #include "maindialog.h" -#include +#include #include +#include -MainDialog::MainDialog(QWidget *parent) : QWidget(parent) + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +MainDialog::MainDialog(QWidget *parent) : QDialog(parent) { //内存分配 m_uuid = QUuid::createUuid().toString(); m_submitBtn = new QPushButton(tr("Sign in"),this); //登录或者确认或者注册或者重置密码或者绑定手机按钮(重用) m_regBtn = new QPushButton(tr("Sign up"),this); //返回登录或者注册账户按钮(重用) m_loginDialog = new LoginDialog(this); //登录页面 - m_regDialog = new RegDialog(this); //注册页面 - m_BindDialog = new BindPhoneDialog(this); //手机绑定页面 - m_passDialog = new PassDialog(this); //忘记密码页面 + //m_regDialog = new RegDialog(this); //注册页面 + //m_BindDialog = new BindPhoneDialog(this); //手机绑定页面 + //m_passDialog = new PassDialog(this); //忘记密码页面 m_containerWidget = new QWidget(this); //业务逻辑主界面 m_baseWidget = new QStackedWidget(this); //用于切换成功页面和业务逻辑操作页面(包括登录等模块) @@ -38,12 +42,8 @@ m_stackedWidget = new QStackedWidget(this); //用于切换业务逻辑操作页面(包括登录,注册,绑定,忘记密码) m_workLayout = new QVBoxLayout; //业务界面主体布局 m_subLayout = new QHBoxLayout; //切换登录模式按钮布局 - m_delBtn = new QPushButton(this); //关闭按钮 - m_cPassTimer = new QTimer(this); //以下都是验证码倒计时计时器,后缀相互对应 - m_cRegTimer = new QTimer(this); - m_cLogTimer = new QTimer(this); - m_cBindTimer = new QTimer(this); - m_successDialog = new SuccessDiaolog(this); //注册成功页面 + m_delBtn = new CloseButton(this); //关闭按钮 + m_timer = new QTimer(this); QHBoxLayout *hbox = new QHBoxLayout; //整体布局 m_blueEffect = new Blueeffect(m_submitBtn); m_animateLayout = new QHBoxLayout; @@ -57,20 +57,15 @@ //计时器初始化 - m_cPassTimer->stop(); - m_cRegTimer->stop(); - m_cLogTimer->stop(); - m_cBindTimer->stop(); - + m_timer->stop(); //隐藏同步开关动画 //控件尺寸以及布局设置 this->setFixedSize(418,505); m_containerWidget->setFixedSize(418,505); m_stackedWidget->addWidget(m_loginDialog); - m_stackedWidget->addWidget(m_regDialog); - m_stackedWidget->addWidget(m_passDialog); - m_stackedWidget->addWidget(m_BindDialog); + // m_stackedWidget->addWidget(m_passDialog); + //m_stackedWidget->addWidget(m_BindDialog); m_submitBtn->setFocusPolicy(Qt::NoFocus); m_titleLable->setFocusPolicy(Qt::NoFocus); @@ -78,7 +73,7 @@ m_titleLable->setText(status); m_titleLable->adjustSize(); - //setFocusPolicy(Qt::NoFocus); + setFocusPolicy(Qt::NoFocus); m_loginDialog->setContentsMargins(0,0,0,0); //title->setGeometry(31 + sizeoff,48 + sizeoff,160,24); m_titleLable->setStyleSheet("font-size: 24px;font-weight:500;"); @@ -92,8 +87,6 @@ m_baseWidget->setFixedSize(418,505); m_baseWidget->setContentsMargins(0,0,0,0); m_baseWidget->addWidget(m_containerWidget); - m_baseWidget->addWidget(m_successDialog); - m_successDialog->set_mode_text(2); m_baseWidget->setCurrentWidget(m_containerWidget); m_submitBtn->setContentsMargins(0,0,0,0); m_regBtn->setFocusPolicy(Qt::NoFocus); @@ -101,31 +94,28 @@ m_delBtn->setMaximumSize(30,30); m_delBtn->setMinimumSize(30,30); m_delBtn->setGeometry(this->width() - 46,14,30,30); - m_delBtn->setFocusPolicy(Qt::NoFocus); +// m_delBtn->setFocusPolicy(Qt::NoFocus); - m_submitBtn->setStyleSheet("QPushButton {font-size:14px;background-color: #3D6BE5;border-radius: 4px;color:rgba(255,255,255,0.85);}" - "QPushButton:hover {font-size:14px;background-color: #415FC4;border-radius: 4px;position:relative;color:rgba(255,255,255,0.85);}" - "QPushButton:click {font-size:14px;background-color: #415FC4;border-radius: 4px;postion:realative;color:rgba(255,255,255,0.85);}"); - m_regBtn->setStyleSheet("QPushButton{font-size:14px;background: transparent;border-radius: 4px;} " - "QPushButton:hover{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}" - "QPushButton:click{font-size:14px;background: transparent;border-radius: 4px;color:rgba(61,107,229,0.85);}"); - - m_delBtn->setFlat(true); - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete.svg"); - m_delBtn->setIcon(pixmap); - m_delBtn->setStyleSheet("QPushButton{background:transparent;border-radius:4px;}" - "QPushButton:hover{background:transparent;background-color:#F86457;" - "border-radius:4px}" - "QPushButton:click{background:transparent;background-color:#E44C50;border-radius:4px}"); + m_submitBtn->setStyleSheet("QPushButton {background-color: #3790FA;border-radius: 4px;color:rgba(255,255,255,0.85);}" + "QPushButton:hover {background-color: #40A9FB;border-radius: 4px;position:relative;color:rgba(255,255,255,0.85);}" + "QPushButton:click {background-color: #40A9FB;border-radius: 4px;postion:realative;color:rgba(255,255,255,0.85);}"); + m_regBtn->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;} " + "QPushButton:hover{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}" + "QPushButton:click{background: transparent;border-radius: 4px;color:rgba(55,144,250,0.85);}"); + +// m_delBtn->setFlat(true); +// QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete.svg"); + m_delBtn->setIcon(QIcon(":/new/image/delete.svg")); - m_delBtn->installEventFilter(this); +// m_delBtn->installEventFilter(this); m_stackedWidget->setCurrentWidget(m_loginDialog); //主窗口布局样式设置 //setStyleSheet("Dialog_login_reg{border-radius:6px;}"); setAttribute(Qt::WA_TranslucentBackground, true); - setWindowFlags(Qt::FramelessWindowHint); + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog | Qt::Tool); + setModal(true); m_workLayout->setSpacing(0); m_workLayout->setContentsMargins(41,55,41,36); @@ -164,8 +154,7 @@ /* 子控件成员公共函数获取,主要是为了用eventFilter函数去更改控件Focus事件 * 处理,防止一些没有必要的重写类生成,并方便及时更改控件子控件的状态属性, * 避免过度使用信号与槽*/ - m_forgetpassBtn = m_passDialog->get_send_msg_btn(); - m_regSendCodeBtn = m_regDialog->get_send_code(); + // m_forgetpassBtn = m_passDialog->get_send_msg_btn(); m_forgetpassSendBtn = m_loginDialog->get_user_mcode(); m_loginDialog->get_user_edit()->setFocus(); @@ -177,57 +166,58 @@ m_loginAccountLineEdit = m_loginDialog->get_user_edit(); //登录界面用户框 m_loginMCodeLineEdit = m_loginDialog->get_mcode_lineedit();//登录界面验证码框 - m_regAccountLineEdit = m_regDialog->get_reg_user(); //注册界面用户框 - m_phoneLineEdit = m_regDialog->get_phone_user(); //注册界面手机框 - m_mcodeLineEdit = m_regDialog->get_valid_code(); //注册界面验证码框 - m_regPassLineEdit = m_regDialog->get_reg_pass(); //注册界面密码框 - m_regConfirmLineEdit = m_regDialog->get_reg_confirm(); //注册界面密码确认框 - - m_passLineEdit = m_passDialog->get_reg_phone(); //忘记密码界面用户框 - m_passPasswordLineEdit = m_passDialog->get_reg_pass(); //忘记密码界面密码框 - m_passConfirmLineEdit = m_passDialog->get_reg_pass_confirm();//忘记密码确认密码框 - m_passMCodeLineEdit = m_passDialog->get_valid_code(); //忘记密码验证码框 - - //忘记密码错误提示 - m_passTips = m_passDialog->get_passtips(); + // m_passTips = m_passDialog->get_passtips(); //登录错误提示 m_loginCodeStatusTips = m_loginDialog->get_tips_code(); m_loginTips = m_loginDialog->get_tips_pass(); + m_loginPassLineEdit ->setContextMenuPolicy (Qt::NoContextMenu); //注册输入提示 - m_errorPassTips = m_passDialog->get_tips(); - m_errorRegTips = m_regDialog->get_tips(); + //m_errorPassTips = m_passDialog->get_tips(); //注册错误消息提示 - m_accountTips = m_regDialog->get_user_tip(); - m_regTips = m_regDialog->get_pass_tip(); - /*界面逻辑有关信号与槽函数连接*/ connect(m_delBtn,SIGNAL(clicked()),this,SLOT(on_close())); - connect(m_loginDialog->get_forget_btn(),SIGNAL(clicked()),this,SLOT(linked_forget_btn())); - connect(m_regBtn,SIGNAL(clicked()),this,SLOT(linked_register_btn())); + connect(m_loginDialog->get_forget_btn(),SIGNAL(clicked()),this,SLOT(on_pass_btn())); + connect(m_regBtn,SIGNAL(clicked()),this,SLOT(on_reg_btn())); connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - connect(m_forgetpassBtn,SIGNAL(clicked()),this,SLOT(on_send_code())); - connect(m_cPassTimer,SIGNAL(timeout()),this,SLOT(on_timer_timeout())); - connect(m_cRegTimer,SIGNAL(timeout()),this,SLOT(on_timer_reg_out())); - connect(m_cLogTimer,SIGNAL(timeout()),this,SLOT(on_timer_log_out())); - connect(m_cBindTimer,SIGNAL(timeout()),this,SLOT(on_timer_bind_out())); - connect(m_regSendCodeBtn,SIGNAL(clicked()),this,SLOT(on_send_code_reg())); + //connect(m_forgetpassBtn,SIGNAL(clicked()),this,SLOT(on_send_code())); + connect(m_timer,SIGNAL(timeout()),this,SLOT(on_timer_timeout())); connect(m_forgetpassSendBtn,SIGNAL(clicked()),this,SLOT(on_send_code_log())); - connect(m_BindDialog->get_send_code(),SIGNAL(clicked()),this,SLOT(on_send_code_bind())); - connect(m_successDialog->m_backloginBtn,SIGNAL(clicked()),this,SLOT(back_normal())); - connect(m_passPasswordLineEdit,SIGNAL(textChanged(QString)),this,SLOT(cleanconfirm(QString))); - connect(m_regPassLineEdit,SIGNAL(textChanged(QString)),this,SLOT(cleanconfirm(QString))); - connect(m_loginDialog->get_mcode_lineedit(),SIGNAL(returnPressed()),m_submitBtn,SIGNAL(clicked()),Qt::UniqueConnection); - connect(m_loginDialog->get_login_code(),SIGNAL(returnPressed()),m_submitBtn,SIGNAL(clicked()),Qt::UniqueConnection); - connect(m_regDialog->get_valid_code(),SIGNAL(returnPressed()),m_submitBtn,SIGNAL(clicked()),Qt::UniqueConnection); - connect(m_BindDialog->get_code_lineedit(),SIGNAL(returnPressed()),m_submitBtn,SIGNAL(clicked()),Qt::UniqueConnection); - connect(m_passDialog->get_valid_code(),SIGNAL(returnPressed()),m_submitBtn,SIGNAL(clicked()),Qt::UniqueConnection); + //connect(m_BindDialog->get_send_code(),SIGNAL(clicked()),this,SLOT(on_send_code_bind())); + //connect(m_passPasswordLineEdit,SIGNAL(textChanged(QString)),this,SLOT(cleanconfirm(QString))); + connect(m_loginDialog->get_mcode_lineedit(),SIGNAL(returnPressed()),this,SLOT(on_login_btn())); + connect(m_loginDialog->get_login_code(),SIGNAL(returnPressed()),this,SLOT(on_login_btn())); + //connect(m_BindDialog->get_code_lineedit(),SIGNAL(returnPressed()),m_submitBtn,SIGNAL(clicked()),Qt::UniqueConnection); + //connect(m_passDialog->get_valid_code(),SIGNAL(returnPressed()),m_submitBtn,SIGNAL(clicked()),Qt::UniqueConnection); connect(m_loginDialog->get_stack_widget(),&QStackedWidget::currentChanged,[this] (int) { m_blueEffect->stop(); }); + + connect(m_loginAccountLineEdit,&QLineEdit::textChanged,[this] (const QString &changed) { + // qDebug() << changed; + if (m_loginDialog->get_stack_widget()->currentIndex() == 0) { + m_NameLogin = changed; + } else { + m_PhoneLogin = changed; + QRegExp regExp("^1[3-9]\\d{9}$"); + if(regExp.exactMatch(m_PhoneLogin) == true) { + if(m_loginCodeStatusTips->isHidden() == false) { + m_loginCodeStatusTips->hide(); + } + } + } + }); + + connect(m_loginDialog->get_stack_widget(),&QStackedWidget::currentChanged,[this] (int index) { + if (m_loginDialog->get_stack_widget()->currentIndex() == 0) { + m_loginAccountLineEdit->setText(m_NameLogin); + } else { + m_loginAccountLineEdit->setText(m_PhoneLogin); + } + }); //为各个子控件安装事件过滤 m_submitBtn->installEventFilter(this); @@ -237,45 +227,17 @@ m_loginAccountLineEdit->installEventFilter(this); m_loginMCodeLineEdit->installEventFilter(this); - m_passPasswordLineEdit->installEventFilter(this); - m_passMCodeLineEdit->installEventFilter(this); - m_passConfirmLineEdit->installEventFilter(this); - m_passLineEdit->installEventFilter(this); - - m_regPassLineEdit->installEventFilter(this); - m_regAccountLineEdit->installEventFilter(this); - m_regConfirmLineEdit->installEventFilter(this); - m_phoneLineEdit->installEventFilter(this); - m_mcodeLineEdit->installEventFilter(this); - - - m_BindDialog->get_code_lineedit()->installEventFilter(this); - m_BindDialog->get_phone_lineedit()->installEventFilter(this); m_stackedWidget->installEventFilter(this); - //对话框模态处理 - setWindowModality(Qt::ApplicationModal); - //把对话框放置屏幕中央 - QDesktopWidget* desktop = QApplication::desktop(); - move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2); - //初始化一下验证码计时器激活时间 - timerout_num_bind = 60; timerout_num = 60; - timerout_num_log = 60; - timerout_num_reg = 60; } /* 确认密码框如果遇到新密码或者注册密码改变,立即改变 * 成空的状态,防止用户多余操作(舍弃)*/ void MainDialog::cleanconfirm(QString str) { //qDebug()<currentWidget() == m_passDialog) { - //m_passConfirmLineEdit->setText(""); - } else if(m_stackedWidget->currentWidget() == m_regDialog) { - //m_regConfirmLineEdit->setText(""); - } } /* 登录按钮返回给上级控件接口 */ @@ -284,42 +246,102 @@ } /* 设置DBUS客户端 */ -void MainDialog::set_client(DbusHandleClient *c,QThread *t) { +void MainDialog::set_client(DBusUtils *c) { m_dbusClient = c; - m_workThread = t; - connect(this,SIGNAL(dologin(QString,QString,QString)),m_dbusClient,SLOT(login(QString,QString,QString))); - connect(this,SIGNAL(doreg(QString, QString, QString, QString,QString)),m_dbusClient,SLOT(registered(QString, QString, QString, QString,QString))); - connect(this,SIGNAL(dobind(QString, QString, QString, QString,QString)),m_dbusClient,SLOT(bindPhone(QString, QString, QString, QString,QString))); - connect(this,SIGNAL(dogetmcode_phone_reg(QString,QString)),m_dbusClient,SLOT(get_mcode_by_phone(QString,QString))); - connect(this,SIGNAL(dogetmcode_phone_log(QString,QString)),m_dbusClient,SLOT(get_mcode_by_phone(QString,QString))); - connect(this,SIGNAL(dogetmcode_number_pass(QString,QString)),m_dbusClient,SLOT(get_mcode_by_username(QString,QString))); - connect(this,SIGNAL(dogetmcode_number_bind(QString,QString)),m_dbusClient,SLOT(get_mcode_by_phone(QString,QString))); - connect(this,SIGNAL(dorest(QString, QString, QString,QString)),m_dbusClient,SLOT(user_resetpwd(QString, QString, QString,QString))); - connect(this,SIGNAL(dophonelogin(QString,QString,QString)),m_dbusClient,SLOT(user_phone_login(QString,QString,QString))); - connect(m_dbusClient,SIGNAL(finished_ret_log(int)),this,SLOT(setret_login(int))); - connect(m_dbusClient,SIGNAL(finished_ret_reg(int)),this,SLOT(setret_reg(int))); - connect(m_dbusClient,SIGNAL(finished_ret_phonelogin(int)),this,SLOT(setret_phone_login(int))); - connect(m_dbusClient,SIGNAL(finished_ret_rest(int)),this,SLOT(setret_rest(int))); - connect(m_dbusClient,SIGNAL(finished_ret_bind(int)),this,SLOT(setret_bind(int))); - connect(m_dbusClient,SIGNAL(finished_ret_code_log(int)),this,SLOT(setret_code_phone_login(int))); - connect(m_dbusClient,SIGNAL(finished_ret_code_reg(int)),this,SLOT(setret_code_phone_reg(int))); - connect(m_dbusClient,SIGNAL(finished_ret_code_pass(int)),this,SLOT(setret_code_user_pass(int))); - connect(m_dbusClient,SIGNAL(finished_ret_code_bind(int)),this,SLOT(setret_code_user_bind(int))); - - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface", "finished_login", this, SLOT(on_login_finished(int,QString))); - //client->connectdbus("finished_login",this,SLOT(on_login_finished(int))); - //connect(client,SIGNAL(finished_user_phone_login(int)),this,SLOT(on_login_finished(int))); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_user_phone_login",this,SLOT(on_login_finished(int,QString))); - //connect(client,SIGNAL(finished_mcode_by_phone(int)),this,SLOT(on_get_mcode_by_phone(int))); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_mcode_by_phone",this,SLOT(on_get_mcode_by_phone(int,QString))); - //connect(client,SIGNAL(finished_user_resetpwd(int)),this,SLOT(on_pass_finished(int))); - //connect(client,SIGNAL(finished_mcode_by_username(int)),this,SLOT(on_get_mcode_by_name(int))); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_user_resetpwd",this,SLOT(on_pass_finished(int,QString))); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_mcode_by_username",this,SLOT(on_get_mcode_by_name(int,QString))); - //connect(client,SIGNAL(finished_registered(int)),this,SLOT(on_reg_finished(int))); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_registered",this,SLOT(on_reg_finished(int,QString))); - //connect(client,SIGNAL(finished_bindPhone(int)),this,SLOT(on_bind_finished(int))); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_bindPhone",this,SLOT(on_bind_finished(int,QString))); + + connect(this, &MainDialog::dologin, this, [=] (QString kylinID,QString pass) { + QList argList; + argList << kylinID << pass; + m_dbusClient->callMethod("userLogin",argList); + }); + + connect(this, &MainDialog::dogetmcode_phone_log, this, [=] (QString phone) { + QList argList; + argList << phone; + m_dbusClient->callMethod("getMCodeByPhone",argList); + }); + + connect(this, &MainDialog::dophonelogin, this, [=] (QString phone,QString code) { + QList argList; + argList << phone << code; + m_dbusClient->callMethod("phoneLogin",argList); + }); + + connect(m_dbusClient,&DBusUtils::taskFinished,this,[=] (const QString &taskName,int ret) { + if (taskName == "userLogin") { + if (ret != 0) { + emit on_login_failed(); + set_back(); + m_blueEffect->stop(); //登录失败,执行此处,关闭登录执行过程效果,并打印错误消息 + m_submitBtn->setText(tr("Sign in")); + m_loginDialog->get_mcode_lineedit()->setText(""); + if (m_loginDialog->get_stack_widget()->currentIndex() == 0) { + m_loginDialog->set_code(messagebox(ret)); + m_loginTips->show(); + + m_loginDialog->get_mcode_widget()->set_change(1); + m_loginDialog->get_mcode_widget()->repaint(); + setshow(m_stackedWidget); + m_loginDialog->get_mcode_widget()->set_change(0); + } else { + m_loginDialog->set_code(messagebox(ret)); + m_loginCodeStatusTips->show(); + setshow(m_stackedWidget); + } + return ; + } else { + //qDebug() << ret; + } + } else if (taskName == "phoneLogin") { + if (m_stackedWidget->currentWidget() != m_loginDialog && m_loginDialog->get_stack_widget()->currentIndex()) { + emit on_login_failed(); + set_back(); + //m_blueEffect->stop(); //登录失败,执行此处,关闭登录执行过程效果,并打印错误消息 + m_submitBtn->setText(tr("Sign in")); + return ; + } + if (ret != 0) { + emit on_login_failed(); + set_back(); + m_blueEffect->stop(); //登录失败,执行此处,关闭登录执行过程效果,并打印错误消息 + m_submitBtn->setText(tr("Sign in")); + m_loginDialog->get_mcode_lineedit()->setText(""); + if (m_loginDialog->get_stack_widget()->currentIndex() == 0) { + m_loginDialog->set_code(messagebox(ret)); + m_loginTips->show(); + + m_loginDialog->get_mcode_widget()->set_change(1); + m_loginDialog->get_mcode_widget()->repaint(); + setshow(m_stackedWidget); + m_loginDialog->get_mcode_widget()->set_change(0); + return ; + } else { + m_loginDialog->set_code(messagebox(ret)); + m_loginCodeStatusTips->show(); + setshow(m_stackedWidget); + return ; + } + } + } else if (taskName == "getMCodeByPhone") { + if (m_stackedWidget->currentWidget() != m_loginDialog && m_loginDialog->get_stack_widget()->currentIndex() != 1) { + return ; + } + if (ret == 0) { + //not do + } else { + m_loginDialog->get_mcode_lineedit()->setText(""); + m_loginDialog->set_code(messagebox(ret)); + m_loginCodeStatusTips->show(); + setshow(m_stackedWidget); + + return ; + } + } + }); + + m_dbusClient->connectSignal( "finishedPassLogin", this, SLOT(on_login_finished(int))); + m_dbusClient->connectSignal("finishedPhoneLogin",this,SLOT(on_login_finished(int))); + m_dbusClient->connectSignal("finishedMCodeByPhone",this,SLOT(on_get_mcode_by_phone(int))); } /* 窗口控件动态显示处理过渡处理函数,每次窗口布局显示或者 @@ -332,159 +354,13 @@ widget->adjustSize(); } -/* 客户端回调函数集,一般处理异常出现的情况,成功一般 - * 不处理,除非是成功之后还要执行操作的 */ -void MainDialog::setret_reg(int ret) { - if(ret != 0) { - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(messagebox(ret)); - m_errorRegTips->show(); - setshow(m_stackedWidget); - return ; - } else { - } -} - -void MainDialog::setret_login(int ret) { - if(ret != 0) { - m_loginDialog->get_mcode_lineedit()->setText(""); - if(m_loginDialog->get_stack_widget()->currentIndex() == 0) { - m_loginDialog->set_code(messagebox(ret)); - m_loginTips->show(); - - m_loginDialog->get_mcode_widget()->set_change(1); - m_loginDialog->get_mcode_widget()->repaint(); - setshow(m_stackedWidget); - m_loginDialog->get_mcode_widget()->set_change(0); - } else { - m_loginDialog->set_code(messagebox(ret)); - m_loginCodeStatusTips->show(); - setshow(m_stackedWidget); - } - return ; - } else { - - } -} - -void MainDialog::setret_phone_login(int ret) { - if(m_stackedWidget->currentWidget() != m_loginDialog && m_loginDialog->get_stack_widget()->currentIndex()) { - return ; - } - if(ret != 0) { - m_loginDialog->get_mcode_lineedit()->setText(""); - if(m_loginDialog->get_stack_widget()->currentIndex() == 0) { - m_loginDialog->set_code(messagebox(ret)); - m_loginTips->show(); - - m_loginDialog->get_mcode_widget()->set_change(1); - m_loginDialog->get_mcode_widget()->repaint(); - setshow(m_stackedWidget); - m_loginDialog->get_mcode_widget()->set_change(0); - return ; - } else { - m_loginDialog->set_code(messagebox(ret)); - m_loginCodeStatusTips->show(); - setshow(m_stackedWidget); - return ; - } - } -} - -void MainDialog::setret_rest(int ret) { - if(ret != 0) { - m_passDialog->get_valid_code()->setText(""); - m_passDialog->set_code(messagebox(ret)); - m_errorPassTips->show(); - setshow(m_stackedWidget); - - return ; - }else { - - } -} - -void MainDialog::setret_bind(int ret) { - if(ret != 0) { - m_BindDialog->get_code_lineedit()->setText(""); - m_BindDialog->set_code(messagebox(ret)); - m_BindDialog->get_tips()->show(); - setshow(m_stackedWidget); - - return ; - } else { - } -} - -void MainDialog::setret_code_phone_login(int ret) { - if(m_stackedWidget->currentWidget() != m_loginDialog && m_loginDialog->get_stack_widget()->currentIndex() != 1) { - return ; - } - if(ret == 0) { - //not do - } else { - m_loginDialog->get_mcode_lineedit()->setText(""); - m_loginDialog->set_code(messagebox(ret)); - m_loginCodeStatusTips->show(); - setshow(m_stackedWidget); - - return ; - } -} - -void MainDialog::setret_code_user_bind(int ret) { - if(m_stackedWidget->currentWidget() != m_BindDialog) { - return ; - } - if(ret == 0) { - //not do - } else { - m_BindDialog->get_code_lineedit()->setText(""); - m_BindDialog->set_code(messagebox(ret)); - m_BindDialog->get_tips()->show(); - setshow(m_stackedWidget); - return ; - } -} - -void MainDialog::setret_code_phone_reg(int ret) { - if(m_stackedWidget->currentWidget() != m_regDialog) { - return ; - } - if(ret == 0) { - //not do - } else { - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(messagebox(ret)); - m_errorRegTips->show(); - setshow(m_stackedWidget); - - return ; - } -} - -void MainDialog::setret_code_user_pass(int ret) { - if(m_stackedWidget->currentWidget() != m_passDialog) { - return ; - } - if(ret == 0) { - //not do - } else { - m_passDialog->get_valid_code()->setText(""); - m_passDialog->set_code(messagebox(ret)); - m_errorPassTips->show(); - setshow(m_stackedWidget); - return ; - } -} - LoginDialog* MainDialog::get_dialog() { return m_loginDialog; } /* 错误消息提示盒子,所有服务器消息基本上来源于此,默认 * 返回未知代码,显示错误以及代码编号 */ -QString MainDialog::messagebox(int code) { +QString MainDialog::messagebox(const int &code) const { QString ret = tr("Error code:") + QString::number(code,10)+ tr("!"); switch(code) { case 101:ret = tr("Internal error occurred!");break; @@ -499,8 +375,12 @@ case 110:ret = tr("Please check your information!");break; case 401:ret = tr("Please check your account!");break; case 500:ret = tr("Failed due to server error!");break; - case 501:ret = tr("Please check your information!");break; + case 501:ret = tr("User and passsword can't be empty!");break; case 502:ret = tr("User existing!");break; + case 503:ret = tr("User doesn't exist!");break; + case 504:ret = tr("Network can not reach!");break; + case 505:ret = tr("Phone can't be empty!");break; + case 511:ret = tr("Account or password error!");break; case 610:ret = tr("Phone number already in used!");break; case 611:ret = tr("Please check your format!");break; case 612:ret = tr("Your are reach the limit!");break; @@ -509,6 +389,10 @@ case 615:ret = tr("Account doesn't exist!");break; case 616:ret = tr("User has bound the phone!");break; case 619:ret = tr("Sending code error occurred!");break; + case 632:ret = tr("Phone code is expired!");break; + case 702:ret = tr("Phone code error!");break; + case 703:ret = tr("Code can not be empty!");break; + case 704:ret = tr("MCode can not be empty!");break; case -1:ret = tr("Please check your information!");break; } @@ -517,11 +401,78 @@ /* 1.登录逻辑处理槽函数 */ void MainDialog::on_login_btn() { + emit on_submit_clicked(); m_baseWidget->setEnabled(false); //防止用户在登录按钮按完之后到处乱点,下同 set_staus(false); m_delBtn->setEnabled(true); + if (m_loginDialog->get_stack_widget()->currentIndex() == 0) { + if (m_loginDialog->get_mcode_lineedit()->text().trimmed() == "") { + m_loginDialog->set_code(messagebox(703)); + m_loginTips->show(); + m_baseWidget->setEnabled(true); + set_staus(true); + m_loginDialog->get_mcode_widget()->set_change(1); + m_loginDialog->get_mcode_widget()->repaint(); + setshow(m_stackedWidget); + m_loginDialog->get_mcode_lineedit()->setText(""); + m_loginDialog->get_mcode_widget()->set_change(0); + emit on_login_failed(); + return ; + } + if (m_loginDialog->get_user_edit()->text().trimmed() == "" || + m_loginDialog->get_login_pass()->text().trimmed() == "" + ) { + m_loginDialog->set_code(messagebox(501)); + m_loginTips->show(); + m_baseWidget->setEnabled(true); + set_staus(true); + m_loginDialog->get_mcode_widget()->set_change(1); + m_loginDialog->get_mcode_widget()->repaint(); + setshow(m_stackedWidget); + m_loginDialog->get_mcode_lineedit()->setText(""); + m_loginDialog->get_mcode_widget()->set_change(0); + emit on_login_failed(); + return ; + } + if (m_loginDialog->get_user_edit()->text().trimmed().contains("+")) { + m_loginDialog->set_code(messagebox(503)); + m_loginTips->show(); + m_baseWidget->setEnabled(true); + set_staus(true); + m_loginDialog->get_mcode_widget()->set_change(1); + m_loginDialog->get_mcode_widget()->repaint(); + setshow(m_stackedWidget); + m_loginDialog->get_mcode_lineedit()->setText(""); + m_loginDialog->get_mcode_widget()->set_change(0); + emit on_login_failed(); + return ; + } + } + if (m_loginDialog->get_stack_widget()->currentIndex() == 1) { + if (m_loginDialog->get_login_code()->text().trimmed() == "") { + m_loginDialog->set_code(messagebox(704)); + m_loginCodeStatusTips->show(); + m_baseWidget->setEnabled(true); + set_staus(true); + setshow(m_stackedWidget); + m_loginDialog->get_login_code()->setText(""); + emit on_login_failed(); + return ; + } + + if (m_loginDialog->get_user_edit()->text().trimmed() == "") { + m_loginDialog->set_code(messagebox(505)); + m_loginCodeStatusTips->show(); + m_baseWidget->setEnabled(true); + set_staus(true); + setshow(m_stackedWidget); + m_loginDialog->get_login_code()->setText(""); + emit on_login_failed(); + return ; + } + } //如果验证码输入错误,执行此处 - if(m_loginDialog->get_stack_widget()->currentIndex() == 0 && + if (m_loginDialog->get_stack_widget()->currentIndex() == 0 && QString(m_loginDialog->get_mcode_widget()->get_verificate_code()) != m_loginDialog->get_mcode_lineedit()->text() && m_bAutoLogin == false) { m_loginDialog->set_code(tr("Your code is wrong!")); @@ -536,36 +487,44 @@ emit on_login_failed(); return ; } + if (m_loginDialog->get_user_name().length() < 11 && m_loginDialog->get_stack_widget()->currentIndex() == 1) { + m_baseWidget->setEnabled(true); + m_loginDialog->set_code(tr("Please check your phone!")); + m_loginCodeStatusTips->show(); + set_staus(true); + setshow(m_stackedWidget); + emit on_login_failed(); + return ; + } + //如果信息正确可提交,执行此处 - if(m_loginDialog->get_user_name() != "" && + if (m_loginDialog->get_user_name() != "" && m_loginDialog->get_user_pass() != "" && m_loginDialog->get_stack_widget()->currentIndex() == 0){ m_szAccount = m_loginDialog->get_user_name(); m_szPass = m_loginDialog->get_user_pass(); - - m_szRegPass = m_szPass; - m_szRegAccount = m_szAccount; + m_szRegPass = m_szPass.trimmed(); + m_szRegAccount = m_szAccount.trimmed(); //qDebug()<setText(""); m_blueEffect->startmoive(); - emit dologin(m_szRegAccount,m_szRegPass,m_uuid); //触发登录信号,告知客户端进行登录操作 + emit dologin(m_szRegAccount,m_szRegPass); //触发登录信号,告知客户端进行登录操作 - } else if(m_loginDialog->get_user_name() != "" - && m_loginDialog->get_login_code()->text() != "" + } else if (m_loginDialog->get_user_name().trimmed() != "" + && m_loginDialog->get_login_code()->text().trimmed() != "" && m_loginDialog->get_stack_widget()->currentIndex() == 1) { QString phone,mcode; //如果用户选择手机登录,执行此处 - phone = m_loginDialog->get_user_name(); - mcode = m_loginDialog->get_login_code()->text(); - + mcode = m_loginDialog->get_login_code()->text().trimmed(); + phone = m_loginDialog->get_user_name().trimmed(); m_submitBtn->setText(""); m_blueEffect->startmoive(); - emit dophonelogin(phone,mcode,m_uuid); + emit dophonelogin(phone,mcode); } else { emit on_login_failed(); //信息填写不完整执行此处,包括密码登录以及手机登录 - if(m_loginDialog->get_stack_widget()->currentIndex() == 0) { - m_loginDialog->set_code(messagebox(-1)); + if (m_loginDialog->get_stack_widget()->currentIndex() == 0) { + m_loginDialog->set_code(messagebox(501)); m_loginTips->show(); m_baseWidget->setEnabled(true); set_staus(true); @@ -578,7 +537,7 @@ m_loginDialog->get_mcode_lineedit()->setText(""); m_baseWidget->setEnabled(true); set_staus(true); - m_loginDialog->set_code(messagebox(-1)); + m_loginDialog->set_code(messagebox(505)); m_loginCodeStatusTips->show(); setshow(m_stackedWidget); return ; @@ -586,287 +545,64 @@ } } -/* 2.注册逻辑处理槽函数 */ -void MainDialog::on_reg_btn() { - m_baseWidget->setEnabled(false); - m_delBtn->setEnabled(true); - bool ok_mcode = m_regDialog->get_user_mcode() != ""; - bool ok_phone = m_regDialog->get_user_phone() != ""; - bool ok_account = m_regDialog->get_user_account() != ""; - bool ok_passwd = m_regDialog->get_user_passwd() != ""; - bool ok_confirm = m_regDialog->get_reg_confirm()->text() != ""; - int ret = -1; - if(ok_mcode && ok_phone && ok_account && ok_passwd &&ok_confirm) { - QString account,passwd,phone,mcode,confirm; - //qstrcpy(account,box_reg->get_user_account().toStdString().c_str()); - account = m_regDialog->get_user_account(); - phone = m_regDialog->get_user_phone(); - //qstrcpy(phone,box_reg->get_user_phone().toStdString().c_str()); - //qstrcpy(passwd,box_reg->get_user_passwd().toStdString().c_str()); - //qstrcpy(mcode,box_reg->get_user_mcode().toStdString().c_str()); - //qstrcpy(confirm,box_reg->get_reg_confirm()->text().toStdString().c_str()); - passwd = m_regDialog->get_user_passwd(); - mcode = m_regDialog->get_user_mcode(); - confirm = m_regDialog->get_reg_confirm()->text(); - if(confirm != passwd) { - m_baseWidget->setEnabled(true); - m_passDialog->set_code(tr("Please check your password!")); - m_errorPassTips->show(); - setshow(m_stackedWidget); - return ; +QString MainDialog::replace_blank(QString &str) { + QString filter = ""; + QString ret = ""; + bool first = false; + for(QChar c : str) { + if (c != ' ' && !first) { + filter.push_front(c); + first = true; + } else if (first) { + filter.push_front(c); + } + } + for(QChar c : qAsConst(filter)) { + if (c != ' ' && !first) { + ret.push_front(c); + first = true; + } else if (first) { + ret.push_front(c); } - if(!m_regDialog->get_reg_pass()->check()) { - m_baseWidget->setEnabled(true); - m_passDialog->set_code(tr("Please check your password!")); - m_errorPassTips->show(); - setshow(m_stackedWidget); - return ; - } - m_szRegAccount = account; - m_szRegPass = passwd; - emit doreg(account,passwd,phone,mcode,m_uuid); - } else { - m_baseWidget->setEnabled(true); - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(messagebox(ret)); - m_errorRegTips->show(); - setshow(m_stackedWidget); - return ; - } -} - -/* 3.忘记密码进入按钮处理槽函数 */ -void MainDialog::on_pass_btn() { - int ret = -1; - m_baseWidget->setEnabled(false); - m_delBtn->setEnabled(true); - bool ok_phone = m_passDialog->get_user_name() == ""; - bool ok_pass = m_passDialog->get_user_newpass() == ""; - bool ok_confirm = m_passDialog->get_user_confirm() == ""; - bool ok_code = m_passDialog->get_user_mcode() == ""; - if(!ok_phone && !ok_pass && !ok_code && !ok_confirm) { - QString phone,pass,code,confirm; - phone = m_passDialog->get_user_name(); - pass = m_passDialog->get_user_newpass(); - confirm = m_passDialog->get_user_confirm(); - code = m_passDialog->get_user_mcode(); -// qstrcpy(phone,box_pass->get_user_name().toStdString().c_str()); -// qstrcpy(pass,box_pass->get_user_newpass().toStdString().c_str()); -// qstrcpy(confirm,box_pass->get_user_confirm().toStdString().c_str()); -// qstrcpy(code,box_pass->get_user_mcode().toStdString().c_str()); - - if(m_passDialog->get_reg_pass()->check() == false) { - m_baseWidget->setEnabled(true); - m_passDialog->set_code(tr("At least 6 bit, include letters and digt")); - m_errorPassTips->show(); - setshow(m_stackedWidget); - return ; - } - if(confirm != pass) { - m_baseWidget->setEnabled(true); - m_passDialog->set_code(tr("Please check your password!")); - m_errorPassTips->show(); - setshow(m_stackedWidget); - return ; - } - //qDebug()<setEnabled(true); - m_passDialog->get_valid_code()->setText(""); - m_passDialog->set_code(messagebox(ret)); - m_errorPassTips->show(); - setshow(m_stackedWidget); - return ; - } -} - -/* 4.绑定手机号码逻辑处理槽函数 */ -void MainDialog::on_bind_btn() { - int ret = -1; - m_baseWidget->setEnabled(false); - m_delBtn->setEnabled(true); - bool ok_phone = m_BindDialog->get_phone() == ""; - bool ok_pass = m_szPass == ""; - bool ok_account = m_szAccount == ""; - bool ok_code = m_BindDialog->get_code() == ""; - if(!ok_phone && !ok_pass && !ok_code && !ok_account) { - QString phone,pass,account_s,code; - phone = m_BindDialog->get_phone(); - //qstrcpy(pass,passwd.toStdString().c_str()); - pass = m_szPass; - //qstrcpy(account_s,account.toStdString().c_str()); - account_s = m_szAccount; - //qstrcpy(code,box_bind->get_code().toStdString().c_str()); - code = m_BindDialog->get_code(); - emit dobind(account_s,pass,phone,code,m_uuid); - }else { - m_BindDialog->get_code_lineedit()->setText(""); - m_BindDialog->set_code(messagebox(ret)); - m_BindDialog->get_tips()->show(); - m_baseWidget->setEnabled(true); - setshow(m_stackedWidget); - return ; - } -} - - -/* 从成功注册,修改密码成功界面返回所需要的处理 */ -void MainDialog::back_normal() { - //回到登录框 - - m_delBtn->show(); - //qDebug()<<"back normal"; - m_baseWidget->setCurrentWidget(m_containerWidget); - m_successDialog->hide(); - setshow(m_baseWidget); - m_titleLable->setText(tr("Sign in Cloud")); - m_stackedWidget->setCurrentWidget(m_loginDialog); - m_loginDialog->set_clear(); - - //设置注册时候的账号密码为登录账号密码,然后执行登录逻辑 - if(m_bAutoLogin == true) { - m_loginDialog->get_login_pass()->setText(m_szRegPass); - m_loginDialog->get_user_edit()->setText(m_szRegAccount); - m_submitBtn->click(); } + return ret; } -/* 从忘记密码或者注册界面或者或者手机绑定 - * 界面返回到登录界面的必要操作 */ -void MainDialog::back_login_btn() { - //qDebug()<currentIndex(); - if(m_stackedWidget->currentWidget() != m_loginDialog) { - m_titleLable->setText(tr("Sign in Cloud")); - if(m_stackedWidget->currentWidget() == m_regDialog) { - m_regDialog->get_reg_pass()->clear(); - m_regDialog->get_reg_user()->clear(); - m_regDialog->get_phone_user()->clear(); - m_regDialog->get_valid_code()->clear(); - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_reg_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - } else if(m_stackedWidget->currentWidget() == m_passDialog) { - m_passDialog->get_reg_pass()->clear(); - m_passDialog->get_reg_phone()->clear(); - m_passDialog->get_reg_pass_confirm()->clear(); - m_passDialog->get_valid_code()->clear(); - //qDebug()<<"back login"; - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_pass_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - } else if(m_stackedWidget->currentWidget() == m_BindDialog) { - m_BindDialog->setclear(); - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_bind_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - } - m_loginDialog->set_clear(); - m_stackedWidget->setCurrentWidget(m_loginDialog); - m_regBtn->setText(tr("Sign up")); - m_submitBtn->setText(tr("Sign in")); - m_regDialog->hide(); - setshow(m_stackedWidget); - m_passDialog->hide(); - setshow(m_stackedWidget); - - disconnect(m_regBtn,SIGNAL(clicked()),this,SLOT(back_login_btn())); - connect(m_regBtn,SIGNAL(clicked()),this,SLOT(linked_register_btn())); - } +/* 2.注册逻辑处理槽函数 */ +void MainDialog::on_reg_btn() { + QDesktopServices::openUrl(QUrl("https://id.kylinos.cn/registered")); } -/* 进入忘记密码界面的一些必要处理,重用了登录按钮 */ -void MainDialog::linked_forget_btn() { - if(m_stackedWidget->currentWidget()!= m_passDialog) { - - m_titleLable->setText(tr("Forget")); - m_stackedWidget->setCurrentWidget(m_passDialog); - m_submitBtn->setText(tr("Set")); - m_regBtn->setText(tr("Back")); - m_passDialog->set_clear(); - m_regDialog->hide(); - setshow(m_stackedWidget); - m_loginDialog->hide(); - - setshow(m_stackedWidget); - - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_pass_btn())); - disconnect(m_regBtn,SIGNAL(clicked()),this,SLOT(linked_register_btn())); - connect(m_regBtn,SIGNAL(clicked()),this,SLOT(back_login_btn())); - } +/* 3.忘记密码进入按钮处理槽函数 */ +void MainDialog::on_pass_btn() { + QDesktopServices::openUrl(QUrl("https://id.kylinos.cn/find")); } -/* 进入注册界面的一些必要处理,重用了登录按钮 */ -void MainDialog::linked_register_btn() { - if(m_stackedWidget->currentWidget()!= m_regDialog) { - - m_titleLable->setText(tr("Create Account")); - m_stackedWidget->setCurrentWidget(m_regDialog); - m_regBtn->setText(tr("Back")); - m_submitBtn->setText(tr("Sign up now")); - m_passDialog->hide(); - m_loginDialog->hide(); - m_regDialog->set_clear(); - setshow(m_stackedWidget); - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_reg_btn())); - disconnect(m_regBtn,SIGNAL(clicked()),this,SLOT(linked_register_btn())); - connect(m_regBtn,SIGNAL(clicked()),this,SLOT(back_login_btn())); - } -} -/* 注册验证码发送按钮处理 */ -void MainDialog::on_send_code_reg() { +/* 手机登录验证码发送按钮处理 */ +void MainDialog::on_send_code_log() { + //qDebug() <get_user_name().length(); QString phone; - m_regDialog->get_send_code()->setEnabled(false); - if( m_regDialog->get_user_account() == "" || m_regDialog->get_user_phone() == "") { - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(messagebox(-1)); - m_errorRegTips->show(); - m_regDialog->get_send_code()->setEnabled(true); - setshow(m_stackedWidget); - return ; - } - if(m_regDialog->get_reg_pass()->check() == false) { - m_regDialog->get_send_code()->setEnabled(true); - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(tr("At least 6 bit, include letters and digt")); - m_errorRegTips->show(); - setshow(m_stackedWidget); - return ; - } - if(m_regDialog->get_reg_confirm()->text() != m_regDialog->get_reg_pass()->text()) { - m_regDialog->get_send_code()->setEnabled(true); - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(tr("Please confirm your password!")); - m_errorRegTips->show(); + m_loginDialog->get_user_mcode()->setEnabled(false); + if (m_loginDialog->get_user_name().length() < 11) { + m_baseWidget->setEnabled(true); + m_loginDialog->get_user_mcode()->setEnabled(true); + m_loginDialog->set_code(tr("Please check your phone!")); + m_loginCodeStatusTips->show(); setshow(m_stackedWidget); return ; } - if(m_regDialog->get_user_phone() != "") { - phone = m_regDialog->get_user_phone(); - emit dogetmcode_phone_reg(phone,m_uuid); - } else { - m_regDialog->get_send_code()->setEnabled(true); - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(messagebox(-1)); - m_errorRegTips->show(); - setshow(m_stackedWidget); - - return ; + if (m_loginCodeStatusTips->isHidden() == false) { + m_loginCodeStatusTips->hide(); } -} - -/* 手机登录验证码发送按钮处理 */ -void MainDialog::on_send_code_log() { - QString phone; - m_loginDialog->get_user_mcode()->setEnabled(false); - if(m_loginDialog->get_user_name() != "") { + if (m_loginDialog->get_user_name() != "") { phone = m_loginDialog->get_user_name(); - emit dogetmcode_phone_log(phone,m_uuid); + emit dogetmcode_phone_log(phone); } else { m_loginDialog->get_user_mcode()->setEnabled(true); m_loginDialog->get_mcode_lineedit()->setText(""); - m_loginDialog->set_code(messagebox(-1)); + m_loginDialog->set_code(messagebox(704)); m_loginCodeStatusTips->show(); setshow(m_stackedWidget); @@ -874,625 +610,218 @@ } } -/* 手机绑定验证码发送按钮处理 */ -void MainDialog::on_send_code_bind() { - QString name; - int ret = -1; - m_BindDialog->get_send_code()->setEnabled(false); - if(m_BindDialog->get_phone() != "") { - //qstrcpy(name,box_bind->get_phone().toStdString().c_str()); - name = m_BindDialog->get_phone(); - emit dogetmcode_number_bind(name,m_uuid); - }else { - m_BindDialog->get_code_lineedit()->setText(""); - m_BindDialog->set_code(messagebox(ret)); - m_BindDialog->get_tips()->show(); - m_BindDialog->get_send_code()->setEnabled(true); - setshow(m_stackedWidget); - return ; - } -} - -/* 忘记密码验证码发送按钮处理 */ -void MainDialog::on_send_code() { - QString name; - m_passDialog->get_send_msg_btn()->setEnabled(false); - if(m_passDialog->get_reg_pass()->check() == false) { - m_passDialog->get_valid_code()->setText(""); - m_passDialog->set_code(tr("At least 6 bit, include letters and digt")); - m_errorPassTips->show(); - m_passDialog->get_send_msg_btn()->setEnabled(true); - setshow(m_stackedWidget); - return ; - } - if(m_passDialog->get_reg_pass()->text() != m_passDialog->get_reg_pass_confirm()->text()) { - m_passDialog->get_valid_code()->setText(""); - m_passDialog->set_code(tr("Please confirm your password!")); - m_errorPassTips->show(); - m_passDialog->get_send_msg_btn()->setEnabled(true); - setshow(m_stackedWidget); - return ; - } - - if(m_passDialog->get_user_name() != "" && m_passDialog->get_user_confirm() !="" && m_passDialog->get_user_newpass() != "") { - //qstrcpy(name,box_pass->get_user_name().toStdString().c_str()); - name = m_passDialog->get_user_name(); - emit dogetmcode_number_pass(name,m_uuid); - }else { - m_passDialog->get_valid_code()->setText(""); - m_errorPassTips->show(); - m_passDialog->set_code(messagebox(-1)); - m_passDialog->get_send_msg_btn()->setEnabled(true); - setshow(m_stackedWidget); - return ; - } -} /* 忘记密码验证码的计时器处理 */ void MainDialog::on_timer_timeout() { - if(timerout_num > 0) { - m_forgetpassBtn->setText(tr("Resend ( %1 )").arg(timerout_num)); + if (timerout_num > 0) { + + m_timer->start(1000); + m_forgetpassSendBtn->setEnabled(false); + m_forgetpassSendBtn->setText(tr("Resend ( %1 )").arg(timerout_num)); timerout_num --; - }else if(timerout_num == 0) { + } else if (timerout_num == 0) { timerout_num = 60; - m_forgetpassBtn->setEnabled(true); - m_forgetpassBtn->setText(tr("Get phone code")); - m_cPassTimer->stop(); - } -} - -/* 绑定手机验证码的计时器处理 */ -void MainDialog::on_timer_bind_out() { - if(timerout_num_bind > 0) { - m_BindDialog->get_send_code()->setText(tr("Resend ( %1 )").arg(timerout_num_bind)); - timerout_num_bind --; - }else if(timerout_num_bind == 0) { - timerout_num_bind = 60; - m_BindDialog->get_send_code()->setEnabled(true); - m_BindDialog->get_send_code()->setText(tr("Get phone code")); - m_cBindTimer->stop(); - } -} - -/* 手机登录验证码的计时器处理 */ -void MainDialog::on_timer_log_out() { - if(timerout_num_log > 0) { - m_forgetpassSendBtn->setText(tr("Resend ( %1 )").arg(timerout_num_log)); - timerout_num_log --; - }else if(timerout_num_log == 0) { - timerout_num_log = 60; m_forgetpassSendBtn->setEnabled(true); - m_forgetpassSendBtn->setText(tr("Send")); - m_cLogTimer->stop(); - } -} - -/* 注册账户验证码的计时器处理 */ -void MainDialog::on_timer_reg_out() { - if(timerout_num_reg > 0) { - m_regSendCodeBtn->setText(tr("Resend ( %1 )").arg(timerout_num_reg)); - timerout_num_reg --; - }else if(timerout_num_reg == 0) { - timerout_num_reg = 60; - m_regSendCodeBtn->setEnabled(true); - m_regSendCodeBtn->setText(tr("Send")); - m_cRegTimer->stop(); + m_forgetpassSendBtn->setText(tr("Get")); + m_timer->stop(); } } /* 登录回调槽函数,登录回执消息后执行此处 */ -void MainDialog::on_login_finished(int ret,QString uuid) { - if(uuid != this->m_uuid) { - //qDebug()<m_uuid; - return ; - } +void MainDialog::on_login_finished(int ret) { + //qDebug() << "ssssssssssssssss2"; //qDebug()<stop(); - m_titleLable->setText(tr("Binding Phone")); - m_stackedWidget->setCurrentWidget(m_BindDialog); - m_regBtn->setText(tr("Back")); - m_submitBtn->setText(tr("Bind now")); - m_BindDialog->setclear(); - setshow(m_stackedWidget); - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_bind_btn())); - disconnect(m_regBtn,SIGNAL(clicked()),this,SLOT(linked_register_btn())); - connect(m_regBtn,SIGNAL(clicked()),this,SLOT(back_login_btn())); - return ; - } //登录返回成功,执行此处 - if(ret == 0) { + if (ret == 0) { //m_blueEffect->stop(); //m_submitBtn->setText(tr("Sign in")); emit on_login_success(); //发送成功登录信号给主页面 } else { + //qDebug() << "cscacacasca"; emit on_login_failed(); set_back(); m_blueEffect->stop(); //登录失败,执行此处,关闭登录执行过程效果,并打印错误消息 m_submitBtn->setText(tr("Sign in")); - if(m_loginDialog->get_stack_widget()->currentIndex() == 0) { + if (m_loginDialog->get_stack_widget()->currentIndex() == 0) { m_loginDialog->set_code(messagebox(ret)); m_loginTips->show(); m_loginDialog->get_mcode_widget()->set_change(1); m_loginDialog->get_mcode_widget()->repaint(); setshow(m_stackedWidget); return ; - } else if(m_loginDialog->get_stack_widget()->currentIndex() == 1) { + } else if (m_loginDialog->get_stack_widget()->currentIndex() == 1) { m_loginDialog->set_code(messagebox(ret)); m_loginCodeStatusTips->show(); setshow(m_stackedWidget); return ; } } -} - -/* 手机绑定回调槽函数,手机绑定回执消息后执行此处 */ -void MainDialog::on_bind_finished(int ret,QString uuid) { - if(uuid != this->m_uuid) { - return ; - } - m_baseWidget->setEnabled(true); - if(ret == 0) { - timerout_num_bind = 0; - m_cBindTimer->stop(); - m_submitBtn->setText(tr("Sign in")); - m_BindDialog->get_send_code()->setEnabled(true); - m_BindDialog->get_send_code()->setText(tr("Send")); - m_BindDialog->setclear(); - m_titleLable->setText(tr("Sign in Cloud")); - m_regBtn->setText(tr("Sign up")); - m_stackedWidget->setCurrentWidget(m_loginDialog); - setshow(m_stackedWidget); - m_bAutoLogin = true; - m_baseWidget->setCurrentWidget(m_successDialog); - m_successDialog->set_mode_text(3); - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_bind_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - disconnect(m_regBtn,SIGNAL(clicked()),this,SLOT(back_login_btn())); - connect(m_regBtn,SIGNAL(clicked()),this,SLOT(linked_register_btn())); - } else { - m_BindDialog->set_code(messagebox(ret)); - m_BindDialog->get_tips()->show(); - setshow(m_stackedWidget); - return ; - } -} - -/* 注册回调槽函数,注册回执消息后执行此处 */ -void MainDialog::on_reg_finished(int ret,QString uuid) { - if(this->m_uuid != uuid) { - return ; - } - m_baseWidget->setEnabled(true); - //qDebug()<stop(); - m_regSendCodeBtn->setEnabled(true); - m_regSendCodeBtn->setText(tr("Send")); - m_submitBtn->setText(tr("Sign in")); - m_regDialog->get_reg_pass()->clear(); - m_regDialog->get_reg_user()->clear(); - m_regDialog->get_phone_user()->clear(); - m_regDialog->get_valid_code()->clear(); - m_bAutoLogin = true; - m_baseWidget->setCurrentWidget(m_successDialog); - m_delBtn->hide(); - m_successDialog->set_mode_text(0); - m_regBtn->setText(tr("Sign up")); - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_reg_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - disconnect(m_regBtn,SIGNAL(clicked()),this,SLOT(back_login_btn())); - connect(m_regBtn,SIGNAL(clicked()),this,SLOT(linked_register_btn())); - } else { - m_regDialog->set_code(messagebox(ret)); - m_errorRegTips->show(); - setshow(m_stackedWidget); - return ; - } - -} - -/* 忘记密码回调槽函数,忘记密码回执消息后执行此处 */ -void MainDialog::on_pass_finished(int ret,QString uuid) { - if(uuid != this->m_uuid) { - return ; - } - if(is_used == false) { - return ; - } - m_baseWidget->setEnabled(true); - if(ret == 0) { - //qDebug()<<"cascascascascascascascascascascasca"; - timerout_num = 0; - m_cPassTimer->stop(); - //qDebug()<<"wb11"; - m_forgetpassBtn->setEnabled(true); - m_forgetpassBtn->setText(tr("Send")); - m_submitBtn->setText(tr("Sign in")); - //qDebug()<<"wb22"; - m_passDialog->get_reg_pass()->clear(); - m_passDialog->get_reg_phone()->clear(); - m_passDialog->get_reg_pass_confirm()->clear(); - m_passDialog->get_valid_code()->clear(); - //qDebug()<<"wb33"; - m_baseWidget->setCurrentWidget(m_successDialog); - m_delBtn->hide(); - m_successDialog->set_mode_text(1); - //qDebug()<<"wb44"; - m_regBtn->setText(tr("Sign up")); - //qDebug()<<"wb55"; - disconnect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_pass_btn())); - connect(m_submitBtn,SIGNAL(clicked()),this,SLOT(on_login_btn())); - disconnect(m_regBtn,SIGNAL(clicked()),this,SLOT(back_login_btn())); - connect(m_regBtn,SIGNAL(clicked()),this,SLOT(linked_register_btn())); - //qDebug()<<"wb66"; - } else { - m_passDialog->set_code(messagebox(ret)); - m_errorPassTips->show(); - setshow(m_stackedWidget); - return ; - } + //qDebug()<<"scascasca"; } /* 手机号直接发送验证码回调函数,发送手机验证码回执消息后执行此处 */ -void MainDialog::on_get_mcode_by_phone(int ret,QString uuid) { - if(uuid != this->m_uuid) { - return ; - } - if(ret != 0) { - if(m_stackedWidget->currentWidget() == m_loginDialog) { - m_loginDialog->get_user_mcode()->setEnabled(true); - m_loginDialog->get_login_pass()->setText(""); - m_loginDialog->get_mcode_lineedit()->setText(""); - m_loginDialog->set_code(messagebox(ret)); - if(m_loginDialog->get_stack_widget()->currentIndex() == 0){ - m_loginTips->show(); - } else if(m_loginDialog->get_stack_widget()->currentIndex() == 1) { - m_loginCodeStatusTips->show(); - } - setshow(m_stackedWidget); - } else if(m_stackedWidget->currentWidget() == m_regDialog) { - m_regDialog->get_send_code()->setEnabled(true); - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(messagebox(ret)); - m_errorRegTips->show(); - setshow(m_stackedWidget); - } else if(m_stackedWidget->currentWidget() == m_passDialog) { - m_passDialog->get_valid_code()->setText(""); - m_passDialog->get_send_msg_btn()->setEnabled(true); - m_passDialog->set_code(messagebox(ret)); - m_errorPassTips->show(); - setshow(m_stackedWidget); - } else if(m_stackedWidget->currentWidget() == m_BindDialog) { - m_BindDialog->get_send_code()->setEnabled(true); - m_BindDialog->get_code_lineedit()->setText(""); - m_BindDialog->set_code(messagebox(ret)); - m_BindDialog->get_tips()->show(); - setshow(m_stackedWidget); - } - return ; - } else if(ret == 0) { - if(m_stackedWidget->currentWidget() == m_loginDialog) { - m_cLogTimer->start(1000); - timerout_num_log = 60; - m_forgetpassSendBtn->setEnabled(false); - } else if(m_stackedWidget->currentWidget() == m_regDialog) { - m_cRegTimer->start(1000); - timerout_num_reg = 60; - m_regSendCodeBtn->setEnabled(false); - } else if(m_stackedWidget->currentWidget() == m_passDialog) { - m_cPassTimer->start(1000); - timerout_num = 60; - m_forgetpassBtn->setEnabled(false); - } else if(m_stackedWidget->currentWidget() == m_BindDialog) { - m_cBindTimer->start(1000); - timerout_num_bind = 60; - m_BindDialog->get_send_code()->setEnabled(false); - } - } -} - -/* 根据用户名发送验证码回调函数,发送手机验证码回执消息后执行此处 */ -void MainDialog::on_get_mcode_by_name(int ret,QString uuid) { - if(uuid != this->m_uuid) { - return ; - } - - if(is_used == false) { - return ; - } - if(ret != 0) { - if(m_stackedWidget->currentWidget() == m_loginDialog) { +void MainDialog::on_get_mcode_by_phone(int ret) { + //qDebug() << ret; + if (ret != 0) { + if (m_stackedWidget->currentWidget() == m_loginDialog) { m_loginDialog->get_user_mcode()->setEnabled(true); m_loginDialog->get_login_pass()->setText(""); m_loginDialog->get_mcode_lineedit()->setText(""); m_loginDialog->set_code(messagebox(ret)); - if(m_loginDialog->get_stack_widget()->currentIndex() == 0){ + if (m_loginDialog->get_stack_widget()->currentIndex() == 0){ m_loginTips->show(); - } else if(m_loginDialog->get_stack_widget()->currentIndex() == 1) { + } else if (m_loginDialog->get_stack_widget()->currentIndex() == 1) { m_loginCodeStatusTips->show(); } setshow(m_stackedWidget); - } else if(m_stackedWidget->currentWidget() == m_regDialog) { - m_regDialog->get_send_code()->setEnabled(true); - m_regDialog->get_valid_code()->setText(""); - m_regDialog->set_code(messagebox(ret)); - m_errorRegTips->show(); - setshow(m_stackedWidget); - } else if(m_stackedWidget->currentWidget() == m_passDialog) { - m_passDialog->get_send_msg_btn()->setEnabled(true); - m_passDialog->get_valid_code()->setText(""); - m_passDialog->set_code(messagebox(ret)); - m_errorPassTips->show(); - setshow(m_stackedWidget); - } else if(m_stackedWidget->currentWidget() == m_BindDialog) { - m_BindDialog->get_send_code()->setEnabled(true); - m_BindDialog->get_code_lineedit()->setText(""); - m_BindDialog->set_code(messagebox(ret)); - m_BindDialog->get_tips()->show(); - setshow(m_stackedWidget); } return ; - } else if(ret == 0) { - if(m_stackedWidget->currentWidget() == m_loginDialog) { - m_loginDialog->get_user_mcode()->setEnabled(true); - m_cLogTimer->start(1000); - timerout_num_log = 60; - m_forgetpassSendBtn->setEnabled(false); - } else if(m_stackedWidget->currentWidget() == m_regDialog) { - m_regDialog->get_send_code()->setEnabled(true); - m_cRegTimer->start(1000); - timerout_num_reg = 60; - m_regSendCodeBtn->setEnabled(false); - } else if(m_stackedWidget->currentWidget() == m_passDialog) { - m_passDialog->get_send_msg_btn()->setEnabled(true); - m_cPassTimer->start(1000); - timerout_num = 60; - m_forgetpassBtn->setEnabled(false); - } else if(m_stackedWidget->currentWidget() == m_BindDialog) { - m_BindDialog->get_send_code()->setEnabled(true); - m_cBindTimer->start(1000); - timerout_num_bind = 60; - m_BindDialog->get_send_code()->setEnabled(false); - } + } else if (ret == 0) { + m_forgetpassSendBtn->setEnabled(false); + timerout_num = 60; + m_timer->start(1000); } } /* 窗口重绘,加入阴影 */ void MainDialog::paintEvent(QPaintEvent *event) { - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - - QPainter painter(this); - QColor m_defaultBackgroundColor = qRgb(0, 0, 0); - QPainterPath path1; - path1.setFillRule(Qt::WindingFill); - path1.addRoundedRect(10, 10, this->width() - 20, this->height() - 20, 6, 6); - - painter.setRenderHint(QPainter::Antialiasing, true); - painter.fillPath(path1, QBrush(QColor(m_defaultBackgroundColor.red(), - m_defaultBackgroundColor.green(), - m_defaultBackgroundColor.blue()))); - - QColor color(0, 0, 0, 15); - for (int i = 0; i < 6; i++) - { - QPainterPath path; - path.setFillRule(Qt::WindingFill); - path.addRoundedRect(10 - i, 10 - i, this->width() - (10 - i) * 2, this->height() - (10 - i) * 2, 6, 6); - color.setAlpha(120 - qSqrt(i) * 50); - painter.setPen(color); - painter.drawPath(path); - } + Q_UNUSED(event) - painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(QBrush(palette().color(QPalette::Base))); - painter.setPen(Qt::transparent); - QRect rect = this->rect(); - rect.setX(10); - rect.setY(10); - rect.setWidth(rect.width() - 10); - rect.setHeight(rect.height() - 10); - // rect: 绘制区域 10 圆角弧度 6px - painter.drawRoundedRect(rect, 6, 6); + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); + p.restore(); } /* 子控件事件过滤,主要针对获得或者失去焦点时捕捉 */ bool MainDialog::eventFilter(QObject *w, QEvent *e) { - if(w == m_delBtn) { - if(e->type() == QEvent::Enter) { - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete_click.svg"); - m_delBtn->setIcon(pixmap); - } - if(e->type() == QEvent::Leave) { - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete.svg"); - m_delBtn->setIcon(pixmap); - } - } +// if (w == m_delBtn) { +// if (e->type() == QEvent::Enter) { +// QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete_click.svg"); +// m_delBtn->setIcon(pixmap); +// } +// if (e->type() == QEvent::Leave) { +// QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/delete.svg"); +// m_delBtn->setIcon(pixmap); +// } +// } //手机绑定的四个控件捕捉 - if(w == m_BindDialog->get_code_lineedit()) { - if (e->type() == QEvent::FocusIn && !m_BindDialog->get_tips()->isHidden()) { - m_BindDialog->get_tips()->hide(); - setshow(m_stackedWidget); - } - } - if(w == m_BindDialog->get_phone_lineedit()) { - if (e->type() == QEvent::FocusIn && !m_BindDialog->get_tips()->isHidden()) { - m_BindDialog->get_tips()->hide(); - setshow(m_stackedWidget); - } - } - - //注册页面的控件捕捉 - if(w == m_regAccountLineEdit) { - if (e->type() == QEvent::FocusIn && m_accountTips->isHidden()) { - - m_accountTips->show(); - - setshow(m_stackedWidget); - } else if(e->type() == QEvent::FocusOut){ - m_accountTips->hide(); - m_accountTips->adjustSize(); - setshow(m_stackedWidget); - } - if (e->type() == QEvent::FocusIn && !m_errorRegTips->isHidden()) { - m_errorRegTips->hide(); - setshow(m_stackedWidget); - } - } - if(w == m_regPassLineEdit) { - if (e->type() == QEvent::FocusIn && m_regTips->isHidden()) { - m_regTips->show(); - m_regTips->adjustSize(); - - setshow(m_stackedWidget); - } else if(e->type() == QEvent::FocusOut){ - m_regTips->hide(); - - setshow(m_stackedWidget); - } - if (e->type() == QEvent::FocusIn && !m_errorRegTips->isHidden()) { - m_errorRegTips->hide(); - setshow(m_stackedWidget); - } - } - if(w == m_regConfirmLineEdit) { - if (e->type() == QEvent::FocusIn && !m_errorRegTips->isHidden()) { - m_errorRegTips->hide(); - setshow(m_stackedWidget); - } - } - if(w == m_mcodeLineEdit) { - if (e->type() == QEvent::FocusIn && !m_errorRegTips->isHidden()) { - m_errorRegTips->hide(); - setshow(m_stackedWidget); - } - } - if(w == m_phoneLineEdit) { - if (e->type() == QEvent::FocusIn && !m_errorRegTips->isHidden()) { - m_errorRegTips->hide(); - setshow(m_stackedWidget); - } - } //登录页面的控件捕捉 - if(w == m_loginPassLineEdit) { - if (e->type() == QEvent::FocusIn && !m_loginTips->isHidden()) { - m_loginTips->hide(); + if (m_stackedWidget->currentWidget() == m_loginDialog) { + if (w == m_loginPassLineEdit) { + if (e->type() == QEvent::FocusIn && !m_loginTips->isHidden()) { + m_loginTips->hide(); - setshow(m_stackedWidget); - } - } - if(w ==m_loginAccountLineEdit) { - if (e->type() == QEvent::FocusIn && !m_loginTips->isHidden()) { - m_loginTips->hide(); + // setshow(m_stackedWidget); + } + if (e->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(e); + if (keyEvent->matches(QKeySequence::Paste)) { + return true; + } + if (keyEvent->matches(QKeySequence::Cut)) { + return true; + } + if (keyEvent->matches(QKeySequence::Copy)) { + return true; + } + if (keyEvent->matches(QKeySequence::Undo)) { + return true; + } + if (keyEvent->matches(QKeySequence::Redo)) { + return true; + } + } + if (e->type() == QEvent::MouseButtonRelease) { + QMouseEvent *mouseEvent = static_cast(e); + if (mouseEvent->button() == Qt::MidButton) { + return true; + } + } + } + if (w ==m_loginAccountLineEdit) { + if (e->type() == QEvent::FocusIn && !m_loginTips->isHidden()) { + m_loginTips->hide(); - setshow(m_stackedWidget); - } - if (e->type() == QEvent::FocusIn && !m_loginCodeStatusTips->isHidden()) { - m_loginCodeStatusTips->hide(); + // setshow(m_stackedWidget); + } + if (e->type() == QEvent::FocusIn && !m_loginCodeStatusTips->isHidden()) { + m_loginCodeStatusTips->hide(); - setshow(m_stackedWidget); + // setshow(m_stackedWidget); + } } - } - if(w == m_loginMCodeLineEdit) { - if (e->type() == QEvent::FocusIn && !m_loginTips->isHidden()) { - m_loginTips->hide(); + if (w == m_loginMCodeLineEdit) { + if (e->type() == QEvent::FocusIn && !m_loginTips->isHidden()) { + m_loginTips->hide(); - setshow(m_stackedWidget); + // setshow(m_stackedWidget); + } } - } - if(w == m_loginLineEdit) { - if (e->type() == QEvent::FocusIn && !m_loginCodeStatusTips->isHidden()) { - m_loginCodeStatusTips->hide(); + if (w == m_loginLineEdit) { + if (e->type() == QEvent::FocusIn && !m_loginCodeStatusTips->isHidden()) { + m_loginCodeStatusTips->hide(); - setshow(m_stackedWidget); + // setshow(m_stackedWidget); + } } } //忘记密码页面的控件捕捉 - if(w == m_passPasswordLineEdit) { - if (e->type() == QEvent::FocusIn && !m_errorPassTips->isHidden()) { - m_errorPassTips->hide(); - setshow(m_stackedWidget); - } - if (e->type() == QEvent::FocusIn && m_passTips->isHidden()) { - m_passTips->show(); - setshow(m_stackedWidget); - - } else if (e->type() == QEvent::FocusOut && !m_passTips->isHidden()) { - m_passTips->hide(); - - setshow(m_stackedWidget); - } - } - if(w == m_passConfirmLineEdit) { - if (e->type() == QEvent::FocusIn && !m_errorPassTips->isHidden()) { - m_errorPassTips->hide(); - - setshow(m_stackedWidget); - - } - } - if(w == m_passMCodeLineEdit) { - if (e->type() == QEvent::FocusIn && !m_errorPassTips->isHidden()) { - m_errorPassTips->hide(); - - setshow(m_stackedWidget); - - } - } - if(w == m_passLineEdit) { - if (e->type() == QEvent::FocusIn && !m_errorPassTips->isHidden()) { - m_errorPassTips->hide(); - - setshow(m_stackedWidget); - - } - } - - - if(w == m_stackedWidget) { - if(e->type() == QEvent::FocusOut) { - setshow(m_stackedWidget); - } - } - - if(w == m_submitBtn) { - if (e->type() == QEvent::FocusIn && !m_loginTips->isHidden()) { + if (w == m_submitBtn) { + if (e->type() == QEvent::FocusIn && !m_loginTips->isHidden() && m_stackedWidget->currentWidget() == m_loginDialog) { m_loginTips->hide(); - setshow(m_stackedWidget); + // setshow(m_stackedWidget); } - if (e->type() == QEvent::FocusIn && !m_errorRegTips->isHidden()) { - m_errorRegTips->hide(); - setshow(m_stackedWidget); - - } - if (e->type() == QEvent::FocusIn && !m_errorPassTips->isHidden()) { - m_errorPassTips->hide(); - setshow(m_stackedWidget); - - } - if (e->type() == QEvent::FocusIn && !m_loginCodeStatusTips->isHidden()) { + if (e->type() == QEvent::FocusIn && !m_loginCodeStatusTips->isHidden() && m_stackedWidget->currentWidget() == m_loginDialog) { m_loginCodeStatusTips->hide(); - setshow(m_stackedWidget); + // setshow(m_stackedWidget); } + } return QWidget::eventFilter(w,e); } @@ -1507,30 +836,17 @@ m_titleLable->setText(tr("Sign in Cloud")); m_stackedWidget->setCurrentWidget(m_loginDialog); m_loginDialog->set_clear(); - if(m_stackedWidget->currentWidget() == m_loginDialog) { + if (m_stackedWidget->currentWidget() == m_loginDialog) { m_loginDialog->set_clear(); - }else if(m_stackedWidget->currentWidget() == m_regDialog) { - m_regDialog->set_clear(); - emit m_regBtn->clicked(); - }else if(m_stackedWidget->currentWidget() == m_passDialog) { - m_passDialog->set_clear(); - emit m_regBtn->clicked(); } m_loginDialog->set_window2(); - m_delBtn->raise(); - setshow(m_baseWidget); + //m_delBtn->raise(); } -void MainDialog::set_staus(bool ok) { - if(m_baseWidget->currentWidget() == m_containerWidget) { - if(m_stackedWidget->currentWidget() == m_loginDialog) { +void MainDialog::set_staus(const bool &ok) { + if (m_baseWidget->currentWidget() == m_containerWidget) { + if (m_stackedWidget->currentWidget() == m_loginDialog) { m_loginDialog->set_staus(ok); - } else if(m_stackedWidget->currentWidget() == m_BindDialog) { - m_BindDialog->set_staus(ok); - } else if(m_stackedWidget->currentWidget() == m_passDialog) { - m_passDialog->set_staus(ok); - } else if(m_stackedWidget->currentWidget() == m_regDialog) { - m_regDialog->set_staus(ok); } m_stackedWidget->setEnabled(ok); m_submitBtn->setEnabled(ok); @@ -1554,44 +870,27 @@ set_staus(true); m_blueEffect->stop(); m_submitBtn->setText(tr("Sign in")); - m_loginDialog->set_code(messagebox(108)); - m_loginDialog->get_mcode_widget()->set_change(1); - m_loginTips->show(); + if (m_loginDialog->get_stack_widget()->currentIndex() == 0) { + m_loginDialog->set_code(messagebox(108)); + m_loginDialog->get_mcode_widget()->set_change(1); + m_loginTips->show(); + } else { + m_loginDialog->set_code(messagebox(108)); + m_loginCodeStatusTips->show(); + } setshow(m_stackedWidget); } /* 关闭按钮触发处理 */ void MainDialog::on_close() { - //qDebug()<<"yes"; - m_forgetpassSendBtn->setEnabled(true); - m_forgetpassSendBtn->setText(tr("Send")); - m_baseWidget->setEnabled(true); - m_blueEffect->stop(); - set_staus(true); - - m_loginDialog->get_mcode_widget()->set_change(1); - back_login_btn(); - set_clear(); close(); } void MainDialog::closedialog() { - m_forgetpassSendBtn->setEnabled(true); - m_forgetpassSendBtn->setText(tr("Send")); - m_baseWidget->setEnabled(true); - m_blueEffect->stop(); - m_bAutoLogin = false; - set_staus(true); - m_submitBtn->setText(tr("Sign in")); - m_loginDialog->get_mcode_widget()->set_change(1); - - back_login_btn(); - set_clear(); close(); } MainDialog::~MainDialog() { } - diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/maindialog.h ukui-control-center-3.0.3/plugins/account/networkaccount/maindialog.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/maindialog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/maindialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -32,79 +32,55 @@ #include #include #include -#include "logindialog.h" -#include "regdialog.h" -#include "successdiaolog.h" -#include "passdialog.h" #include #include #include "passwordlineedit.h" -#include "dbushandleclient.h" +#include "dbusutils.h" #include -#include "bindphonedialog.h" #include #include #include "tips.h" #include "svghandler.h" #include "blueeffect.h" +#include "logindialog.h" +#include +#include "CloseButton/closebutton.h" -class MainDialog : public QWidget +class MainDialog : public QDialog { Q_OBJECT public: explicit MainDialog(QWidget *parent = nullptr); QString status = tr("Sign in Cloud"); int timerout_num = 60; - int timerout_num_reg = 60; - int timerout_num_log = 60; - int timerout_num_bind = 60; - QString messagebox(int code); - void set_client(DbusHandleClient *c,QThread *t); + QString messagebox(const int &code) const; + void set_client(DBusUtils *c); QPushButton *get_login_submit(); + QString replace_blank(QString &str); LoginDialog *get_dialog(); bool retok = true; void set_clear(); void setshow(QWidget *w); bool is_used = false; - void set_staus(bool ok); + void set_staus(const bool &ok); void closedialog(); void setnormal(); ~MainDialog(); public slots: - void linked_forget_btn(); - void linked_register_btn(); - void back_login_btn(); - void back_normal(); void on_login_btn(); void on_pass_btn(); void on_reg_btn(); - void on_login_finished(int ret,QString m_uuid); - void on_pass_finished(int ret,QString m_uuid); - void on_reg_finished(int ret,QString m_uuid); - void on_get_mcode_by_name(int ret,QString m_uuid); - void on_get_mcode_by_phone(int ret,QString m_uuid); + void on_login_finished(int ret); + //void on_reg_finished(int ret,QString m_uuid); + void on_get_mcode_by_phone(int ret); void on_timer_timeout(); - void on_send_code(); - void on_send_code_reg(); void on_send_code_log(); - void on_send_code_bind(); - void on_timer_reg_out(); - void on_timer_log_out(); - void on_timer_bind_out(); + //void on_send_code_bind(); void on_close(); - void on_bind_finished(int ret,QString m_uuid); - void on_bind_btn(); + //void on_bind_finished(int ret,QString m_uuid); + //void on_bind_btn(); void cleanconfirm(QString str); - void setret_login(int ret); - void setret_phone_login(int ret); - void setret_rest(int ret); - void setret_reg(int ret); - void setret_bind(int ret); - void setret_code_phone_login(int ret); - void setret_code_phone_reg(int ret); - void setret_code_user_pass(int ret); - void setret_code_user_bind(int ret); void set_back(); protected: void paintEvent(QPaintEvent *event); @@ -124,42 +100,24 @@ QVBoxLayout *m_workLayout; QHBoxLayout *m_subLayout; QPoint m_startPoint; - QPushButton *m_delBtn; - PassDialog *m_passDialog; - RegDialog *m_regDialog; - QLabel *m_accountTips; - QLabel *m_passTips; - Tips *m_errorPassTips; - Tips *m_errorRegTips; - PasswordLineEdit *m_regPassLineEdit; - QLineEdit *m_regAccountLineEdit; + CloseButton *m_delBtn; PasswordLineEdit *m_loginPassLineEdit; - QLineEdit *m_mcodeLineEdit; - QLineEdit *m_phoneLineEdit; - QLineEdit *m_passLineEdit; - PasswordLineEdit *m_passConfirmLineEdit; - PasswordLineEdit *m_passPasswordLineEdit; - QLineEdit *m_passMCodeLineEdit; + QLineEdit *m_loginLineEdit; QLineEdit *m_loginAccountLineEdit; - PasswordLineEdit *m_regConfirmLineEdit; Tips *m_loginTips; - QLabel *m_regTips; + //QLabel *m_regTips; QLineEdit *m_loginMCodeLineEdit; Tips *m_loginCodeStatusTips; - QPushButton *m_regSendCodeBtn; - QPushButton *m_forgetpassBtn; + //QPushButton *m_regSendCodeBtn; + //QPushButton *m_forgetpassBtn; QPushButton *m_forgetpassSendBtn; QString *m_szPassName; - QTimer *m_cPassTimer; - QTimer *m_cRegTimer; - QTimer *m_cLogTimer; - QTimer *m_cBindTimer; - DbusHandleClient *m_dbusClient; + QTimer *m_timer; + DBusUtils *m_dbusClient; QWidget *m_containerWidget; QStackedWidget *m_baseWidget; - SuccessDiaolog *m_successDialog; - BindPhoneDialog *m_BindDialog; + //BindPhoneDialog *m_BindDialog; Blueeffect *m_blueEffect; QThread *m_workThread; bool m_bIsSendOk = false; @@ -169,19 +127,18 @@ SVGHandler *m_svgHandler; QHBoxLayout *m_animateLayout; + QString m_PhoneLogin; + QString m_NameLogin; + signals: + void on_submit_clicked(); + void on_close_event(); void on_login_failed(); void on_login_success(); void on_allow_send(); - void dologin(QString username,QString pwd,QString uuid); - void dogetmcode_phone_log(QString phonenumb,QString uuid); - void dogetmcode_phone_reg(QString phonenumb,QString uuid); - void dogetmcode_number_bind(QString username,QString uuid); - void dogetmcode_number_pass(QString username,QString uuid); - void dorest(QString username, QString newpwd, QString mCode,QString uuid); - void doreg(QString username, QString pwd, QString phonenumb, QString mcode,QString uuid); - void dophonelogin(QString phone, QString mCode,QString uuid); - void dobind(QString username, QString pwd, QString phone, QString mCode,QString uuid); + void dologin(QString username,QString pwd); + void dogetmcode_phone_log(QString phonenumb); + void dophonelogin(QString phone,QString mCode); }; diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/mainwidget.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/mainwidget.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/mainwidget.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/mainwidget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -21,266 +21,496 @@ #include #include #include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +const int version[3] = {1, 4, 1}; MainWidget::MainWidget(QWidget *parent) : QWidget(parent) { - m_dbusClient = new DbusHandleClient(); //创建一个通信客户端 - thread = new QThread(); //为创建的客户端做异步处理 - m_dbusClient->moveToThread(thread); - m_szUuid = QUuid::createUuid().toString(); - connect(this,SIGNAL(dooss(QString)),m_dbusClient,SLOT(init_oss(QString))); - connect(this,SIGNAL(docheck()),m_dbusClient,SLOT(check_login())); - connect(this,SIGNAL(doconf()),m_dbusClient,SLOT(init_conf())); - connect(this,SIGNAL(doman()),m_dbusClient,SLOT(manual_sync())); - connect(this,SIGNAL(dochange(QString,int)),m_dbusClient,SLOT(change_conf_value(QString,int))); - connect(this,SIGNAL(dologout()),m_dbusClient,SLOT(logout())); - connect(m_dbusClient,SIGNAL(finished_oss(int)),this,SLOT(setret_oss(int))); - connect(m_dbusClient,SIGNAL(finished_check_oss(QString)),this,SLOT(setname(QString))); - connect(m_dbusClient,SIGNAL(finished_check(QString)),this,SLOT(setret_check(QString))); - connect(m_dbusClient,SIGNAL(finished_conf(int)),this,SLOT(setret_conf(int))); - connect(m_dbusClient,SIGNAL(finished_man(int)),this,SLOT(setret_man(int))); - connect(m_dbusClient,SIGNAL(finished_change(int)),this,SLOT(setret_change(int))); - connect(m_dbusClient,SIGNAL(finished_logout(int)),this,SLOT(setret_logout(int))); - connect(thread,&QThread::finished,thread,&QObject::deleteLater); - thread->start(); //线程开始 - m_mainWidget = new QStackedWidget(this); - m_mainWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint); - emit docheck(); //检测是否登录 + initMemoryAlloc(); + + //系统版本号检测 + QProcess proc; + QStringList option; + option << "-c" << "lsb_release -r | awk -F'\t' '{print $2}'"; + proc.start("/bin/bash",option); + proc.waitForFinished(); + QByteArray ar = proc.readAll().toStdString().c_str(); + m_confName = "All-" + ar.replace("\n","") + ".conf"; + m_szConfPath = QDir::homePath() + "/.cache/kylinId/" + m_confName; + + //麒麟ID客户端检测 + QProcess kylinIDProc; + QStringList kIdOptions; + kIdOptions << "-c" << "ps aux | grep kylin-id"; + kylinIDProc.start("/bin/bash",kIdOptions); + kylinIDProc.waitForFinished(-1); + QByteArray result = kylinIDProc.readAll(); + if (result.contains("/usr/bin/kylin-id")) { + m_bIsKylinId = true; + } + + //版本控制 + QProcess kylinssoVerProc; + QStringList kylinssoOptions; + kylinssoOptions << "-c" << "dpkg -l | grep kylin-sso-client | awk -F' ' '{print $3}'"; + kylinssoVerProc.start("/bin/bash", kylinssoOptions); + kylinssoVerProc.waitForFinished(-1); + QByteArray kRet = kylinssoVerProc.readAll(); + QByteArrayList versionNum = kRet.split('.'); + + if (versionNum.size() == 3) { + for(int i = 0;i < 3;i ++) { + if (versionNum.at(i).toInt() < version[i]) { + m_bIsOldBackEnds = true; + break; + } else if (versionNum.at(i).toInt() > version[i]) { + m_bIsOldBackEnds = false; + break; + } + } + } else { + m_bIsOldBackEnds = true; + } + + + if (m_bIsOldBackEnds) { + QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"), QString("/org/freedesktop/NetworkManager"), QString("org.freedesktop.NetworkManager"), + "PropertiesChanged", this, SLOT(checkNetWork(QVariantMap))); + } + + + m_szUuid = QUuid::createUuid().toString(); + m_bTokenValid = false; init_gui(); //初始化gui - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","finished_init_oss",this,SLOT(finished_load(int,QString))); - //connect(client,SIGNAL(backcall_start_download_signal()),this,SLOT(download_files())); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","backcall_start_download_signal",this,SLOT(download_files())); - //connect(client,SIGNAL(backcall_end_download_signal()),this,SLOT(download_over())); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","backcall_end_download_signal",this,SLOT(download_over())); - //connect(client,SIGNAL(backcall_start_push_signal()),this,SLOT(push_files())); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","backcall_start_push_signal",this,SLOT(push_files())); - //connect(client,SIGNAL(backcall_end_push_signal()),this,SLOT(push_over())); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","backcall_end_push_signal",this,SLOT(push_over())); - QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface","backcall_key_info",this,SLOT(get_key_info(QString))); -} -/* 检测第一次登录,为用户添加名字 */ -void MainWidget::setname(QString n) { - //qDebug()<setText(tr("Your account:%1").arg(m_szCode)); - m_mainWidget->setCurrentWidget(m_widgetContainer); - m_bTokenValid = true; //开启登录状态 - m_autoSyn->set_change(0,"0"); + initSignalSlots(); + if (m_bIsOldBackEnds) { + isNetWorkOnline(); + } - for(int i = 0;i < m_szItemlist.size();i ++) { - m_itemList->get_item(i)->set_change(0,"0"); + if (m_bIsOnline == false ||m_szCode == tr("Disconnected")) { + m_autoSyn->get_swbtn()->setDisabledFlag(true); + for (int i = 0;i < m_szItemlist.size(); i ++ ) { + m_itemList->get_item(i)->get_swbtn()->setDisabledFlag(true); + } + } else { + m_autoSyn->get_swbtn()->setDisabledFlag(false); + for (int i = 0;i < m_szItemlist.size(); i ++ ) { + m_itemList->get_item(i)->get_swbtn()->setDisabledFlag(false); } - - m_dbusClient->m_bFirstAttempt = false; //关闭第一次打开状态 - return ; } -} + + layoutUI(); + dbusInterface(); + m_checkTimer->setSingleShot(true); + m_checkTimer->setInterval(500); + m_checkTimer->start(); -/* 客户端回调函数集 */ -void MainWidget::setret_oss(int ret) { - if(ret == 0) { - //qDebug()<<"init oss is 0"; + QFile tokenFile(QDir::homePath() + "/.cache/kylinId/token"); + if (tokenFile.exists() && tokenFile.size() > 1) { + m_mainWidget->setCurrentWidget(m_widgetContainer); } else { - //emit dologout(); + m_mainWidget->setCurrentWidget(m_nullWidget); } } -void MainWidget::setret_logout(int ret) { - //do nothing - //qDebug()<set_back(); - m_bIsStopped = false; - } +void MainWidget::checkNetStatus(bool status) { + emit isOnline(status); } -void MainWidget::setret_conf(int ret) { - //qDebug()<closedialog(); +void MainWidget::checkNetWork(QVariantMap map) { + QVariant ret = map.value("Connectivity"); + if (ret.toInt() == 0) { + return ; + } + if (ret.toInt() != 1 && ret.toInt() != 3 ) { + m_bIsOnline = true; + m_autoSyn->get_swbtn()->setDisabledFlag(false); + for (int i = 0;i < m_szItemlist.size(); i ++ ) { + m_itemList->get_item(i)->get_swbtn()->setDisabledFlag(false); + } + m_lazyTimer->setInterval(500); + m_lazyTimer->setSingleShot(true); + m_lazyTimer->start(); - m_cSyncDelay->start(1000); - //QFuture res1 = QtConcurrent::run(this, &config_list_widget::handle_conf); - } else { - QProcess p; - p.start("killall kylin-sso-client"); - p.waitForFinished(); - emit dologout(); + return ; + } + m_bIsOnline = false; + m_autoSyn->get_swbtn()->setDisabledFlag(true); + for (int i = 0;i < m_szItemlist.size(); i ++ ) { + m_itemList->get_item(i)->get_swbtn()->setDisabledFlag(true); } } -void MainWidget::setret_man(int ret) { - if(ret == 0) { - //emit doconf(); - //qDebug()<<"1111 manul"; - } +void MainWidget::isNetWorkOnline() +{ + QtConcurrent::run([=] { + QVariant ret; + QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.NetworkManager", + "CheckConnectivity"); + QDBusMessage response = QDBusConnection::systemBus().call(message); + + if (response.type() == QDBusMessage::ReplyMessage) { + QDBusVariant value = qvariant_cast(response.arguments().takeFirst()); + ret = value.variant(); + if (ret.isValid() == false) { + ret = response.arguments().takeFirst(); + if (ret.toInt() != 3 && ret.toInt() != 1) { + emit isOnline(true); + return ; + } + } + } + emit isOnline(false); + return ; + }); + } -void MainWidget::setret_check(QString ret) { - //qDebug()<m_bFirstAttempt = true; - } else if(!(ret == "" || ret =="201" || ret == "203" || ret == "401" ) &&!m_bTokenValid){ - m_bTokenValid = true; - m_szCode = ret; - m_infoTab->setText(tr("Your account:%1").arg(ret)); - m_mainWidget->setCurrentWidget(m_widgetContainer); +void MainWidget::dbusInterface() { + if (m_bIsKylinId) { + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinID/path"), QString("org.kylinID.interface"), + "finishedLogout", this, SLOT(finishedLogout(int))); //登出结果反馈 + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinID/path"), QString("org.kylinID.interface"), + "finishedVerifyToken", this, SLOT(checkUserName(QString))); //用户凭据验证结果反馈 + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinID/path"), QString("org.kylinID.interface"), + "finishedPassLogin", this, SLOT(loginSuccess(int)));//登录结果反馈 + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinID/path"), QString("org.kylinID.interface"), + "finishedPhoneLogin", this, SLOT(loginSuccess(int)));//登录结果反馈 + + //登出接口调用 + connect(this, &MainWidget::kylinIdLogOut, this, [=] () { + QDBusMessage message = QDBusMessage::createMethodCall("org.kylinID.service","/org/kylinID/path", + "org.kylinID.interface", + "logout"); + QDBusConnection::sessionBus().call(message); + m_mainWidget->setCurrentWidget(m_nullWidget); + }); + + //验证Token接口调用 + connect(this, &MainWidget::kylinIdCheck, this, [=] () { + QDBusMessage message = QDBusMessage::createMethodCall("org.kylinID.service","/org/kylinID/path", + "org.kylinID.interface", + "checkLogin"); + QDBusConnection::sessionBus().call(message); + }); + } + + m_dbusClient->connectSignal("finished_init_oss",this,SLOT(finished_load(int,QString))); + m_dbusClient->connectSignal("finishedConfLoad",this,SLOT(finished_conf(int))); + m_dbusClient->connectSignal("backcall_start_download_signal",this,SLOT(download_files())); + m_dbusClient->connectSignal("backcall_end_download_signal",this,SLOT(download_over())); + m_dbusClient->connectSignal("backcall_start_push_signal",this,SLOT(push_files())); + m_dbusClient->connectSignal("backcall_end_push_signal",this,SLOT(push_over())); + m_dbusClient->connectSignal("backcall_key_info",this,SLOT(get_key_info(QString))); + m_dbusClient->connectSignal("finishedVerifyToken",this,SLOT(checkUserName(QString))); + m_dbusClient->connectSignal("finishedLogout",this,SLOT(finishedLogout(int))); + if (!m_bIsOldBackEnds) { + m_dbusClient->connectSignal("isOnline",this,SLOT(checkNetStatus(bool))); + } + connect(this, &MainWidget::docheck, m_dbusClient, [=]() { + QList argList; + m_dbusClient->callMethod("checkLogin",argList); + }); - handle_conf(); + connect(m_dbusClient, &DBusUtils::infoFinished,this,[=] (const QString &name) { + if (name != "0") { + showDesktopNotify(tr("Network can not reach!")); + } + }); - //QFuture res1 = QtConcurrent::run(this, &config_list_widget::handle_conf); - } else if((ret == "" || ret =="201" || ret == "203" || ret == "401" ) && m_bTokenValid == false){ - m_bTokenValid = true; - m_mainWidget->setCurrentWidget(m_nullWidget); - } else if(!(ret == "" || ret =="201" || ret == "203" || ret == "401" ) && m_bTokenValid){ - m_infoTab->setText(tr("Your account:%1").arg(ret)); - m_szCode = ret; - m_mainWidget->setCurrentWidget(m_widgetContainer); - handle_conf(); - //QFuture res1 = QtConcurrent::run(this, &config_list_widget::handle_conf); + connect(this, &MainWidget::dooss, m_dbusClient, [=](QString uuid) { + QList argList; + argList << uuid; + m_dbusClient->callMethod("init_oss",argList); + }); + + connect(this, &MainWidget::doconf, m_dbusClient, [=]() { + QList argList; + m_dbusClient->callMethod("init_conf",argList); + }); + + connect(this, &MainWidget::doman, m_dbusClient, [=]() { + QList argList; + m_dbusClient->callMethod("manual_sync",argList); + }); + + connect(this, &MainWidget::dochange, m_dbusClient, [=](QString name,bool flag) { + QList argList; + int var = flag ? 1 : 0; + argList << name << var; + m_dbusClient->callMethod("change_conf_value",argList); + }); + + connect(this, &MainWidget::doquerry, m_dbusClient, [=](QString name) { + QList argList; + argList << name; + m_dbusClient->callMethod("querryUploaded",argList); + }); + + connect(this, &MainWidget::dosend, m_dbusClient, [=](QString info) { + QListargs; + args<callMethod("sendClientInfo",args); + }); + + + connect(this, &MainWidget::dologout, m_dbusClient, [=]() { + QList argList; + m_dbusClient->callMethod("logout",argList); + + }); + + connect(this, &MainWidget::dosingle, m_dbusClient, [=](QString key) { + QList argList; + argList << key; + m_dbusClient->callMethod("single_sync",argList); + }); + + connect(this, &MainWidget::doselect, m_dbusClient, [=](QStringList keyList) { + QList argList; + argList << keyList; + m_dbusClient->callMethod("selectSync",argList); + }); + + connect(m_dbusClient,&DBusUtils::taskFinished,this,[=] (const QString &taskName,int ret) { + Q_UNUSED(taskName); + if (ret == 504) { + if (taskName == "logout") { + m_mainWidget->setCurrentWidget(m_nullWidget); + } + } + + if (taskName == "logout") { + m_autoSyn->set_change(0,"0"); + m_autoSyn->set_active(true); + m_keyInfoList.clear(); + + m_mainWidget->setCurrentWidget(m_nullWidget); + __once__ = false; + __run__ = false; + m_bIsStopped = true; + bIsLogging = false; + } + }); + + connect(m_dbusClient, &DBusUtils::querryFinished, this , [=] (const QStringList &list) { + QStringList keyList = list; + m_isOpenDialog = false; + QFile fileConf(m_szConfPath); + if (m_pSettings != nullptr && fileConf.exists() && fileConf.size() > 1) + m_syncTimeLabel->setText(tr("The latest time sync is: ") + ConfigFile(m_szConfPath).Get("Auto-sync","time").toString().toStdString().c_str()); + else + m_syncTimeLabel->setText(tr("Waiting for initialization...")); + if (keyList.size() > 2) { + if (m_bIsOnline == false) { + showDesktopNotify(tr("Network can not reach!")); + return ; + } + QList args; + QFile file(QDir::homePath() + "/.cache/kylinId/keys"); + args << m_szCode; + QString localDate; + QFile fileFLag(QDir::homePath() + "/.config/gsettings-set/" + m_szCode + "/User_Save_Flag"); + if (fileFLag.exists() && fileFLag.open(QIODevice::ReadOnly)) { + fileFLag.waitForReadyRead(-1); + localDate = fileFLag.readAll().toStdString().c_str(); + }else { + m_manTimer->setSingleShot(true); + m_manTimer->setInterval(1000); + m_manTimer->start(); + emit isSync(true); + return; + } + if (localDate == keyList.at(0) || !file.exists()) { + m_manTimer->setSingleShot(true); + m_manTimer->setInterval(1000); + m_manTimer->start(); + emit isSync(true); + } else { + m_autoSyn->make_itemoff(); + m_pSettings->setValue("Auto-sync/enable","false"); + m_pSettings->sync(); + m_bAutoSyn = false; + m_syncDialog = new SyncDialog(m_szCode,m_szConfPath); + m_syncDialog->m_List = keyList.isEmpty() ? m_szItemlist : keyList; + connect(m_syncDialog, &SyncDialog::sendKeyMap, this,[=] (QStringList keyList) { + Q_UNUSED(keyList); + m_bAutoSyn = true; + m_autoSyn->make_itemon(); + m_pSettings->setValue("Auto-sync/enable","true"); + m_pSettings->sync(); + m_syncDialog->close(); + m_listTimer->setSingleShot(true); + m_listTimer->setInterval(1000); + m_listTimer->start(); + }); + + connect(m_syncDialog, &SyncDialog::coverMode, this, [=] () { + m_bAutoSyn = true; + m_autoSyn->make_itemon(); + m_pSettings->setValue("Auto-sync/enable","true"); + m_pSettings->sync(); + m_syncDialog->close(); + m_manTimer->setSingleShot(true); + m_manTimer->setInterval(1000); + m_manTimer->start(); + emit isSync(true); + }); + m_syncDialog->checkOpt(); + m_syncDialog->show(); + + } + } else { + m_manTimer->setSingleShot(true); + m_manTimer->setInterval(1000); + m_manTimer->start(); + emit isSync(true); + } + }); +} + +void MainWidget::finishedLogout(int ret) { + if (ret != 0 && ret != 401) { + showDesktopNotify(tr("Logout failed,please check your connection")); } } -void MainWidget::setret_change(int ret) { - if(ret == 0) { - //emit docheck(); +void MainWidget::checkUserName(QString name) { + m_szCode = name; + if (name == "" || name =="201" || name == "203" || name == "401" || name == "500" || name == "502") { + if (m_mainWidget->currentWidget() != m_nullWidget) { + m_mainWidget->setCurrentWidget(m_nullWidget); + } + if (m_bIsKylinId) { + emit kylinIdLogOut(); + } else { + emit dologout(); + } + return ; + } + + m_autoSyn->get_swbtn()->setDisabled(false); + m_autoSyn->get_swbtn()->setDisabledFlag(false); + for(int itemCnt = 0;itemCnt < m_szItemlist.size(); itemCnt ++) { + if (m_itemList->get_item(itemCnt) != nullptr) { + m_itemList->get_item(itemCnt)->get_swbtn()->setDisabledFlag(false); + } + } + + m_pSettings = new QSettings(m_szConfPath,QSettings::IniFormat); + m_pSettings->setIniCodec(QTextCodec::codecForName("UTF-8")); + m_infoTab->setText(tr("Your account:%1").arg(m_szCode)); + QFile fileConf(m_szConfPath); + if (m_pSettings != nullptr && fileConf.exists()) + m_syncTimeLabel->setText(tr("The latest time sync is: ") + ConfigFile(m_szConfPath).Get("Auto-sync","time").toString().toStdString().c_str()); + else + m_syncTimeLabel->setText(tr("Waiting for initialization...")); + //setshow(m_mainWidget); + if (m_bTokenValid == false) { + if (m_mainWidget->currentWidget() != m_widgetContainer) { + m_mainWidget->setCurrentWidget(m_widgetContainer); + } + QtConcurrent::run([=] () { + + QProcess proc; + QStringList options; + options << "-c" << "ps -ef|grep kylin-sso-client"; + proc.start("/bin/bash",options); + proc.waitForFinished(); + QString ifn = proc.readAll(); + + if (ifn.contains("/usr/bin/kylin-sso-client")) { + emit isRunning(); + } + }); } + if (bIsLogging == false) { + QFile file (m_szConfPath); + QFile token (QDir::homePath() + "/.cache/kylinId/token"); + if (file.exists() == false && token.exists() == true && m_isOpenDialog == false && token.size() > 1) { + emit dooss(m_szUuid); + } + } + + //dooss(m_szUuid); + if(m_autoSyn->get_swbtn()->isChecked() == true) { + m_autoSyn->set_change(0,"0"); + for (int i = 0;i < m_szItemlist.size();i ++) { + m_itemList->get_item(i)->set_change(0,"0"); + } + } + handle_conf(); } -/* 初始化GUI */ -void MainWidget::init_gui() { - //Allocator - m_szConfPath = QDir::homePath() + "/.cache/kylinssoclient/All.conf"; //All.conf文件地址 +void MainWidget::initMemoryAlloc() { + m_dbusClient = new DBusUtils(this); //创建一个通信客户端 + + m_mainWidget = new QStackedWidget(this); + m_vboxLayout = new QVBoxLayout;//整体布局 m_infoTabWidget = new QWidget(this);//用户信息窗口 m_widgetContainer = new QWidget(this);//业务逻辑窗口,包括用户信息以及同步 m_infoWidget = new QWidget(this);//名字框 m_itemList = new ItemList();//滑动按钮列表 - //ld = new LoginDialog(this); m_autoSyn = new FrameItem(this);//自动同步按钮 m_title = new QLabel(this);//标题 m_infoTab = new QLabel(m_infoWidget);//名字 m_exitCloud_btn = new QPushButton(tr("Exit"),this);//退出按钮 m_workLayout = new QVBoxLayout;//业务逻辑布局 - //qDebug()<<"222222"; - m_mainDialog = new MainDialog;//登录窗口 - //qDebug()<<"111111"; - m_editDialog = new EditPassDialog;//修改密码窗口 - //qDebug()<<"000000"; m_infoLayout = new QHBoxLayout;//信息框布局 - //gif = new QLabel(exit_page);//同步动画 - //pm = new QMovie(":/new/image/autosync.gif"); - m_blueEffect_sync = new Blueeffect(m_exitCloud_btn); //同步动画 - m_blueEffect_sync->settext(tr("Sync")); - - m_animateLayout = new QHBoxLayout; - m_animateLayout->addWidget(m_blueEffect_sync); - m_animateLayout->setMargin(0); - m_animateLayout->setSpacing(0); - m_animateLayout->setAlignment(Qt::AlignCenter); - m_exitCloud_btn->setLayout(m_animateLayout); - - m_cLoginTimer = new QTimer(this); - m_cLoginTimer->stop(); - - m_editDialog->hide(); - m_mainDialog->hide(); - m_editDialog->set_client(m_dbusClient,thread);//安装客户端通信 - m_mainDialog->set_client(m_dbusClient,thread); - QVBoxLayout *VBox_tab = new QVBoxLayout; - QHBoxLayout *HBox_tab_sub = new QHBoxLayout; - QHBoxLayout *HBox_tab_btn_sub = new QHBoxLayout; - QString btns = "QPushButton {font-size:14px;background: #E7E7E7;color:rgba(0,0,0,0.85);border-radius: 4px;}" - "QPushButton:hover{font-size:14px;color:rgba(61,107,229,0.85);position:relative;border-radius: 4px;}" - "QPushButton:click{font-size:14px;color:rgba(61,107,229,0.85);position:relative;border-radius: 4px;}"; + m_blueEffect_sync = new Blueeffect(m_exitCloud_btn); //同步动画 + m_exitCode = new QLabel(this); m_nullWidget = new QWidget(this); m_welcomeLayout = new QVBoxLayout; m_welcomeImage = new QSvgWidget(":/new/image/96_color.svg"); m_welcomeMsg = new QLabel(this); m_login_btn = new QPushButton(tr("Sign in"),this); - m_cSyncDelay = new QTimer(this); - m_cSyncDelay->stop(); m_svgHandler = new SVGHandler(this); - m_syncTooltips = new Tooltips(m_exitCloud_btn); - m_syncTipsText = new QLabel(m_syncTooltips); - m_tipsLayout = new QHBoxLayout; m_stackedWidget = new QStackedWidget(this); m_nullwidgetContainer = new QWidget(this); - m_infoText = new QLabel(this); - m_cRetry = new QTimer(this); - - m_stackedWidget->addWidget(m_itemList); - m_stackedWidget->addWidget(m_nullwidgetContainer); - m_stackedWidget->setContentsMargins(0,0,0,0); - - m_tipsLayout->addWidget(m_syncTipsText); - m_tipsLayout->setMargin(0); - m_tipsLayout->setSpacing(0); - m_tipsLayout->setAlignment(Qt::AlignCenter); - m_syncTooltips->setLayout(m_tipsLayout); - m_syncTipsText->setText(tr("Stop sync")); - m_exitCloud_btn->installEventFilter(this); - - - m_syncTooltips->setFixedSize(86,44); - // gif = new QLabel(status); - // gif->setWindowFlags(Qt::FramelessWindowHint);//无边框 - // gif->setAttribute(Qt::WA_TranslucentBackground);//背景透明 - // pm = new QMovie(":/new/image/gif.gif"); - m_openEditDialog_btn = new EditPushButton(m_infoWidget); - //login->setStyleSheet(btns); - - //控件初始化设置 - m_infoTabWidget->setFocusPolicy(Qt::NoFocus); - m_title->setText(tr("Sync your settings")); - m_title->setStyleSheet("font-size:18px;font-weight:500;"); - - - m_infoTab->setText(tr("Your account:%1").arg(m_szCode)); - m_infoTab->setStyleSheet("font-size:14px;"); - // status->setText(syn[0]); - // status->setProperty("objectName","status"); //give object a name - // status->setStyleSheet(qss_btn_str); - // status->setProperty("is_on",false); - // status->style()->unpolish(status); - // status->style()->polish(status); - // status->update(); - //gif->setStyleSheet("border-radius:4px;border:none;"); - - m_autoSyn->set_itemname(tr("Auto sync")); - m_autoSyn->make_itemon(); - m_autoSyn->get_swbtn()->set_id(m_szItemlist.size()); - m_widgetContainer->setFocusPolicy(Qt::NoFocus); - m_openEditDialog_btn->setFixedSize(34,34); - m_openEditDialog_btn->installEventFilter(this); - m_mainWidget->addWidget(m_widgetContainer); + m_syncTimeLabel = new QLabel(this); + m_cLoginTimer = new QTimer(this); + m_lazyTimer = new QTimer(this); + m_listTimer = new QTimer(this); + m_singleTimer = new QTimer(this); + m_checkTimer = new QTimer(this); + m_manTimer = new QTimer(this); + m_pSettings = nullptr; - //控件大小尺寸设置 - setContentsMargins(0,0,32,0); - setMinimumWidth(550); - m_infoTabWidget->resize(200,72); - m_stackedWidget->adjustSize(); - m_autoSyn->get_widget()->setFixedHeight(50); - m_infoTab->setFixedHeight(40); + m_animateLayout = new QHBoxLayout; +} +void MainWidget::layoutUI() { + QVBoxLayout *VBox_tab = new QVBoxLayout; + QHBoxLayout *HBox_tab_sub = new QHBoxLayout; + QHBoxLayout *HBox_tab_btn_sub = new QHBoxLayout; - m_infoWidget->setFixedHeight(36); - m_itemList->setMinimumWidth(550); - m_welcomeImage->setFixedSize(96,96); + m_animateLayout->addWidget(m_blueEffect_sync); + m_animateLayout->setMargin(0); + m_animateLayout->setSpacing(0); + m_animateLayout->setAlignment(Qt::AlignCenter); + m_exitCloud_btn->setLayout(m_animateLayout); -// gif->setMinimumSize(120,36); -// gif->setMaximumSize(120,36); -// gif->resize(120,36); + m_stackedWidget->addWidget(m_itemList); + m_stackedWidget->addWidget(m_nullwidgetContainer); + m_stackedWidget->setContentsMargins(0,0,0,0); - //布局 HBox_tab_sub->addWidget(m_title,0,Qt::AlignLeft); HBox_tab_sub->setMargin(0); HBox_tab_sub->setSpacing(0); @@ -288,8 +518,7 @@ m_infoLayout->addWidget(m_infoTab); m_infoLayout->setMargin(0); m_infoLayout->setSpacing(4); - m_infoLayout->addWidget(m_openEditDialog_btn); - m_infoLayout->setAlignment(Qt::AlignBottom); + m_infoLayout->setAlignment(Qt::AlignCenter); m_infoWidget->setLayout(m_infoLayout); m_infoWidget->adjustSize(); HBox_tab_btn_sub->addWidget(m_infoWidget,0,Qt::AlignLeft); @@ -305,35 +534,21 @@ m_infoTabWidget->setContentsMargins(0,0,0,0); m_widgetContainer->setMinimumWidth(550); + m_syncTimeLabel->setText(tr("Waitting for sync!")); + m_syncTimeLabel->setContentsMargins(20,0,0,0); m_workLayout->addWidget(m_infoTabWidget); m_workLayout->setSpacing(0); m_workLayout->setContentsMargins(1,0,1,0); m_workLayout->addSpacing(16); m_workLayout->addWidget(m_autoSyn->get_widget()); - m_workLayout->addSpacing(8); - m_workLayout->addWidget(m_infoText); - m_workLayout->addSpacing(8); + m_workLayout->addSpacing(16); + m_workLayout->addWidget(m_syncTimeLabel); + m_workLayout->addSpacing(16); m_workLayout->addWidget(m_stackedWidget); m_widgetContainer->setLayout(m_workLayout); - m_login_btn->setFixedSize(180,36); - m_openEditDialog_btn->setFlat(true); - m_openEditDialog_btn->setStyleSheet("QPushButton{background:transparent;}"); - m_welcomeMsg->setText(tr("Synchronize your personalized settings and data")); - - m_infoText->setText(tr("Synchronize your computer's settings into your cloud account here.")); - m_infoText->setStyleSheet("QLabel{color:rgba(0,0,0,0.65);font-size:12px}"); - m_infoText->adjustSize(); - - m_welcomeMsg->setStyleSheet("font-size:18px;"); - - m_exitCloud_btn->setStyleSheet("QPushButton[on=true]{background-color:#3D6BE5;border-radius:4px;}"); - m_exitCloud_btn->setProperty("on",false); - - m_exitCloud_btn->setFixedSize(120,36); - m_welcomeLayout->addSpacing(120); m_welcomeLayout->addWidget(m_welcomeImage,0,Qt::AlignCenter); @@ -341,106 +556,321 @@ m_welcomeLayout->setSpacing(0); m_welcomeLayout->addSpacing(20); m_welcomeLayout->addWidget(m_welcomeMsg,0,Qt::AlignCenter); - m_welcomeLayout->addSpacing(32); + m_welcomeLayout->addSpacing(8); + m_welcomeLayout->addWidget(m_exitCode,0,Qt::AlignCenter); m_welcomeLayout->addWidget(m_login_btn,0,Qt::AlignCenter); m_welcomeLayout->addStretch(); m_welcomeLayout->setAlignment(Qt::AlignCenter | Qt::AlignTop); m_nullWidget->setLayout(m_welcomeLayout); m_nullWidget->adjustSize(); m_mainWidget->addWidget(m_nullWidget); + m_mainWidget->setCurrentWidget(m_nullWidget); m_vboxLayout->addWidget(m_mainWidget); m_vboxLayout->setAlignment(Qt::AlignCenter | Qt::AlignTop); this->setLayout(m_vboxLayout); +} - m_exitCloud_btn->setFocusPolicy(Qt::NoFocus); - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/edit.svg"); - m_openEditDialog_btn->setIcon(pixmap); +void MainWidget::initSignalSlots() { + for (int btncnt = 0;btncnt < m_itemList->get_list().size();btncnt ++) { + connect(m_itemList->get_item(btncnt), &FrameItem::itemChanged, this, [=] (const QString &name,bool checked) { + if (m_bIsOldBackEnds) { + isNetWorkOnline(); + } + if (m_mainWidget->currentWidget() == m_nullWidget) { + return ; + } - int cItem = 0; + if (m_bIsOnline == false) { + showDesktopNotify(tr("Network can not reach!")); + return ; + } + emit dochange(m_itemMap.key(name),checked); + if ( m_exitCloud_btn->property("on") == true || !m_bAutoSyn) { + if (m_itemList->get_item_by_name(name)->get_swbtn()->getDisabledFlag() == true) + m_itemList->get_item_by_name(name)->set_active(false); + else { + m_itemList->get_item_by_name(name)->set_active(true); + } + return ; + } else if (checked == true && m_exitCloud_btn->property("on") == false && m_bAutoSyn){ + m_key = m_itemMap.key(name); + if (m_key != "") { + //QCoreApplication::processEvents(QEventLoop::AllEvents, 500); + m_singleTimer->setSingleShot(true); + m_singleTimer->setInterval(1000); + m_singleTimer->start(); + } - for(QString key : m_szItemlist) { - m_itemMap.insert(key,m_itemList->get_item(cItem)->get_itemname()); - cItem ++; + } + if (m_itemMap.key(name) == "shortcut" && checked == true) { + showDesktopNotify(tr("This operation may cover your settings!")); + } + }); } + connect(this, &MainWidget::isOnline, [=] (bool checked) { + if (checked == true) { + if(m_bIsOnline == true) { + m_checkTimer->setSingleShot(true); + m_checkTimer->setInterval(500); + m_checkTimer->start(); + return ; + } + m_bIsOnline = true; + m_autoSyn->get_swbtn()->setDisabledFlag(false); + for (int i = 0;i < m_szItemlist.size(); i ++ ) { + m_itemList->get_item(i)->get_swbtn()->setDisabledFlag(false); + } + } else { + m_bIsOnline = false; + m_autoSyn->get_swbtn()->setDisabledFlag(true); + for (int i = 0;i < m_szItemlist.size(); i ++ ) { + m_itemList->get_item(i)->get_swbtn()->setDisabledFlag(true); + } + } + }); + + connect(this, &MainWidget::isSync, [=] (bool checked) { + if (checked == false) { + for(int itemCnt = 0;itemCnt < m_szItemlist.size(); itemCnt ++) { + if (m_itemList->get_item(itemCnt) != nullptr) { + m_itemList->get_item(itemCnt)->get_swbtn()->setDisabled(false); + } + } + } else { + for(int itemCnt = 0;itemCnt < m_szItemlist.size(); itemCnt ++) { + if (m_itemList->get_item(itemCnt) != nullptr) { + m_itemList->get_item(itemCnt)->get_swbtn()->setDisabled(true); + } + } + } + + }); + + connect(this,&MainWidget::oldVersion,[=] () { + if (m_mainWidget->currentWidget() != m_nullWidget) { + on_login_out(); + } + m_login_btn->hide(); + m_welcomeMsg->setText(tr("The Cloud Account Service version is out of date!")); + }); + //连接信号 - connect(m_autoSyn->get_swbtn(),SIGNAL(status(int,int)),this,SLOT(on_auto_syn(int,int))); + connect(m_mainWidget,&QStackedWidget::currentChanged,this,[this] (int index) { + if (m_mainWidget->widget(index) == m_nullWidget) { + setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); + download_over(); + m_mainWidget->adjustSize(); + adjustSize(); + } else { + setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); + m_mainWidget->adjustSize(); + adjustSize(); + } + }); + + connect(m_autoSyn->get_swbtn(),SIGNAL(checkedChanged(bool)),this,SLOT(on_auto_syn(bool))); connect(m_login_btn,SIGNAL(clicked()),this,SLOT(on_login())); - connect(m_openEditDialog_btn,SIGNAL(clicked()),this,SLOT(neweditdialog())); connect(m_exitCloud_btn,SIGNAL(clicked()),this,SLOT(on_login_out())); - connect(m_editDialog,SIGNAL(account_changed()),this,SLOT(on_login_out())); - connect(m_mainDialog,SIGNAL(on_login_success()),this,SLOT(open_cloud())); - connect(m_mainDialog->get_login_submit(),&QPushButton::clicked, [this] () { - m_cLoginTimer->setSingleShot(true); - m_cLoginTimer->start(15000); - }); - connect(m_mainDialog,&MainDialog::on_login_failed,[this] () { - m_cLoginTimer->stop(); - m_bIsStopped = true; + connect(this,&MainWidget::isRunning,this,[=] { + download_files(); }); + //All.conf的 + QString tokenFile = QDir::homePath() + "/.cache/kylinId/token"; + m_fsWatcher.addPath(tokenFile); - connect(m_cRetry,&QTimer::timeout, [this] () { - emit doman(); - m_cRetry->stop(); + + connect(&m_fsWatcher,&QFileSystemWatcher::fileChanged,this,[=] () { + QFile token(tokenFile); + if (!token.exists() || token.size() < 1) { + if (m_mainWidget->currentWidget() != m_nullWidget) { + m_mainWidget->setCurrentWidget(m_nullWidget); + } + } else { + m_checkTimer->setSingleShot(true); + m_checkTimer->setInterval(500); + m_checkTimer->start(); + } }); - connect(m_cLoginTimer,&QTimer::timeout,[this]() { - if(m_bIsStopped){ + + connect(m_singleTimer, &QTimer::timeout,this, [this] () { + if (m_bIsOnline == false) { + m_listTimer->stop(); + showDesktopNotify(tr("Network can not reach!")); + return ; + } + if (m_key == "") { return ; } - if(m_mainWidget->currentWidget() == m_widgetContainer) { - m_cLoginTimer->stop(); - } else if (m_mainWidget->currentWidget() == m_nullWidget) { - m_mainDialog->setnormal(); - emit dologout(); - m_cLoginTimer->stop(); + emit dosingle(m_key); + m_singleTimer->stop(); + }); + + connect(m_lazyTimer,&QTimer::timeout,this,[this] () { + //emit doman(); + if (m_bIsKylinId) { + emit kylinIdCheck(); + } else { + emit docheck(); } + m_lazyTimer->stop(); }); - for(int btncnt = 0;btncnt < m_itemList->get_list().size();btncnt ++) { - connect(m_itemList->get_item(btncnt)->get_swbtn(),SIGNAL(status(int,int)),this,SLOT(on_switch_button(int,int))); - } - connect(m_cSyncDelay,&QTimer::timeout,[=] () { - emit doman(); - m_cSyncDelay->stop(); + connect(m_listTimer,&QTimer::timeout,this,[this] () { + if (m_bIsOnline == false) { + m_listTimer->stop(); + showDesktopNotify(tr("Network can not reach!")); + return ; + } + emit doselect(m_syncDialog->m_List); + m_listTimer->stop(); }); - //All.conf的 - QString all_conf_path = QDir::homePath() + "/.cache/kylinssoclient/"; - m_fsWatcher.addPath(all_conf_path); + connect(m_checkTimer, &QTimer::timeout, this, [this] () { + if (m_bIsKylinId) { + emit kylinIdCheck(); + } else { + emit docheck(); + } + m_checkTimer->stop(); + }); - connect(&m_fsWatcher,&QFileSystemWatcher::directoryChanged,[this] () { - QFile conf(QDir::homePath()+ "/.cache/kylinssoclient/All.conf"); - if(conf.exists() == true) { - handle_conf(); + connect(m_manTimer, &QTimer::timeout, this, [this] () { + if (m_bIsOnline == false) { + m_manTimer->stop(); + showDesktopNotify(tr("Network can not reach!")); + return ; } + emit doman(); + m_manTimer->stop(); }); + connect(m_stackedWidget, &QStackedWidget::currentChanged,this, [this] (int index) { + Q_UNUSED(index); + if (m_stackedWidget->currentWidget() == m_itemList) { + setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); + } else { + setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); + } + }); - connect(m_autoSyn->get_swbtn(),&SwitchButton::status,[=] (int on,int id) { - if(on == 1) { + connect(m_autoSyn->get_swbtn(),&SwitchButton::checkedChanged, this, [=] (bool checked) { + if (checked == true && m_pSettings != nullptr) { m_stackedWidget->setCurrentWidget(m_itemList); m_keyInfoList.clear(); - m_infoText->setText(tr("Synchronize your computer's settings into your cloud account here.")); __once__ = false; m_autoSyn->set_change(0,"0"); - for(int i = 0;i < m_szItemlist.size();i ++) { - if(m_itemList->get_item(i)->get_swbtn()->get_swichbutton_val() == 1) { + for (int i = 0;i < m_szItemlist.size();i ++) { + if (m_itemList->get_item(i)->get_swbtn()->getDisabledFlag() == true) { m_itemList->get_item(i)->set_change(0,"0"); } } - - m_cRetry->start(1000); - + QFile file( m_szConfPath); + if (file.exists() == false) { + if (m_bIsOnline == false) { + showDesktopNotify(tr("Network can not reach!")); + return ; + } + emit dooss(m_szUuid); + return ; + } else { + if (m_bIsOnline == false) { + showDesktopNotify(tr("Network can not reach!")); + return ; + } + emit doquerry(m_szCode); + } } else { m_stackedWidget->setCurrentWidget(m_nullwidgetContainer); } }); - // + connect(m_cLoginTimer,&QTimer::timeout,this,[this]() { + if (m_mainDialog == nullptr) { + return ; + } + + if (m_mainWidget->currentWidget() == m_widgetContainer) { + m_cLoginTimer->stop(); + return ; + } else if (m_mainWidget->currentWidget() == m_nullWidget) { + m_mainDialog->setnormal(); + //on_login_out(); + } + m_cLoginTimer->stop(); + }); + +} + +/* 初始化GUI */ +void MainWidget::init_gui() { + //m_mainWidget->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + m_exitCode->setFixedHeight(24); + + m_mainWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint); + + m_login_btn->setFixedSize(180,36); + m_welcomeMsg->setText(tr("Synchronize your personalized settings and data")); + + m_welcomeMsg->setStyleSheet("font-size:18px;"); + + m_exitCloud_btn->setStyleSheet("QPushButton[on=true]{background-color:#3790FA;border-radius:4px;}"); + m_exitCloud_btn->setProperty("on",false); + + m_exitCloud_btn->setFixedSize(120,36); + + m_exitCode->setStyleSheet("QLabel{color:#F53547}"); + + m_blueEffect_sync->settext(tr("Sync")); + + //控件初始化设置 + m_infoTabWidget->setFocusPolicy(Qt::NoFocus); + m_title->setText(tr("Sync your settings")); + m_title->setStyleSheet("font-size:18px;font-weight:500;"); + + + m_infoTab->setText(tr("Your account:%1").arg(m_szCode)); + m_autoSyn->set_itemname(tr("Auto sync")); + m_autoSyn->make_itemon(); + m_widgetContainer->setFocusPolicy(Qt::NoFocus); + m_mainWidget->addWidget(m_widgetContainer); + + //控件大小尺寸设置 + setContentsMargins(0,0,32,0); + setMinimumWidth(550); + m_infoTabWidget->resize(200,72); + m_stackedWidget->adjustSize(); + m_autoSyn->get_widget()->setFixedHeight(50); + m_infoTab->setFixedHeight(40); + + + m_infoWidget->setFixedHeight(36); + m_mainWidget->setMinimumWidth(550); + m_widgetContainer->setMinimumWidth(550); + m_welcomeImage->setFixedSize(96,96); + + m_key = ""; + m_exitCode->setText(" "); + + m_exitCloud_btn->setFocusPolicy(Qt::NoFocus); + + if (m_mainWidget->currentWidget() == m_nullWidget) { + setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored); + } else { + setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); + } + int cItem = 0; + + + for (const QString &key : qAsConst(m_szItemlist)) { + m_itemMap.insert(key,m_itemList->get_item(cItem)->get_itemname()); + cItem ++; + } + setMaximumWidth(960); m_welcomeMsg->adjustSize(); m_itemList->adjustSize(); @@ -452,74 +882,121 @@ /* 打开登录框处理事件 */ void MainWidget::on_login() { - m_editDialog->m_bIsUsed = false; - m_mainDialog->is_used = true; - m_mainDialog->set_clear(); - //qDebug()<<"login"; - m_mainDialog->show(); + m_isOpenDialog = true; + if (m_bIsKylinId) { + QDBusMessage message = QDBusMessage::createMethodCall("org.kylinID.service","/org/kylinID/path", + "org.kylinID.interface", + "openKylinID"); + QDBusMessage response = QDBusConnection::sessionBus().call(message); + + if (response.type() == QDBusMessage::ReplyMessage) { + QVariant var = response.arguments().takeFirst(); + if (var.toInt() != 0) { + showDesktopNotify(tr("KylinID open error!")); + } + } + } else { + m_mainDialog = new MainDialog; + m_mainDialog->setAttribute(Qt::WA_DeleteOnClose); + //m_editDialog->m_bIsUsed = false; + m_mainDialog->set_client(m_dbusClient); + m_mainDialog->is_used = true; + m_mainDialog->set_clear(); + m_exitCode->setText(" "); + + connect(m_mainDialog,SIGNAL(on_login_success()),this,SLOT(open_cloud())); + connect(m_mainDialog, &MainDialog::on_submit_clicked, this, [=] (){ + m_bIsStopped = false; + bIsLogging = true; + m_cLoginTimer->setSingleShot(true); + m_cLoginTimer->setInterval(10000); + m_cLoginTimer->start(); + }); + connect(m_mainDialog,&MainDialog::on_login_failed,this, [this] () { + m_cLoginTimer->stop(); + m_bIsStopped = true; + bIsLogging = false; + }); + m_mainDialog->show(); + } } /* 登录过程处理事件 */ void MainWidget::open_cloud() { + if (m_bIsOnline == false) { + showDesktopNotify(tr("Network can not reach!")); + return ; + } + m_checkTimer->setSingleShot(true); + m_checkTimer->setInterval(500); + m_checkTimer->start(); + m_mainDialog->on_close(); + m_mainDialog = nullptr; + bIsLogging = false; + emit isSync(true); + m_mainWidget->setCurrentWidget(m_widgetContainer); emit dooss(m_szUuid); //m_mainDialog->on_close(); } -bool MainWidget::eventFilter(QObject *watched, QEvent *event) { - if(watched == m_openEditDialog_btn) { - if(event->type() == QEvent::Enter) { - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/edit_hover.svg"); - m_openEditDialog_btn->setIcon(pixmap); - } - if(event->type() == QEvent::Leave) { - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/edit.svg"); - m_openEditDialog_btn->setIcon(pixmap); - } - } - if(watched == m_exitCloud_btn) { - if(event->type() == QEvent::Enter && m_syncTooltips->isHidden() == true && m_exitCloud_btn->property("on") == true) { - QPoint pos; - pos.setX(m_exitCloud_btn->mapToGlobal(QPoint(0, 0)).x() + 26); - pos.setY(m_exitCloud_btn->mapToGlobal(QPoint(0, 0)).y() + 26); - m_syncTooltips->move(pos); - m_syncTooltips->show(); - } - if((event->type() == QEvent::Leave && m_syncTooltips->isHidden() == false) || m_exitCloud_btn->property("on") == false) { - m_syncTooltips->hide(); - } + +void MainWidget::finished_conf(int ret) { + if (m_bIsOnline == false) { + showDesktopNotify(tr("Network can not reach!")); + return ; + } + if (ret == 0) { + m_bTokenValid = true; + emit doquerry(m_szCode); } - return QWidget::eventFilter(watched,event); } /* 登录成功处理事件 */ -void MainWidget::finished_load(int ret,QString uuid) { - //qDebug()<<"wb111"<m_szUuid; - if(uuid != this->m_szUuid) { + if (ret == 301) { + if (m_mainWidget->currentWidget() != m_nullWidget) { + showDesktopNotify(tr("Unauthorized device or OSS falied.\nPlease retry or relogin!")); + // m_exitCode->setText(tr("Please check your connection!")); + return ; + } + } + if (ret == 401 || ret == 201) { + if (m_mainWidget->currentWidget() != m_nullWidget) { + m_exitCode->setText(tr("Authorization failed!")); + on_login_out(); + return ; + } + } + if (uuid != this->m_szUuid) { return ; } - //qDebug()<<"wb222"<set_change(0,"0"); + for (int i = 0;i < m_szItemlist.size();i ++) { + m_itemList->get_item(i)->set_change(0,"0"); + } emit doconf(); - } else if(ret == 401 || ret == 203 || ret == 201) { - emit dologout(); } } /* 读取滑动按钮列表 */ void MainWidget::handle_conf() { - if(__once__ ) { + if (__once__ || m_pSettings == nullptr) { return ; } - - if(ConfigFile(m_szConfPath).Get("Auto-sync","enable").toString() == "true") { + if (m_pSettings != nullptr && m_pSettings->value("Auto-sync/enable").toString() == "true") { m_stackedWidget->setCurrentWidget(m_itemList); m_autoSyn->make_itemon(); - for(int i = 0;i < m_szItemlist.size();i ++) { + m_autoSyn->set_active(true); + for (int i = 0;i < m_szItemlist.size();i ++) { + m_itemList->get_item(i)->make_itemon(); m_itemList->get_item(i)->set_active(true); } m_bAutoSyn = true; @@ -527,22 +1004,22 @@ m_stackedWidget->setCurrentWidget(m_nullwidgetContainer); m_autoSyn->make_itemoff(); m_bAutoSyn = false; - for(int i = 0;i < m_szItemlist.size();i ++) { - judge_item(ConfigFile(m_szConfPath).Get(m_szItemlist[i],"enable").toString(),i); + for (int i = 0;i < m_szItemlist.size();i ++) { + judge_item( ConfigFile(m_szConfPath).Get(m_szItemlist.at(i),"enable").toString(),i); } - for(int i = 0;i < m_szItemlist.size();i ++) { + for (int i = 0;i < m_szItemlist.size();i ++) { m_itemList->get_item(i)->set_active(m_bAutoSyn); } return ; } - for(int i = 0;i < m_szItemlist.size();i ++) { - judge_item(ConfigFile(m_szConfPath).Get(m_szItemlist[i],"enable").toString(),i); + for (int i = 0;i < m_szItemlist.size();i ++) { + judge_item( ConfigFile(m_szConfPath).Get(m_szItemlist.at(i),"enable").toString(),i); } } /* 判断功能是否开启 */ -bool MainWidget::judge_item(QString enable,int cur) { - if(enable == "true") { +bool MainWidget::judge_item(const QString &enable,const int &cur) const { + if (enable == "true") { m_itemList->get_item(cur)->make_itemon(); } else { m_itemList->get_item(cur)->make_itemoff(); @@ -550,76 +1027,49 @@ return true; } -/* 滑动按钮点击后改变功能状态 */ -void MainWidget::handle_write(int on, int id) { - char name[32]; - if(id == -1) { - qstrcpy(name,"Auto-sync"); - } else { - qstrcpy(name,m_szItemlist[id].toStdString().c_str()); - } - emit dochange(name,on); -} -/* 滑动按钮点击处理事件 */ -void MainWidget::on_switch_button(int on,int id) { - if(m_mainWidget->currentWidget() == m_nullWidget) { - return ; +/* 自动同步滑动按钮点击后改变功能状态 */ +void MainWidget::on_auto_syn(bool checked) { + if (m_bIsOldBackEnds) { + isNetWorkOnline(); } - if(!m_bAutoSyn) { + if (m_mainWidget->currentWidget() == m_nullWidget) { return ; } //emit docheck(); - handle_write(on,id); -} + //m_bAutoSyn = on; + for (int i = 0;i < m_szItemlist.size();i ++) { + m_itemList->get_item(i)->set_active(m_bAutoSyn); + } -/* 自动同步滑动按钮点击后改变功能状态 */ -void MainWidget::on_auto_syn(int on,int id) { - if(m_mainWidget->currentWidget() == m_nullWidget) { + if (m_bIsOnline == false) { + showDesktopNotify(tr("Network can not reach!")); return ; } - //emit docheck(); - m_bAutoSyn = on; - for(int i = 0;i < m_szItemlist.size();i ++) { - m_itemList->get_item(i)->set_active(m_bAutoSyn); - } - handle_write(on,-1); + emit dochange("Auto-sync",checked); } /* 登出处理事件 */ void MainWidget::on_login_out() { - m_bTokenValid = false; - m_dbusClient->m_bFirstAttempt = true; - //qDebug()<< "wb777"; - emit dologout(); - if(m_editDialog->isVisible() == true) { - m_editDialog->close(); - } - //qDebug()<<"1213131"; - m_szCode = ""; - m_mainDialog->set_clear(); - m_editDialog->set_clear(); - m_autoSyn->set_change(0,"0"); - m_autoSyn->set_active(true); - m_keyInfoList.clear(); - m_infoText->setText(tr("Synchronize your computer's settings into your cloud account here.")); - m_mainWidget->setCurrentWidget(m_nullWidget); - __once__ = false; - __run__ = false; - m_bIsStopped = false; -} -/* 修改密码打开处理事件 */ -void MainWidget::neweditdialog() { - //emit docheck(); - m_editDialog->m_bIsUsed = true; - m_mainDialog->is_used = false; - m_editDialog->set_clear(); - m_editDialog->m_szCode = m_szCode; - m_editDialog->show(); - m_editDialog->raise(); + if (m_exitCloud_btn->property("on") == false) { + if (m_bIsKylinId) { + emit kylinIdLogOut(); + } else { + emit dologout(); + } + m_bTokenValid = false; + + } else { + emit dosend("exit"); + QProcess proc; + proc.startDetached("killall kylin-sso-client"); + push_over(); + } + } + /* 动态布局显示处理函数 */ void MainWidget::setshow(QWidget *widget) { widget->hide(); @@ -639,26 +1089,28 @@ /* 同步回调函数集 */ void MainWidget::download_files() { - if(__once__ == true) { + if (__once__ == true || m_pSettings == nullptr) { return ; } - if(m_mainWidget->currentWidget() == m_nullWidget) { + if (m_mainWidget->currentWidget() == m_nullWidget) { return ; } //emit docheck(); - if(m_exitCloud_btn->property("on") == false) { + if (m_exitCloud_btn->property("on") == false) { m_exitCloud_btn->setProperty("on",true); m_exitCloud_btn->style()->unpolish(m_exitCloud_btn); m_exitCloud_btn->style()->polish(m_exitCloud_btn); m_exitCloud_btn->update(); m_exitCloud_btn->setText(""); + m_exitCloud_btn->setToolTip(tr("Stop sync")); m_blueEffect_sync->startmoive(); + emit isSync(true); + //showDesktopNotify("同步开始"); } + m_syncTimeLabel->setText(tr("The latest time sync is: ") + ConfigFile(m_szConfPath).Get("Auto-sync","time").toString().toStdString().c_str()); - m_infoText->setText(tr("Sync downloading,please wait!")); - - if(m_autoSyn->get_swbtn()->get_swichbutton_val() == 0) { + if (m_autoSyn->get_swbtn()->getDisabledFlag() == true) { return ; } m_autoSyn->set_change(1,"0"); @@ -667,26 +1119,28 @@ void MainWidget::push_files() { - if(__once__ == true) { + if (__once__ == true) { return ; } - if(m_mainWidget->currentWidget() == m_nullWidget) { + if (m_mainWidget->currentWidget() == m_nullWidget) { return ; } // emit docheck(); - if(m_exitCloud_btn->property("on") == false) { + if (m_exitCloud_btn->property("on") == false) { m_exitCloud_btn->setText(""); m_exitCloud_btn->setProperty("on",true); m_exitCloud_btn->style()->unpolish(m_exitCloud_btn); m_exitCloud_btn->style()->polish(m_exitCloud_btn); m_exitCloud_btn->update(); + m_exitCloud_btn->setToolTip(tr("Stop sync")); m_blueEffect_sync->startmoive(); + emit isSync(true); + // showDesktopNotify("同步开始"); } + m_syncTimeLabel->setText(tr("The latest time sync is: ") + ConfigFile(m_szConfPath).Get("Auto-sync","time").toString().toStdString().c_str()); - m_infoText->setText(tr("Sync uploading,please wait!")); - - if(m_autoSyn->get_swbtn()->get_swichbutton_val() == 0) { + if (m_autoSyn->get_swbtn()->getDisabledFlag() == true) { return ; } m_autoSyn->set_change(1,"0"); @@ -695,80 +1149,82 @@ void MainWidget::download_over() { //emit docheck(); + if (m_pSettings == nullptr) return; - if(m_exitCloud_btn->property("on") == true) { + if (m_exitCloud_btn->property("on") == true) { m_blueEffect_sync->stop(); m_exitCloud_btn->setText(tr("Exit")); m_exitCloud_btn->setProperty("on",false); m_exitCloud_btn->style()->unpolish(m_exitCloud_btn); m_exitCloud_btn->style()->polish(m_exitCloud_btn); + m_exitCloud_btn->setToolTip(""); m_exitCloud_btn->update(); + m_bAutoSyn = true; + emit isSync(false); + //showDesktopNotify("同步结束"); } - if(__once__ == false) { - m_infoText->setText(tr("Synchronize your computer's settings into your cloud account here.")); + m_syncTimeLabel->setText(tr("The latest time sync is: ") + ConfigFile(m_szConfPath).Get("Auto-sync","time").toString().toStdString().c_str()); + if (__once__ == false) { + m_autoSyn->set_change(0,"0"); } - else { - m_infoText->setText(tr("Sync failed, please check your internet connection or login out to retry!")); - } + } void MainWidget::push_over() { //emit docheck(); - if(m_exitCloud_btn->property("on") == true) { + if (m_pSettings == nullptr) return; + if (m_exitCloud_btn->property("on") == true) { m_blueEffect_sync->stop(); m_exitCloud_btn->setText(tr("Exit")); m_exitCloud_btn->setProperty("on",false); m_exitCloud_btn->style()->unpolish(m_exitCloud_btn); m_exitCloud_btn->style()->polish(m_exitCloud_btn); + m_exitCloud_btn->setToolTip(""); m_exitCloud_btn->update(); + m_bAutoSyn = true; + emit isSync(false); + //showDesktopNotify("同步结束"); } - if(__once__ == false) { - m_infoText->setText(tr("Synchronize your computer's settings into your cloud account here.")); + m_syncTimeLabel->setText(tr("The latest time sync is: ") + ConfigFile(m_szConfPath).Get("Auto-sync","time").toString().toStdString().c_str()); + if (__once__ == false) { m_autoSyn->set_change(0,"0"); } - else { - m_infoText->setText(tr("Sync failed, please check your internet connection or login out to retry!")); - } - } void MainWidget::get_key_info(QString info) { - - if(m_mainWidget->currentWidget() == m_nullWidget) { + qDebug() << info; + if (m_mainWidget->currentWidget() == m_nullWidget) { return ; } - if(info == "Upload") { + if (info.contains("Upload")) { return ; } - if(info == "Download") { + if (info == "Download") { return ; } bool bIsFailed = false; - //qDebug()<<"networkaccount:"+info; - if(info.contains(",")) { + if (info.contains(",")) { m_keyInfoList = info.split(','); } else { m_keyInfoList << info; } - if(m_keyInfoList.size() == 1) { + if (m_keyInfoList.size() == 1 && m_szItemlist.contains(m_keyInfoList[0]) ) { m_autoSyn->set_change(-1,m_keyInfoList[0]); m_autoSyn->make_itemoff(); - for(int i = 0;i < m_szItemlist.size();i ++) { - m_itemList->get_item(i)->set_active(false); - } - handle_write(0,-1); + emit dochange("Auto-sync",false); + m_stackedWidget->setCurrentWidget(m_nullwidgetContainer); __once__ = true; return ; - } else if(m_keyInfoList.size() > 1){ + } else if (m_keyInfoList.size() > 1){ bIsFailed = true; } else { m_autoSyn->set_change(0,"0"); - for(int i = 0;i < m_szItemlist.size();i ++) { - if(m_itemList->get_item(i)->get_swbtn()->get_swichbutton_val() == 1) { + for (int i = 0;i < m_szItemlist.size();i ++) { + if (m_itemList->get_item(i)->get_swbtn()->getDisabledFlag() == false) { m_itemList->get_item(i)->set_change(0,"0"); } } @@ -777,43 +1233,65 @@ //m_keyInfoList.size() > 1的情况 //说明size大于2 - if(bIsFailed) { + if (bIsFailed) { QString keys = ""; - for(QString key : m_keyInfoList) { - if(key != m_keyInfoList.last()) { + for (QString key : m_keyInfoList) { + if (key != m_keyInfoList.last()) { - if(m_itemMap.value(key).isEmpty() == false) - { + if (m_itemMap.value(key).isEmpty() == false) { m_itemList->get_item_by_name(m_itemMap.value(key))->set_change(-1,"Failed!"); keys.append(tr("%1,").arg(m_itemMap.value(key))); } } } - m_infoText->setText(tr("Synchronized failed: %1 please retry or login out to get a better experience.").arg(keys)); - m_infoText->adjustSize(); m_autoSyn->make_itemoff(); - for(int i = 0;i < m_szItemlist.size();i ++) { + for (int i = 0;i < m_szItemlist.size();i ++) { m_itemList->get_item(i)->set_active(false); } m_autoSyn->set_change(-1,"Failed!"); - handle_write(0,-1); + emit dochange("Auto-sync",false); __once__ = true; } m_keyInfoList.clear(); } +void MainWidget::showDesktopNotify(const QString &message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(tr("Kylin Cloud Account")) + <<((unsigned int) 0) + <setCurrentWidget(m_widgetContainer); + emit kylinIdCheck(); + emit dooss(m_szUuid); + } +} + + /* 析构函数 */ MainWidget::~MainWidget() { + + m_fsWatcher.removePath(QDir::homePath() + "/.cache/kylinId/"); delete m_itemList; - delete m_mainDialog; - delete m_editDialog; - delete m_dbusClient; + m_itemList = nullptr; delete m_welcomeImage; - if(thread) - { - thread->quit(); - } - thread->wait(); + m_welcomeImage = nullptr; } - - diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/mainwidget.h ukui-control-center-3.0.3/plugins/account/networkaccount/mainwidget.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/mainwidget.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/mainwidget.h 2021-04-14 01:27:20.000000000 +0000 @@ -28,20 +28,20 @@ #include "frameitem.h" #include #include -#include "editpushbutton.h" #include "maindialog.h" #include -#include "editpassdialog.h" -#include "configfile.h" +#include "syncdialog.h" +#include #include #include -#include "dbushandleclient.h" +#include "dbusutils.h" #include -#include "tooltips.h" #include +#include "configfile.h" #include "svghandler.h" #include "blueeffect.h" + class MainWidget : public QWidget { Q_OBJECT @@ -53,27 +53,36 @@ QWidget* get_login_dialog(); void setshow(QWidget *w); void init_gui(); + void initMemoryAlloc(); + void initSignalSlots(); + void layoutUI(); + void dbusInterface(); void handle_conf(); - bool judge_item(QString enable,int cur); - void handle_write(int on,int id); + bool judge_item(const QString &enable,const int &cur) const; + void showDesktopNotify(const QString &message); + void isNetWorkOnline(); protected: - bool eventFilter(QObject *watched, QEvent *event); private: ItemList *m_itemList; FrameItem *m_autoSyn; QLabel *m_title; QLabel *m_infoTab; + QLabel *m_exitCode; Blueeffect *m_blueEffect_sync; QPushButton *m_exitCloud_btn; QWidget *m_widgetContainer; QWidget *m_infoTabWidget; QVBoxLayout *m_vboxLayout; - QPushButton *m_openEditDialog_btn; - EditPassDialog *m_editDialog; QStackedWidget *m_mainWidget; QWidget *m_nullWidget; - DbusHandleClient *m_dbusClient; + DBusUtils *m_dbusClient; + QString m_confName; QPushButton *m_login_btn; + QTimer *m_lazyTimer; + QTimer *m_listTimer; + QTimer *m_singleTimer; + QTimer *m_manTimer; + QTimer *m_checkTimer; QLabel *m_welcomeMsg; QSvgWidget *m_welcomeImage; QVBoxLayout *m_welcomeLayout; @@ -82,57 +91,74 @@ QWidget *m_nullwidgetContainer; QString m_szCode = tr("Disconnected"); QString m_szConfPath; - QStringList m_szItemlist = {"wallpaper","ukui-screensaver","ukui-menu","ukui-panel","ukui-panel2","indicator-china-weather","kylin-video"}; + QStringList m_szItemlist = {"wallpaper","ukui-screensaver","font","avatar","ukui-menu","ukui-panel","ukui-panel2", + "themes","mouse","touchpad","keyboard","shortcut","area","datetime","default-open", + "notice","option","peony","boot","power","editor","terminal", + "indicator-china-weather","kylin-video"}; MainDialog* m_mainDialog; QWidget *m_infoWidget; QHBoxLayout *m_infoLayout; QThread *thread; bool m_bAutoSyn = true; bool m_bTokenValid = false; + bool m_isOpenDialog = false; QTimer *m_cLoginTimer; - QTimer *m_cSyncDelay; QString m_szUuid; - QTimer *m_cRetry; QFileSystemWatcher m_fsWatcher; SVGHandler *m_svgHandler; - Tooltips *m_syncTooltips; - QLabel *m_syncTipsText; QHBoxLayout *m_animateLayout; - QHBoxLayout *m_tipsLayout; QMap m_itemMap; + QString m_key; QStringList m_keyInfoList; - QLabel *m_infoText; bool __once__ = false; bool __run__ = false; bool m_bIsStopped = false; + QLabel *m_syncTimeLabel; + int m_indexChanged; + bool m_statusChanged; + SyncDialog *m_syncDialog; + bool bIsLogging = false; + QSettings *m_pSettings; + bool m_bIsKylinId = false; + bool m_bIsOnline = true; + bool m_bIsOldBackEnds = false; public slots: - void neweditdialog(); void on_login_out(); void on_login(); void open_cloud(); void finished_load(int ret,QString m_szUuid); - void on_switch_button(int on,int id); - void on_auto_syn(int on,int id); + void finished_conf(int ret); + void on_auto_syn(bool checked); void download_files(); void push_files(); void download_over(); void push_over(); - void setret_oss(int ret); - void setret_conf(int ret); - void setret_change(int ret); - void setret_logout(int ret); - void setret_man(int ret); - void setname(QString n); - void setret_check(QString ret); void get_key_info(QString info); + void checkUserName(QString name); + void finishedLogout(int ret); + void loginSuccess(int ret); + void checkNetWork(QVariantMap map); + void checkNetStatus(bool status); signals: - void dooss(QString m_szUuid); + void dooss(const QString &m_szUuid); void doman(); void dologout(); void doconf(); - void dochange(QString name,int flag); + void dochange(const QString &name,bool checked); void docheck(); + void dosingle(const QString &key); + void doselect(QStringList keyList); + void isRunning(); + void oldVersion(); + void doquerry(const QString &name); + void dosend(const QString &info); + + void kylinIdLogOut(); + void kylinIdCheck(); + + void isSync(bool checked); + void isOnline(bool checked); }; #endif // CONFIG_LIST_WIDGET_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/mcodewidget.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/mcodewidget.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/mcodewidget.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/mcodewidget.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -40,7 +40,7 @@ /* 该函数实现了鼠标点击后验证码更新的操作 ,用ok变量控制以防止界面刷新就更新 */ void MCodeWidget::mousePressEvent(QMouseEvent *ev) { - if(ev->button() == Qt::LeftButton) + if (ev->button() == Qt::LeftButton) { m_bIsOk = true; reflushVerification(); @@ -59,7 +59,7 @@ QPainter painter(this); QPoint p; painter.fillRect(this->rect(), Qt::white); - if(m_bIsOk) { + if (m_bIsOk) { produceVerificationCode(); produceRandomColor(); m_bIsOk = false; @@ -79,8 +79,8 @@ int charSpace = (charWidth - this->fontMetrics().width("W"))/2; charSpace += 14/2; painter.translate(i*charWidth+charSpace,0); - if(qrand()%2) { - if(qrand()%2) + if (qrand()%2) { + if (qrand()%2) { painter.rotate(qrand()% 20); } @@ -94,11 +94,11 @@ } else { double xShear = qrand()%4/10.0; double yShear = qrand()%4/10.0; - if(qrand()%2) + if (qrand()%2) { xShear = -xShear; } - if(qrand()%2) + if (qrand()%2) { yShear = -yShear; } @@ -137,8 +137,8 @@ } /* 控制字母是否能改变,用于外部控制 */ -void MCodeWidget::set_change(int ok_num) { - if(ok_num == 0) { +void MCodeWidget::set_change(const int &ok_num) { + if (ok_num == 0) { m_bIsOk = false; }else { m_bIsOk = true; @@ -147,7 +147,9 @@ MCodeWidget::~MCodeWidget(){ delete[] m_colorArray; + m_colorArray = nullptr; delete[] m_verificationCode; + m_verificationCode = nullptr; } /* 刷新验证码 ,实际上是重绘 */ diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/mcodewidget.h ukui-control-center-3.0.3/plugins/account/networkaccount/mcodewidget.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/mcodewidget.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/mcodewidget.h 2021-04-14 01:27:20.000000000 +0000 @@ -34,7 +34,7 @@ MCodeWidget(QWidget *parent = 0); ~MCodeWidget(); QChar *get_verificate_code(); - void set_change(int bIsOk); + void set_change(const int &bIsOk); protected: void mousePressEvent(QMouseEvent *ev); void paintEvent(QPaintEvent *event); diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/networkaccount.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/networkaccount.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/networkaccount.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/networkaccount.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -19,29 +19,35 @@ */ #include "networkaccount.h" -networkaccount::networkaccount() +networkaccount::networkaccount() : mFirstLoad(true) { - pluginWidget = new MainWidget(); - pluginName = tr("NetworkAccount"); + //~ contents_path /networkaccount/Cloud Account + pluginName = tr("Cloud Account"); pluginType = ACCOUNT; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); } - -QString networkaccount::get_plugin_name(){ +QString networkaccount::get_plugin_name() { return pluginName; } -int networkaccount::get_plugin_type(){ +int networkaccount::get_plugin_type() { return pluginType; } -QWidget * networkaccount::get_plugin_ui(){ +QWidget * networkaccount::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + pluginWidget = new MainWidget(); + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + } return pluginWidget; } -void networkaccount::plugin_delay_control(){ +void networkaccount::plugin_delay_control() { } +const QString networkaccount::name() const { + return QStringLiteral("networkaccount"); +} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/networkaccount.h ukui-control-center-3.0.3/plugins/account/networkaccount/networkaccount.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/networkaccount.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/networkaccount.h 2021-04-14 01:27:20.000000000 +0000 @@ -41,15 +41,16 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: void initComponent(); private: - // Ui::networkaccount *ui; QString pluginName; int pluginType; QWidget * pluginWidget; + bool mFirstLoad; }; #endif // NETWORKACCOUNT_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/networkaccount.pro ukui-control-center-3.0.3/plugins/account/networkaccount/networkaccount.pro --- ukui-control-center-2.0.3/plugins/account/networkaccount/networkaccount.pro 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/networkaccount.pro 2021-04-14 01:27:20.000000000 +0000 @@ -5,12 +5,17 @@ include(../../../env.pri) TEMPLATE = lib -CONFIG += c++11 plugin +CONFIG += c++11 plugin link_pkgconfig +PKGCONFIG += gsettings-qt TARGET = $$qtLibraryTarget(networkaccount) DESTDIR = ../.. target.path = $${PLUGIN_INSTALL_DIRS} +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) +include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) + INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ # The following define makes your compiler emit warnings if you use @@ -25,60 +30,38 @@ #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ - areacodelineedit.cpp \ - bindphonedialog.cpp \ blueeffect.cpp \ - boxitem.cpp \ - combobox.cpp \ configfile.cpp \ - dbushandleclient.cpp \ - editpassdialog.cpp \ - editpushbutton.cpp \ + dbusutils.cpp \ frameitem.cpp \ - infolabel.cpp \ itemlist.cpp \ logindialog.cpp \ maindialog.cpp \ mainwidget.cpp \ mcodewidget.cpp \ networkaccount.cpp \ - passdialog.cpp \ passwordlineedit.cpp \ - popupwidget.cpp \ - regdialog.cpp \ - successdiaolog.cpp \ svghandler.cpp \ - switchbutton.cpp \ + syncdialog.cpp \ tips.cpp \ - tooltips.cpp + visblebutton.cpp HEADERS += \ - areacodelineedit.h \ - bindphonedialog.h \ blueeffect.h \ - boxitem.h \ - combobox.h \ configfile.h \ - dbushandleclient.h \ - editpassdialog.h \ - editpushbutton.h \ + dbusutils.h \ frameitem.h \ - infolabel.h \ itemlist.h \ logindialog.h \ maindialog.h \ mainwidget.h \ mcodewidget.h \ networkaccount.h \ - passdialog.h \ passwordlineedit.h \ - popupwidget.h \ - regdialog.h \ - successdiaolog.h \ svghandler.h \ - switchbutton.h \ + syncdialog.h \ tips.h \ - tooltips.h + visblebutton.h FORMS += \ diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/passdialog.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/passdialog.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/passdialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/passdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,197 +0,0 @@ -/* -*- 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 "passdialog.h" - -PassDialog::PassDialog(QWidget *parent) : QWidget(parent) -{ - m_phoneLineEdit = new QLineEdit(this); - m_passLineEdit = new PasswordLineEdit(this); - m_confirmLineEdit = new PasswordLineEdit(this); - m_mcodeLineEdit = new QLineEdit(this); - m_sendMsgBtn = new QPushButton(tr("Get the phone binding code"),this); - m_passwordTips = new QLabel(this); - - m_workLayout = new QVBoxLayout; - m_hboxLayout = new QHBoxLayout; - m_errorTips = new Tips(this); - m_svgHandler = new SVGHandler(this); - QString str = ("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3D6BE5;font-size: 14px;color: rgba(0,0,0,0.85);lineedit-password-character: 42;}" - "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}" - "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}"); - m_phoneLineEdit->setFixedSize(QSize(338,36)); - m_passLineEdit->setFixedSize(QSize(338,36)); - m_confirmLineEdit->setFixedSize(QSize(338,36)); - m_mcodeLineEdit->setFixedSize(QSize(120,34)); - m_sendMsgBtn->setFixedSize(QSize(198,34)); - m_phoneLineEdit->setFocusPolicy(Qt::StrongFocus); - m_phoneLineEdit->setFocus(); - - - m_phoneLineEdit->setPlaceholderText(tr("Your account here")); - m_passLineEdit->setPlaceholderText(tr("Your new password here")); - m_passLineEdit->setEchoMode(QLineEdit::Password); - m_confirmLineEdit->setPlaceholderText(tr("Confirm your new password")); - m_confirmLineEdit->setEchoMode(QLineEdit::Password); - m_mcodeLineEdit->setPlaceholderText(tr("Your code here")); - m_mcodeLineEdit->setMaxLength(4); - - m_phoneLineEdit->setTextMargins(12,0,0,0); - m_passLineEdit->setTextMargins(12,0,0,0); - m_confirmLineEdit->setTextMargins(12,0,0,0); - m_mcodeLineEdit->setTextMargins(12,0,0,0); - m_passwordTips->setFixedHeight(16); - - //valid_code->setStyleSheet(str); - QRegExp regx("[0-9]+$"); - QValidator *validator = new QRegExpValidator(regx, m_mcodeLineEdit ); - m_mcodeLineEdit->setValidator( validator ); - - QRegExp regx_acc("^[a-zA-Z0-9_@.-]+$"); - QValidator *validator_acc = new QRegExpValidator(regx_acc, m_phoneLineEdit ); - m_phoneLineEdit->setValidator(validator_acc); - -// QRegExp regx_pas("^[a-zA-Z0-9_-]{4,16}$"); -// QValidator *validator_pas = new QRegExpValidator(regx_pas, reg_pass ); -// reg_phone->setValidator(validator_acc); - - m_passwordTips->setText(tr("At least 6 bit, include letters and digt")); - m_passwordTips->setStyleSheet("font-size:14px;"); - //reg_pass->setStyleSheet(str); - //reg_phone->setStyleSheet(str); - //reg_pass_confirm->setStyleSheet(str); - //send_msg_btn->setStyleSheet("QPushButton{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(0,0,0,0.85);} " - // "QPushButton:hover{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(61,107,229,0.85);}" - // "QPushButton:click{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(61,107,229,0.85);}"); - - m_workLayout->setMargin(0); - m_workLayout->setSpacing(8); - m_workLayout->addWidget(m_phoneLineEdit); - m_workLayout->addWidget(m_passLineEdit); - m_workLayout->addWidget(m_passwordTips); - m_passwordTips->setContentsMargins(12,0,0,0); - m_workLayout->addWidget(m_confirmLineEdit); - m_hboxLayout->setMargin(0); - m_hboxLayout->setSpacing(16); - m_hboxLayout->addWidget(m_mcodeLineEdit); - m_hboxLayout->addWidget(m_sendMsgBtn); - m_hboxLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - m_workLayout->addLayout(m_hboxLayout); - m_workLayout->addWidget(m_errorTips); - m_workLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - - m_sendMsgBtn->setFocusPolicy(Qt::NoFocus); - setLayout(m_workLayout); - - adjustSize(); - - m_errorTips->hide(); - m_passwordTips->hide(); - m_passwordTips->setAttribute(Qt::WA_DontShowOnScreen); - connect(m_passLineEdit,&PasswordLineEdit::verify_text,[this] () { - m_passwordTips->setText(tr("Your password is valid!")); - }); - connect(m_passLineEdit,&PasswordLineEdit::false_text,[this] () { - m_passwordTips->setText(tr("At least 6 bit, include letters and digt")); - }); - connect(m_mcodeLineEdit,SIGNAL(textChanged(QString)),this,SLOT(change_uppercase())); - connect(this,SIGNAL(code_changed()),this,SLOT(setstyleline())); -} - -/* 获取错误代码 */ -void PassDialog::set_code(QString codenum) { - m_errorCode = codenum; - emit code_changed(); -} - -/* 设置错误代码更新 */ -void PassDialog::setstyleline() { - m_errorTips->set_text(m_errorCode); -} - -/* 以下均为类接口函数 */ -QLabel* PassDialog::get_passtips() { - return m_passwordTips; -} - -void PassDialog::change_uppercase() { - QString str = m_mcodeLineEdit->text(); - m_mcodeLineEdit->setText(str.toUpper()); -} - -QPushButton* PassDialog::get_send_msg_btn() { - return m_sendMsgBtn; -} - -QString PassDialog::get_user_name() { - return m_phoneLineEdit->text(); -} - -QString PassDialog::get_user_mcode() { - return m_mcodeLineEdit->text(); -} - -QString PassDialog::get_user_confirm() { - return m_confirmLineEdit->text(); -} - -QString PassDialog::get_user_newpass() { - return m_passLineEdit->text(); -} - -PasswordLineEdit* PassDialog::get_reg_pass() { - return m_passLineEdit; -} - -QLineEdit* PassDialog::get_reg_phone() { - return m_phoneLineEdit; -} - -PasswordLineEdit* PassDialog::get_reg_pass_confirm() { - return m_confirmLineEdit; -} - -QLineEdit* PassDialog::get_valid_code() { - return m_mcodeLineEdit; -} - -void PassDialog::set_staus(bool ok) { - m_passLineEdit->setEnabled(ok); - m_confirmLineEdit->setEnabled(ok); - m_phoneLineEdit->setEnabled(ok); - m_mcodeLineEdit->setEnabled(ok); - m_sendMsgBtn->setEnabled(ok); -} - -/* 清空忘记密码框 */ -void PassDialog::set_clear() { - if(!m_errorTips->isHidden()) { - m_errorTips->hide(); - } - m_passLineEdit->get_visble()->setChecked(false); - m_confirmLineEdit->get_visble()->setChecked(false); - m_passLineEdit->setText(""); - m_phoneLineEdit->setText(""); - m_confirmLineEdit->setText(""); - m_mcodeLineEdit->setText(""); -} - -Tips* PassDialog::get_tips() { - return m_errorTips; -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/passdialog.h ukui-control-center-3.0.3/plugins/account/networkaccount/passdialog.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/passdialog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/passdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -/* -*- 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 PASSDIALOG_H -#define PASSDIALOG_H - -#include -#include -#include "areacodelineedit.h" -#include -#include -#include -#include -#include "passwordlineedit.h" -#include "tips.h" -#include "svghandler.h" - -class PassDialog : public QWidget -{ - Q_OBJECT -public: - explicit PassDialog(QWidget *parent = nullptr); - QPushButton* get_send_msg_btn(); - QString get_user_name(); - QString get_user_newpass(); - QString get_user_confirm(); - QString get_user_mcode(); - QLineEdit* get_reg_phone(); - PasswordLineEdit* get_reg_pass(); - PasswordLineEdit* get_reg_pass_confirm(); - QLineEdit* get_valid_code(); - void set_code(QString codenum); - void set_clear(); - Tips* get_tips(); - QLabel* get_passtips(); - void set_staus(bool ok); -public slots: - void change_uppercase(); - void setstyleline(); - -signals: - void code_changed(); -private: - QLineEdit *m_phoneLineEdit; - PasswordLineEdit *m_passLineEdit; - PasswordLineEdit *m_confirmLineEdit; - QLineEdit *m_mcodeLineEdit; - QPushButton *m_sendMsgBtn; - QVBoxLayout *m_workLayout; - QHBoxLayout *m_hboxLayout; - Tips *m_errorTips; - QString m_errorCode; - SVGHandler *m_svgHandler; - QLabel *m_passwordTips; -}; - -#endif // PASSDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/passwordlineedit.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/passwordlineedit.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/passwordlineedit.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/passwordlineedit.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -22,30 +22,27 @@ PasswordLineEdit::PasswordLineEdit(QWidget *parent) : QLineEdit(parent) { setEchoMode(QLineEdit::Password); - m_changeStatusBtn = new QPushButton(this); + m_changeStatusBtn = new VisbleButton(this); m_workLayout = new QHBoxLayout; m_svgHandler = new SVGHandler(this); m_changeStatusBtn->setCursor(Qt::PointingHandCursor); - m_changeStatusBtn->setCheckable(true); - m_changeStatusBtn->setFlat(true); m_changeStatusBtn->setFixedSize(32,32); - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/invisible.svg"); - m_changeStatusBtn->setIcon(pixmap); - connect(m_changeStatusBtn,&QPushButton::toggled,[this] (bool checked) { - if(checked) { + QPixmap pixmap = m_svgHandler->loadSvgColor(":/new/image/invisible.svg","gray",16); + m_changeStatusBtn->setPixmap(pixmap); + connect(m_changeStatusBtn,&VisbleButton::toggled,[this] (bool checked) { + if (checked) { setEchoMode(QLineEdit::Normal); - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/visible.svg"); - m_changeStatusBtn->setIcon(pixmap); + QPixmap pixmap = m_svgHandler->loadSvgColor(":/new/image/visible.svg","gray",16); + m_changeStatusBtn->setPixmap(pixmap); } else { setEchoMode(QLineEdit::Password); - QPixmap pixmap = m_svgHandler->loadSvg(":/new/image/invisible.svg"); - m_changeStatusBtn->setIcon(pixmap); + QPixmap pixmap = m_svgHandler->loadSvgColor(":/new/image/invisible.svg","gray",16); + m_changeStatusBtn->setPixmap(pixmap); } }); //点击后可见或者不可见 - m_changeStatusBtn->setStyleSheet("QPushButton{width: 16px;height: 16px;qproperty-flat: true;" - "margin-right: 8px;border: none;border-width: 0;" - "background: transparent;}"); + m_changeStatusBtn->setStyleSheet("QLabel{width: 16px;height: 16px;" + "margin-right: 8px;border: none;border-width: 0;}"); m_workLayout->addStretch(); m_workLayout->addWidget(m_changeStatusBtn); @@ -56,24 +53,24 @@ bool number = false; bool line = false; for(QChar c:text) { - if(c>='A' && c <= 'Z') { + if (c>='A' && c <= 'Z') { uper = true; continue; } - if(c>='a' && c <='z') { + if (c>='a' && c <='z') { normal = true; continue; } - if(c>='0' && c<='9') { + if (c>='0' && c<='9') { number = true; continue; } } - if(text.length() >= 6) { + if (text.length() >= 6) { line = true; } bool ok = uper && number && line == true ?true:normal && number && line; - if(ok) { + if (ok) { emit verify_text(); } else { emit false_text(); @@ -81,37 +78,39 @@ }); m_changeStatusBtn->setFocusPolicy(Qt::NoFocus); setLayout(m_workLayout); + setMaxLength(30); + setTextMargins(12,0,28,0); } /* 获取密码显示按钮 */ -QPushButton* PasswordLineEdit::get_visble() { +VisbleButton* PasswordLineEdit::get_visble() { return m_changeStatusBtn; } /* 密码检测模块 */ -bool PasswordLineEdit::check() { +bool PasswordLineEdit::check() const { bool uper = false; bool normal = false; bool number = false; bool line = false; - if(this->text() != "") { + if (this->text() != "") { QString str = this->text(); for(QChar c:str) { - if(c>='A' && c <= 'Z') { + if (c>='A' && c <= 'Z') { uper = true; continue; } - if(c>='a' && c <='z') { + if (c>='a' && c <='z') { normal = true; continue; } - if(c>='0' && c<='9') { + if (c>='0' && c<='9') { number = true; continue; } } - if(text().length() >= 6) { + if (text().length() >= 6) { line = true; } } else { diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/passwordlineedit.h ukui-control-center-3.0.3/plugins/account/networkaccount/passwordlineedit.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/passwordlineedit.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/passwordlineedit.h 2021-04-14 01:27:20.000000000 +0000 @@ -27,16 +27,17 @@ #include #include #include "svghandler.h" +#include "visblebutton.h" class PasswordLineEdit : public QLineEdit { Q_OBJECT public: PasswordLineEdit(QWidget *parent = nullptr); - bool check(); - QPushButton* get_visble(); + bool check() const; + VisbleButton* get_visble(); private: - QPushButton *m_changeStatusBtn; + VisbleButton *m_changeStatusBtn; SVGHandler *m_svgHandler; QHBoxLayout *m_workLayout; signals: diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/popupwidget.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/popupwidget.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/popupwidget.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/popupwidget.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,68 +0,0 @@ -/* -*- 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 "popupwidget.h" - -PopupWidget::PopupWidget(QWidget *parent) : QWidget(parent) -{ - m_borderRadius = 4; - m_positionX = m_positionY = 6; - m_alphaValue = 10; - setStyleSheet("ql_popup{border-radius:4px;}"); - setAttribute(Qt::WA_TranslucentBackground, true); - setWindowFlags(Qt::FramelessWindowHint | Qt::Popup); -} - -/* 主要目的是绘制阴影 */ -void PopupWidget::paintEvent(QPaintEvent *event) -{ - - QPainter painter(this); - QColor m_defaultBackgroundColor = qRgb(0, 0, 0); - QPainterPath path1; - path1.setFillRule(Qt::WindingFill); - path1.addRoundedRect(m_positionX, m_positionY, this->width() - (m_positionX * 2), this->height() - (m_positionY * 2), m_borderRadius, m_borderRadius); - - painter.setRenderHint(QPainter::Antialiasing, true); - painter.fillPath(path1, QBrush(QColor(m_defaultBackgroundColor.red(), - m_defaultBackgroundColor.green(), - m_defaultBackgroundColor.blue()))); - - QColor color(0, 0, 0, m_alphaValue); - for (int i = 0; i < m_positionX; i++) - { - QPainterPath path; - path.setFillRule(Qt::WindingFill); - path.addRoundedRect(m_positionX - i, m_positionY - i, this->width() - (m_positionX - i) * 2, this->height() - (m_positionY - i) * 2, m_borderRadius, m_borderRadius); - color.setAlpha(120 - qSqrt(i) * 50); - painter.setPen(color); - painter.drawPath(path); - } - - painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(QBrush(palette().color(QPalette::Base))); - painter.setPen(Qt::transparent); - QRect rect = this->rect(); - rect.setX(m_positionX); - rect.setY(m_positionY); - rect.setWidth(rect.width() - m_positionY); - rect.setHeight(rect.height() - m_positionX); - // rect: 绘制区域 15:圆角弧度 - painter.drawRoundedRect(rect, m_borderRadius, m_borderRadius); -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/popupwidget.h ukui-control-center-3.0.3/plugins/account/networkaccount/popupwidget.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/popupwidget.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/popupwidget.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* -*- 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 QL_POPUP_H -#define QL_POPUP_H - -#include -#include -#include -#include -#include -#include - -class PopupWidget : public QWidget -{ - Q_OBJECT -public: - explicit PopupWidget(QWidget *parent = nullptr); - int m_positionX; - int m_positionY; - int m_borderRadius; - int m_alphaValue; -protected: - void paintEvent(QPaintEvent *event); -signals: - -}; - -#endif // QL_POPUP_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/README ukui-control-center-3.0.3/plugins/account/networkaccount/README --- ukui-control-center-2.0.3/plugins/account/networkaccount/README 2020-05-14 07:08:48.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -作者: 彭代欣(David Peng) -完成时间: 2020年05月13日15:17:41 -项目名称: 云账户模块 -项目程序: 库文件 -联系方式: pengdaixin@kylinos.cn - - -类名:area_code_lineedit -定义:area_code_lineedit.h -实现:area_code_lineedit.cpp -继承:QLineEdit -用途:用于注册页面手机号码输入框 -说明:顾名思义,是一个LineEdit,不过是封装了区域选择框的LineEdit,区域选择框可以详见ql_combobox类。 - -类名:bindphonedialog -定义:bindphonedialog.h -实现:bindphonedialog.cpp -继承:QWidget -用途:用于登录时遇到手机未绑定的情况下,强制要求用户绑定手机号码。 -说明:实际上这并不是一个Dialog,而且仅仅是LoginDialog包装过的一个内部Widget,主要是凸显这个绑定页面的作用。 - -类名:config_file -定义:config_file.h -实现:config_file.cpp -继承:QObejct -用途:工具类,主要是用与主页面中读取All.conf文件。 -说明:对QSettings的操作的封装,只封装了读取,写入。 - -类名:config_list_widget -定义:config_list_widget.h -实现:config_list_widget.cpp -继承:QWidget -用途:云账户的主页面,所有操作都为此页面服务。 -说明:包含了两个页面,一个登录前的页面,一个登录后的页面,也是分发DBus客户端的源头。由于最初本是用ListWidget实现,结果发现布局太难控,重写为QWidget,名字也就不改了。 - -类名:dbushandleclient -定义:dbushandleclient.h -实现:dbushandleclient.cpp -继承:QObject -用途:Dbus服务代理操作类,用于分发获取和请求DBus内容,是整个界面的后端接口。 -说明:由于封装成了工具类,必须由客户端发送信号调用,然后接口的返回也必须得调用回调函数,但是最好别在回调函数里执行操作,因为有时候回调会很慢。这个DBUS服务使用了UUID来唯一识别。该类会调用DBus服务。 - -类名:dialog_login_reg -定义:dialog_login_reg.h -实现:dialog_login_reg.cpp -继承:QWidget -用途:主页面登录框,模态。可实现登录、注册、重置密码、手机号码登录等多重操作。 -说明:这个登录框实际上应该说是一个系列操作框,包含了注册、登录、重置密码、手机号码登录等操作,其中夹杂的许多重用,虽然看上去让人不太满意,但是确实提高了程序的效率,为了更好的让读者理解那么多diconnect和connect的操作,先说明一下这些操作的序列拓扑。首先进入登录框,有登录、注册、忘记密码选项,如果只是登录,那就不需要disconnect又connect回来任何信号,因为默认就是登录的信号占有。如果进入注册界面,那么就要除去登录的信号占有并改成注册的信号占有,返回登录界面就要除去注册的信号占有并改为登录的信号占有,其余类似。不过由于返回的都是登录界面所以只有登录界面的信号时常解除时常占有,其余界面各不影响。不过记住一点,界面的切换如果有重用一定要记得改变信号,这里列出重用的部分:1、标题,大部分框都公用一个,除了成功提示框。2、登录按钮,实际上是多重按钮,可以变为注册、确认修改密码等按钮,同样不适用于“成功”框。3、注册按钮,不适用于“成功”框。 -4、改变登录方式的两个按钮、仅用于“登录”框。此外,该对话框还重写了QPaintEvent,添加了阴影边框效果。该类会调用DBus服务。 - - -类名:editpassdialog -定义:editpassdialog.h -实现:editpassdialog.cpp -继承:QWidget -用途:用户在已经登录的情况下,在主页面修改密码,修改成功后自动退出登录。 -说明:是一个模态对话框,不过继承的是QWidget,与Dialog_login_reg一样拥有边框阴影效果,不过不同的一点是这里没有重用,就是一个功能的对话框。该类会调用DBus服务。 - -类名:item_list -定义:item_list.h -实现:item_list.cpp -继承:QListWidget -用途:云账户界面的可选择项目列表。 -说明:该类就是一个界面组合类,可以自由添加新项目。 - -类名:logindialog -定义:logindialog.h -实现:logindialog.cpp -继承:QWidget -用途:登录界面类。 -说明:该类由Dialog_reg_login类所内含,包括了所有登录界面。 - -类名:mcode_widget -定义:mcode_widget.h -实现:mcode_widget.cpp -继承:QLabel -用途:登录时候输入的验证码。 -说明:重绘实现验证码,仅支持数字验证码。 - -类名:network_item -定义:network_item.h -实现:network_item.cpp -继承:QFrame -用途:主页面项目的列表项的封装类。 -说明:封装了一个QLabel装名称,一个ql_switchbutton实现开关。 - -类名:networkaccount -定义:networkaccount.h -实现:networkaccount.cpp -继承:QObject -用途:本插件的接口类,用于插件对接。 -说明:封装了接口必须的定义,以便插件成功载入。 - -类名:passdialog -定义:passdialog.h -实现:passdialog.cpp -继承:QWidget -用途:忘记密码界面框。 -说明:本界面内含于Dialog_login_reg类,实现了重置密码的界面。 - -类名:ql_box_item -定义:ql_box_item.h -实现:ql_box_item.cpp -继承:QWidget -用途:手机区域框下拉列表项目,显示国家名字以及对应区号。 -说明:内置于area_code_lineedit里的的ql_combobox类。 - -类名:ql_combobobx -定义:ql_combobobx.h -实现:ql_combobobx.cpp -继承:QWidget -用途:手机号码区域下拉框。 -说明:内置于area_code_lineedit类里,有别于官方QComboBox类。 - -类名:ql_lineedit_pass -定义:ql_lineedit_pass.h -实现:ql_lineedit_pass.cpp -继承:QLineEdit -用途:各种密码输入框。 -说明:自带密码格式检测功能的密码输入框。 - -类名:ql_popup -定义:ql_popup.h -实现:ql_popup.cpp -继承:QWidget -用途:手机区域输入框的下拉窗口。 -说明:拥有阴影边框,圆角。 - -类名:ql_pushbutton_edit -定义:ql_pushbutton_edit.h -实现:ql_pushbutton_edit.cpp -继承:QPushButton -用途:登录时修改密码的按钮。 -说明:透明图标样式的按钮,并带有提示功能。 - -类名:ql_swichbutton -定义:ql_swichbutton.h -实现:ql_swichbutton.cpp -继承:QWidget -用途:云账户主页面的滑动按钮。 -说明:内置于network_item类。 - -类名:qtooltips -定义:qtooltips.h -实现:qtooltips.cpp -继承:QWidget -用途:修改密码按钮提示框。 -说明:内置于ql_pushbutton_edit类。 - -类名:regdialog -定义:regdialog.h -实现:regdialog.cpp -继承:QWidget -用途:注册界面框。 -说明:本界面内含于Dialog_login_reg类,实现了注册账户的界面。 - -类名:successdiaolog -定义:successdiaolog.h -实现:successdiaolog.cpp -继承:QWidget -用途:成功提示框。 -说明:本界面内含于Dialog_login_reg类。 - - - - - - - - - diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/regdialog.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/regdialog.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/regdialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/regdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,220 +0,0 @@ -/* -*- 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 "regdialog.h" - -RegDialog::RegDialog(QWidget *parent) : QWidget(parent) -{ - this->setFixedWidth(338); - m_phoneLineEdit = new AreaCodeLineEdit(this); - m_accountLineEdit = new QLineEdit(this); - m_passLineEdit = new PasswordLineEdit(this); - m_confirmLineEdit = new PasswordLineEdit(this); - m_mcodeLineEdit = new QLineEdit(this); - m_sendMsgBtn = new QPushButton(tr("Get"),this); - - m_workLayout = new QVBoxLayout; - m_mcodeLayout = new QHBoxLayout; - m_passTips = new QLabel(this); - m_accountTips = new QLabel(this); - m_errorTips = new Tips(this); - m_svgHandler = new SVGHandler(this); - - QString str = ("QLineEdit{background-color:#F4F4F4;border-radius: 4px;border:1px none #3D6BE5;font-size: 14px;color: rgba(0,0,0,0.85);lineedit-password-character: 42;}" - "QLineEdit:hover{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}" - "QLineEdit:focus{background-color:#F4F4F4;border-radius: 4px;border:1px solid #3D6BE5;font-size: 14px;color:rgba(0,0,0,0.85)}"); - m_phoneLineEdit->setFixedSize(QSize(338,36)); - m_accountLineEdit->setFixedSize(QSize(338,36)); - m_passLineEdit->setFixedSize(QSize(338,36)); - m_mcodeLineEdit->setFixedSize(QSize(192,36)); - m_sendMsgBtn->setFixedSize(QSize(130,36)); - m_confirmLineEdit->setFixedSize(QSize(338,36)); - m_phoneLineEdit->setFocusPolicy(Qt::StrongFocus); - - - - m_phoneLineEdit->setMaxLength(11); - m_passLineEdit->setPlaceholderText(tr("Your password here")); - m_passLineEdit->setEchoMode(QLineEdit::Password); - m_confirmLineEdit->setEchoMode(QLineEdit::Password); - m_accountLineEdit->setPlaceholderText(tr("Your account here")); - m_confirmLineEdit->setPlaceholderText(tr("Confirm your password")); - m_mcodeLineEdit->setPlaceholderText(tr("Your code here")); - m_mcodeLineEdit->setMaxLength(4); - m_accountTips->setText(tr("This operation is permanent")); - m_accountTips->setContentsMargins(12,0,0,0); - m_accountTips->setFixedHeight(16); - m_passTips->setText(tr("At least 6 bit, include letters and digt")); - m_passTips->setFixedHeight(16); - m_passTips->setContentsMargins(12,0,0,0); - m_accountTips->setStyleSheet("font-size:14px;"); - m_passTips->setStyleSheet("font-size:14px;"); - - m_confirmLineEdit->setTextMargins(12,0,0,0); - m_accountLineEdit->setTextMargins(12,0,0,0); - m_passLineEdit->setTextMargins(12,0,0,0); - m_mcodeLineEdit->setTextMargins(12,0,0,0); - //valid_code->setStyleSheet(str); - - QRegExp regx("[a-zA-Z0-9]+$"); - QValidator *validator = new QRegExpValidator(regx, m_mcodeLineEdit ); - m_mcodeLineEdit->setValidator( validator ); - - //reg_pass->setStyleSheet(str); - //reg_phone->setStyleSheet(str); - // reg_user->setStyleSheet(str); - // reg_confirm->setStyleSheet(str); - //send_msg_btn->setStyleSheet("QPushButton{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(0,0,0,0.85);} " - // "QPushButton:hover{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(61,107,229,0.85);}" - // "QPushButton:click{background-color:#F4F4F4;font-size:14px;border-radius: 4px;border:4px solid #F4F4F4;color:rgba(61,107,229,0.85);}"); - - m_workLayout->setMargin(0); - m_workLayout->setSpacing(8); - m_workLayout->addWidget(m_phoneLineEdit); - m_workLayout->addWidget(m_accountLineEdit); - m_workLayout->addWidget(m_accountTips); - m_workLayout->addWidget(m_passLineEdit); - m_workLayout->addWidget(m_passTips); - m_workLayout->addWidget(m_confirmLineEdit); - m_mcodeLayout->setMargin(0); - m_mcodeLayout->setSpacing(16); - m_mcodeLayout->addWidget(m_mcodeLineEdit); - m_mcodeLayout->addWidget(m_sendMsgBtn); - m_mcodeLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - m_workLayout->addLayout(m_mcodeLayout); - m_workLayout->addWidget(m_errorTips); - m_workLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); - setLayout(m_workLayout); - - QRegExp regx_phn("^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"); - QValidator *validator_phn = new QRegExpValidator(regx_phn, m_phoneLineEdit); - m_phoneLineEdit->setValidator(validator_phn); - - QRegExp regx_acc("^[a-zA-Z0-9_@.-]+$"); - QValidator *validator_acc = new QRegExpValidator(regx_acc, m_accountLineEdit ); - m_accountLineEdit->setValidator(validator_acc); - - m_passTips->hide(); - m_passTips->setAttribute(Qt::WA_DontShowOnScreen); - m_accountTips->hide(); - m_accountTips->setAttribute(Qt::WA_DontShowOnScreen); - - m_errorTips->hide(); - m_errorTips->setAttribute(Qt::WA_DontShowOnScreen); - m_sendMsgBtn->setFocusPolicy(Qt::NoFocus); - connect(m_mcodeLineEdit,SIGNAL(textChanged(QString)),this,SLOT(change_uppercase())); - connect(this,SIGNAL(code_changed()),this,SLOT(setstyleline())); - connect(m_passLineEdit,&PasswordLineEdit::verify_text,[this] () { - m_passTips->setText(tr("Your password is valid!")); - }); - connect(m_passLineEdit,&PasswordLineEdit::false_text,[this] () { - m_passTips->setText(tr("At least 6 bit, include letters and digt")); - }); - adjustSize(); - m_phoneLineEdit->setFocus(); -} - -void RegDialog::set_staus(bool ok) { - m_confirmLineEdit->setEnabled(ok); - m_accountLineEdit->setEnabled(ok); - m_phoneLineEdit->setEnabled(ok); - m_mcodeLineEdit->setEnabled(ok); - m_sendMsgBtn->setEnabled(ok); -} - -/* 更新设置错误提示 */ -void RegDialog::setstyleline() { - m_errorTips->set_text(m_errorCode); -} - -/* 获取错误代码 */ -void RegDialog::set_code(QString codenum) { - m_errorCode = codenum; - emit code_changed(); -} - -PasswordLineEdit* RegDialog::get_reg_confirm() { - return m_confirmLineEdit; -} - -QLabel* RegDialog::get_pass_tip() { - - return m_passTips; -} - -QLabel* RegDialog::get_user_tip() { - return m_accountTips; -} - -QLineEdit* RegDialog::get_reg_user() { - return m_accountLineEdit; -} - -PasswordLineEdit* RegDialog::get_reg_pass() { - return m_passLineEdit; -} - -QLineEdit* RegDialog::get_valid_code() { - return m_mcodeLineEdit; -} - -AreaCodeLineEdit* RegDialog::get_phone_user() { - return m_phoneLineEdit; -} - -QPushButton* RegDialog::get_send_code() { - return m_sendMsgBtn; -} - -/* 小写字母转大写,备用 */ -void RegDialog::change_uppercase() { - QString str = m_mcodeLineEdit->text(); - m_mcodeLineEdit->setText(str.toUpper()); -} - -QString RegDialog::get_user_mcode() { - return m_mcodeLineEdit->text(); -} - -QString RegDialog::get_user_phone() { - return m_phoneLineEdit->text(); -} - -QString RegDialog::get_user_account() { - return m_accountLineEdit->text(); -} -QString RegDialog::get_user_passwd() { - return m_passLineEdit->text(); -} - -/* 清空注册框 */ -void RegDialog::set_clear() { - if(!m_errorTips->isHidden()) { - m_errorTips->hide(); - } - m_passLineEdit->get_visble()->setChecked(false); - m_passLineEdit->setText(""); - m_accountLineEdit->setText(""); - m_phoneLineEdit->setText(""); - m_mcodeLineEdit->setText(""); -} - -Tips* RegDialog::get_tips() { - return m_errorTips; -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/regdialog.h ukui-control-center-3.0.3/plugins/account/networkaccount/regdialog.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/regdialog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/regdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -/* -*- 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 REGDIALOG_H -#define REGDIALOG_H - -#include -#include -#include "areacodelineedit.h" -#include -#include -#include -#include -#include -#include -#include "passwordlineedit.h" -#include "tips.h" -#include "svghandler.h" - -class RegDialog : public QWidget -{ - Q_OBJECT -public: - explicit RegDialog(QWidget *parent = nullptr); - QLabel* get_pass_tip(); - QLabel* get_user_tip(); - QLineEdit* get_reg_user(); - PasswordLineEdit* get_reg_pass(); - QLineEdit* get_valid_code(); - AreaCodeLineEdit* get_phone_user(); - PasswordLineEdit* get_reg_confirm(); - QPushButton* get_send_code(); - QString get_user_phone(); - QString get_user_account(); - QString get_user_passwd(); - QString get_user_mcode(); - void set_staus(bool ok); - void set_code(QString codenum); - void set_clear(); - Tips* get_tips(); -public slots: - void change_uppercase(); - void setstyleline(); -protected: - -signals: - void code_changed(); -private: - AreaCodeLineEdit *m_phoneLineEdit; - QLineEdit *m_accountLineEdit; - PasswordLineEdit *m_passLineEdit; - QLineEdit *m_mcodeLineEdit; - PasswordLineEdit *m_confirmLineEdit; - QPushButton *m_sendMsgBtn; - QVBoxLayout *m_workLayout; - QHBoxLayout *m_mcodeLayout; - QLabel *m_accountTips; - QLabel *m_passTips; - Tips *m_errorTips; - QString m_errorCode; - SVGHandler *m_svgHandler; -}; - -#endif // REGDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/successdiaolog.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/successdiaolog.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/successdiaolog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/successdiaolog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -/* -*- 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 "successdiaolog.h" - -SuccessDiaolog::SuccessDiaolog(QWidget *parent) : QWidget(parent) -{ - m_bkgWidget = new QSvgWidget(":/new/image/success.svg"); - m_textLabel = new QLabel(this); - m_backloginBtn = new QPushButton(this); - m_workLayout = new QVBoxLayout; - - m_bkgWidget->setFixedSize(148,148); - - m_textLabel->setStyleSheet("font-size:24px"); - - m_textLabel->adjustSize(); - - m_backloginBtn->setFixedSize(338,36); - m_backloginBtn->setText(tr("Reback sign in")); - m_backloginBtn->setStyleSheet("QPushButton {font-size:14px;background-color: #3D6BE5;border-radius: 4px;color:rgba(255,255,255,0.85);}" - "QPushButton:hover {font-size:14px;background-color: #415FC4;border-radius: 4px;position:relative;color:rgba(255,255,255,0.85);}" - "QPushButton:click {font-size:14px;background-color: #415FC4;border-radius: 4px;postion:realative;color:rgba(255,255,255,0.85);}"); - m_backloginBtn->setContentsMargins(0,16,0,0); - - m_workLayout->setContentsMargins(41,100,41,110); - m_workLayout->setSpacing(0); - m_workLayout->addWidget(m_bkgWidget,0,Qt::AlignCenter); - m_workLayout->addWidget(m_textLabel,0,Qt::AlignCenter); - m_workLayout->addStretch(); - m_workLayout->addWidget(m_backloginBtn,0,Qt::AlignCenter | Qt::AlignBottom); - - setLayout(m_workLayout); -} - -/* 成功消息统一接收机制 */ -void SuccessDiaolog::set_mode_text(int mode) { - if(mode == 0) { - m_textLabel->setText(tr("Sign up success!")); - m_backloginBtn->setText(tr("Confirm")); - } else if(mode == 1) { - m_textLabel->setText(tr("Reset success!")); - m_backloginBtn->setText(tr("Confirm")); - } else if(mode == 2) { - m_textLabel->setText(tr("Sign in success!")); - m_backloginBtn->setText(tr("Confirm")); - } else if(mode == 3) { - m_textLabel->setText(tr("Binding phone success!")); - m_backloginBtn->setText(tr("Confirm")); - } -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/successdiaolog.h ukui-control-center-3.0.3/plugins/account/networkaccount/successdiaolog.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/successdiaolog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/successdiaolog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -/* -*- 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 SUCCESSDIAOLOG_H -#define SUCCESSDIAOLOG_H - -#include -#include -#include -#include -#include -#include -#include -#include -class SuccessDiaolog : public QWidget -{ - Q_OBJECT -public: - explicit SuccessDiaolog(QWidget *parent = nullptr); - QPushButton *m_backloginBtn; - QLabel *m_textLabel; - QSvgWidget *m_bkgWidget; - void set_mode_text(int mode); -private: - QVBoxLayout *m_workLayout; -signals: - -}; - -#endif // SUCCESSDIAOLOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/svghandler.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/svghandler.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/svghandler.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/svghandler.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -1,20 +1,42 @@ #include "svghandler.h" #include -SVGHandler::SVGHandler(QObject *parent) : QObject(parent) -{ +#define THEME_SCHEMA "org.ukui.style" +#define THEME_KEY "styleName" +SVGHandler::SVGHandler(QObject *parent,bool highLight) : QObject(parent) +{ + m_color = "default"; + if (highLight) { + QByteArray id(THEME_SCHEMA); + themeSettings = new QGSettings(id,QByteArray(),this); + + if (themeSettings->get(THEME_KEY).toString() == "ukui-dark") { + m_color = "white"; + } else { + m_color = "black"; + } + + connect(themeSettings,&QGSettings::changed,this,[=] (const QString &key) { + if (key == THEME_KEY) { + if (themeSettings->get(key).toString() == "ukui-dark") { + m_color = "white"; + } else { + m_color = "default"; + } + } + }); + } } -const QPixmap SVGHandler::loadSvg(const QString &fileName) +const QPixmap SVGHandler::loadSvg(const QString &fileName,int size) { - int size = 24; const auto ratio = qApp->devicePixelRatio(); if ( 2 == ratio) { - size = 48; + size = 2 * size; } else if (3 == ratio) { - size = 96; + size = 3 * size; } QPixmap pixmap(size, size); QSvgRenderer renderer(fileName); @@ -29,7 +51,7 @@ return pixmap; } -const QPixmap SVGHandler::loadSvgColor(const QString &path, const QString color, int size) +const QPixmap SVGHandler::loadSvgColor(const QString &path, const QString &color, int size) { int origSize = size; const auto ratio = qApp->devicePixelRatio(); @@ -48,6 +70,11 @@ painter.end(); pixmap.setDevicePixelRatio(ratio); + + if (color != m_color && m_color != "default") { + return drawSymbolicColoredPixmap(pixmap, m_color); + } + return drawSymbolicColoredPixmap(pixmap, color); } @@ -63,7 +90,7 @@ color.setGreen(255); color.setBlue(255); img.setPixelColor(x, y, color); - } else if( "black" == cgColor) { + } else if ( "black" == cgColor) { color.setRed(0); color.setGreen(0); color.setBlue(0); diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/svghandler.h ukui-control-center-3.0.3/plugins/account/networkaccount/svghandler.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/svghandler.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/svghandler.h 2021-04-14 01:27:20.000000000 +0000 @@ -6,17 +6,20 @@ #include #include #include +#include class SVGHandler : public QObject { Q_OBJECT public: - explicit SVGHandler(QObject *parent = nullptr); - const QPixmap loadSvg(const QString &fileName); - static const QPixmap loadSvgColor(const QString &path, const QString color, int size = 48); - static QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor); + explicit SVGHandler(QObject *parent = nullptr,bool highLight = false); + const QPixmap loadSvg(const QString &fileName,int size = 24); + const QPixmap loadSvgColor(const QString &path, const QString &color, int size = 48); + QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString cgColor); private: -signals: + QGSettings *themeSettings; + QString m_color; +Q_SIGNALS: }; diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/switchbutton.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/switchbutton.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/switchbutton.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/switchbutton.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,149 +0,0 @@ -/* -*- 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 "switchbutton.h" - -SwitchButton::SwitchButton(QWidget *parent) : QWidget(parent) { - m_buttonColor = new QColor; - setMaximumSize(48,24); - setMinimumSize(48,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())); -} - -/* 绘制SwitchButton */ -void SwitchButton::paintEvent(QPaintEvent *event) { - Q_UNUSED(event); - QPainter painter(this); - painter.setRenderHint(QPainter::SmoothPixmapTransform); - painter.setRenderHint(QPainter::Antialiasing); //kan ju ci - painter.setPen(Qt::NoPen); - QColor colorActiveOn(61,107,229); - QColor colorActiveOff(204,204,204); - QColor colorInactive(233,233,233); - if(m_bIsActive == 1 && m_bIsOn) { - *m_buttonColor = colorActiveOn; - } else if(m_bIsActive == 1 && !m_bIsOn) { - *m_buttonColor = colorActiveOff; - } else { - *m_buttonColor = colorInactive; - } - if(m_bIsOn) { - painter.save(); - painter.setBrush(*m_buttonColor); - QRectF active_rect = QRectF(0,0,m_fWidth,m_fHeight); - painter.drawRoundedRect(active_rect, 0.5 * m_fHeight, 0.5 * m_fHeight); //hua yi ge yuan - painter.restore(); - painter.save(); - painter.setBrush(Qt::white); - painter.drawEllipse(m_fCurrentValue,4, 16, 16); - painter.restore(); - } else { - painter.save(); - painter.setBrush(*m_buttonColor); - QRectF inactive_rect = QRectF(0 ,0,m_fWidth,m_fHeight); - painter.drawRoundedRect(inactive_rect, 0.5 * m_fHeight, 0.5 * m_fHeight); - painter.restore(); //kai shi shua - painter.save(); - painter.setBrush(*m_buttonColor); - QRectF blueRect = QRectF(m_fHeight * 0.16, m_fHeight * 0.16,m_fWidth - m_fHeight * 0.33, m_fHeight * 0.67); - painter.drawRoundedRect(blueRect, 0.45 * m_fHeight, 0.45 * m_fHeight); - painter.restore(); - painter.save(); - painter.setBrush(Qt::white); - painter.drawEllipse(m_fCurrentValue,4, 16, 16); - painter.restore(); - } -} - -/* 给SwitchButton设置一个id,方便管理 */ -void SwitchButton::set_id(int id) { - this->m_buttonID = id; -} - -/* 让SwitchButton处于可用状态 */ -void SwitchButton::set_active(bool ok) { - m_bIsActive = ok; - update(); -} - -/* 获取按钮是否可用 */ -int SwitchButton::get_active() { - return m_bIsActive; -} - -/* 播放按钮开启关闭动画 */ -void SwitchButton::startAnimation() { //滑动按钮动作播放 - if(m_bIsActive == 0) { - return ; - } - 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) { - if(m_bIsActive == 0) { - return ; - } - Q_UNUSED(event); - m_bIsOn = !m_bIsOn; - emit status(m_bIsOn,m_buttonID); - m_cTimer->start(); - return QWidget::mousePressEvent(event); -} - -/* 获取开关状况 */ -int SwitchButton::get_swichbutton_val() { - return this->m_bIsOn; -} - -SwitchButton::~SwitchButton() { - delete m_buttonColor; -} - -/* 设置开关状态 */ -void SwitchButton::set_swichbutton_val(int on) { - this->m_bIsOn = on; - m_cTimer->start(); -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/switchbutton.h ukui-control-center-3.0.3/plugins/account/networkaccount/switchbutton.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/switchbutton.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/switchbutton.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* -*- 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 QL_SWICHBUTTON_H -#define QL_SWICHBUTTON_H - -#include -#include -#include - -class SwitchButton : public QWidget -{ - Q_OBJECT -public: - explicit SwitchButton(QWidget *parent = nullptr); - ~SwitchButton(); - void set_swichbutton_val(int m_bIsOn); - int get_swichbutton_val(); - void set_id(int m_buttonID); - int get_id(); - int get_active(); - void set_active(bool ok); -private: - int m_bIsActive = 1; - int m_bIsOn = 1; - QColor *m_buttonColor; - QTimer *m_cTimer; - float m_fWidth; - float m_fHeight; - float m_fCurrentValue; - int m_buttonID; - void paintEvent(QPaintEvent *event); - void mousePressEvent(QMouseEvent *event); -signals: - void status(int m_bIsOn,int m_buttonID); -private slots: - void startAnimation(); -}; - -#endif // QL_SWICHBUTTON_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/syncdialog.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/syncdialog.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/syncdialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/syncdialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,170 @@ +/* -*- 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 "syncdialog.h" +#include +#include +#include "configfile.h" +#include +#include + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +SyncDialog::SyncDialog(QString name,QString path, QWidget *parent) : QDialog(parent) +{ + mTitle = new QLabel(this); + mTips = new QLabel(this); + mListWidget = new QListWidget(this); + mSyncButton = new QPushButton(tr("Sync"),this); + mCancelButton = new QPushButton(tr("Do not"),this); + setAttribute(Qt::WA_DeleteOnClose); + mMainLayout = new QVBoxLayout; + mHBoxLayout = new QHBoxLayout; + + connect(mSyncButton, &QPushButton::clicked,this,[=] { + if (m_List.isEmpty()) { + emit coverMode(); + return ; + } + + emit sendKeyMap(m_List); + }); + connect(mCancelButton, &QPushButton::clicked,this,[=] { + emit coverMode(); + }); + initUI(); + +} + +void SyncDialog::checkOpt() { + mDate = m_List.at(0); + //qDebug() << m_List.size()<setText(tr("Last sync at %1").arg(mDate)); + //qDebug() << m_List.size()<<"mList"; + for(const QString &item : qAsConst(m_szItemlist)) { + if (m_List.contains(item)) { + QCheckBox * checkBox = new QCheckBox(m_szItemNameList.at(m_szItemlist.indexOf(item)),this); + QListWidgetItem * items = new QListWidgetItem(mListWidget,0); + mListWidget->addItem(items); + mListWidget->setItemWidget(items,checkBox); + items->setSizeHint(QSize(mListWidget->size().width(), 20)); + QStringList filter; + filter << "indicator-china-weather" << "kylin-video" << "terminal" + << "editor" << "peony"; + + connect(checkBox, &QCheckBox::toggled, this, [=] (bool status) { + if (status == true) { + m_List.removeAll(item); + } else { + m_List.append(item); + } + }); + if (filter.contains(item)) { + checkBox->setChecked(false); + } else { + m_List.removeAll(item); + checkBox->setChecked(true); + } + } + } +} + +void SyncDialog::initUI() { + setFixedSize(400,380); + setContentsMargins(32,32,32,23); + mTitle->setStyleSheet("font-size:18px;font-weight:500"); + + mListWidget->setFixedHeight(160); + mSyncButton->setFixedSize(100,36); + mCancelButton->setFixedSize(100,36); + mListWidget->setContentsMargins(0,0,0,0); + mListWidget->setSpacing(8); + + mTitle->setText(tr("Sync now?")); + mTips->setText(tr("Last sync at %1").arg(mDate)); + + mMainLayout->setContentsMargins(0,0,0,0); + mHBoxLayout->setContentsMargins(0,0,0,0); + + mMainLayout->setSpacing(0); + mHBoxLayout->setSpacing(16); + + mHBoxLayout->addWidget(mSyncButton); + mHBoxLayout->addWidget(mCancelButton); + mHBoxLayout->setAlignment(Qt::AlignRight); + + mMainLayout->addWidget(mTitle); + mMainLayout->addSpacing(8); + mMainLayout->addWidget(mTips); + mMainLayout->addSpacing(16); + mMainLayout->addWidget(mListWidget); + mMainLayout->addSpacing(40); + mMainLayout->addLayout(mHBoxLayout); + setLayout(mMainLayout); + setAttribute(Qt::WA_TranslucentBackground, true); + setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog | Qt::Tool); + setModal(true); + hide(); +} + +/* 窗口重绘,阴影设置 */ +void SyncDialog::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); + p.restore(); +} + diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/syncdialog.h ukui-control-center-3.0.3/plugins/account/networkaccount/syncdialog.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/syncdialog.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/syncdialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,76 @@ +/* -*- 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 SYNCDIALOG_H +#define SYNCDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class SyncDialog : public QDialog +{ + Q_OBJECT +public: + explicit SyncDialog(QString name,QString path,QWidget *parent = nullptr); + void initUI(); + + QStringList m_szItemNameList = {tr("Wallpaper"),tr("ScreenSaver"),tr("Font"),tr("Avatar"),tr("Menu"),tr("Tab"),tr("Quick Start"), + tr("Themes"),tr("Mouse"),tr("TouchPad"),tr("KeyBoard"),tr("ShortCut"), + tr("Area"),tr("Date/Time"),tr("Default Open"),tr("Notice"),tr("Option"),tr("Peony"), + tr("Boot"),tr("Power"),tr("Editor"),tr("Terminal"),tr("Weather"),tr("Media")}; + + QStringList m_szItemlist = {"wallpaper","ukui-screensaver","font","avatar","ukui-menu","ukui-panel","ukui-panel2", + "themes","mouse","touchpad","keyboard","shortcut","area","datetime","default-open", + "notice","option","peony","boot","power","editor","terminal", + "indicator-china-weather","kylin-video"}; + + QStringList m_List; + void checkOpt(); + +protected: + void paintEvent(QPaintEvent * event); + +private: + QLabel * mTitle; + QLabel * mTips; + QPushButton * mSyncButton; + QPushButton * mCancelButton; + + QString mDate; + + QListWidget * mListWidget; + + QVBoxLayout * mMainLayout; + QHBoxLayout * mHBoxLayout; + +signals: + void sendKeyMap(const QStringList &list); + void coverMode(); +}; + +#endif // SYNCDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/tips.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/tips.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/tips.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/tips.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -8,19 +8,20 @@ m_iconWidget->setFixedSize(16,16); m_workLayout->addWidget(m_iconWidget); m_workLayout->addWidget(m_textLabel); - m_workLayout->setContentsMargins(12,0,0,0); + m_workLayout->setContentsMargins(0,0,0,0); m_workLayout->setSpacing(8); - m_textLabel->setStyleSheet("QLabel{font-size:14px;color:#F53547}"); + m_textLabel->setStyleSheet("QLabel{color:#F53547}"); setLayout(m_workLayout); m_szContext = ""; hide(); } -void Tips::set_text(const QString text) { +void Tips::set_text(const QString &text) { m_szContext = text; this->m_textLabel->setText(m_szContext); } Tips::~Tips() { delete m_iconWidget; + m_iconWidget = nullptr; } diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/tips.h ukui-control-center-3.0.3/plugins/account/networkaccount/tips.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/tips.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/tips.h 2021-04-14 01:27:20.000000000 +0000 @@ -12,7 +12,7 @@ { Q_OBJECT public: - void set_text(const QString m_textLabel); + void set_text(const QString &m_textLabel); explicit Tips(QWidget *parent = nullptr); ~Tips(); private: diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/tooltips.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/tooltips.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/tooltips.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/tooltips.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* -*- 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 "tooltips.h" - -Tooltips::Tooltips(QWidget *parent) : QWidget(parent) -{ - m_postionX = 6; - m_postionY = 6; - m_alphaValue = 10; - m_borderRadius = 4; - - setStyleSheet("ql_popup{border-radius:4px;}"); - setAttribute(Qt::WA_TranslucentBackground, true); - setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip); -} - -/* 重绘加上边框阴影 */ -void Tooltips::paintEvent(QPaintEvent *event) -{ - - QPainter painter(this); - QColor m_defaultBackgroundColor = qRgb(0, 0, 0); - QPainterPath path1; - path1.setFillRule(Qt::WindingFill); - path1.addRoundedRect(m_postionX, m_postionY, this->width() - (m_postionX * 2), this->height() - (m_postionY * 2), m_borderRadius, m_borderRadius); - - painter.setRenderHint(QPainter::Antialiasing, true); - painter.fillPath(path1, QBrush(QColor(m_defaultBackgroundColor.red(), - m_defaultBackgroundColor.green(), - m_defaultBackgroundColor.blue()))); - - QColor color(0, 0, 0, m_alphaValue); - for (int i = 0; i < 5; i++) - { - QPainterPath path; - path.setFillRule(Qt::WindingFill); - path.addRoundedRect(m_postionX - i, m_postionY - i, this->width() - (m_postionX - i) * 2, this->height() - (m_postionY - i) * 2, m_borderRadius, m_borderRadius); - color.setAlpha(80 - qSqrt(i) * 40); - painter.setPen(color); - painter.drawPath(path); - } - - painter.setRenderHint(QPainter::Antialiasing); - painter.setBrush(QBrush(palette().color(QPalette::Base))); - painter.setPen(Qt::transparent); - QRect rect = this->rect(); - rect.setX(m_postionX); - rect.setY(m_postionY); - rect.setWidth(rect.width() - m_postionY); - rect.setHeight(rect.height() - m_postionX); - painter.drawRoundedRect(rect, m_borderRadius, m_borderRadius); -} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/tooltips.h ukui-control-center-3.0.3/plugins/account/networkaccount/tooltips.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/tooltips.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/tooltips.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -/* -*- 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 QTOOLTIPS_H -#define QTOOLTIPS_H - -#include -#include -#include -#include -#include - -class Tooltips : public QWidget -{ - Q_OBJECT -public: - Tooltips(QWidget *parent = nullptr); - int m_postionX; - int m_postionY; - int m_borderRadius; - int m_alphaValue; -protected: - void paintEvent(QPaintEvent *event); -}; - -#endif // QTOOLTIPS_H diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/visblebutton.cpp ukui-control-center-3.0.3/plugins/account/networkaccount/visblebutton.cpp --- ukui-control-center-2.0.3/plugins/account/networkaccount/visblebutton.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/visblebutton.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,27 @@ +#include "visblebutton.h" + +VisbleButton::VisbleButton(QWidget *parent) : QLabel(parent) +{ + status = false; + setFixedSize(16,16); +} + +void VisbleButton::enterEvent(QEvent *event) { + +} + +void VisbleButton::leaveEvent(QEvent *event) { + +} + +void VisbleButton::mousePressEvent(QMouseEvent *event) { + status = !status; + emit clicked(status); + emit toggled(status); +} + +void VisbleButton::setChecked(bool checked) { + status = checked; + emit clicked(status); + emit toggled(status); +} diff -Nru ukui-control-center-2.0.3/plugins/account/networkaccount/visblebutton.h ukui-control-center-3.0.3/plugins/account/networkaccount/visblebutton.h --- ukui-control-center-2.0.3/plugins/account/networkaccount/visblebutton.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/networkaccount/visblebutton.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,25 @@ +#ifndef VISBLEBUTTON_H +#define VISBLEBUTTON_H + +#include +#include +#include + +class VisbleButton : public QLabel +{ + Q_OBJECT +public: + explicit VisbleButton(QWidget *parent = nullptr); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void mousePressEvent(QMouseEvent *event); + void setChecked(bool checked); +private: + bool status; + +signals: + void clicked(bool checked); + void toggled(bool checked); +}; + +#endif // VISBLEBUTTON_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricdeviceinfo.cpp ukui-control-center-3.0.3/plugins/account/userinfo/biometricdeviceinfo.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricdeviceinfo.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricdeviceinfo.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,193 @@ +/** + * 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 + + +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"); + 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; +} + +/* For the type FeatureInfo */ +QDBusArgument &operator<<(QDBusArgument &argument, const FeatureInfo &featureInfo) +{ + argument.beginStructure(); + argument << featureInfo.uid << featureInfo.biotype + << featureInfo.device_shortname << featureInfo.index + << featureInfo.index_name; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, FeatureInfo &featureInfo) +{ + argument.beginStructure(); + argument >> featureInfo.uid >> featureInfo.biotype + >> featureInfo.device_shortname >> featureInfo.index + >> featureInfo.index_name; + argument.endStructure(); + return argument; +} + +void registerMetaType() +{ + qRegisterMetaType("DeviceInfo"); + qDBusRegisterMetaType(); +} + + +QString GetDefaultDevice(const QString &userName) +{ +// QString configPath = QString("/home/%1/" UKUI_BIOMETRIC_CONFIG_PATH).arg(userName); +// QSettings settings(configPath, QSettings::IniFormat); +// qDebug() << "configure path: " << settings.fileName(); + + QString configPath = QDir::homePath() + "/" + UKUI_BIOMETRIC_CONFIG_PATH; + QSettings settings(configPath, QSettings::IniFormat); + + QString defaultDevice = settings.value("DefaultDevice").toString(); + + if(defaultDevice.isEmpty()) + { + QString configPath = QString("/var/lib/lightdm-data/%1/" UKUI_BIOMETRIC_CONFIG_PATH).arg(userName); + QSettings settings(configPath, QSettings::IniFormat); + defaultDevice = settings.value("DefaultDevice").toString(); + } + + if(defaultDevice.isEmpty()) + { + QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat); + defaultDevice = sysSettings.value("DefaultDevice").toString(); + } + + return defaultDevice; +} + +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; +} + +int GetMaxFailedAutoRetry(const QString &userName) +{ + return getValueFromSettings(userName, "MaxFailedAutoRetry"); +} + +int GetMaxTimeoutAutoRetry(const QString &userName) +{ + return getValueFromSettings(userName, "MaxTimeoutAutoRetry"); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricdeviceinfo.h ukui-control-center-3.0.3/plugins/account/userinfo/biometricdeviceinfo.h --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricdeviceinfo.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricdeviceinfo.h 2021-04-14 01:27:20.000000000 +0000 @@ -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 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 BIOMETRIC_PAM_DOUBLE "BIOMETRIC_PAM_DOUBLE" +#define BIOMETRIC_PAM "BIOMETRIC_PAM" +#define BIOMETRIC_IGNORE "BIOMETRIC_IGNORE" +#define BIOMETRIC_SUCCESS "BIOMETRIC_SUCCESS" + +/** + * @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状态 + */ +enum IdentifyOpsStatus { + IDENTIFY_MATCH = 400, + IDENTIFY_NOTMATCH, + IDENTIFY_ERROR, + IDENTIFY_STOPBYUSER, + IDENTIFY_TIMEOUT, + IDENTIFY_MAX +}; + +/** + * @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; +}; + +struct FeatureInfo { + int uid; + int biotype; + QString device_shortname; + int index; + QString index_name; +}; + +enum BioType { + BIOTYPE_FINGERPRINT, + BIOTYPE_FINGERVEIN, + BIOTYPE_IRIS, + BIOTYPE_FACE, + BIOTYPE_VOICEPRINT, + __MAX_NR_BIOTYPES +}; + + +QString transferBioType(int type); + +QDBusArgument &operator <<(QDBusArgument &arg, const DeviceInfo &deviceInfo); +const QDBusArgument &operator >>(const QDBusArgument &arg, DeviceInfo &deviceInfo); +QDBusArgument &operator<<(QDBusArgument &argument, const FeatureInfo &featureInfo); +const QDBusArgument &operator>>(const QDBusArgument &argument, FeatureInfo &featureInfo); + +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 获取失败后自动重新开始的最大次数 + * @param userName + * @return + */ +int GetMaxFailedAutoRetry(const QString &userName); + +/** + * @brief 获取超时后自动重新开始的最大次数 + * @param userName + * @return + */ +int GetMaxTimeoutAutoRetry(const QString &userName); + +#endif // BIOMETRICDEVICEINFO_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricenroll.cpp ukui-control-center-3.0.3/plugins/account/userinfo/biometricenroll.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricenroll.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricenroll.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,471 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 "biometricenroll.h" +#include "ui_biometricenroll.h" +#include + +#include "CloseButton/closebutton.h" +#include "biometricdeviceinfo.h" +#include "biometricproxy.h" +#include "servicemanager.h" + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +BiometricEnrollDialog::BiometricEnrollDialog(QDBusInterface *service,int bioType, + int deviceId, int uid, QWidget *parent) : + QDialog(parent), + ui(new Ui::BiometricEnrollDialog), + serviceInterface(service), + type(bioType), + deviceId(deviceId), + uid(uid), + movie(nullptr), + ops(IDLE), + isProcessed(false), + opsResult(UNDEFINED) +{ + ui->setupUi(this); + setupInit(); + + connect(serviceInterface, SIGNAL(StatusChanged(int,int)), + this, SLOT(onStatusChanged(int,int))); + + connect(serviceInterface, SIGNAL(ProcessChanged(int,QString,int,QString)), + this, SLOT(onProcessChanged(int,QString,int,QString))); + + ServiceManager *sm = ServiceManager::instance(); + connect(sm, &ServiceManager::serviceStatusChanged, + this, [&](bool activate){ + if(!activate) + { + close(); + } + }); + +} + +BiometricEnrollDialog::~BiometricEnrollDialog() +{ + delete ui; +} + +void BiometricEnrollDialog::setProcessed(bool val) +{ + isProcessed = val; + if(isProcessed){ + ui->biometricEnrollLable->setPixmap(QPixmap("/usr/share/ukui-biometric/images/huawei/00.svg")); + } + else{ + ui->biometricEnrollLable->setPixmap(getImage(type)); + if(!movie) + movie = new QMovie(getGif(type)); + } +} + +void BiometricEnrollDialog::setupInit() +{ + setWindowTitle(tr("")); + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + + ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); + + if(isProcessed){ + ui->biometricEnrollLable->setPixmap(QPixmap("/usr/share/ukui-biometric/images/huawei/00.svg")); + } + else{ + ui->biometricEnrollLable->setPixmap(getImage(type)); + if(!movie) + movie = new QMovie(getGif(type)); + } + ui->biometricButtonWidget->hide(); + ui->biometricFinishLabel->hide(); +} + +QString BiometricEnrollDialog::transferBioType(int type) +{ + switch(type) { + case BIOTYPE_FINGERPRINT: + return tr("FingerPrint"); + case BIOTYPE_FINGERVEIN: + return tr("Fingervein"); + case BIOTYPE_IRIS: + return tr("Iris"); + case BIOTYPE_FACE: + return tr("Face"); + case BIOTYPE_VOICEPRINT: + return tr("VoicePrint"); + } + return QString(); +} + +void BiometricEnrollDialog::setTitle(int biotype) +{ + QString title = transferBioType(type); + switch(biotype) { + case ENROLL: + title += tr("Enroll"); + break; + case VERIFY: + title += tr("Verify"); + break; + case SEARCH: + title += tr("Search"); + break; + } + + ui->biometricOpsLbl->setText(title); +} + +void BiometricEnrollDialog::setPrompt(QString text) +{ + ui->biometricPromptLbl->setText(text); +} + +void BiometricEnrollDialog::on_closeBtn_clicked() +{ + close(); +} + +BiometricEnrollDialog::Result BiometricEnrollDialog::getResult() +{ + return opsResult; +} + +int BiometricEnrollDialog::enroll(int drvId, int uid, int idx, const QString &idxName) +{ + QList args; + args << drvId << uid << idx << idxName; + + this->setTitle(ENROLL); + this->setPrompt(tr("Permission is required.\n" + "Please authenticate yourself to continue")); + ui->closeBtn->setEnabled(false); + + serviceInterface->callWithCallback("Enroll", args, this, + SLOT(enrollCallBack(const QDBusMessage &)), + SLOT(errorCallBack(const QDBusError &))); + ops = ENROLL; + + return exec(); +} + +void BiometricEnrollDialog::enrollCallBack(const QDBusMessage &reply) +{ + int result; + result = reply.arguments()[0].value(); + qDebug() << "Enroll result: " << result; + + ui->closeBtn->setEnabled(true); + + switch(result) { + case DBUS_RESULT_SUCCESS: { /* 录入成功 */ + opsResult = SUCESS; + setPrompt(tr("Enroll successfully")); + showFinishPrompt(); + break; + } + default: + opsResult = ERROR; + handleErrorResult(result); + break; + } + ops = IDLE; +} + +int BiometricEnrollDialog::verify(int drvId, int uid, int idx) +{ + QList args; + args << drvId << uid << idx; + + this->setTitle(VERIFY); + + serviceInterface->callWithCallback("Verify", args, this, + SLOT(verifyCallBack(const QDBusMessage &)), + SLOT(errorCallBack(const QDBusError &))); + ops = VERIFY; + + return exec(); +} + +QString BiometricEnrollDialog::getGif(int type) +{ + switch(type) { + case BIOTYPE_FINGERPRINT: + return "/usr/share/ukui-biometric/images/FingerPrint.gif"; + case BIOTYPE_FINGERVEIN: + return "/usr/share/ukui-biometric/images/fingervein.gif"; + case BIOTYPE_IRIS: + return "/usr/share/ukui-biometric/images/iris.gif"; + case BIOTYPE_VOICEPRINT: + return "/usr/share/ukui-biometric/images/voiceprint.gif"; + } + return QString(); +} + +QString BiometricEnrollDialog::getImage(int type) +{ + switch(type) { + case BIOTYPE_FINGERPRINT: + return "/usr/share/ukui-biometric/images/FingerPrint.png"; + case BIOTYPE_FINGERVEIN: + return "/usr/share/ukui-biometric/images/FingerVein.png"; + case BIOTYPE_IRIS: + return "/usr/share/ukui-biometric/images/Iris.png"; + case BIOTYPE_VOICEPRINT: + return "/usr/share/ukui-biometric/images/VoicePrint.png"; + } + return QString(); +} + +void BiometricEnrollDialog::verifyCallBack(const QDBusMessage &reply) +{ + int result; + result = reply.arguments()[0].value(); + qDebug() << "Verify result: " << result; + + if(result >= 0) { + opsResult = SUCESS; + setPrompt(tr("Verify successfully")); + showFinishPrompt(); + } else if(result == DBUS_RESULT_NOTMATCH) { + setPrompt(tr("Not Match")); + ui->biometricEnrollLable->setPixmap(QIcon::fromTheme("dialog-error").pixmap(QSize(64,64))); + //showFinishPrompt(); + } else { + handleErrorResult(result); + } + + ops = IDLE; +} + +void BiometricEnrollDialog::resetUI() +{ + if(isProcessed){ + ui->biometricEnrollLable->setPixmap(QPixmap("/usr/share/ukui-biometric/images/huawei/00.svg")); + } + else{ + ui->biometricEnrollLable->setPixmap(getImage(type)); + if(!movie) + movie = new QMovie(getGif(type)); + } + ui->biometricButtonWidget->hide(); + ui->biometricFinishLabel->hide(); + ui->biometricPromptLbl->show(); + ui->biometricPromptLbl->clear(); + + ui->biometricOpsLbl->show(); + +} + +void BiometricEnrollDialog::on_biometricFinishbtn_clicked() +{ + close(); +} + +void BiometricEnrollDialog::on_biometricConBtn_clicked() +{ + resetUI(); + enroll(deviceId,uid,-1,"指纹2"); +} + +int BiometricEnrollDialog::search(int drvId, int uid, int idxStart, int idxEnd) +{ + QList args; + args << drvId << uid << idxStart << idxEnd; + + this->setTitle(SEARCH); + + serviceInterface->callWithCallback("Search", args, this, + SLOT(searchCallBack(const QDBusMessage &)), + SLOT(errorCallBack(const QDBusError &))); + + ops = SEARCH; + + return exec(); +} + +void BiometricEnrollDialog::searchCallBack(const QDBusMessage &reply) +{ + return ; + +} + + +void BiometricEnrollDialog::showFinishPrompt() +{ + ui->biometricEnrollLable->setPixmap(QIcon::fromTheme("ukui-dialog-success").pixmap(QSize(64,64))); + if(ops == ENROLL) + ui->biometricFinishLabel->setText(tr("Enroll successfully")); + else if(ops == VERIFY) + ui->biometricFinishLabel->setText(tr("Verify successfully")); + + ui->biometricFinishLabel->show(); + + ui->biometricPromptLbl->hide(); + ui->biometricOpsLbl->hide(); + ui->biometricButtonWidget->show(); + + ui->biometricConBtn->hide(); +} + +void BiometricEnrollDialog::StopOpsCallBack(const QDBusMessage &reply) +{ + int ret = reply.arguments().at(0).toInt(); + accept(); +} + +void BiometricEnrollDialog::errorCallBack(const QDBusError &error) +{ + qDebug() << "DBus Error: " << error.message(); + accept(); +} + +void BiometricEnrollDialog::closeEvent(QCloseEvent *event) +{ + serviceInterface->call("StopOps", deviceId,5); +} + +void BiometricEnrollDialog::onProcessChanged(int drvId,QString aa, int statusType,QString bb) +{ + int count = statusType * 15 / 100; + QString filename = QString("/usr/share/ukui-biometric/images/huawei/") + (count < 10 ? "0" : "") + + QString::number(count) + ".svg"; + + ui->biometricEnrollLable->setPixmap(QPixmap(filename)); +} + +void BiometricEnrollDialog::onStatusChanged(int drvId, int statusType) +{ + if (!(drvId == deviceId && statusType == STATUS_NOTIFY)) + return; + + ui->closeBtn->setEnabled(true); + + //过滤掉当录入时使用生物识别授权接收到的认证的提示信息 + if(ops == ENROLL) { + QDBusMessage reply = serviceInterface->call("UpdateStatus", drvId); + if(reply.type() == QDBusMessage::ErrorMessage) { + qDebug() << "DBUS: " << reply.errorMessage(); + return; + } + int devStatus = reply.arguments().at(3).toInt(); + qDebug() << devStatus; + + if(!(devStatus >= 201 && devStatus < 203)) { + return; + } + } + else if(ops == IDLE) + { + return; + } + + if(!isProcessed && movie->state() != QMovie::Running) + { + ui->biometricEnrollLable->setMovie(movie); + movie->start(); + } + + QDBusMessage notifyReply = serviceInterface->call("GetNotifyMesg", drvId); + if(notifyReply.type() == QDBusMessage::ErrorMessage) { + qDebug() << "DBUS: " << notifyReply.errorMessage(); + return; + } + QString prompt = notifyReply.arguments().at(0).toString(); + qDebug() << prompt; + + setPrompt(prompt); +} + +void BiometricEnrollDialog::handleErrorResult(int error) +{ + switch(error) { + case DBUS_RESULT_ERROR: { + //操作失败,需要进一步获取失败原因 + QDBusMessage msg = serviceInterface->call("GetOpsMesg", deviceId); + if(msg.type() == QDBusMessage::ErrorMessage) + { + qDebug() << "UpdateStatus error: " << msg.errorMessage(); + setPrompt(tr("D-Bus calling error")); + return; + } + setPrompt(msg.arguments().at(0).toString()); + qDebug() << "GetOpsMesg: deviceId--" << deviceId; + break; + } + case DBUS_RESULT_DEVICEBUSY: + //设备忙 + setPrompt(tr("Device is busy")); + break; + case DBUS_RESULT_NOSUCHDEVICE: + //设备不存在 + setPrompt(tr("No such device")); + break; + case DBUS_RESULT_PERMISSIONDENIED: + //没有权限 + setPrompt(tr("Permission denied")); + break; + } + +} + + +void BiometricEnrollDialog::paintEvent(QPaintEvent * event){ + Q_UNUSED(event) + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); + p.restore(); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricenroll.h ukui-control-center-3.0.3/plugins/account/userinfo/biometricenroll.h --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricenroll.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricenroll.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,105 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 BIOMETRICENROLL_H +#define BIOMETRICENROLL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "HoverWidget/hoverwidget.h" + + +namespace Ui { +class BiometricEnrollDialog; +} + +class BiometricEnrollDialog : public QDialog +{ + Q_OBJECT + +public: + explicit BiometricEnrollDialog(QDBusInterface *service,int bioType, + int deviceId, int uid, QWidget *parent = nullptr); + ~BiometricEnrollDialog(); + enum Result {SUCESS, ERROR, UNDEFINED}; + + void setProcessed(bool val); + void setTitle(int opsType); + void setPrompt(QString text); + + int enroll(int drvId, int uid, int idx, const QString &idxName); + int verify(int drvId, int uid, int idx); + int search(int drvId, int uid, int idxStart, int idxEnd); + QString getGif(int type); + QString getImage(int type); + Result getResult(); + void resetUI(); + +protected: + void paintEvent(QPaintEvent * event); + void closeEvent(QCloseEvent *event); + +private slots: + void on_closeBtn_clicked(); + void on_biometricFinishbtn_clicked(); + void on_biometricConBtn_clicked(); + void onStatusChanged(int, int); + void onProcessChanged(int, QString,int,QString); + void enrollCallBack(const QDBusMessage &); + void verifyCallBack(const QDBusMessage &); + void searchCallBack(const QDBusMessage &); + void StopOpsCallBack(const QDBusMessage &); + void showFinishPrompt(); + void errorCallBack(const QDBusError &); + +private: + Ui::BiometricEnrollDialog *ui; + void setupInit(); + void handleErrorResult(int error); + QString transferBioType(int type); + + Result opsResult; + QDBusInterface *serviceInterface; + enum OPS{IDLE, ENROLL, VERIFY, SEARCH} ops; + + int type; + int deviceId; + int uid; + bool isProcessed; + + QMovie *movie; + +private slots: + +}; + +#endif // BIOMETRICENROLL_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricenroll.ui ukui-control-center-3.0.3/plugins/account/userinfo/biometricenroll.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricenroll.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricenroll.ui 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,366 @@ + + + BiometricEnrollDialog + + + + 0 + 0 + 340 + 420 + + + + + 340 + 420 + + + + + 360 + 450 + + + + Dialog + + + + 8 + + + 8 + + + 8 + + + 8 + + + 8 + + + + + 8 + + + 8 + + + 8 + + + 8 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 30 + + + + Biometrics + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + Qt::NoFocus + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 0 + + + + + + + Qt::PlainText + + + Qt::AlignCenter + + + true + + + + + + + + + + + + 0 + 50 + + + + + + + Qt::AlignCenter + + + true + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 150 + + + + + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 120 + 120 + + + + + + + Qt::AlignCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::AlignCenter + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + 0 + 60 + + + + + + + 0 + + + + + + 150 + 36 + + + + + 120 + 36 + + + + Continue to enroll + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 120 + 36 + + + + + 120 + 36 + + + + Finish + + + + + + + + + + + + + + + CloseButton + QPushButton +
CloseButton/closebutton.h
+
+
+ + +
diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricmoreinfo.cpp ukui-control-center-3.0.3/plugins/account/userinfo/biometricmoreinfo.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricmoreinfo.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricmoreinfo.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,250 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 "biometricmoreinfo.h" +#include "ui_biometricmoreinfo.h" +#include + +#include "CloseButton/closebutton.h" +#include "biometricdeviceinfo.h" +#include "biometricproxy.h" + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +enum VerifyType { + VERIFY_HARDWARE, + VERIFY_SOFTWARE, + VERIFY_MIX, + VERIFY_OTHER +}; + +enum StorageType { + STORAGE_DEVICE, + STORAGE_OS, + STORAGE_MIX +}; + +enum BusType { + BUS_SERIAL, + BUS_USB, + BUS_PCIE, + BUS_ANY = 100, + BUS_OTHER +}; + +enum IdentifyType { + IDENTIFY_HARDWARE, + IDENTIFY_SOFTWARE, + IDENTIFY_MIX, + IDENTIFY_OTHER +}; + +struct SearchResult { + int uid; + int index; + QString indexName; +}; + +BiometricMoreInfoDialog::BiometricMoreInfoDialog( DeviceInfoPtr deviceinfo, QWidget *parent) : + QDialog(parent), + deviceInfo(deviceinfo), + ui(new Ui::BiometricMoreInfoDialog) +{ + ui->setupUi(this); + setupInit(); + + QString verifyType = transferVerifyType(deviceInfo->verifyType); + QString busType = transferBusType(deviceInfo->busType); + QString storageType = transferStorageType(deviceInfo->storageType); + QString identifyType = transferIdentifyType(deviceInfo->identifyType); + QString devStatus = deviceInfo->deviceNum > 0 ? tr("Connected") : tr("Unconnected"); + + qDebug()<bioBusTypeLbl->setText(busType); + ui->bioVerifyTypeLbl->setText(verifyType); + ui->bioStorageTypeLbl->setText(storageType); + ui->bioIdentificationTypeLbl->setText(identifyType); + ui->bioDeviceStatusLbll->setText(devStatus); + + defaultDeviceBtn = new SwitchButton(ui->biometricDefaultFrame); + // defaultDeviceBtn->setChecked(false); + if(getDefaultDevice() == deviceinfo->shortName) + defaultDeviceBtn->setChecked(true); + else + defaultDeviceBtn->setChecked(false); + + ui->biometridDefaulltDeviceLayout->addWidget(defaultDeviceBtn); + connect(defaultDeviceBtn, &SwitchButton::checkedChanged, [=](bool checked){ + if(checked) + setDefaultDevice(deviceinfo->shortName); + else + setDefaultDevice(""); + }); + + mWatcher = nullptr; + if(!mWatcher){ + mWatcher = new QFileSystemWatcher(this); + mWatcher->addPath(QDir::homePath() + "/" + UKUI_BIOMETRIC_CONFIG_PATH); + connect(mWatcher,&QFileSystemWatcher::fileChanged,this,[=](const QString &path){ + mWatcher->addPath(QDir::homePath() + "/" + UKUI_BIOMETRIC_CONFIG_PATH); + defaultDeviceBtn->blockSignals(true); + if(getDefaultDevice() == deviceinfo->shortName) + defaultDeviceBtn->setChecked(true); + else + defaultDeviceBtn->setChecked(false); + defaultDeviceBtn->blockSignals(false); + }); + } +} + +BiometricMoreInfoDialog::~BiometricMoreInfoDialog() +{ + delete ui; +} + +QString BiometricMoreInfoDialog::transferBioType(int type) +{ + switch(type) { + case BIOTYPE_FINGERPRINT: + return tr("FingerPrint"); + case BIOTYPE_FINGERVEIN: + return tr("Fingervein"); + case BIOTYPE_IRIS: + return tr("Iris"); + case BIOTYPE_FACE: + return tr("Face"); + case BIOTYPE_VOICEPRINT: + return tr("VoicePrint"); + } + return QString(); +} + +QString BiometricMoreInfoDialog::transferVerifyType(int type) +{ + switch(type) { + case VERIFY_HARDWARE: + return tr("Hardware Verification"); + case VERIFY_SOFTWARE: + return tr("Software Verification"); + case VERIFY_MIX: + return tr("Mix Verification"); + case VERIFY_OTHER: + return tr("Other Verification"); + } + return QString(); +} +QString BiometricMoreInfoDialog::transferStorageType(int type) +{ + switch(type) { + case STORAGE_DEVICE: + return tr("Device Storage"); + case STORAGE_OS: + return tr("OS Storage"); + case STORAGE_MIX: + return tr("Mix Storage"); + } + return QString(); +} +QString BiometricMoreInfoDialog::transferBusType(int type) +{ + switch(type) { + case BUS_SERIAL: + return tr("Serial"); + case BUS_USB: + return tr("USB"); + case BUS_PCIE: + return tr("PCIE"); + case BUS_ANY: + return tr("Any"); + case BUS_OTHER: + return tr("Other"); + } + return QString(); +} +QString BiometricMoreInfoDialog::transferIdentifyType(int type) +{ + switch(type) { + case VERIFY_HARDWARE: + return tr("Hardware Identification"); + case VERIFY_SOFTWARE: + return tr("Software Identification"); + case VERIFY_MIX: + return tr("Mix Identification"); + case VERIFY_OTHER: + return tr("Other Identification"); + } + return QString(); +} + +void BiometricMoreInfoDialog::on_closeBtn_clicked() +{ + close(); +} + +void BiometricMoreInfoDialog::setupInit() +{ + setWindowTitle(tr("")); + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + + ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); + +} + +void BiometricMoreInfoDialog::paintEvent(QPaintEvent * event){ + Q_UNUSED(event) + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); + p.restore(); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricmoreinfo.h ukui-control-center-3.0.3/plugins/account/userinfo/biometricmoreinfo.h --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricmoreinfo.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricmoreinfo.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,84 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 BIOMETRICMOREINFO_H +#define BIOMETRICMOREINFO_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "HoverWidget/hoverwidget.h" +#include "biometricdeviceinfo.h" +#include "biometricproxy.h" +#include "SwitchButton/switchbutton.h" + +namespace Ui { +class BiometricMoreInfoDialog; +} + +class BiometricMoreInfoDialog : public QDialog +{ + Q_OBJECT + +public: + explicit BiometricMoreInfoDialog(DeviceInfoPtr deviceinfo, QWidget *parent = nullptr); + + ~BiometricMoreInfoDialog(); + + +protected: + void paintEvent(QPaintEvent * event); + + +private slots: + void on_closeBtn_clicked(); + +private: + Ui::BiometricMoreInfoDialog *ui; + + void setupInit(); + + QString transferBioType(int type); + QString transferVerifyType(int type); + QString transferStorageType(int type); + QString transferBusType(int type); + QString transferIdentifyType(int type); + + DeviceInfoPtr deviceInfo; + SwitchButton *defaultDeviceBtn; + QFileSystemWatcher *mWatcher; + +private slots: + +}; + +#endif // BIOMETRICENROLL_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricmoreinfo.ui ukui-control-center-3.0.3/plugins/account/userinfo/biometricmoreinfo.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricmoreinfo.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricmoreinfo.ui 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,306 @@ + + + BiometricMoreInfoDialog + + + + 0 + 0 + 350 + 300 + + + + + 350 + 300 + + + + + 350 + 300 + + + + Dialog + + + + 8 + + + 8 + + + 8 + + + 8 + + + 8 + + + + + 8 + + + 8 + + + 8 + + + 8 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 30 + + + + Biometrics + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + Qt::NoFocus + + + + + + + + + + + + 8 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 50 + + + + + 0 + + + 22 + + + 0 + + + 22 + + + 0 + + + + + + + Default device + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + 0 + 0 + + + + + 12 + + + 12 + + + + + + + Verify Type: + + + + + + + Bus Type: + + + + + + + Device Status: + + + + + + + + + + + + + + + + + + + + + Storage Type: + + + + + + + Identification Type: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + + + CloseButton + QPushButton +
CloseButton/closebutton.h
+
+
+ + +
diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricproxy.cpp ukui-control-center-3.0.3/plugins/account/userinfo/biometricproxy.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricproxy.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricproxy.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,302 @@ +/** + * 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 +#include +#include + +void setDefaultDevice(const QString &deviceName) +{ + QString configPath = QDir::homePath() + "/" + UKUI_BIOMETRIC_CONFIG_PATH; + QSettings settings(configPath, QSettings::IniFormat); + + settings.setValue("DefaultDevice", deviceName); + settings.sync(); + + //由于greeter没有权限访问家目录,所以单独写一个配置文件 + QString configFile1 = QString("/var/lib/lightdm-data/%1/.biometric_auth/ukui_biometric.conf").arg(getenv("USER")); + QSettings settings1(configFile1, QSettings::IniFormat); + + settings1.setValue("DefaultDevice", deviceName); + settings1.sync(); + +} + +QString getDefaultDevice() +{ + QString configPath = QDir::homePath() + "/" + UKUI_BIOMETRIC_CONFIG_PATH; + QSettings settings(configPath, QSettings::IniFormat); + + 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; +} + +BiometricProxy::BiometricProxy(QObject *parent) + : QDBusAbstractInterface(BIOMETRIC_DBUS_SERVICE, + BIOMETRIC_DBUS_PATH, + BIOMETRIC_DBUS_INTERFACE, + QDBusConnection::systemBus(), + parent) +{ + registerMetaType(); + setTimeout(2147483647); + + configFile = QDir::homePath() + "/.biometric_auth/ukui_biometric.conf"; +} + +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(); +} + +QStringList BiometricProxy::getFeaturelist(int drvid, int uid, int indexStart, int indexEnd) +{ + QStringList list; + QList qlist; + FeatureInfo *featureInfo; + int listsize; + QDBusMessage result = call(QStringLiteral("GetFeatureList"),drvid,uid,indexStart,indexEnd); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return list; + } + QList variantList = result.arguments(); + listsize = variantList[0].value(); + variantList[1].value() >> qlist; + for (int i = 0; i < listsize; i++) { + featureInfo = new FeatureInfo; + qlist[i].variant().value() >> *featureInfo; + list.append(featureInfo->index_name); + delete featureInfo; + } + return list; +} + +bool BiometricProxy::renameFeature(int drvid, int uid, int index, QString newname) +{ + QDBusMessage result = call(QStringLiteral("Rename"),drvid,uid,index,newname); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return false; + } + return result.arguments().first().value(); +} + +bool BiometricProxy::deleteFeature(int drvid, int uid, int indexStart, int indexEnd) +{ + QDBusMessage result = call(QStringLiteral("Clean"),drvid,uid,indexStart,indexEnd); + if(result.type() == QDBusMessage::ErrorMessage) + { + qWarning() << "GetDevList error:" << result.errorMessage(); + return false; + } + return result.arguments().first().value(); +} + +DeviceList BiometricProxy::GetDrvList() +{ + QDBusMessage result = call(QStringLiteral("GetDrvList")); + 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; +} + +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; +} + +QString BiometricProxy::getDefaultDevice() +{ + QSettings settings(configFile, QSettings::IniFormat); + + return settings.value("DefaultDevice").toString(); +} + +void BiometricProxy::setDefaultDevice(const QString &deviceName) +{ + QSettings settings(configFile, QSettings::IniFormat); + + settings.setValue("DefaultDevice", deviceName); + settings.sync(); + + //由于greeter没有权限访问家目录,所以单独写一个配置文件 + QString configFile1 = QString("/var/lib/lightdm-data/%1/.biometric_auth/ukui_biometric.conf").arg(getenv("USER")); + QSettings settings1(configFile1, QSettings::IniFormat); + + settings1.setValue("DefaultDevice", deviceName); + settings1.sync(); + +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/biometricproxy.h ukui-control-center-3.0.3/plugins/account/userinfo/biometricproxy.h --- ukui-control-center-2.0.3/plugins/account/userinfo/biometricproxy.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/biometricproxy.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,167 @@ +/** + * 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 "biometricdeviceinfo.h" + +#define SERVICE "biometric-authentication.service" +#define DBUS_SERVICE "org.ukui.Biometric" +#define DBUS_PATH "/org/ukui/Biometric" +#define DBUS_INTERFACE "org.ukui.Biometric" + +/** + * @brief UpdateStauts调用返回的结果 + */ +struct StatusReslut +{ + int result; + int enable; + int devNum; + int devStatus; + int opsStatus; + int notifyMessageId; +}; + +void setDefaultDevice(const QString &deviceName); +QString getDefaultDevice(); + +/** + * @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 = 5); + /** + * @brief 删除生物特征 + * @return + */ + bool deleteFeature(int drvid, int uid, int indexStart = 0, int indexEnd = -1); + /** + * @brief 重命名生物特征 + * @return + */ + bool renameFeature(int drvid, int uid, int index ,QString newname); + /** + * @brief 获取当前用户已连接设备对应特征数目 + * @param uid 用户id + * @param indexStart 用于认证的特征索引范围 + * @param indexEnd + * @return + */ + int GetFeatureCount(int uid, int indexStart = 0, int indexEnd = -1); + QStringList getFeaturelist(int drvid,int uid,int indexStart = 0,int indexEnd = -1); + + /** + * @brief 获取已连接的设备列表 + * @return + */ + DeviceList GetDevList(); + /** + * @brief 获取驱动列表 + * @return + */ + DeviceList GetDrvList(); + /** + * @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); + + QString getDefaultDevice(); + void setDefaultDevice(const QString &deviceName); + +private: + QString configFile; + + +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); + +}; + +#endif // BIOMETRICPROXY_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changefacedialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/changefacedialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/changefacedialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changefacedialog.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -22,9 +22,11 @@ #include "FlowLayout/flowlayout.h" #include "elipsemaskwidget.h" +#include "CloseButton/closebutton.h" #include #include +#include #define FACEPATH "/usr/share/ukui/faces/" @@ -40,64 +42,77 @@ setAttribute(Qt::WA_DeleteOnClose); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); + // ui->closeBtn->setProperty("useIconHighlightEffect", true); + // ui->closeBtn->setProperty("iconHighlightEffectMode", 1); + // ui->closeBtn->setFlat(true); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); + // ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" + // "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); -// ui->frame->setStyleSheet("QFrame{background: #ffffff; border: none; border-radius: 6px;}"); -// ui->closeBtn->setStyleSheet("QPushButton{background: #ffffff; border: none;}"); +// ui->frame->setStyleSheet("QFrame{background: #ffffff; border: none; border-radius: 6px;}"); +// ui->closeBtn->setStyleSheet("QPushButton{background: #ffffff; border: none;}"); + ui->customfaceBtn->setStyleSheet("background: transparent; text-align:left"); - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); + selectedFaceIcon = ""; - ElipseMaskWidget * cfMaskWidget = new ElipseMaskWidget(ui->faceLabel); -// cfMaskWidget->setBgColor("#F4F4F4"); + btnsGroup = new QButtonGroup; + + ElipseMaskWidget *cfMaskWidget = new ElipseMaskWidget(ui->faceLabel); +// cfMaskWidget->setBgColor("#F4F4F4"); cfMaskWidget->setGeometry(0, 0, ui->faceLabel->width(), ui->faceLabel->height()); - loadSystemFaces(); + ui->saveBtn->setEnabled(false); + loadSystemFaces(); - connect(ui->closeBtn, &QPushButton::clicked, [=]{ + connect(ui->cancelBtn, &QPushButton::clicked, [=]{ close(); }); connect(ui->customfaceBtn, &QPushButton::clicked, [=]{ showLocalFaceDialog(); }); + + connect(ui->saveBtn, &QPushButton::clicked, [=]{ + emit face_file_send(selectedFaceIcon); + close(); + }); } ChangeFaceDialog::~ChangeFaceDialog() { delete ui; + ui = nullptr; } -void ChangeFaceDialog::loadSystemFaces(){ - - FlowLayout * facesFlowLayout = new FlowLayout(ui->facesWidget); +void ChangeFaceDialog::loadSystemFaces() +{ + FlowLayout *facesFlowLayout = new FlowLayout(ui->facesWidget, 0, 5, 5); ui->facesWidget->setLayout(facesFlowLayout); - //遍历头像目录 + // 遍历头像目录 QStringList facesList; QDir facesDir = QDir(FACEPATH); - foreach (QString filename, facesDir.entryList(QDir::Files)){ -// facesList.append(FACEPATH + filename); + foreach (QString filename, facesDir.entryList(QDir::Files)) { +// facesList.append(FACEPATH + filename); QString fullface = QString("%1%2").arg(FACEPATH).arg(filename); if (fullface.endsWith(".svg")) continue; if (fullface.endsWith("3.png")) continue; - QPushButton * button = new QPushButton; + QPushButton *button = new QPushButton; + button->setCheckable(true); button->setAttribute(Qt::WA_DeleteOnClose); - button->setFixedSize(QSize(48, 48)); -// button->setStyleSheet("QPushButton{border: none;}"); + button->setFixedSize(QSize(64, 64)); +// button->setStyleSheet("QPushButton{border: none;}"); - QHBoxLayout * mainHorLayout = new QHBoxLayout(button); + btnsGroup->addButton(button); + + QHBoxLayout *mainHorLayout = new QHBoxLayout(button); mainHorLayout->setSpacing(0); mainHorLayout->setMargin(0); - QLabel * iconLabel = new QLabel(button); + QLabel *iconLabel = new QLabel(button); iconLabel->setScaledContents(true); iconLabel->setPixmap(QPixmap(fullface)); @@ -106,31 +121,73 @@ button->setLayout(mainHorLayout); connect(button, &QPushButton::clicked, [=]{ - //show dialog更新头像 + // show dialog更新头像 setFace(fullface); - emit face_file_send(fullface, ui->usernameLabel->text()); + selectedFaceIcon = fullface; + + if (!ui->saveBtn->isEnabled()) + ui->saveBtn->setEnabled(true); + +// emit face_file_send(fullface, ui->usernameLabel->text()); }); facesFlowLayout->addWidget(button); } } -void ChangeFaceDialog::setFace(QString iconfile){ +void ChangeFaceDialog::setFace(QString iconfile) +{ ui->faceLabel->setPixmap(QPixmap(iconfile)); } -void ChangeFaceDialog::setUsername(QString username){ +void ChangeFaceDialog::setUsername(QString username) +{ ui->usernameLabel->setText(username); } -void ChangeFaceDialog::setAccountType(QString atype){ +void ChangeFaceDialog::setAccountType(QString atype) +{ ui->typeLabel->setText(atype); } -void ChangeFaceDialog::showLocalFaceDialog(){ - QString filters = "Face files(*.png *.jpg *.svg)"; +void ChangeFaceDialog::showLocalFaceDialog() +{ + QString filters = "Face files(*.jpg *.jpeg *.png *.svg)"; QFileDialog fd; + QList usb_list = fd.sidebarUrls(); + int sidebarNum = 8;// 最大添加U盘数,可以自己定义 + QString home_path = QDir::homePath().section("/", -1, -1); + QString mnt = "/media/" + home_path + "/"; + QDir mntDir(mnt); + mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + QFileInfoList file_list = mntDir.entryInfoList(); + QList mntUrlList; + for (int i = 0; i < sidebarNum && i < file_list.size(); ++i) { + QFileInfo fi = file_list.at(i); + mntUrlList << QUrl("file://" + fi.filePath()); + } + + QFileSystemWatcher m_fileSystemWatcher(&fd); + m_fileSystemWatcher.addPath("/media/" + home_path + "/"); + connect(&m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, &fd, + [=, &sidebarNum, &mntUrlList, &usb_list, &fd](const QString path) { + QDir m_wmntDir(path); + m_wmntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + QFileInfoList m_wfilist = m_wmntDir.entryInfoList(); + mntUrlList.clear(); + for (int i = 0; i < sidebarNum && i < m_wfilist.size(); ++i) { + QFileInfo m_fi = m_wfilist.at(i); + mntUrlList << QUrl("file://" + m_fi.filePath()); + } + fd.setSidebarUrls(usb_list + mntUrlList); + fd.update(); + }); + + connect(&fd, &QFileDialog::finished, &fd, [=, &usb_list, &fd]() { + fd.setSidebarUrls(usb_list); + }); + fd.setDirectory(QString(const_cast(g_get_user_special_dir(G_USER_DIRECTORY_PICTURES)))); fd.setAcceptMode(QFileDialog::AcceptOpen); fd.setViewMode(QFileDialog::List); @@ -143,6 +200,8 @@ fd.setLabelText(QFileDialog::FileType, tr("FileType: ")); fd.setLabelText(QFileDialog::Reject, tr("Cancel")); + fd.setSidebarUrls(usb_list + mntUrlList); + if (fd.exec() != QDialog::Accepted) return; @@ -152,17 +211,26 @@ QFile pic(selectedfile); int size = pic.size(); - if (size >= 2097152) { - QMessageBox::warning(this, tr("Warning"), tr("The avatar is larger than 2M, please choose again")); + qDebug() << "size is" << size; + if (size >= 1048576) { + QMessageBox::warning(this, tr("Warning"), + tr("The avatar is larger than 1M, please choose again")); return; } setFace(selectedfile); - emit face_file_send(selectedfile, ui->usernameLabel->text()); + + selectedFaceIcon = selectedfile; + + if (!ui->saveBtn->isEnabled()) + ui->saveBtn->setEnabled(true); +// emit face_file_send(selectedfile); } -void ChangeFaceDialog::paintEvent(QPaintEvent *event) { - Q_UNUSED(event); +void ChangeFaceDialog::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + QPainter p(this); p.setRenderHint(QPainter::Antialiasing); QPainterPath rectPath; @@ -175,12 +243,14 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); // 模糊这个黑底 QImage img = pixmap.toImage(); qt_blurImage(img, 10, false, false); + // 挖掉中心 pixmap = QPixmap::fromImage(img); QPainter pixmapPainter2(&pixmap); @@ -192,9 +262,9 @@ // 绘制阴影 p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + // 绘制一个背景 p.save(); - p.fillPath(rectPath,palette().color(QPalette::Base)); - + p.fillPath(rectPath, palette().color(QPalette::Base)); p.restore(); } diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changefacedialog.h ukui-control-center-3.0.3/plugins/account/userinfo/changefacedialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/changefacedialog.h 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changefacedialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 @@ -68,8 +69,13 @@ private: Ui::ChangeFaceDialog *ui; +private: + QString selectedFaceIcon; + + QButtonGroup * btnsGroup; + Q_SIGNALS: - void face_file_send(QString file, QString username); + void face_file_send(QString file); }; #endif // CHANGEFACEDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changefacedialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/changefacedialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/changefacedialog.ui 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changefacedialog.ui 2021-04-14 01:27:20.000000000 +0000 @@ -6,20 +6,20 @@ 0 0 - 390 - 412 + 420 + 470 - 390 - 412 + 420 + 470 - 390 - 412 + 420 + 470 @@ -33,10 +33,10 @@ 0 - 9 + 0 - 9 + 0 0 @@ -74,63 +74,21 @@ 0 - - - 8 - - - 8 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 32 - 32 - - - - - 32 - 32 - - - - - - - - - - - 24 + 0 32 - 16 + 32 32 - 32 + 24 @@ -140,7 +98,26 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 16 + + + + + + + 12 + @@ -166,16 +143,16 @@ - 2 + 3 - + - + @@ -187,6 +164,45 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 32 + + + + + + + + System Icon + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 16 + + + + + @@ -221,9 +237,17 @@ 36 + + + true + + Select face from local + + false + @@ -241,6 +265,80 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 30 + + + + + + + + 12 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 120 + 36 + + + + + 120 + 36 + + + + Cancel + + + + + + + + 120 + 36 + + + + + 120 + 36 + + + + Save + + + + + diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changegroupdialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/changegroupdialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/changegroupdialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changegroupdialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,420 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 "changegroupdialog.h" +#include "ui_changegroupdialog.h" +#include "definegroupitem.h" +#include "ImageUtil/imageutil.h" +#include "creategroupdialog.h" +#include "editgroupdialog.h" +#include "delgroupdialog.h" +#include "CloseButton/closebutton.h" + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +ChangeGroupDialog::ChangeGroupDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ChangeGroupDialog) +{ + ui->setupUi(this); + setupInit(); + signalsBind(); +} + +ChangeGroupDialog::~ChangeGroupDialog() +{ + delete ui; + ui = nullptr; +} + +void ChangeGroupDialog::connectToServer() +{ + serviceInterface = new QDBusInterface("org.ukui.groupmanager", + "/org/ukui/groupmanager", + "org.ukui.groupmanager.interface", + QDBusConnection::systemBus()); + if (!serviceInterface->isValid()) + { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } + // 将以后所有DBus调用的超时设置为 milliseconds + serviceInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} + +void ChangeGroupDialog::loadGroupInfo() +{ + qDebug() << "loadGroupInfo"; + QDBusMessage msg = serviceInterface->call("getGroup"); + if(msg.type() == QDBusMessage::ErrorMessage) { + printf("get group info fail.\n"); + } + QDBusArgument argument = msg.arguments().at(0).value(); + QList infos; + argument >> infos; + + groupList = new QList(); + for (int i = 0; i < infos.size(); i++) + { + custom_struct *dbus_struct = new custom_struct; + infos.at(i).value() >> *dbus_struct; + groupList->push_back(dbus_struct); + } +} + +void ChangeGroupDialog::loadPasswdInfo() +{ + qDebug() << "loadPasswdInfo"; + QDBusMessage msg = serviceInterface->call("getPasswd"); + if(msg.type() == QDBusMessage::ErrorMessage) { + printf("get passwd info fail.\n"); + } + QDBusArgument argument = msg.arguments().at(0).value(); + QList infos; + argument >> infos; + + passwdList = new QList(); + for (int i = 0; i < infos.size(); i++){ + custom_struct *dbus_struct = new custom_struct; + infos.at(i).value() >> *dbus_struct; + passwdList->push_back(dbus_struct); + } +} + +void ChangeGroupDialog::refreshList() +{ + qDebug() << "refresh list"; + int count = ui->listWidget->count(); + for(int i = count; i >= 0; i--){ + QListWidgetItem *item = ui->listWidget->item(i); + ui->listWidget->takeItem(i); + ui->listWidget->removeItemWidget(item); + delete item; + item = nullptr; + } + loadGroupInfo(); + loadAllGroup(); +} + +bool ChangeGroupDialog::polkitEdit() +{ + PolkitQt1::Authority::Result result; + //PolkitQt1::SystemBusNameSubject subject(message().service()); + + result = PolkitQt1::Authority::instance()->checkAuthorizationSync( + "org.ukui.groupmanager.action.edit", + PolkitQt1::UnixProcessSubject(QCoreApplication::applicationPid()), + PolkitQt1::Authority::AllowUserInteraction); + if (result == PolkitQt1::Authority::Yes) { //认证通过 + qDebug() << QString("operation authorized"); + return true; + } else { + qDebug() << QString("not authorized"); + return false; + } +} + +bool ChangeGroupDialog::polkitDel() +{ + PolkitQt1::Authority::Result result; + //PolkitQt1::SystemBusNameSubject subject(message().service()); + + result = PolkitQt1::Authority::instance()->checkAuthorizationSync( + "org.ukui.groupmanager.action.del", + PolkitQt1::UnixProcessSubject(QCoreApplication::applicationPid()), + PolkitQt1::Authority::AllowUserInteraction); + if (result == PolkitQt1::Authority::Yes) { //认证通过 + qDebug() << QString("operation authorized"); + return true; + } else { + qDebug() << QString("not authorized"); + return false; + } +} + +bool ChangeGroupDialog::polkitAdd() +{ + PolkitQt1::Authority::Result result; + //PolkitQt1::SystemBusNameSubject subject(message().service()); + + result = PolkitQt1::Authority::instance()->checkAuthorizationSync( + "org.ukui.groupmanager.action.add", + PolkitQt1::UnixProcessSubject(QCoreApplication::applicationPid()), + PolkitQt1::Authority::AllowUserInteraction); + if (result == PolkitQt1::Authority::Yes) { //认证通过 + qDebug() << QString("operation authorized"); + return true; + } else { + qDebug() << QString("not authorized"); + return false; + } +} + +void ChangeGroupDialog::loadAllGroup() +{ + for(int i = 0; i < groupList->size(); i++){ + bool idSetEnable = true; + DefineGroupItem * singleWidget = new DefineGroupItem(groupList->at(i)->groupname); + singleWidget->setDeleteable(true); + singleWidget->setUpdateable(true); + singleWidget->setEditable(true); + + for(int j = 0; j < passwdList->size(); j++){ + if(passwdList->at(j)->groupid == groupList->at(i)->groupid){ + singleWidget->setDeleteable(false); + idSetEnable = false; + } + } + singleWidget->setFrameShape(QFrame::Shape::Box); + singleWidget->setProperty("userData", true); + + QListWidgetItem * item = new QListWidgetItem(ui->listWidget); + item->setSizeHint(QSize(ui->listWidget->width() - 5, 50)); + item->setData(Qt::UserRole, ""); + ui->listWidget->setItemWidget(item, singleWidget); + + QPushButton *itemDelBtn = singleWidget->delBtnComponent(); + QPushButton *itemEditBtn = singleWidget->editBtnComponent(); + + connect(itemDelBtn, &QPushButton::clicked, [=](){ + bool reply = polkitDel(); + qDebug() << "call polkitdel " << reply; + if(reply){ + DelGroupDialog *delDialog = new DelGroupDialog(groupList->at(i)->groupname); + QPushButton *delBtn = delDialog->delBtnComponent(); + connect(delBtn, &QPushButton::clicked, [=](){ + QDBusReply reply = serviceInterface->call("del",groupList->at(i)->groupname); + if (reply.isValid()){ + // use the returned value + qDebug() << "get call value" << reply.value(); + // qDebug() << "current index" << ui->listWidget->currentIndex(); + ui->listWidget->removeItemWidget(item); + delete item; + + ui->listWidget->scrollTo(ui->listWidget->currentIndex()); + delDialog->close(); + } else { + // call failed. Show an error condition. + qDebug() << "call failed" << reply.error(); + } + refreshList(); + }); + delDialog->exec(); + } + }); + connect(itemEditBtn, &QPushButton::clicked, [=](){ + bool reply = polkitEdit(); + qDebug() << "call polkitedit " << reply; + if(reply){ + EditGroupDialog *editDialog = new EditGroupDialog(groupList->at(i)->usergroup,groupList->at(i)->groupid, + groupList->at(i)->groupname, idSetEnable); + connect(editDialog, &EditGroupDialog::needRefresh, this, &ChangeGroupDialog::needRefreshSlot); + QLineEdit *lineName = editDialog->lineNameComponent(); + QLineEdit *lineId = editDialog->lineIdComponent(); + lineName->setText(groupList->at(i)->groupname); + lineId->setText(groupList->at(i)->groupid); + editDialog->exec(); + } + + }); + } +// ui->listWidget->setSortingEnabled(true); +} + +void ChangeGroupDialog::setupInit() +{ + setWindowTitle(tr("User group")); + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + + ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); + + ui->listWidget->setFocusPolicy(Qt::NoFocus); + ui->listWidget->setSelectionMode(QAbstractItemView::NoSelection); + ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listWidget->setSpacing(1); + + connectToServer(); + initNewGroupBtn(); + loadGroupInfo(); + loadPasswdInfo(); + loadAllGroup(); +} + +void ChangeGroupDialog::signalsBind() +{ + connect(ui->cancelPushBtn, &QPushButton::clicked, [=]{ + close(); + }); +} + +void ChangeGroupDialog::initNewGroupBtn() +{ + addWgt = new HoverWidget(""); + addWgt->setObjectName("addwgt"); + addWgt->setMinimumSize(QSize(454, 50)); + addWgt->setMaximumSize(QSize(454, 50)); + addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); + + QHBoxLayout *addLyt = new QHBoxLayout; + + QLabel * iconLabel = new QLabel(); + QLabel * textLabel = new QLabel(tr("Add user group")); + QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); + iconLabel->setPixmap(pixgray); + addLyt->addWidget(iconLabel); + addLyt->addWidget(textLabel); + addLyt->addStretch(); + addWgt->setLayout(addLyt); + + // 悬浮改变Widget状态 + connect(addWgt, &HoverWidget::enterWidget, this, [=](){ + QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); + iconLabel->setPixmap(pixgray); + textLabel->setStyleSheet("color: palette(base);"); + + }); + // 还原状态 + connect(addWgt, &HoverWidget::leaveWidget, this, [=](){ + QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); + iconLabel->setPixmap(pixgray); + textLabel->setStyleSheet("color: palette(windowText);"); + }); + + connect(addWgt, &HoverWidget::widgetClicked, this, [=](){ + bool reply = polkitAdd(); + qDebug() << "call polkitadd " << reply; + if(reply){ + CreateGroupDialog *dialog = new CreateGroupDialog(); + QPushButton *certainBtn = dialog->certainBtnComponent(); + QLineEdit *lineId = dialog->lineIdComponent(); + QLineEdit *lineName = dialog->lineNameComponent(); + QListWidget *cglist = dialog->listWidgetComponent(); + + connect(certainBtn, &QPushButton::clicked, this, [=](){ + for (int j = 0; j < groupList->size(); j++){ + if(lineId->text() == groupList->at(j)->groupid){ + QMessageBox invalid(QMessageBox::Question, tr("Tips"), tr("Invalid Id!")); + invalid.setIcon(QMessageBox::Warning); + invalid.setStandardButtons(QMessageBox::Ok); + invalid.setButtonText(QMessageBox::Ok, QString(tr("OK"))); + invalid.exec(); + return; + } + if(lineName->text() == groupList->at(j)->groupname){ + QMessageBox invalid(QMessageBox::Question, tr("Tips"), tr("Invalid Group Name!")); + invalid.setIcon(QMessageBox::Warning); + invalid.setStandardButtons(QMessageBox::Ok); + invalid.setButtonText(QMessageBox::Ok, QString(tr("OK"))); + invalid.exec(); + return; + } + } + + QDBusReply reply = serviceInterface->call("add",lineName->text(),lineId->text()); + if (reply.isValid()){ + // use the returned value + qDebug() << "get call value" << reply.value(); + } else { + // call failed. Show an error condition. + qDebug() << "call failed" << reply.error(); + } + + for (int i = 0; i < cglist->count(); i++){ + QListWidgetItem *item = cglist->item(i); + QCheckBox *box = static_cast (cglist->itemWidget(item)); + if(box->isChecked()){ + QDBusReply reply = serviceInterface->call("addUserToGroup", + lineName->text(),box->text()); + if (reply.isValid()){ + // use the returned value + qDebug() << "addUserToGroupget call value" << reply.value() << lineName->text() << box->text(); + } else { + // call failed. Show an error condition. + qDebug() << "addUserToGroup call failed" << reply.error(); + } + } else { + QDBusReply reply = serviceInterface->call("delUserFromGroup", + lineId->text(),box->text()); + if (reply.isValid()){ + // use the returned value + qDebug() << "delUserFromGroup get call value" << reply.value() << lineName->text() << box->text();; + } else { + // call failed. Show an error condition. + qDebug() << "delUserFromGroup call failed" << reply.error() << lineName->text() << box->text();; + } + } + } + refreshList(); + ui->listWidget->scrollToBottom(); + dialog->close(); + }); + dialog->exec(); + } + }); + ui->addLyt->addWidget(addWgt); +} + +void ChangeGroupDialog::paintEvent(QPaintEvent * event){ + Q_UNUSED(event) + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); + p.restore(); +} + +void ChangeGroupDialog::needRefreshSlot() +{ + refreshList(); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changegroupdialog.h ukui-control-center-3.0.3/plugins/account/userinfo/changegroupdialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/changegroupdialog.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changegroupdialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,110 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 CHANGEGROUPDIALOG_H +#define CHANGEGROUPDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HoverWidget/hoverwidget.h" + +struct custom_struct +{ + QString groupname; + QString passphrase; + QString groupid; + QString usergroup; + + friend QDBusArgument &operator<<(QDBusArgument &argument, const custom_struct&mystruct) + { + argument.beginStructure(); + argument << mystruct.groupname << mystruct.passphrase << mystruct.groupid << mystruct.usergroup; + argument.endStructure(); + return argument; + } + + friend const QDBusArgument &operator>>(const QDBusArgument &argument, custom_struct&mystruct) + { + argument.beginStructure(); + argument >> mystruct.groupname >> mystruct.passphrase >> mystruct.groupid >> mystruct.usergroup; + argument.endStructure(); + return argument; + } + +}; + +Q_DECLARE_METATYPE(custom_struct) + +namespace Ui { +class ChangeGroupDialog; +} + +class ChangeGroupDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ChangeGroupDialog(QWidget *parent = nullptr); + ~ChangeGroupDialog(); + +public: + void connectToServer(); + void initNewGroupBtn(); + void loadGroupInfo(); + void loadPasswdInfo(); + void loadAllGroup(); + bool polkitEdit(); + bool polkitDel(); + bool polkitAdd(); + void refreshList(); + +public: + QDBusInterface *serviceInterface; + QList *groupList; + QList *passwdList; + +protected: + void paintEvent(QPaintEvent * event); + +private: + Ui::ChangeGroupDialog *ui; + + HoverWidget *addWgt; + + void setupInit(); + void signalsBind(); + +private slots: + void needRefreshSlot(); +}; + +#endif // CHANGEGROUPDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changegroupdialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/changegroupdialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/changegroupdialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changegroupdialog.ui 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,229 @@ + + + ChangeGroupDialog + + + + 0 + 0 + 567 + 645 + + + + + 0 + 0 + + + + + 540 + 645 + + + + + 567 + 645 + + + + Dialog + + + + 0 + + + 44 + + + 12 + + + 24 + + + 10 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 38 + + + + User Group Settings + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 12 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 455 + 360 + + + + + 455 + 360 + + + + + + + + + 454 + 50 + + + + + 454 + 50 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 8 + + + 0 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 18 + + + + + + + + 20 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changepwddialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/changepwddialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/changepwddialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changepwddialog.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -21,36 +21,65 @@ #include "ui_changepwddialog.h" #include "elipsemaskwidget.h" +#include "passwdcheckutil.h" #include #include +#include "CloseButton/closebutton.h" + +/* qt会将glib里的signals成员识别为宏,所以取消该宏 + * 后面如果用到signals时,使用Q_SIGNALS代替即可 + **/ +#ifdef signals +#undef signals +#endif + +extern "C" { +#include +#include + +} + + #define PWD_LOW_LENGTH 6 #define PWD_HIGH_LENGTH 20 + extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); -ChangePwdDialog::ChangePwdDialog(QWidget *parent) : + +ChangePwdDialog::ChangePwdDialog(bool _isCurrentUser, QString _username, QWidget *parent) : QDialog(parent), - ui(new Ui::ChangePwdDialog) + isCurrentUser(_isCurrentUser), + ui(new Ui::ChangePwdDialog), + currentUserName(_username) { ui->setupUi(this); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(tr("Change pwd")); - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); + curPwdTip = ""; + + timerForCheckPwd = new QTimer; + timerForCheckPwd->setInterval(1000); + timerForCheckPwd->setSingleShot(true); + ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); ui->pwdFrame->setFrameShape(QFrame::Shape::Box); + ui->tipLabel->setAlignment(Qt::AlignCenter); + ui->tipLabel->setStyleSheet("color:red;"); + +// ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); + +// isCurrentUser = true; + + pcThread = new PwdCheckThread(); - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); initPwdChecked(); setupComponent(); @@ -60,9 +89,50 @@ ChangePwdDialog::~ChangePwdDialog() { delete ui; + ui = nullptr; + +// pcThread->terminate(); +// delete pcThread; +} + +bool ChangePwdDialog::checkOtherPasswd(QString name, QString pwd){ + FILE * stream; + char command[128]; + char output[256]; + + QByteArray ba1 = name.toLatin1(); + + // + if (pwd.contains("'")){ + snprintf(command, 128, "/usr/bin/checkTest %s \"%s\"", ba1.data(), pwd.toLatin1().data()); + } else { + + snprintf(command, 128, "/usr/bin/checkTest %s '%s'", ba1.data(), pwd.toLatin1().data()); + } + + if ((stream = popen(command, "r")) == NULL){ + return false; + } + + while(fgets(output, 256, stream) != NULL){ + qDebug() << "output:" << QString(output).simplified(); + } + +// if (fread(output, sizeof(char), 128, stream) > 0){ +// pclose(stream); +// return true; +// } + + + + pclose(stream); + return false; } void ChangePwdDialog::initPwdChecked(){ + + + #ifdef ENABLEPQ int ret; void *auxerror; @@ -83,6 +153,12 @@ } else { enablePwdQuality = true; } + + if (PasswdCheckUtil::getCurrentPamState()) + enablePwdQuality = true; + else + enablePwdQuality = false; + #else enablePwdQuality = false; #endif @@ -93,11 +169,13 @@ ElipseMaskWidget * cpMaskWidget = new ElipseMaskWidget(ui->faceLabel); cpMaskWidget->setGeometry(0, 0, ui->faceLabel->width(), ui->faceLabel->height()); - ui->pwdtypeComboBox->addItem(tr("General Pwd")); + ui->pwdtypeComboBox->setText(tr("General Pwd")); + ui->curPwdLineEdit->setEchoMode(QLineEdit::Password); ui->pwdLineEdit->setEchoMode(QLineEdit::Password); ui->pwdsureLineEdit->setEchoMode(QLineEdit::Password); + ui->curPwdLineEdit->setPlaceholderText(tr("Current Password")); ui->pwdLineEdit->setPlaceholderText(tr("New Password")); ui->pwdsureLineEdit->setPlaceholderText(tr("New Password Identify")); @@ -105,12 +183,62 @@ } void ChangePwdDialog::setupConnect(){ - connect(ui->closeBtn, &QPushButton::clicked, [=]{ - close(); + + connect(pcThread, &PwdCheckThread::complete, this, [=](bool re){ + curPwdTip = re ? "" : tr("Pwd input error, re-enter!"); + + if (pwdTip.isEmpty() && pwdSureTip.isEmpty()){ + ui->tipLabel->setText(curPwdTip); + } + + if (curPwdTip.isEmpty()){ + pwdTip.isEmpty() ? ui->tipLabel->setText(pwdSureTip) : ui->tipLabel->setText(pwdTip); + } + + refreshConfirmBtnStatus(); }); - connect(ui->pwdLineEdit, &QLineEdit::textChanged, [=](QString text){ - pwdLegalityCheck(text); + if (isCurrentUser){ + + connect(timerForCheckPwd, &QTimer::timeout, [=]{ + /* 密码为空不检测 */ + if (ui->curPwdLineEdit->text().isEmpty()){ + return; + } + + pcThread->setArgs(currentUserName, ui->curPwdLineEdit->text()); + + pcThread->start(); + + }); + + connect(ui->curPwdLineEdit, &QLineEdit::textChanged, [=]{ + pwdLegalityCheck(); + + ui->confirmPushBtn->setEnabled(false); + + timerForCheckPwd->start(); + }); + + connect(ui->confirmPushBtn, &QPushButton::clicked, [=]{ + this->accept(); + + emit passwd_send(ui->pwdLineEdit->text()); + }); + } else { + connect(ui->confirmPushBtn, &QPushButton::clicked, [=]{ + this->accept(); + + emit passwd_send2(ui->pwdLineEdit->text()); + }); + } + + + + connect(ui->pwdLineEdit, &QLineEdit::textChanged, [=]{ + pwdLegalityCheck(); + + refreshConfirmBtnStatus(); }); connect(ui->pwdsureLineEdit, &QLineEdit::textChanged, [=](QString text){ if (!text.isEmpty() && text != ui->pwdLineEdit->text()){ @@ -121,18 +249,15 @@ ui->tipLabel->setText(pwdSureTip); if (pwdSureTip.isEmpty()){ - pwdTip.isEmpty() ? ui->tipLabel->setText(nameTip) : ui->tipLabel->setText(pwdTip); + pwdTip.isEmpty() ? ui->tipLabel->setText(curPwdTip) : ui->tipLabel->setText(pwdTip); } refreshConfirmBtnStatus(); }); connect(ui->cancelPushBtn, &QPushButton::clicked, [=]{ - reject(); - }); - connect(ui->confirmPushBtn, &QPushButton::clicked, [=]{ - this->accept(); - emit passwd_send(ui->pwdLineEdit->text(), ui->usernameLabel->text()); +// reject(); + close(); }); } @@ -141,18 +266,19 @@ } -void ChangePwdDialog::setUsername(QString username){ - ui->usernameLabel->setText(username); -} - -void ChangePwdDialog::setPwdType(QString type){ - ui->pwdtypeComboBox->setCurrentText(type); +void ChangePwdDialog::setUsername(QString realname){ + ui->usernameLabel->setText(realname); } void ChangePwdDialog::setAccountType(QString aType){ ui->aTypeLabel->setText(aType); } +void ChangePwdDialog::haveCurrentPwdEdit(bool have){ + ui->curPwdLineEdit->setVisible(have); + ui->label->setVisible(have); +} + void ChangePwdDialog::paintEvent(QPaintEvent *event) { Q_UNUSED(event) @@ -168,6 +294,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); @@ -194,37 +321,42 @@ } -void ChangePwdDialog::pwdLegalityCheck(QString pwd){ - if (enablePwdQuality){ +void ChangePwdDialog::pwdLegalityCheck(){ + // + if (!checkCharLegitimacy(ui->pwdLineEdit->text())){ + pwdTip = tr("Contains illegal characters!"); + } else if (QString::compare(ui->pwdLineEdit->text(), ui->curPwdLineEdit->text()) == 0 && !ui->pwdLineEdit->text().isEmpty()){ + pwdTip = tr("Same with old pwd"); + } else { + if (enablePwdQuality){ #ifdef ENABLEPQ - void * auxerror; - int ret; - const char * msg; - char buf[256]; - - QByteArray ba = pwd.toLatin1(); - - ret = pwquality_check(settings, ba.data(), NULL, NULL, &auxerror); - if (ret < 0 && pwd.length() > 0){ - msg = pwquality_strerror(buf, sizeof(buf), ret, auxerror); - pwdTip = QString(msg); - } else { - pwdTip = ""; - } + void * auxerror; + int ret; + const char * msg; + char buf[256]; + + QByteArray ba = ui->pwdLineEdit->text().toLatin1(); + QByteArray ba1 = ui->curPwdLineEdit->text().toLatin1(); + + if (isCurrentUser){ + ret = pwquality_check(settings, ba.data(), ba1.data(), currentUserName.toLatin1().data(), &auxerror); + } else { + ret = pwquality_check(settings, ba.data(), NULL, currentUserName.toLatin1().data(), &auxerror); + } + + if (ret < 0 && ui->pwdLineEdit->text().length() > 0){ + msg = pwquality_strerror(buf, sizeof(buf), ret, auxerror); + pwdTip = QString(msg); + } else { + pwdTip = ""; + } #endif - } else { //系统未开启pwdquality模块 - if (pwd.length() < PWD_LOW_LENGTH) { - pwdTip = tr("Password length needs to more than %1 character!").arg(PWD_LOW_LENGTH - 1); - } else if (pwd.length() > PWD_HIGH_LENGTH) { - pwdTip = tr("Password length needs to less than %1 character!").arg(PWD_HIGH_LENGTH + 1); - } else { + } else { //系统未开启pwdquality模块 pwdTip = ""; } } - - //防止先输入确认密码,再输入密码后pwdsuretipLabel无法刷新 if (!ui->pwdsureLineEdit->text().isEmpty()){ if (ui->pwdLineEdit->text() == ui->pwdsureLineEdit->text()) { @@ -236,19 +368,38 @@ ui->tipLabel->setText(pwdTip); if (pwdTip.isEmpty()){ - pwdSureTip.isEmpty() ? ui->tipLabel->setText(nameTip) : ui->tipLabel->setText(pwdSureTip); + pwdSureTip.isEmpty() ? ui->tipLabel->setText(curPwdTip) : ui->tipLabel->setText(pwdSureTip); } +} - refreshConfirmBtnStatus(); +bool ChangePwdDialog::checkCharLegitimacy(QString password){ + foreach (QChar ch, password){ + if (int(ch.toLatin1() <= 0 || int(ch.toLatin1()) > 127)){ + return false; + } + } + return true; } void ChangePwdDialog::refreshConfirmBtnStatus(){ - if (!ui->tipLabel->text().isEmpty() || \ - ui->pwdLineEdit->text().isEmpty() || ui->pwdLineEdit->text() == tr("New Password") || \ - ui->pwdsureLineEdit->text().isEmpty() || ui->pwdsureLineEdit->text() == tr("New Password Identify") || - !nameTip.isEmpty() || !pwdTip.isEmpty() || !pwdSureTip.isEmpty()) - ui->confirmPushBtn->setEnabled(false); - else - ui->confirmPushBtn->setEnabled(true); + + if (getuid() && isCurrentUser){ + if (!ui->tipLabel->text().isEmpty() || \ + ui->curPwdLineEdit->text().isEmpty() || ui->curPwdLineEdit->text() == tr("Current Password") || \ + ui->pwdLineEdit->text().isEmpty() || ui->pwdLineEdit->text() == tr("New Password") || \ + ui->pwdsureLineEdit->text().isEmpty() || ui->pwdsureLineEdit->text() == tr("New Password Identify") || + !curPwdTip.isEmpty() || !pwdTip.isEmpty() || !pwdSureTip.isEmpty()) + ui->confirmPushBtn->setEnabled(false); + else + ui->confirmPushBtn->setEnabled(true); + } else { + if (!ui->tipLabel->text().isEmpty() || \ + ui->pwdLineEdit->text().isEmpty() || ui->pwdLineEdit->text() == tr("New Password") || \ + ui->pwdsureLineEdit->text().isEmpty() || ui->pwdsureLineEdit->text() == tr("New Password Identify") || + !pwdTip.isEmpty() || !pwdSureTip.isEmpty()) + ui->confirmPushBtn->setEnabled(false); + else + ui->confirmPushBtn->setEnabled(true); + } } diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changepwddialog.h ukui-control-center-3.0.3/plugins/account/userinfo/changepwddialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/changepwddialog.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changepwddialog.h 2021-05-20 13:08:14.000000000 +0000 @@ -23,7 +23,11 @@ #include #include #include +#include +#include + +#include "pwdcheckthread.h" #ifdef ENABLEPQ extern "C" { @@ -47,7 +51,7 @@ Q_OBJECT public: - explicit ChangePwdDialog(QWidget *parent = 0); + explicit ChangePwdDialog(bool _isCurrentUser, QString _username, QWidget *parent = 0); ~ChangePwdDialog(); public: @@ -58,20 +62,26 @@ void refreshConfirmBtnStatus(); void setFace(QString iconfile); - void setUsername(QString username); + void setUsername(QString realname); void setPwdType(QString type); void setAccountType(QString text); + void haveCurrentPwdEdit(bool have); + + bool isCurrentUser; protected: void paintEvent(QPaintEvent *); -private slots: - void pwdLegalityCheck(QString pwd); private: Ui::ChangePwdDialog *ui; - QString nameTip; + + bool checkCharLegitimacy(QString password); + bool checkOtherPasswd(QString name, QString pwd); + + QString currentUserName; QString pwdTip; QString pwdSureTip; + QString curPwdTip; bool enablePwdQuality; @@ -79,8 +89,19 @@ pwquality_settings_t *settings; #endif +private: + PwdCheckThread * pcThread; + + QTimer * timerForCheckPwd; + + +private Q_SLOTS: + void pwdLegalityCheck(); + Q_SIGNALS: - void passwd_send(QString pwd, QString username); + void passwd_send(QString pwd); + void passwd_send2(QString pwd); + void pwdCheckOver(); }; #endif // CHANGEPWDDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changepwddialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/changepwddialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/changepwddialog.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changepwddialog.ui 2021-05-20 13:08:14.000000000 +0000 @@ -6,20 +6,20 @@ 0 0 - 401 - 458 + 364 + 450 - 401 - 458 + 360 + 450 - 401 - 458 + 384 + 450 @@ -33,16 +33,22 @@ 0 - 9 + 0 - 9 + 0 0 + + + 0 + 0 + + 0 @@ -60,26 +66,45 @@ 0 - 0 + 32 - 0 + 32 - 0 + 32 - 0 + 32 + + 0 + + + 0 + - 8 + 0 - 8 + 0 + + + + 0 + 0 + + + + Change Pwd + + + + Qt::Horizontal @@ -92,63 +117,40 @@ - - - - - 32 - 32 - - - - - 32 - 32 - - - - - - - - 24 + 12 - 32 + 0 - 16 + 0 - 32 + 0 - 48 + 0 - - - 0 + + + Qt::Vertical - - - - - 0 - 0 - - - - Change Pwd - - - - + + QSizePolicy::Fixed + + + + 20 + 10 + + + @@ -189,9 +191,9 @@ - 8 + 3 - + @@ -204,7 +206,7 @@ - + @@ -235,7 +237,29 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + 0 + 0 + + 0 @@ -255,7 +279,7 @@ - 8 + 10 0 @@ -267,14 +291,14 @@ 0 - 10 + 20 - + 0 0 @@ -287,7 +311,7 @@ - 104 + 16777215 16777215 @@ -301,13 +325,13 @@ 0 - 30 + 0 16777215 - 30 + 16777215 @@ -333,18 +357,15 @@ 0 - - - - 0 - 25 - + + + + 0 + 0 + - - - 16777215 - 25 - + + @@ -354,11 +375,50 @@ + + + + + + 104 + 0 + + + + + 104 + 16777215 + + + + Cur pwd + + + + + + + + 0 + 36 + + + + + 16777215 + 36 + + + + + + + - + 0 0 @@ -385,13 +445,13 @@ 0 - 32 + 36 16777215 - 32 + 36 @@ -403,7 +463,7 @@ - + 0 0 @@ -416,7 +476,7 @@ - 104 + 16777215 16777215 @@ -430,13 +490,13 @@ 0 - 32 + 36 16777215 - 32 + 36 @@ -449,25 +509,9 @@ 6 - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 110 - 20 - - - - - - + 0 0 @@ -485,22 +529,6 @@ - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 24 - - - - - diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changetypedialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/changetypedialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/changetypedialog.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changetypedialog.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -19,6 +19,7 @@ */ #include "changetypedialog.h" #include "ui_changetypedialog.h" +#include "CloseButton/closebutton.h" #include "elipsemaskwidget.h" @@ -34,20 +35,21 @@ setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(tr("Change type")); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); +// ui->closeBtn->setProperty("useIconHighlightEffect", true); +// ui->closeBtn->setProperty("iconHighlightEffectMode", 1); +// ui->closeBtn->setFlat(true); +// ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" +// "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); // ui->frame->setStyleSheet("QFrame{background: #ffffff; border: none; border-radius: 6px;}"); // ui->closeBtn->setStyleSheet("QPushButton{background: #ffffff; border: none;}"); - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); +// ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); setupComonpent(); @@ -57,6 +59,7 @@ ChangeTypeDialog::~ChangeTypeDialog() { delete ui; + ui = nullptr; } void ChangeTypeDialog::setupComonpent(){ @@ -69,9 +72,9 @@ ui->confirmPushBtn->setEnabled(false); - connect(ui->closeBtn, &QPushButton::clicked, [=]{ - close(); - }); +// connect(ui->closeBtn, &CloseButton::clicked, [=]{ +// close(); +// }); connect(ui->cancelPushBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) reject(); @@ -79,7 +82,7 @@ connect(ui->confirmPushBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) this->accept(); - emit type_send(ui->buttonGroup->checkedId(), ui->usernameLabel->text()); + emit type_send(ui->buttonGroup->checkedId()); }); } @@ -114,11 +117,13 @@ }); } -void ChangeTypeDialog::forbidenChange(int total){ - if (total <= 1 && currenttype == 1){ - ui->standardRadioButton->setEnabled(false); - } else { +void ChangeTypeDialog::forbidenChange(int can){ + if (can == -1) + return; + if (can){ ui->standardRadioButton->setEnabled(true); + } else { + ui->standardRadioButton->setEnabled(false); } } @@ -136,6 +141,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changetypedialog.h ukui-control-center-3.0.3/plugins/account/userinfo/changetypedialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/changetypedialog.h 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changetypedialog.h 2021-05-20 13:08:14.000000000 +0000 @@ -44,7 +44,7 @@ void setCurrentAccountTypeLabel(QString aType); void setCurrentAccountTypeBtn(int id); - void forbidenChange(int total); + void forbidenChange(int can); protected: void paintEvent(QPaintEvent *); @@ -56,7 +56,7 @@ bool currentloginstatus; Q_SIGNALS: - void type_send(int type, QString username); + void type_send(int type); }; #endif // CHANGETYPEDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changetypedialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/changetypedialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/changetypedialog.ui 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changetypedialog.ui 2021-05-20 13:08:14.000000000 +0000 @@ -6,19 +6,19 @@ 0 0 - 542 + 527 542 - 397 + 420 539 - 542 + 527 542 @@ -30,16 +30,16 @@ 0 - 0 + 12 - 9 + 6 - 9 + 12 - 0 + 10 @@ -54,29 +54,45 @@ 0 - 0 + 32 - 0 + 32 - 0 + 32 - 0 + 32 0 + + 0 + - 8 + 0 - 8 + 0 + + + + 0 + 0 + + + + Change Account Type + + + + Qt::Horizontal @@ -89,25 +105,6 @@ - - - - - 32 - 32 - - - - - 32 - 32 - - - - - - - @@ -116,36 +113,39 @@ 12 - 32 + 0 - 16 + 0 - 32 + 0 - 48 + 0 + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + 12 - - - - 0 - 0 - - - - Change Account Type - - - - @@ -161,7 +161,7 @@ - + Qt::Vertical @@ -171,7 +171,7 @@ 20 - 20 + 10 @@ -179,7 +179,7 @@ - 8 + 12 0 @@ -215,9 +215,9 @@ - 8 + 3 - + @@ -230,7 +230,7 @@ - + @@ -261,7 +261,7 @@ - + Qt::Vertical @@ -271,253 +271,297 @@ 20 - 12 + 10 - - - - 0 - 88 - - - - - 16777215 - 88 - - - - - 0 - - - 0 - - - 0 + + + 1 + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 450 + 185 + - - 0 - - - 0 - - - - - 16 - - - 16 - - - 0 - - - - - - 16 - 0 - + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 450 + 68 + + + + + 450 + 16777215 + + + + + 0 - - - 16 - 16777215 - + + 0 - - + + 0 - - buttonGroup - - - - - - - 12 + + 0 + + + 0 - - - - 0 - 0 - + + + 16 - - standard user + + 6 - - - - - - - 0 - 0 - + + 0 - - Standard users can use most software, but cannot install software and change system settings - - + + + + + 16 + 0 + + + + + 16 + 16777215 + + + + + + + buttonGroup + + + + + + + 3 + + + + + + 0 + 0 + + + + standard user + + + + + + + + 0 + 0 + + + + Standard users can use most software, but cannot change system settings + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - - Qt::Horizontal - - - - 40 - 20 - + + + + + + + 0 + 0 + + + + + 450 + 68 + + + + + 450 + 16777215 + + + + + 0 - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 4 - - - - - - - - - 0 - 88 - - - - - 16777215 - 88 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 16 - - - 16 - - - 0 - - - - - - 16 - 0 - + + 0 - - - 16 - 16777215 - + + 0 - - + + 0 - - buttonGroup - - - - - - - 12 + + 0 - - - - 0 - 0 - + + + 16 - - administrator + + 6 - - - - - - - 0 - 0 - + + 0 - - Administrators can make any changes they need - - + + + + + 16 + 0 + + + + + 16 + 16777215 + + + + + + + buttonGroup + + + + + + + 3 + + + + + + 0 + 0 + + + + administrator + + + + + + + + 0 + 0 + + + + Administrators can make any changes they need + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - + + + + widget_2 + widget + @@ -531,7 +575,7 @@ 20 - 36 + 8 diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changeusername.cpp ukui-control-center-3.0.3/plugins/account/userinfo/changeusername.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/changeusername.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changeusername.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,81 @@ +#include "changeusername.h" +#include "ui_changeusername.h" + + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +ChangeUserName::ChangeUserName(QWidget *parent) : + QDialog(parent), + ui(new Ui::ChangeUserName) +{ + ui->setupUi(this); + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + + ui->saveBtn->setEnabled(false); + + connect(ui->lineEdit, &QLineEdit::textChanged, this, [=](QString txt){ + if (!txt.isEmpty()){ + ui->saveBtn->setEnabled(true); + } else { + ui->saveBtn->setEnabled(false); + } + }); + + + connect(ui->cancelBtn, &QPushButton::clicked, [=]{ + close(); + }); + + connect(ui->saveBtn, &QPushButton::clicked, [=]{ + emit sendNewName(ui->lineEdit->text()); + close(); + }); +} + +ChangeUserName::~ChangeUserName() +{ + delete ui; +} + +void ChangeUserName::paintEvent(QPaintEvent *event) { + Q_UNUSED(event) + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); + p.restore(); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changeusername.h ukui-control-center-3.0.3/plugins/account/userinfo/changeusername.h --- ukui-control-center-2.0.3/plugins/account/userinfo/changeusername.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changeusername.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,30 @@ +#ifndef CHANGEUSERNAME_H +#define CHANGEUSERNAME_H + +#include +#include +#include + +namespace Ui { +class ChangeUserName; +} + +class ChangeUserName : public QDialog +{ + Q_OBJECT + +public: + explicit ChangeUserName(QWidget *parent = nullptr); + ~ChangeUserName(); + +private: + Ui::ChangeUserName *ui; + +protected: + void paintEvent(QPaintEvent *); + +Q_SIGNALS: + void sendNewName(QString name); +}; + +#endif // CHANGEUSERNAME_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changeusername.ui ukui-control-center-3.0.3/plugins/account/userinfo/changeusername.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/changeusername.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changeusername.ui 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,208 @@ + + + ChangeUserName + + + + 0 + 0 + 380 + 186 + + + + + 380 + 186 + + + + + 380 + 186 + + + + Change Username + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 8 + + + 32 + + + 32 + + + 32 + + + 24 + + + + + + + Change Username + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 316 + 36 + + + + + 316 + 36 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 32 + + + + + + + + 16 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 33 + + + + + 100 + 33 + + + + Cancel + + + + + + + + 100 + 33 + + + + + 100 + 33 + + + + Save + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changevaliddialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/changevaliddialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/changevaliddialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changevaliddialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -19,6 +19,7 @@ */ #include "changevaliddialog.h" #include "ui_changevaliddialog.h" +#include "CloseButton/closebutton.h" #include #include @@ -29,24 +30,29 @@ ChangeValidDialog::ChangeValidDialog(QString userName, QWidget *parent) : QDialog(parent), - _name(userName), - ui(new Ui::ChangeValidDialog) + ui(new Ui::ChangeValidDialog), + _name(userName) { ui->setupUi(this); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(tr("Change valid")); - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); +// ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); +// ui->closeBtn->setProperty("useIconHighlightEffect", true); +// ui->closeBtn->setProperty("iconHighlightEffectMode", 1); +// ui->closeBtn->setFlat(true); + +// ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" +// "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); + + ui->monthCombox->setMaxVisibleItems(3); + ui->yearCombox->setMaxVisibleItems(3); + ui->dayCombox->setMaxVisibleItems(3); ui->validFrame->setFrameShape(QFrame::Shape::Box); @@ -61,12 +67,13 @@ ChangeValidDialog::~ChangeValidDialog() { delete ui; + ui = nullptr; } void ChangeValidDialog::setupConnect(){ - connect(ui->closeBtn, &QPushButton::clicked, [=]{ - close(); - }); +// connect(ui->closeBtn, &CloseButton::clicked, [=]{ +// close(); +// }); connect(ui->cancelBtn, &QPushButton::clicked, [=]{ reject(); }); @@ -91,10 +98,20 @@ }); connect(ui->certainBtn, &QPushButton::clicked, [=]{ + QDBusInterface * tmpSysinterface = new QDBusInterface("com.control.center.qt.systemdbus", + "/", + "com.control.center.interface", + QDBusConnection::systemBus()); + + if (!tmpSysinterface->isValid()){ + qCritical() << "Create Client Interface Failed When execute chage: " << QDBusConnection::systemBus().lastError(); + return; + } + int year = ui->yearCombox->currentData().toInt(); - QString cmd; + if (year == 0){ - cmd = QString("chage -M %1 %2").arg(99999).arg(_name); + tmpSysinterface->call("setPasswdAging", 99999, _name); } else { int month = ui->monthCombox->currentData().toInt(); int day = ui->dayCombox->currentData().toInt(); @@ -103,21 +120,11 @@ int setDays = lastChangeDate.daysTo(selected); - cmd = QString("chage -M %1 %2").arg(setDays).arg(_name); - + tmpSysinterface->call("setPasswdAging", setDays, _name); } - QDBusInterface * tmpSysinterface = new QDBusInterface("com.control.center.qt.systemdbus", - "/", - "com.control.center.interface", - QDBusConnection::systemBus()); - - if (!tmpSysinterface->isValid()){ - qCritical() << "Create Client Interface Failed When execute chage: " << QDBusConnection::systemBus().lastError(); - return; - } - tmpSysinterface->call("systemRun", cmd); delete tmpSysinterface; + tmpSysinterface = nullptr; close(); }); @@ -138,13 +145,20 @@ void ChangeValidDialog::_getCurrentPwdStatus(){ // QString cmd = "passwd -S " + _name; + QString valid; - QProcess * process = new QProcess; - process->start(cmd); - process->waitForFinished(); + FILE *stream; + char buf[256]; + + if ((stream = popen(cmd.toLatin1().data(), "r" )) == NULL){ + return; + } + + while(fgets(buf, 256, stream) != NULL){ + valid = QString(buf).simplified(); + } - QByteArray ba = process->readAllStandardOutput(); - QString valid = QString(ba.data()).simplified(); + pclose(stream); if (valid.startsWith(_name)){ QStringList validList = valid.split(" "); @@ -199,7 +213,7 @@ ui->yearCombox->addItem(QObject::tr("Never"), 0); for (int year = begin.year(); year <= canSelect.year(); year++){ - ui->yearCombox->addItem(QString::number(year)+QObject::tr("Year"), year); + ui->yearCombox->addItem(QString::number(year)/*+QObject::tr("Year")*/, year); } if (delayDays > 10000) @@ -217,21 +231,30 @@ int year = ui->yearCombox->currentData().toInt(); if (year > 0){ - ui->monthCombox->addItem(QObject::tr("Jan"), 1); - ui->monthCombox->addItem(QObject::tr("Feb"), 2); - ui->monthCombox->addItem(QObject::tr("Mar"), 3); - ui->monthCombox->addItem(QObject::tr("Apr"), 4); - ui->monthCombox->addItem(QObject::tr("May"), 5); - ui->monthCombox->addItem(QObject::tr("Jun"), 6); - ui->monthCombox->addItem(QObject::tr("Jul"), 7); - ui->monthCombox->addItem(QObject::tr("Aug"), 8); - ui->monthCombox->addItem(QObject::tr("Sep"), 9); - ui->monthCombox->addItem(QObject::tr("Oct"), 10); - ui->monthCombox->addItem(QObject::tr("Nov"), 11); - ui->monthCombox->addItem(QObject::tr("Dec"), 12); - } - + QDate begin = QDate::currentDate().addDays(1); + if (year == begin.year()){ + for (int i = begin.month(); i < 13; i++){ + ui->monthCombox->addItem(QString::number(i), i); + } + } else { + for (int i = 1; i < 13; i++){ + ui->monthCombox->addItem(QString::number(i), i); + } + } +// ui->monthCombox->addItem(/*QObject::tr("Jan")*/"1", 1); +// ui->monthCombox->addItem(/*QObject::tr("Feb")*/"2", 2); +// ui->monthCombox->addItem(/*QObject::tr("Mar")*/"3", 3); +// ui->monthCombox->addItem(/*QObject::tr("Apr")*/"4", 4); +// ui->monthCombox->addItem(/*QObject::tr("May")*/"5", 5); +// ui->monthCombox->addItem(/*QObject::tr("Jun")*/"6", 6); +// ui->monthCombox->addItem(/*QObject::tr("Jul")*/"7", 7); +// ui->monthCombox->addItem(/*QObject::tr("Aug")*/"8", 8); +// ui->monthCombox->addItem(/*QObject::tr("Sep")*/"9", 9); +// ui->monthCombox->addItem(/*QObject::tr("Oct")*/"10", 10); +// ui->monthCombox->addItem(/*QObject::tr("Nov")*/"11", 11); +// ui->monthCombox->addItem(/*QObject::tr("Dec")*/"12", 12); + } ui->monthCombox->blockSignals(false); } @@ -247,10 +270,19 @@ int month = ui->monthCombox->currentData().toInt(); if (month){ QDate selected = QDate(year, month, 1); + QDate begin = QDate::currentDate().addDays(1); int days = selected.daysInMonth(); - for (int d = 1; d <= days; d++){ - ui->dayCombox->addItem(QString::number(d)+QObject::tr("Day"), d); + + if (year == begin.year() && month == begin.month()){ + for (int d = begin.day(); d <= days; d++){ + ui->dayCombox->addItem(QString::number(d)/*+QObject::tr("Day")*/, d); + } + } else { + for (int d = 1; d <= days; d++){ + ui->dayCombox->addItem(QString::number(d)/*+QObject::tr("Day")*/, d); + } } + } } else { @@ -275,6 +307,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/changevaliddialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/changevaliddialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/changevaliddialog.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/changevaliddialog.ui 2021-04-14 01:27:20.000000000 +0000 @@ -7,19 +7,25 @@ 0 0 370 - 410 + 380 + + + 0 + 0 + + 370 - 410 + 380 370 - 410 + 380 @@ -33,16 +39,22 @@ 0 - 9 + 0 - 9 + 0 0 + + + 0 + 0 + + QFrame::NoFrame @@ -54,21 +66,21 @@ 0 - 0 + 40 0 - 0 + 42 - 0 + 6 - 0 + 12 0 @@ -115,6 +127,19 @@ 0 + + + + 0 + 0 + + + + Password Validity Setting + + + + Qt::Horizontal @@ -127,25 +152,6 @@ - - - - - 32 - 32 - - - - - 32 - 32 - - - - - - - @@ -154,34 +160,21 @@ - 18 + 12 - 32 + 0 - 16 + 0 - 32 + 0 - 48 + 0 - - - - 0 - 0 - - - - Password Validity Setting - - - - @@ -220,7 +213,7 @@ - 8 + 12 @@ -252,7 +245,10 @@ - + + 3 + + @@ -265,7 +261,7 @@ - + @@ -343,6 +339,12 @@ + + + 0 + 0 + + 0 @@ -420,10 +422,10 @@ - + - + @@ -434,7 +436,29 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 16 + + + + + + + + 0 + 0 + + 0 diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/creategroupdialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/creategroupdialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/creategroupdialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/creategroupdialog.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,262 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 "creategroupdialog.h" +#include "ui_creategroupdialog.h" +#include "userinfo.h" +#include "changegroupdialog.h" +#include "CloseButton/closebutton.h" + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +CreateGroupDialog::CreateGroupDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CreateGroupDialog), + cgDialog(new ChangeGroupDialog), + _nameHasModified(false), + _idHasModified(false), + _boxModified(false) +{ + ui->setupUi(this); + setupInit(); + getUsersList(); + signalsBind(); +} + +CreateGroupDialog::~CreateGroupDialog() +{ + delete cgDialog; + cgDialog = nullptr; + delete ui; + ui = nullptr; +} + +void CreateGroupDialog::limitInput() +{ + QIntValidator *intValidator = new QIntValidator; + // QRegExp rx("^[a-zA-z]+$");// 首字符为字母 + QRegExp rx("^[a-zA-Z][a-zA-Z0-9_-]*${32}"); + QRegExpValidator *regValidator = new QRegExpValidator(rx); + // intValidator->setRange(0, 65535); + intValidator->setBottom(0); + // 整形输入限制 + ui->lineEdit_id->setValidator(intValidator); + // 字母输入限制 + ui->lineEdit_name->setValidator(regValidator); + // 字符长度限制 + // ui->lineEdit_name->setMaxLength(4); +} + +void CreateGroupDialog::refreshCertainBtnStatus() +{ + if (ui->lineEdit_name->text().isEmpty() + || ui->lineEdit_id->text().isEmpty()) + ui->certainBtn->setEnabled(false); + else + ui->certainBtn->setEnabled(_nameHasModified || _idHasModified); +} + +UserInfomationss CreateGroupDialog::_acquireUserInfo(QString objpath) +{ + UserInfomationss user; + + // 默认值 + user.current = false; + user.logined = false; + user.autologin = false; + + QDBusInterface *iproperty = new QDBusInterface("org.freedesktop.Accounts", + objpath, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + QDBusReply > reply = iproperty->call("GetAll", + "org.freedesktop.Accounts.User"); + if (reply.isValid()) { + QMap propertyMap; + propertyMap = reply.value(); + user.username = propertyMap.find("UserName").value().toString(); + if (user.username == QString(g_get_user_name())) { + user.current = true; + user.logined = true; + } + } else + qDebug() << "reply failed"; + + delete iproperty; + iproperty = nullptr; + + return user; +} + +void CreateGroupDialog::getUsersList() +{ + qDebug() << "当前文件 :" << __FILE__ << "当前函数 :" << __FUNCTION__ << "当前行号 :" << __LINE__; + QStringList allUsers; + sysdispatcher = new SystemDbusDispatcher(this); + + QStringList objectpaths = sysdispatcher->list_cached_users(); + allUserInfoMap.clear(); + // root + if (!getuid()) { + UserInfomationss root; + root.username = g_get_user_name(); + root.current = true; + root.logined = true; + root.autologin = false; + root.uid = 0; + root.accounttype = ADMINISTRATOR; + // root.iconfile = DEFAULTFACE; + allUserInfoMap.insert(root.username, root); + } + for (QString objectpath : objectpaths) { + UserInfomationss user; + user = _acquireUserInfo(objectpath); + allUserInfoMap.insert(user.username, user); + } + for (QVariant tmp : allUserInfoMap.keys()) { + allUsers << tmp.toString(); + } + QStringList usersList = allUsers; + + for (int i = 0; i < usersList.size(); i++) { + QListWidgetItem *item = new QListWidgetItem(ui->listWidget); + item->setSizeHint(QSize(ui->listWidget->width(), 36)); + item->setData(Qt::UserRole, ""); + QCheckBox *box = new QCheckBox(usersList.at(i)); + ui->listWidget->addItem(item); + ui->listWidget->setItemWidget(item, box); + connect(box, &QCheckBox::clicked, this, [=](bool checked){ + qDebug() << "checkbox clicked" << checked; + _boxModified = true; + refreshCertainBtnStatus(); + }); + } +} + +QPushButton *CreateGroupDialog::certainBtnComponent() +{ + return ui->certainBtn; +} + +QLineEdit *CreateGroupDialog::lineNameComponent() +{ + return ui->lineEdit_name; +} + +QLineEdit *CreateGroupDialog::lineIdComponent() +{ + return ui->lineEdit_id; +} + +QListWidget *CreateGroupDialog::listWidgetComponent() +{ + return ui->listWidget; +} + +void CreateGroupDialog::signalsBind() +{ + connect(ui->cancelBtn, &QPushButton::clicked, [=](){ + close(); + }); + connect(ui->lineEdit_name, &QLineEdit::textChanged, [=](QString txt){ + Q_UNUSED(txt); + refreshCertainBtnStatus(); + }); + connect(ui->lineEdit_id, &QLineEdit::textChanged, [=](QString txt){ + Q_UNUSED(txt); + refreshCertainBtnStatus(); + }); + connect(ui->lineEdit_id, &QLineEdit::textEdited, [=](){ + for (int j = 0; j < cgDialog->groupList->size(); j++) { + if (ui->lineEdit_id->text() == cgDialog->groupList->at(j)->groupid) { + _idHasModified = false; + } + } + _idHasModified = true; + }); + connect(ui->lineEdit_name, &QLineEdit::textEdited, [=](){ + for (int j = 0; j < cgDialog->groupList->size(); j++) { + if (ui->lineEdit_id->text() == cgDialog->groupList->at(j)->groupname) { + _nameHasModified = false; + } + } + _nameHasModified = true; + }); +} + +void CreateGroupDialog::setupInit() +{ + setWindowTitle(tr("Add user group")); + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + + ui->listWidget->setFocusPolicy(Qt::NoFocus); + ui->listWidget->setSelectionMode(QAbstractItemView::NoSelection); + ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + ui->listWidget->setStyleSheet("QListWidget{border-radius: 4px;}" + "QListWidget::Item{padding-left:20px;}"); + + // 设置确认按钮 + refreshCertainBtnStatus(); + // 限制组名输入规则 + limitInput(); +} + +void CreateGroupDialog::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath, palette().color(QPalette::Base)); + p.restore(); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/creategroupdialog.h ukui-control-center-3.0.3/plugins/account/userinfo/creategroupdialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/creategroupdialog.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/creategroupdialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,88 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 CREATEGROUPDIALOG_H +#define CREATEGROUPDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qtdbus/systemdbusdispatcher.h" + +typedef struct _UserInfomationss { + QString objpath; + QString username; + QString iconfile; + QString passwd; + int accounttype; + int passwdtype; + bool current; + bool logined; + bool autologin; + bool noPwdLogin; + qint64 uid; +}UserInfomationss; + +class ChangeGroupDialog; +namespace Ui { +class CreateGroupDialog; +} + +class CreateGroupDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CreateGroupDialog(QWidget *parent = nullptr); + ~CreateGroupDialog(); + +public: + void limitInput(); + void getUsersList(); + void refreshCertainBtnStatus(); + QPushButton * certainBtnComponent(); + QLineEdit * lineNameComponent(); + QLineEdit * lineIdComponent(); + QListWidget * listWidgetComponent(); + +protected: + void paintEvent(QPaintEvent *event); + +private: + Ui::CreateGroupDialog *ui; + ChangeGroupDialog *cgDialog = nullptr; + bool _nameHasModified; + bool _idHasModified; + bool _boxModified; + QMap allUserInfoMap; + SystemDbusDispatcher * sysdispatcher; + + void setupInit(); + void signalsBind(); + UserInfomationss _acquireUserInfo(QString objpath); +}; + +#endif // CREATEGROUPDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/creategroupdialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/creategroupdialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/creategroupdialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/creategroupdialog.ui 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,313 @@ + + + CreateGroupDialog + + + + 0 + 0 + 423 + 523 + + + + Dialog + + + + 0 + + + 42 + + + 34 + + + 42 + + + 34 + + + + + 24 + + + 40 + + + + + + 0 + 0 + + + + Add New Group + + + + + + + 8 + + + + + 8 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Name + + + + + + + + + + 248 + 0 + + + + + 248 + 16777215 + + + + + + + + + + 8 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Id + + + + + + + + + + 248 + 0 + + + + + 248 + 16777215 + + + + + + + + + + 8 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Members + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 248 + 194 + + + + + 248 + 194 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 16 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 36 + + + + + 100 + 36 + + + + Qt::NoFocus + + + Cancel + + + + + + + + 100 + 36 + + + + + 100 + 36 + + + + Qt::NoFocus + + + Certain + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/createuserdialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/createuserdialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/createuserdialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/createuserdialog.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -19,6 +19,9 @@ */ #include "createuserdialog.h" #include "ui_createuserdialog.h" +#include "CloseButton/closebutton.h" + +#include "passwdcheckutil.h" #include #include @@ -37,19 +40,13 @@ ui(new Ui::CreateUserDialog), usersStringList(userlist) { -// installEventFilter(this); ui->setupUi(this); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(tr("Add new user")); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); ui->tipLabel->setAlignment(Qt::AlignCenter); ui->label_8->adjustSize(); @@ -58,7 +55,7 @@ ui->label_10->adjustSize(); ui->label_10->setWordWrap(true); - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); +// ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); initPwdChecked(); setupComonpent(); @@ -68,6 +65,7 @@ CreateUserDialog::~CreateUserDialog() { delete ui; + ui = nullptr; // delete process; } @@ -94,6 +92,12 @@ enablePwdQuality = true; } + if (PasswdCheckUtil::getCurrentPamState()){ + enablePwdQuality = true; + } else { + enablePwdQuality = false; + } + #else enablePwdQuality = false; #endif @@ -108,40 +112,22 @@ ui->pwdLineEdit->setEchoMode(QLineEdit::Password); ui->pwdsureLineEdit->setEchoMode(QLineEdit::Password); -// ui->pinLineEdit->setEchoMode(QLineEdit::Password); -// ui->pinsureLineEdit->setEchoMode(QLineEdit::Password); - -// QString required = tr("(Required)"); -// QString optional = tr("(Optional)"); -// if (ostype == PC){ -// ui->pwdLabel->setText(required); -// ui->pwdsurelabel->setText(required); -// ui->pinLabel->setText(optional); -// ui->pinsurelabel->setText(optional); -// } -// else{ -// ui->pwdLabel->setText(optional); -// ui->pwdsurelabel->setText(optional); -// ui->pinLabel->setText(required); -// ui->pinsurelabel->setText(required); -// } ui->usernameLineEdit->setPlaceholderText(tr("UserName")); ui->pwdLineEdit->setPlaceholderText(tr("Password")); ui->pwdsureLineEdit->setPlaceholderText(tr("Password Identify")); -// ui->pinLineEdit->setPlaceholderText(tr("PIN Code")); -// ui->pinsureLineEdit->setPlaceholderText(tr("PIN Code Identify")); + ui->pwdTypeComBox->addItem(tr("General Password")); -// //给radiobtn设置id,id即accoutnType,方便直接返回id值 + // 给radiobtn设置id,id即accoutnType,方便直接返回id值 ui->buttonGroup->setId(ui->standardRadioBtn, 0); ui->buttonGroup->setId(ui->adminRadioBtn, 1); -// //默认标准用户 + // 默认标准用户 ui->standardRadioBtn->setChecked(true); - //设置确定按钮 + // 设置确定按钮 refreshConfirmBtnStatus(); // confirm_btn_status_refresh(); @@ -149,10 +135,10 @@ void CreateUserDialog::setupConnect(){ - connect(ui->closeBtn, &QPushButton::clicked, [=](bool checked){ - Q_UNUSED(checked) - close(); - }); +// connect(ui->closeBtn, &CloseButton::clicked, [=](bool checked){ +// Q_UNUSED(checked) +// close(); +// }); connect(ui->usernameLineEdit, &QLineEdit::textChanged, [=](QString text){ nameLegalityCheck(text); @@ -252,33 +238,51 @@ void CreateUserDialog::pwdLegalityCheck(QString pwd){ - if (enablePwdQuality){ -#ifdef ENABLEPQ - void * auxerror; - int ret; - const char * msg; - char buf[256]; - - QByteArray ba = pwd.toLatin1(); - - ret = pwquality_check(settings, ba.data(), NULL, NULL, &auxerror); - if (ret < 0 && pwd.length() > 0){ - msg = pwquality_strerror(buf, sizeof(buf), ret, auxerror); - pwdTip = QString(msg); - } else { - pwdTip = ""; - } -#endif + + if (!checkCharLegitimacy(pwd)){ + pwdTip = tr("Contains illegal characters!"); } else { - if (pwd.length() < PWD_LOW_LENGTH) { - pwdTip = tr("Password length needs to more than %1 character!").arg(PWD_LOW_LENGTH - 1); - } else if (pwd.length() > PWD_HIGH_LENGTH) { - pwdTip = tr("Password length needs to less than %1 character!").arg(PWD_HIGH_LENGTH + 1); + if (enablePwdQuality){ + #ifdef ENABLEPQ + void * auxerror; + int ret; + const char * msg; + char buf[256]; + + QByteArray ba = pwd.toLatin1(); + QByteArray ba1 = ui->usernameLineEdit->text().toLatin1(); + + ret = pwquality_check(settings, ba.data(), NULL, ba1.data(), &auxerror); + if (ret < 0 && pwd.length() > 0){ + msg = pwquality_strerror(buf, sizeof(buf), ret, auxerror); + pwdTip = QString(msg); + } else { + pwdTip = ""; + } + #endif } else { + // if (pwd.length() < PWD_LOW_LENGTH) { + // pwdTip = tr("Password length needs to more than %1 character!").arg(PWD_LOW_LENGTH - 1); + // } else if (pwd.length() > PWD_HIGH_LENGTH) { + // pwdTip = tr("Password length needs to less than %1 character!").arg(PWD_HIGH_LENGTH + 1); + // } else { + // pwdTip = ""; + // } + // const char *s = pwd.toUtf8().data(); + // while (*s && *s >= '0' && *s <= '9') { + // s++; + // } + // if (!bool(*s)) { + // pwdTip = tr("Password cannot be made up entirely by Numbers!"); + // } else { + // pwdTip = ""; + // } pwdTip = ""; } } + + //防止先输入确认密码,再输入密码后pwdsuretipLabel无法刷新 if (!ui->pwdsureLineEdit->text().isEmpty()){ if (ui->pwdLineEdit->text() == ui->pwdsureLineEdit->text()) { @@ -296,6 +300,16 @@ refreshConfirmBtnStatus(); } +bool CreateUserDialog::checkCharLegitimacy(QString password){ + //密码不能包含非标准字符 + foreach (QChar ch, password){ + if (int(ch.toLatin1() <= 0 || int(ch.toLatin1()) > 127)){ + return false; + } + } + return true; +} + void CreateUserDialog::paintEvent(QPaintEvent *event) { Q_UNUSED(event); @@ -310,6 +324,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); @@ -378,36 +393,46 @@ if (username.isEmpty()) nameTip = tr("The user name cannot be empty"); else if (username.startsWith("_") || username.left(1).contains((QRegExp("[0-9]")))){ - nameTip = tr("The first character must be lowercase letters!"); + nameTip = tr("Must be begin with lower letters!"); } else if (username.contains(QRegExp("[A-Z]"))){ - nameTip = tr("User name can not contain capital letters!"); + nameTip = tr("Can not contain capital letters!"); } else if (nameTraverse(username)) if (username.length() > 0 && username.length() < USER_LENGTH){ - /* - * 此处代码需要优化 - */ -// back = false; -// QString cmd = QString("getent group %1").arg(username); -// process = new QProcess(this); -// connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(name_conflict_group_slot())); -// process->start(cmd); + + QString cmd = QString("getent group %1").arg(username); + QString output; + + FILE *stream; + char buf[256]; + + if ((stream = popen(cmd.toLatin1().data(), "r" )) == NULL){ + return; + } + + while(fgets(buf, 256, stream) != NULL){ + output = QString(buf).simplified(); + } + + pclose(stream); if (usersStringList.contains(username)){ - nameTip = tr("The user name is already in use, please use a different one."); - } else { + nameTip = tr("Name already in use, change another one."); + } else if (!output.isEmpty()) { + nameTip = tr("Name corresponds to group already exists."); + }else { nameTip = ""; } } else { - nameTip = tr("User name length need to less than %1 letters!").arg(USER_LENGTH); + nameTip = tr("Name length must less than %1 letters!").arg(USER_LENGTH); } else { - nameTip = tr("The user name can only be composed of letters, numbers and underline!"); + nameTip = tr("Can only contain letters,digits,underline!"); } QStringList homeDir = getHomeUser(); if (homeDir.contains(username) && nameTip.isEmpty()) { - nameTip = tr("The username is configured, please change the username"); + nameTip = tr("Username's folder exists, change another one"); } ui->tipLabel->setText(nameTip); diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/createuserdialog.h ukui-control-center-3.0.3/plugins/account/userinfo/createuserdialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/createuserdialog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/createuserdialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -74,6 +74,8 @@ private: Ui::CreateUserDialog *ui; + bool checkCharLegitimacy(QString password); + bool back; bool isCreateUser = false; bool enablePwdQuality; diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/createuserdialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/createuserdialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/createuserdialog.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/createuserdialog.ui 2021-05-20 13:08:14.000000000 +0000 @@ -6,20 +6,26 @@ 0 0 - 400 - 660 + 450 + 620 + + + 0 + 0 + + - 400 - 660 + 450 + 500 - 400 - 660 + 624 + 650 @@ -43,6 +49,24 @@ + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + QFrame::NoFrame @@ -54,26 +78,45 @@ 0 - 0 + 32 - 0 + 32 - 0 + 32 - 0 + 32 + + 0 + + + 0 + - 8 + 0 - 8 + 0 + + + + 0 + 0 + + + + Add New Account + + + + Qt::Horizontal @@ -86,58 +129,26 @@ - - - - - 32 - 32 - - - - - 32 - 32 - - - - - - - - 24 + 0 - 32 + 0 16 - 32 + 0 - 48 + 0 - - - - 0 - 0 - - - - Add New Account - - - - 0 @@ -158,7 +169,7 @@ - 8 + 2 0 @@ -207,7 +218,7 @@ 0 - 33 + 36 @@ -255,7 +266,7 @@ 0 - 33 + 36 @@ -303,7 +314,7 @@ 0 - 33 + 36 @@ -351,7 +362,7 @@ 0 - 33 + 36 @@ -377,6 +388,9 @@ 0 + + color:red; + @@ -390,22 +404,6 @@ - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 8 - - - - - @@ -420,18 +418,21 @@ + + 8 + 0 - 80 + 0 16777215 - 80 + 16777215 @@ -439,7 +440,7 @@ 0 - 0 + 6 0 @@ -453,13 +454,16 @@ - 16 + 6 - 16 + 0 + + + 0 - 16 + 0 @@ -486,9 +490,12 @@ - 12 + 3 + + + 0 - + @@ -496,12 +503,18 @@ 0 + + + 16777215 + 16777215 + + standard user - + @@ -510,13 +523,25 @@ - Standard users can use most software, but cannot install the software and -change system settings + Standard users can use most software, but cannot change system settings + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -527,13 +552,13 @@ 0 - 80 + 0 16777215 - 80 + 16777215 @@ -541,7 +566,7 @@ 0 - 0 + 6 0 @@ -555,13 +580,13 @@ - 16 + 6 - 16 + 0 - 16 + 0 @@ -588,9 +613,9 @@ - 12 + 3 - + @@ -603,7 +628,7 @@ - + @@ -618,6 +643,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -636,7 +674,7 @@ 20 - 24 + 30 diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/definegroupitem.cpp ukui-control-center-3.0.3/plugins/account/userinfo/definegroupitem.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/definegroupitem.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/definegroupitem.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,150 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 "definegroupitem.h" + +DefineGroupItem::DefineGroupItem(QString groupName) +{ +// setAttribute(Qt::WA_DeleteOnClose); + + _deleteable = false; + _updateable = false; + _editable = false; + + QHBoxLayout * baseHorLayout = new QHBoxLayout(this); + baseHorLayout->setSpacing(16); + baseHorLayout->setMargin(0); + + pWidget = new QWidget(this); + + QHBoxLayout * mainHorLayout = new QHBoxLayout(pWidget); + mainHorLayout->setSpacing(0); + //mainHorLayout->setContentsMargins(16, 0, 16, 0); + + pWidget->setLayout(mainHorLayout); + + pLabel = new QLabel(pWidget); + pLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + pLabel->setText(groupName); + + pEditBtn = new QPushButton(this); + pEditBtn->setText(tr("Edit")); + pEditBtn->setFixedSize(60,36); + pEditBtn->hide(); + + QSizePolicy btnSizePolicy = pEditBtn->sizePolicy(); + btnSizePolicy.setVerticalPolicy(QSizePolicy::Expanding); + pEditBtn->setSizePolicy(btnSizePolicy); + + pDelBtn = new QPushButton(this); + pDelBtn->setText(tr("Delete")); + pDelBtn->setFixedSize(60,36); + pDelBtn->hide(); + + QSizePolicy btnSizePolicy2 = pDelBtn->sizePolicy(); + btnSizePolicy2.setVerticalPolicy(QSizePolicy::Expanding); + pDelBtn->setSizePolicy(btnSizePolicy2); + +// QPalette palette = pEditBtn->palette(); +// QColor ColorPlaceholderText(255,255,255,0); +// QBrush brush; +// brush.setColor(ColorPlaceholderText); +// palette.setBrush(QPalette::Button, Qt::white); +// //palette.setBrush(QPalette::ButtonText, brush); +// pEditBtn->setPalette(palette); +// pDelBtn->setPalette(palette); + + mainHorLayout->addWidget(pLabel); + + baseHorLayout->addWidget(pWidget); + baseHorLayout->addWidget(pEditBtn); + baseHorLayout->addWidget(pDelBtn); + baseHorLayout->addSpacing(16); + + setLayout(baseHorLayout); +} + +DefineGroupItem::~DefineGroupItem() +{ +} + +QWidget * DefineGroupItem::widgetComponent(){ + return pWidget; +} + +QLabel * DefineGroupItem::labelComponent(){ + return pLabel; +} + +QPushButton * DefineGroupItem::editBtnComponent(){ + return pEditBtn; +} + +QPushButton * DefineGroupItem::delBtnComponent(){ + return pDelBtn; +} + +void DefineGroupItem::setDeleteable(bool deleteable){ + _deleteable = deleteable; +} + +void DefineGroupItem::setUpdateable(bool updateable){ + _updateable = updateable; +} + +void DefineGroupItem::setEditable(bool editable){ + _editable = editable; +} + +void DefineGroupItem::setShortcutName(QString newName){ + pLabel->setText(newName); +} + +void DefineGroupItem::enterEvent(QEvent *event) +{ + Q_UNUSED(event); + if(_deleteable && _editable){ + pDelBtn->show(); + pEditBtn->show(); + }else if(_editable){ + pEditBtn->show(); + }else if(_deleteable){ + pDelBtn->show(); + } +} + +void DefineGroupItem::leaveEvent(QEvent *event) +{ + Q_UNUSED(event); + pEditBtn->hide(); + pDelBtn->hide(); +} + +void DefineGroupItem::mouseDoubleClickEvent(QMouseEvent *e){ + if (e->button() == Qt::LeftButton && _updateable){ + emit updateShortcutSignal(); + } + QWidget::mouseDoubleClickEvent(e); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/definegroupitem.h ukui-control-center-3.0.3/plugins/account/userinfo/definegroupitem.h --- ukui-control-center-2.0.3/plugins/account/userinfo/definegroupitem.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/definegroupitem.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,74 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 DEFINEGROUPITEM_H +#define DEFINEGROUPITEM_H + +#include +#include +#include + +class QLabel; +class QPushButton; + +class DefineGroupItem : public QFrame +{ + Q_OBJECT + +public: + explicit DefineGroupItem(QString groupName); + ~DefineGroupItem(); + +public: + QWidget * widgetComponent(); + QLabel * labelComponent(); + QPushButton * editBtnComponent(); + QPushButton * delBtnComponent(); + +public: + void setDeleteable(bool deleteable); + void setUpdateable(bool updateable); + void setEditable(bool editable); + + void setShortcutName(QString newName); + void setShortcutBinding(QString newBinding); + +protected: + virtual void enterEvent(QEvent * event); + virtual void leaveEvent(QEvent * event); + virtual void mouseDoubleClickEvent(QMouseEvent * e); + +private: + QWidget * pWidget; + QLabel * pLabel; + QPushButton * pEditBtn; + QPushButton * pDelBtn; + +private: + bool _deleteable; + bool _editable; + bool _updateable; + +Q_SIGNALS: + void updateShortcutSignal(); + +}; + +#endif // DEFINEGROUPITEM_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/delgroupdialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/delgroupdialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/delgroupdialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/delgroupdialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,109 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 "delgroupdialog.h" +#include "ui_delgroupdialog.h" +#include "CloseButton/closebutton.h" + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +DelGroupDialog::DelGroupDialog(QString groupName, QWidget *parent) : + QDialog(parent), + ui(new Ui::DelGroupDialog) +{ + ui->setupUi(this); + setupInit(); + signalsBind(); +} + +DelGroupDialog::~DelGroupDialog() +{ + delete ui; + ui = nullptr; +} + +void DelGroupDialog::signalsBind() +{ + connect(ui->cancelBtn,&QPushButton::clicked,[=](){ + close(); + }); +} + +void DelGroupDialog::setupInit() +{ + setWindowTitle(tr("Delete user group")); + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + + ui->labelPic->setPixmap(QPixmap("://img/plugins/userinfo/notice.png")); + ui->titleLabel->setText(tr("Are you sure to delete the group, which will make some file components in the file system invalid!")); + ui->titleLabel->setWordWrap(true); +} + +QPushButton * DelGroupDialog::delBtnComponent() +{ + return ui->delBtn; +} + +void DelGroupDialog::setNoticeText(QString txt) +{ + qDebug() << "setNoticeText" << txt; +} + +void DelGroupDialog::paintEvent(QPaintEvent * event){ + Q_UNUSED(event) + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); + p.restore(); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/delgroupdialog.h ukui-control-center-3.0.3/plugins/account/userinfo/delgroupdialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/delgroupdialog.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/delgroupdialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,58 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 DELGROUPDIALOG_H +#define DELGROUPDIALOG_H + +#include +#include +#include +#include +#include + +namespace Ui { +class DelGroupDialog; +} + +class DelGroupDialog : public QDialog +{ + Q_OBJECT + +public: + explicit DelGroupDialog(QString groupName, QWidget *parent = nullptr); + ~DelGroupDialog(); + +public: + void setupInit(); + void signalsBind(); + void setNoticeText(QString txt); + QPushButton * delBtnComponent(); + +public: + QPushButton *pDelBtn; + +protected: + void paintEvent(QPaintEvent *event); + +private: + Ui::DelGroupDialog *ui; +}; + +#endif // DELGROUPDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/delgroupdialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/delgroupdialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/delgroupdialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/delgroupdialog.ui 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,163 @@ + + + DelGroupDialog + + + + 0 + 0 + 452 + 232 + + + + + 452 + 232 + + + + + 452 + 232 + + + + Dialog + + + + 32 + + + 10 + + + 42 + + + 42 + + + 34 + + + + + 8 + + + 32 + + + + + + + + + + 30 + 30 + + + + + 30 + 30 + + + + + + + + + + + + + + + 16 + + + + + TextLabel + + + + + + + + + + + 16 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 120 + 36 + + + + + 120 + 36 + + + + Qt::NoFocus + + + Cancel + + + false + + + + + + + + 120 + 36 + + + + + 120 + 36 + + + + Delete + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/deluserdialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/deluserdialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/deluserdialog.cpp 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/deluserdialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -19,6 +19,7 @@ */ #include "deluserdialog.h" #include "ui_deluserdialog.h" +#include "CloseButton/closebutton.h" #include #include @@ -33,13 +34,6 @@ setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); -// ui->frame->setStyleSheet("QFrame{background: #ffffff; border: none; border-radius: 6px;}"); -// ui->closeBtn->setStyleSheet("QPushButton{background: #ffffff;}"); - - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); - setupComonpent(); setupConnect(); } @@ -47,46 +41,63 @@ DelUserDialog::~DelUserDialog() { delete ui; + ui = nullptr; } void DelUserDialog::setupComonpent(){ + ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); +// ui->closeBtn->setFlat(true); +// ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); +// ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" +// "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); + ui->label->adjustSize(); + ui->label->setWordWrap(true); + + ui->buttonGroup->setId(ui->keepRadioBtn, 0); + ui->buttonGroup->setId(ui->delRadioBtn, 1); + + ui->delRadioBtn->setChecked(true); } void DelUserDialog::setupConnect(){ - connect(ui->closeBtn, &QPushButton::clicked, [=](){ - close(); - }); +// connect(ui->closeBtn, &CloseButton::clicked, [=](){ +// close(); +// }); connect(ui->cancelPushBtn, SIGNAL(clicked()), this, SLOT(reject())); - QSignalMapper * differSignalMapper = new QSignalMapper(); - for (QAbstractButton * button : ui->buttonGroup->buttons()){ - connect(button, SIGNAL(clicked()), differSignalMapper, SLOT(map())); - differSignalMapper->setMapping(button, button->text()); - } - -#if QT_VERSION <= QT_VERSION_CHECK(5,12,0) - connect(differSignalMapper, static_cast(&QSignalMapper::mapped), [=](const QString key){ -#else - connect(differSignalMapper, QOverload::of(&QSignalMapper::mapped), [=](const QString key){ -#endif + connect(ui->deleteBtn, &QPushButton::clicked, this, [=]{ this->accept(); - bool removefile; - if (ui->removePushBtn->text() == key) - removefile = true; - else - removefile = false; - emit removefile_send(removefile, ui->usernameLabel->text()); + emit removefile_send(ui->buttonGroup->checkedId()); }); -} -void DelUserDialog::setFace(QString iconfile){ - ui->faceLabel->setPixmap(QPixmap(iconfile)); +// QSignalMapper * differSignalMapper = new QSignalMapper(); +// for (QAbstractButton * button : ui->buttonGroup->buttons()){ +// connect(button, SIGNAL(clicked()), differSignalMapper, SLOT(map())); +// differSignalMapper->setMapping(button, button->text()); +// } + +//#if QT_VERSION <= QT_VERSION_CHECK(5,12,0) +// connect(differSignalMapper, static_cast(&QSignalMapper::mapped), [=](const QString key){ +//#else +// connect(differSignalMapper, QOverload::of(&QSignalMapper::mapped), [=](const QString key){ +//#endif +// this->accept(); +// bool removefile; +// if (ui->removePushBtn->text() == key) +// removefile = true; +// else +// removefile = false; +// emit removefile_send(removefile, ui->usernameLabel->text()); +// }); } + void DelUserDialog::setUsername(QString username){ - ui->usernameLabel->setText(username); + QString title1 = tr("Delete the user '"); + QString title3 = tr("'and:"); + ui->titleLabel->setText(title1 + username + title3); } @@ -103,6 +114,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/deluserdialog.h ukui-control-center-3.0.3/plugins/account/userinfo/deluserdialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/deluserdialog.h 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/deluserdialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -53,7 +53,7 @@ Q_SIGNALS: - void removefile_send(bool removefile, QString username); + void removefile_send(bool removefile); }; #endif // DELUSERDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/deluserdialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/deluserdialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/deluserdialog.ui 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/deluserdialog.ui 2021-05-20 13:08:14.000000000 +0000 @@ -7,19 +7,19 @@ 0 0 502 - 238 + 290 502 - 238 + 290 502 - 238 + 290 @@ -27,16 +27,16 @@ - 10 + 0 0 - 9 + 0 - 9 + 0 0 @@ -54,16 +54,16 @@ 0 - 0 + 32 - 0 + 32 - 0 + 32 - 0 + 24 @@ -82,6 +82,13 @@ 8 + + + + + + + Qt::Horizontal @@ -94,163 +101,188 @@ - - - - - 32 - 32 - - - - - 32 - 32 - - - - - - - - 8 + 0 - 32 + 0 - 16 + 12 - 32 + 0 - 32 + 0 - + - 16 + 12 - + 0 - - - - - - 0 - 0 - - - - - 72 - 72 - - - - - 72 - 72 - - - - - - - true - - - - - - - - 0 - 0 - - - - - - - - - - - - - 0 - - - 12 - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - Delete the user, belonging to the user's desktop, -documents, favorites, music, pictures and video -folder will be deleted! - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - + + + + 0 + 60 + + + + + 16777215 + 60 + + + + QFrame::Box + + + QFrame::Plain + + + + 12 + + + 6 + + + 0 + + + 0 + + + 0 + + + + + + 15 + 0 + + + + + 15 + 16777215 + + + + + + + buttonGroup + + + + + + + keep the user's data, like desktop,documents, favorites, music, pictures and so on + + + + + - - - Qt::Horizontal + + + + 0 + 60 + - + - 40 - 20 + 16777215 + 60 - + + QFrame::Box + + + QFrame::Plain + + + + 12 + + + 6 + + + 0 + + + 0 + + + 0 + + + + + + 15 + 0 + + + + + 15 + 16777215 + + + + + + + buttonGroup + + + + + + + delete whole data belong user + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 40 + + + + + 12 @@ -291,29 +323,7 @@ - - - - 120 - 36 - - - - - 120 - 36 - - - - KeepFile - - - buttonGroup - - - - - + 120 @@ -327,11 +337,8 @@ - RemoveFile + Delete - - buttonGroup - diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/editgroupdialog.cpp ukui-control-center-3.0.3/plugins/account/userinfo/editgroupdialog.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/editgroupdialog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/editgroupdialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,332 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 "editgroupdialog.h" +#include "ui_editgroupdialog.h" +#include "userinfo.h" +#include "changegroupdialog.h" +#include "CloseButton/closebutton.h" + +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +EditGroupDialog::EditGroupDialog(QString usergroup, QString groupid, QString groupname, bool idSetEnable, QWidget *parent) : + QDialog(parent), + ui(new Ui::EditGroupDialog), + cgDialog(new ChangeGroupDialog), + _nameHasModified(false), + _idHasModified(false), + _boxModified(false), + userGroup(usergroup), + groupId(groupid), + groupName(groupname) +{ + ui->setupUi(this); + setupInit(); + idSetEnabled(idSetEnable); + getUsersList(userGroup); + signalsBind(); +} + +EditGroupDialog::~EditGroupDialog() +{ + delete cgDialog; + cgDialog = nullptr; + delete ui; + ui = nullptr; +} + +void EditGroupDialog::limitInput() +{ + QIntValidator *intValidator = new QIntValidator; + //QRegExp rx("^[a-zA-z]+$");// 首字符为字母 + QRegExp rx("[a-zA-z]{32}"); + QRegExpValidator *regValidator = new QRegExpValidator(rx); + //intValidator->setRange(0, 65535); + intValidator->setBottom(0); + // 整形输入限制 + ui->lineEdit_id->setValidator(intValidator); + // 字母输入限制 + ui->lineEdit_name->setValidator(regValidator); + // 字符长度限制 + //ui->lineEdit_name->setMaxLength(4); +} + +void EditGroupDialog::refreshCertainBtnStatus(){ + if (ui->lineEdit_name->text().isEmpty() || + ui->lineEdit_id->text().isEmpty()) + ui->certainBtn->setEnabled(false); + else + ui->certainBtn->setEnabled(_nameHasModified || _idHasModified || _boxModified); +} + +UserInfomations EditGroupDialog::_acquireUserInfo(QString objpath){ + UserInfomations user; + + //默认值 + user.current = false; + user.logined = false; + user.autologin = false; + + QDBusInterface * iproperty = new QDBusInterface("org.freedesktop.Accounts", + objpath, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + QDBusReply > reply = iproperty->call("GetAll", "org.freedesktop.Accounts.User"); + if (reply.isValid()){ + QMap propertyMap; + propertyMap = reply.value(); + user.username = propertyMap.find("UserName").value().toString(); + if (user.username == QString(g_get_user_name())) { + user.current = true; + user.logined = true; + } + } + else + qDebug() << "reply failed"; + + delete iproperty; + iproperty = nullptr; + + return user; +} + + +void EditGroupDialog::getUsersList(QString usergroup) +{ + QStringList allUsers; + sysdispatcher = new SystemDbusDispatcher(this); + + QStringList objectpaths = sysdispatcher->list_cached_users(); + allUserInfoMap.clear(); + //root + if (!getuid()){ + UserInfomations root; + root.username = g_get_user_name(); + root.current = true; + root.logined = true; + root.autologin = false; + root.uid = 0; + root.accounttype = ADMINISTRATOR; + // root.iconfile = DEFAULTFACE; + allUserInfoMap.insert(root.username, root); + } + for (QString objectpath : objectpaths){ + UserInfomations user; + user = _acquireUserInfo(objectpath); + allUserInfoMap.insert(user.username, user); + } + for (QVariant tmp : allUserInfoMap.keys()){ + allUsers << tmp.toString(); + + } + QStringList usersList = allUsers; + QStringList usergroupList = usergroup.split(","); + + for(int i = 0; i < usersList.size(); i++){ + QListWidgetItem * item = new QListWidgetItem(ui->listWidget); + item->setSizeHint(QSize(ui->listWidget->width(), 36)); + item->setData(Qt::UserRole, ""); + QCheckBox * box = new QCheckBox(usersList.at(i)); + ui->listWidget->addItem(item); + ui->listWidget->setItemWidget(item, box); + if(usersList.at(i) == groupName){ + box->setChecked(true); + box->setDisabled(true); + } else{ + for (int j = 0; j < usergroupList.size(); j ++){ + if(usergroupList.at(j) == usersList.at(i)){ + box->setChecked(true); + } + } + } + + connect(box, &QCheckBox::clicked, this, [=](bool checked){ + Q_UNUSED(checked); + qDebug() << "checkbox clicked"; + _boxModified = true; + refreshCertainBtnStatus(); + }); + } +} + +void EditGroupDialog::idSetEnabled(bool idSetEnable) +{ + ui->lineEdit_id->setEnabled(idSetEnable); +} + +void EditGroupDialog::nameSetEnabled() +{ + ui->lineEdit_name->setEnabled(false); +} + +QLineEdit *EditGroupDialog::lineNameComponent() +{ + return ui->lineEdit_name; +} + +QLineEdit *EditGroupDialog::lineIdComponent() +{ + return ui->lineEdit_id; +} + +QListWidget *EditGroupDialog::listWidgetComponent() +{ + return ui->listWidget; +} + +void EditGroupDialog::signalsBind() +{ + connect(ui->cancelBtn,&QPushButton::clicked,[=](){ + close(); + }); + connect(ui->lineEdit_name,&QLineEdit::textChanged,[=](QString txt){ + refreshCertainBtnStatus(); + }); + connect(ui->lineEdit_id,&QLineEdit::textChanged,[=](QString txt){ + refreshCertainBtnStatus(); + }); + connect(ui->lineEdit_id, &QLineEdit::textEdited,[=](){ + for (int j = 0; j < cgDialog->groupList->size(); j++){ + if(ui->lineEdit_id->text() == cgDialog->groupList->at(j)->groupid){ + _idHasModified = false; + return; + } + } + _idHasModified = true; + }); + connect(ui->lineEdit_name, &QLineEdit::textEdited,[=](){ + _nameHasModified = true; + }); + connect(ui->certainBtn, &QPushButton::clicked, this, [=](){ + ChangeGroupDialog *cgDialog = new ChangeGroupDialog; + for (int i = 0; i < ui->listWidget->count(); i++){ + if(_idHasModified){ + for (int j = 0; j < cgDialog->groupList->size(); j++){ + if(ui->lineEdit_id->text() == cgDialog->groupList->at(j)->groupid){ + QMessageBox invalid(QMessageBox::Question, tr("Tips"), tr("Invalid Id!")); + invalid.setIcon(QMessageBox::Warning); + invalid.setStandardButtons(QMessageBox::Ok); + invalid.setButtonText(QMessageBox::Ok, QString(tr("OK"))); + invalid.exec(); + return; + } + } + } + QListWidgetItem *item = ui->listWidget->item(i); + QCheckBox *box = static_cast (ui->listWidget->itemWidget(item)); + + QDBusReply reply = cgDialog->serviceInterface->call("set", + ui->lineEdit_name->text(),ui->lineEdit_id->text()); + if (reply.isValid()){ + // use the returned value + qDebug() << "set get call value" << reply.value(); + } else { + // call failed. Show an error condition. + qDebug() << "set call failed" << reply.error(); + } + + if(box->isChecked()){ + QDBusReply reply = cgDialog->serviceInterface->call("addUserToGroup", + ui->lineEdit_name->text(),box->text()); + if (reply.isValid()){ + // use the returned value + qDebug() << "addUserToGroup get call value" << reply.value(); + } else { + // call failed. Show an error condition. + qDebug() << "addUserToGroup call failed" << reply.error(); + } + } else { + QDBusReply reply = cgDialog->serviceInterface->call("delUserFromGroup", + ui->lineEdit_name->text(),box->text()); + if (reply.isValid()){ + // use the returned value + qDebug() << "delUserFromGroup get call value" << reply.value(); + } else { + // call failed. Show an error condition. + qDebug() << "delUserFromGroup call failed" << reply.error(); + } + } + } + emit needRefresh(); + delete cgDialog; + cgDialog = nullptr; + close(); + }); +} + +void EditGroupDialog::setupInit() +{ + setWindowTitle(tr("Edit user group")); + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + + ui->listWidget->setFocusPolicy(Qt::NoFocus); + ui->listWidget->setSelectionMode(QAbstractItemView::NoSelection); + ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui->listWidget->setStyleSheet("QListWidget{border-radius: 4px;}" + "QListWidget::Item{padding-left:20px;}"); + + // 设置确认按钮 + refreshCertainBtnStatus(); + // 限制组名输入规则 + limitInput(); + nameSetEnabled(); +} + +void EditGroupDialog::paintEvent(QPaintEvent *event) { + Q_UNUSED(event); + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 10, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); + p.restore(); + +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/editgroupdialog.h ukui-control-center-3.0.3/plugins/account/userinfo/editgroupdialog.h --- ukui-control-center-2.0.3/plugins/account/userinfo/editgroupdialog.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/editgroupdialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,95 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * Copyright (C) 2020 KYLINOS 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 EDITGROUPDIALOG_H +#define EDITGROUPDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "qtdbus/systemdbusdispatcher.h" + +typedef struct _UserInfomations { + QString objpath; + QString username; + QString iconfile; + QString passwd; + int accounttype; + int passwdtype; + bool current; + bool logined; + bool autologin; + bool noPwdLogin; + qint64 uid; +}UserInfomations; + +class ChangeGroupDialog; +namespace Ui { +class EditGroupDialog; +} + +class EditGroupDialog : public QDialog +{ + Q_OBJECT + +public: + explicit EditGroupDialog(QString, QString, QString, bool, QWidget *parent = nullptr); + ~EditGroupDialog(); + +public: + void limitInput(); + void getUsersList(QString usergroup); + void refreshCertainBtnStatus(); + QLineEdit * lineNameComponent(); + QLineEdit * lineIdComponent(); + QListWidget * listWidgetComponent(); + void idSetEnabled(bool ); + void nameSetEnabled(); + +protected: + void paintEvent(QPaintEvent *event); + +private: + Ui::EditGroupDialog *ui; + ChangeGroupDialog *cgDialog = nullptr; + bool _nameHasModified; + bool _idHasModified; + bool _boxModified; + QString userGroup; + QString groupId; + QString groupName; + QMap allUserInfoMap; + SystemDbusDispatcher * sysdispatcher; + + void setupInit(); + void signalsBind(); + UserInfomations _acquireUserInfo(QString objpath); + +signals: + void needRefresh(); +}; + +#endif // EDITGROUPDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/editgroupdialog.ui ukui-control-center-3.0.3/plugins/account/userinfo/editgroupdialog.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/editgroupdialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/editgroupdialog.ui 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,325 @@ + + + EditGroupDialog + + + + 0 + 0 + 390 + 523 + + + + + 390 + 523 + + + + + 390 + 523 + + + + Dialog + + + + 0 + + + 42 + + + 42 + + + 42 + + + 34 + + + + + 24 + + + 40 + + + + + + 0 + 0 + + + + Edit User Group + + + + + + + 8 + + + + + 8 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Name + + + + + + + + + + 248 + 0 + + + + + 248 + 16777215 + + + + + + + + + + 8 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Id + + + + + + + + + + 248 + 0 + + + + + 248 + 16777215 + + + + + + + + + + 8 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 32 + + + + + 16777215 + 32 + + + + Members + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 248 + 194 + + + + + 248 + 194 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 16 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 + 36 + + + + + 100 + 36 + + + + Qt::NoFocus + + + Cancel + + + + + + + + 100 + 36 + + + + + 100 + 36 + + + + Qt::NoFocus + + + Certain + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/loginedusers.h ukui-control-center-3.0.3/plugins/account/userinfo/loginedusers.h --- ukui-control-center-2.0.3/plugins/account/userinfo/loginedusers.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/loginedusers.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,47 @@ +#ifndef LOGINEDUSER_H +/* -*- 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. + * + */ +#define LOGINEDUSER_H + +#include + +struct LoginedUsers { + int uid; + QString userName; + QDBusObjectPath objpath; +}; + +QDBusArgument &operator<<(QDBusArgument &argument, const LoginedUsers &mystruct) { + argument.beginStructure(); + argument << mystruct.uid << mystruct.userName << mystruct.objpath;;//< mystruct.usergroup; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, LoginedUsers &mystruct) { + argument.beginStructure(); + argument >> mystruct.uid >> mystruct.userName >> mystruct.objpath;// >> mystruct.usergroup; + argument.endStructure(); + return argument; +} + +Q_DECLARE_METATYPE(LoginedUsers) + +#endif // LOGINEDUSER_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/passwdcheckutil.cpp ukui-control-center-3.0.3/plugins/account/userinfo/passwdcheckutil.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/passwdcheckutil.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/passwdcheckutil.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,47 @@ +/* -*- 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 "passwdcheckutil.h" + +#include +#include + +#define PAM_CONF_FILE "/etc/pam.d/common-password" + +PasswdCheckUtil::PasswdCheckUtil(QObject *parent) : QObject(parent) +{ + +} + +bool PasswdCheckUtil::getCurrentPamState(){ + QFile * readFile = new QFile(PAM_CONF_FILE); + if (!readFile->open(QIODevice::ReadOnly | QIODevice::Text)){ + readFile->close(); + qDebug() << QString("Open conf file %1 failed!").arg(PAM_CONF_FILE); + return false; + } else { + QTextStream stream(readFile); + while(!stream.atEnd()){ + QString line = stream.readLine(); + if (line.contains("pam_pwquality.so")) + return true; + } + return false; + } +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/passwdcheckutil.h ukui-control-center-3.0.3/plugins/account/userinfo/passwdcheckutil.h --- ukui-control-center-2.0.3/plugins/account/userinfo/passwdcheckutil.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/passwdcheckutil.h 2021-04-14 01:27:20.000000000 +0000 @@ -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 PASSWDCHECKUTIL_H +#define PASSWDCHECKUTIL_H + +#include + +class PasswdCheckUtil : public QObject +{ + Q_OBJECT +public: + explicit PasswdCheckUtil(QObject *parent = nullptr); + + static bool getCurrentPamState(); + +}; + +#endif // PASSWDCHECKUTIL_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/pwdcheckthread.cpp ukui-control-center-3.0.3/plugins/account/userinfo/pwdcheckthread.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/pwdcheckthread.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/pwdcheckthread.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,48 @@ +#include "pwdcheckthread.h" + +#include + +PwdCheckThread::PwdCheckThread() +{ +} + +PwdCheckThread::~PwdCheckThread() +{ +} + +void PwdCheckThread::setArgs(const QString &userName, const QString &userPwd){ + uname = userName; + upwd = userPwd; +} + +void PwdCheckThread::run(){ + + FILE * stream; + char command[128]; + char output[256]; + + bool result = false; + + QByteArray ba1 = uname.toLatin1(); + + // + if (upwd.contains("'")){ + snprintf(command, 128, "/usr/bin/checkUserPwd %s \"%s\"", ba1.data(), upwd.toLatin1().data()); + } else { + + snprintf(command, 128, "/usr/bin/checkUserPwd %s '%s'", ba1.data(), upwd.toLatin1().data()); + } + + if ((stream = popen(command, "r")) != NULL){ + + while(fgets(output, 256, stream) != NULL){ + if (QString::compare(QString(output).simplified(), "Succes!") == 0){ + result = true; + } + + } + pclose(stream); + } + + emit complete(result); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/pwdcheckthread.h ukui-control-center-3.0.3/plugins/account/userinfo/pwdcheckthread.h --- ukui-control-center-2.0.3/plugins/account/userinfo/pwdcheckthread.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/pwdcheckthread.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,29 @@ +#ifndef PWDCHECKTHREAD_H +#define PWDCHECKTHREAD_H + +#include +#include + +class PwdCheckThread : public QThread +{ + Q_OBJECT + +public: + explicit PwdCheckThread(); + ~PwdCheckThread(); + +public: + void setArgs(const QString &userName, const QString &userPwd); + void run(); + +private: + QString uname; + QString upwd; + +Q_SIGNALS: + void complete(bool result); + + +}; + +#endif // PWDCHECKTHREAD_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/qtdbus/userdispatcher.cpp ukui-control-center-3.0.3/plugins/account/userinfo/qtdbus/userdispatcher.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/qtdbus/userdispatcher.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/qtdbus/userdispatcher.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -44,7 +44,7 @@ useriface = NULL; } -/*来自gtk控制面板的加密代码*/ +// 来自gtk控制面板的加密代码 QString UserDispatcher::make_crypted (const gchar *plain){ GString *salt; gchar *result; @@ -60,9 +60,14 @@ // /* SHA 256 */ g_string_append (salt, "$6$"); - for (i = 0; i < 16; i++) { - g_string_append_c (salt, salt_char[g_rand_int_range(rand, 0, G_N_ELEMENTS (salt_char) )]); + if (g_file_test("/dev/kyee0", G_FILE_TEST_EXISTS)){ + g_string_append(salt, "KylinSoftKyee"); + } else { + for (i = 0; i < 16; i++) { + g_string_append_c (salt, salt_char[g_rand_int_range(rand, 0, G_N_ELEMENTS (salt_char) )]); + } } + g_string_append_c (salt, '$'); result = g_strdup ((const gchar *)crypt(plain, salt->str)); //运行后找不到crypt undefined symbol: crypt @@ -94,6 +99,11 @@ useriface->call("SetIconFile", QVariant(facefile)); } + +void UserDispatcher::change_user_name(QString newName){ + useriface->call("SetRealName", QVariant(newName)); +} + void UserDispatcher::change_user_autologin(QString username){ QDBusInterface * tmpSysinterface = new QDBusInterface("com.control.center.qt.systemdbus", "/", @@ -107,10 +117,10 @@ tmpSysinterface->call("setAutoLoginStatus", username); delete tmpSysinterface; + tmpSysinterface = nullptr; } bool UserDispatcher::get_autoLogin_status() { QDBusReply reply = userPropert->call("Get", "org.freedesktop.Accounts.User", "AutomaticLogin"); -// qDebug()<<"the status is------>"< - + + more.svg + diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/res/more.svg ukui-control-center-3.0.3/plugins/account/userinfo/res/more.svg --- ukui-control-center-2.0.3/plugins/account/userinfo/res/more.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/res/more.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/run-passwd.cpp ukui-control-center-3.0.3/plugins/account/userinfo/run-passwd.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/run-passwd.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/run-passwd.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,707 @@ + + +/* qt会将glib里的signals成员识别为宏,所以取消该宏 + * 后面如果用到signals时,使用Q_SIGNALS代替即可 + **/ +#ifdef signals +#undef signals +#endif + +extern "C" { +#include +#include + +#include +#include +#include +#include + +} + +#include "run-passwd.h" + +/* Buffer size for backend output */ +#define BUFSIZE 64 + +/* Passwd states */ +//后端passwd的状态,NONE应该是passwd还没有启动,ERROR表示报错但还没退出 +typedef enum { + PASSWD_STATE_NONE, /* Passwd is not asking for anything */ + PASSWD_STATE_AUTH, /* Passwd is asking for our current password */ + PASSWD_STATE_NEW, /* Passwd is asking for our new password */ + PASSWD_STATE_RETYPE, /* Passwd is asking for our retyped new password */ + PASSWD_STATE_ERR /* Passwd reported an error but has not yet exited */ +} PasswdState; + +struct PasswdHandler { +// GtkBuilder *ui; + + const char *current_password; + const char *new_password; + const char *retyped_password; + + /* Communication with the passwd program */ + GPid backend_pid; + + GIOChannel *backend_stdin; + GIOChannel *backend_stdout; + + GQueue *backend_stdin_queue; /* Write queue to backend_stdin */ + + /* GMainLoop IDs */ + guint backend_child_watch_id; /* g_child_watch_add (PID) */ + guint backend_stdout_watch_id; /* g_io_add_watch (stdout) */ + + /* State of the passwd program */ + PasswdState backend_state; + gboolean changing_password; + + PasswdCallback auth_cb; + gpointer auth_cb_data; + + PasswdCallback chpasswd_cb; + gpointer chpasswd_cb_data; +}; + +//GQuark是一个guint32 +static GQuark +passwd_error_quark (void) +{ + static GQuark q = 0; + + //返回错误的标识码 + if (q == 0) { + q = g_quark_from_static_string("passwd_error"); + } + + return q; +} + +/* Error handling */ +#define PASSWD_ERROR (passwd_error_quark ()) + +static void stop_passwd (PasswdHandler *passwd_handler); + +static void free_passwd_resources (PasswdHandler *passwd_handler); + +static gboolean io_watch_stdout (GIOChannel *source, GIOCondition condition, PasswdHandler *passwd_handler); + + +static void free_passwd_resources (PasswdHandler *passwd_handler) +{ + GError *error = NULL; + + /* Remove the child watcher */ + if (passwd_handler->backend_child_watch_id != 0) { + + g_source_remove (passwd_handler->backend_child_watch_id); + + passwd_handler->backend_child_watch_id = 0; + } + + + /* Close IO channels (internal file descriptors are automatically closed) */ + if (passwd_handler->backend_stdin != NULL) { + + if (g_io_channel_shutdown (passwd_handler->backend_stdin, TRUE, &error) != G_IO_STATUS_NORMAL) { + g_warning ("Could not shutdown backend_stdin IO channel: %s", error->message); + g_error_free (error); + error = NULL; + } + + g_io_channel_unref (passwd_handler->backend_stdin); + passwd_handler->backend_stdin = NULL; + } + + if (passwd_handler->backend_stdout != NULL) { + + if (g_io_channel_shutdown (passwd_handler->backend_stdout, TRUE, &error) != G_IO_STATUS_NORMAL) { + g_warning ("Could not shutdown backend_stdout IO channel: %s", error->message); + g_error_free (error); + error = NULL; + } + + g_io_channel_unref (passwd_handler->backend_stdout); + + passwd_handler->backend_stdout = NULL; + } + + /* Remove IO watcher */ + if (passwd_handler->backend_stdout_watch_id != 0) { + + g_source_remove (passwd_handler->backend_stdout_watch_id); + + passwd_handler->backend_stdout_watch_id = 0; + } + + /* Close PID */ + //因为flag为G_SPAWN_DO_NOT_REAP_CHILD,所以child不会自动的被reap掉,需要在子进程上free + if (passwd_handler->backend_pid != -1) { + + g_spawn_close_pid (passwd_handler->backend_pid); + + passwd_handler->backend_pid = -1; + } + + /* Clear backend state */ + passwd_handler->backend_state = PASSWD_STATE_NONE; +} + +static void authenticate (PasswdHandler *passwd_handler) +{ + gchar *s; + + s = g_strdup_printf ("%s\n", passwd_handler->current_password); + g_queue_push_tail (passwd_handler->backend_stdin_queue, s); +} + +static void io_queue_pop (GQueue *queue, GIOChannel *channel) +{ + gchar *buf; + gsize bytes_written; + GError *error = NULL; + + buf = (gchar *)g_queue_pop_head (queue); + + if (buf != NULL) { + //将队列中的首元素写入到channel中 + if (g_io_channel_write_chars (channel, buf, -1, &bytes_written, &error) != G_IO_STATUS_NORMAL) { + g_warning ("Could not write queue element \"%s\" to channel: %s", buf, error->message); + g_error_free (error); + } + + /* Ensure passwords are cleared from memory */ + //清除内存中的passwords + memset (buf, 0, strlen (buf)); + g_free (buf); + } + +} + +static gboolean is_string_complete (gchar *str, ...) +{ + va_list ap; + gchar *arg; + + if (strlen (str) == 0) { + return FALSE; + } + + va_start (ap, str); + + while ((arg = va_arg (ap, char *)) != NULL) { + if (g_strrstr (str, arg) != NULL) { + va_end (ap); + return TRUE; + } + } + + va_end (ap); + + return FALSE; +} + +static gboolean io_watch_stdout (GIOChannel *source, GIOCondition condition, PasswdHandler *passwd_handler) +{ + static GString *str = NULL; /* Persistent buffer */ + + gchar buf[BUFSIZE]; /* Temporary buffer */ + gsize bytes_read; + GError *gio_error = NULL; /* Error returned by functions */ + GError *error = NULL; /* Error sent to callbacks */ + + //GtkBuilder *dialog; + + gboolean reinit = FALSE; + + /* Initialize buffer */ + if (str == NULL) { + str = g_string_new (""); + } + + //dialog = passwd_handler->ui; + //buf将保存从channel中读取到的数据,bytes_read表示从buf中读取的数据长度 + if (g_io_channel_read_chars (source, buf, BUFSIZE, &bytes_read, &gio_error) + != G_IO_STATUS_NORMAL) { + g_warning ("IO Channel read error: %s", gio_error->message); + g_error_free (gio_error); + + return TRUE; + } + + // g_warning("----------bytes_read=%d",bytes_read); + // g_warning("----------io_watch_buf=%s-------",buf); + + str = g_string_append_len (str, buf, bytes_read); + + /* In which state is the backend? */ + switch (passwd_handler->backend_state) { + case PASSWD_STATE_AUTH: + /* Passwd is asking for our current password */ + + if (is_string_complete (str->str, "assword: ", "failure", "wrong", "error", NULL)) { + + if (g_strrstr (str->str, "assword: ") != NULL) { + /* Authentication successful */ + + passwd_handler->backend_state = PASSWD_STATE_NEW; + + /* Trigger callback to update authentication status */ + if (passwd_handler->auth_cb) + passwd_handler->auth_cb (passwd_handler, + NULL, + passwd_handler->auth_cb_data); + + } else { + /* Authentication failed */ + + error = g_error_new_literal (PASSWD_ERROR, PASSWD_ERROR_AUTH_FAILED, + "Authentication failure!"); + + passwd_handler->changing_password = FALSE; + + /* This error can happen both while authenticating or while changing password: + * if chpasswd_cb is set, this means we're already changing password */ + if (passwd_handler->chpasswd_cb) + passwd_handler->chpasswd_cb (passwd_handler, + error, + passwd_handler->auth_cb_data); + else if (passwd_handler->auth_cb) + passwd_handler->auth_cb (passwd_handler, + error, + passwd_handler->auth_cb_data); + + g_error_free (error); + } + + reinit = TRUE; + } + break; + case PASSWD_STATE_NEW: + /* Passwd is asking for our new password */ + + if (is_string_complete (str->str, "assword: ", NULL)) { + /* Advance to next state */ + passwd_handler->backend_state = PASSWD_STATE_RETYPE; + + /* Pop retyped password from queue and into IO channel */ + io_queue_pop (passwd_handler->backend_stdin_queue, passwd_handler->backend_stdin); + + reinit = TRUE; + } + break; + case PASSWD_STATE_RETYPE: + /* Passwd is asking for our retyped new password */ + + // if (is_string_complete (str->str, + // "successfully", + // "short", + // "longer", + // "palindrome", + // "dictionary", + // "simple", + // "simplistic", + // "similar", + // "different", + // "case", + // "wrapped", + // "recovered", + // "recent", + // "unchanged", + // "match", + // "1 numeric or special", + // "failure", + // "length", + // NULL)) { + if (TRUE){ + + if (g_strrstr (str->str, "successfully") != NULL) { + /* Hooray! */ + + /* Trigger callback to update status */ + if (passwd_handler->chpasswd_cb) + passwd_handler->chpasswd_cb (passwd_handler, + NULL, + passwd_handler->chpasswd_cb_data); + } + else { + /* Ohnoes! */ + + if (g_strrstr (str->str, "recovered") != NULL) { + /* What does this indicate? + * "Authentication information cannot be recovered?" from libpam? */ + error = g_error_new_literal (PASSWD_ERROR, PASSWD_ERROR_UNKNOWN, + str->str); + } else if (g_strrstr (str->str, "short") != NULL || + g_strrstr (str->str, "longer") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "New password length is too short!"); + } else if (g_strrstr (str->str, "palindrome") != NULL || + g_strrstr (str->str, "simple") != NULL || + g_strrstr (str->str, "simplistic") != NULL || + g_strrstr (str->str, "dictionary") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password is too simple!"); + } else if (g_strrstr (str->str, "similar") != NULL || + g_strrstr (str->str, "different") != NULL || + g_strrstr (str->str, "case") != NULL || + g_strrstr (str->str, "wrapped") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password is too similar to the old one!"); + } else if (g_strrstr (str->str, "1 numeric or special") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password must contain numbers or special characters!"); + } else if (g_strrstr (str->str, "unchanged") != NULL || + g_strrstr (str->str, "match") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password is the same as the old one!"); + } else if (g_strrstr (str->str, "recent") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password has been used recently!"); + } else if (g_strrstr (str->str, "failure") != NULL) { + /* Authentication failure */ + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_AUTH_FAILED, + "Your password has been changed after you verify!"); + } + else { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_UNKNOWN, + "Unknown error"); + } + + /* At this point, passwd might have exited, in which case + * child_watch_cb should clean up for us and remove this watcher. + * On some error conditions though, passwd just re-prompts us + * for our new password. */ + passwd_handler->backend_state = PASSWD_STATE_ERR; + + passwd_handler->changing_password = FALSE; + + /* Trigger callback to update status */ + if (passwd_handler->chpasswd_cb) + passwd_handler->chpasswd_cb (passwd_handler, + error, + passwd_handler->chpasswd_cb_data); + + g_error_free (error); + + } + + reinit = TRUE; + + /* child_watch_cb should clean up for us now */ + } + break; + case PASSWD_STATE_NONE: + /* Passwd is not asking for anything yet */ + if (is_string_complete (str->str, "assword: ", NULL)) { + + /* If the user does not have a password set, + * passwd will immediately ask for the new password, + * so skip the AUTH phase */ + if (is_string_complete (str->str, "new", "New", NULL)) { + gchar *pw; + + passwd_handler->backend_state = PASSWD_STATE_NEW; + + /* since passwd didn't ask for our old password + * in this case, simply remove it from the queue */ + pw = (gchar *)g_queue_pop_head (passwd_handler->backend_stdin_queue); + g_free (pw); + + /* Pop the IO queue, i.e. send new password */ + io_queue_pop (passwd_handler->backend_stdin_queue, passwd_handler->backend_stdin); + } else { + + passwd_handler->backend_state = PASSWD_STATE_AUTH; + + /* Pop the IO queue, i.e. send current password */ + io_queue_pop (passwd_handler->backend_stdin_queue, passwd_handler->backend_stdin); + } + + reinit = TRUE; + } + break; + default: + /* Passwd has returned an error */ + reinit = TRUE; + break; + } + + if (reinit) { + g_string_free (str, TRUE); + str = NULL; + } + + /* Continue calling us */ + return TRUE; +} + +/* Child watcher */ +static void child_watch_cb (GPid pid, gint status, PasswdHandler *passwd_handler) +{ + //子进程正常结束为非0 + if (WIFEXITED (status)) { + //取得子进程正常退出时返回的结束代码 + if (WEXITSTATUS (status) >= 255) { + g_warning ("Child exited unexpectedly"); + } + } + + free_passwd_resources (passwd_handler); +} + +static void stop_passwd (PasswdHandler *passwd_handler) +{ + /* This is the standard way of returning from the dialog with passwd. + * If we return this way we can safely kill passwd as it has completed + * its task. + */ + + if (passwd_handler->backend_pid != -1) { + kill (passwd_handler->backend_pid, 9); + } + + /* We must run free_passwd_resources here and not let our child + * watcher do it, since it will access invalid memory after the + * dialog has been closed and cleaned up. + * + * If we had more than a single thread we'd need to remove + * the child watch before trying to kill the child. + */ + free_passwd_resources (passwd_handler); +} + +static gboolean spawn_passwd (PasswdHandler *passwd_handler, GError **error) +{ + gchar *argv[2]; + gchar *envp[1]; + gint my_stdin, my_stdout, my_stderr; + + argv[0] = "/usr/bin/passwd"; /* Is it safe to rely on a hard-coded path? */ + argv[1] = NULL; + + envp[0] = NULL; /* If we pass an empty array as the environment, + * will the childs environment be empty, and the + * locales set to the C default? From the manual: + * "If envp is NULL, the child inherits its + * parent'senvironment." + * If I'm wrong here, we somehow have to set + * the locales here. + */ + + //创建一个管道,进行通信,子进程执行passwd命令 + if (!g_spawn_async_with_pipes (NULL, /* Working directory */ + argv, /* Argument vector */ + envp, /* Environment */ + G_SPAWN_DO_NOT_REAP_CHILD, /* Flags */ + NULL, /* Child setup (在子进程调用exec()之前,该函数会被调用)*/ + NULL, /* Data to child setup */ + &passwd_handler->backend_pid, /* PID */ + &my_stdin, /* Stdin */ + &my_stdout, /* Stdout */ + &my_stderr, /* Stderr */ + error)) { /* GError */ + + /* An error occured */ + free_passwd_resources (passwd_handler); + + return FALSE; + } + + /* 2>&1 */ + //复制文件描述符,也就是将stderr重定向到stdout + if (dup2 (my_stderr, my_stdout) == -1) { + /* Failed! */ + g_set_error_literal (error, + PASSWD_ERROR, + PASSWD_ERROR_BACKEND, + strerror (errno)); + + /* Clean up */ + stop_passwd (passwd_handler); + + return FALSE; + } + + /* Open IO Channels */ + //指定一个文件描述符,创建一个IO Channel,默认使用UTF-8编码格式 + passwd_handler->backend_stdin = g_io_channel_unix_new (my_stdin); + passwd_handler->backend_stdout = g_io_channel_unix_new (my_stdout); + + /* Set raw encoding */ + /* Set nonblocking mode */ + //设置通道的编码方式为NULL,设置为非阻塞的方式 + if (g_io_channel_set_encoding (passwd_handler->backend_stdin, NULL, error) != G_IO_STATUS_NORMAL || + g_io_channel_set_encoding (passwd_handler->backend_stdout, NULL, error) != G_IO_STATUS_NORMAL || + g_io_channel_set_flags (passwd_handler->backend_stdin, G_IO_FLAG_NONBLOCK, error) != G_IO_STATUS_NORMAL || + g_io_channel_set_flags (passwd_handler->backend_stdout, G_IO_FLAG_NONBLOCK, error) != G_IO_STATUS_NORMAL ) { + + /* Clean up */ + stop_passwd (passwd_handler); + return FALSE; + } + + /* Turn off buffering */ + //只有通道的编码方式为NULL,才能设置缓冲状态为FASLE,其他任何编码,通道必须被缓冲,这里是为了清掉上次的密码 + g_io_channel_set_buffered (passwd_handler->backend_stdin, FALSE); + g_io_channel_set_buffered (passwd_handler->backend_stdout, FALSE); + + /* Add IO Channel watcher */ + //当IO通道的状态为G_IO_IN(从IO通道读数据时)或者G_IO_PRI(读紧急数据时)时,调用io_watch_stdout + passwd_handler->backend_stdout_watch_id = g_io_add_watch (passwd_handler->backend_stdout, + G_IO_IN /*| G_IO_PRI*/, + (GIOFunc) io_watch_stdout, passwd_handler); + + /* Add child watcher */ + //在指定pid的进程退出时,调用child_watch_cb(),进行错误检查,以及资源回收 + passwd_handler->backend_child_watch_id = g_child_watch_add (passwd_handler->backend_pid, (GChildWatchFunc) child_watch_cb, passwd_handler); + + /* Success! */ + + return TRUE; +} + +static void update_password (PasswdHandler *passwd_handler) +{ + gchar *s; + + s = g_strdup_printf ("%s\n", passwd_handler->new_password); + + g_queue_push_tail (passwd_handler->backend_stdin_queue, s); + /* We need to allocate new space because io_queue_pop() g_free()s + * every element of the queue after it's done */ + g_queue_push_tail (passwd_handler->backend_stdin_queue, g_strdup (s)); +} + +gboolean passwd_change_password (PasswdHandler *passwd_handler, + const char *new_password, + PasswdCallback cb, + const gpointer user_data) +{ + GError *error = NULL; + + passwd_handler->changing_password = TRUE; + + passwd_handler->new_password = new_password; + passwd_handler->chpasswd_cb = cb; + passwd_handler->chpasswd_cb_data = user_data; + + /* Stop passwd if an error occured and it is still running */ + if (passwd_handler->backend_state == PASSWD_STATE_ERR) { + + /* Stop passwd, free resources */ + stop_passwd (passwd_handler); + } + + /* Check that the backend is still running, or that an error + * has occured but it has not yet exited */ + if (passwd_handler->backend_pid == -1) { + /* If it is not, re-run authentication */ + + /* Spawn backend */ + stop_passwd (passwd_handler); + + if (!spawn_passwd (passwd_handler, &error)) { + g_error_free (error); + + return FALSE; + } + + /* Add current and new passwords to queue */ + //将当前的密码和新密码入队,新密码会入队两次 + authenticate (passwd_handler); + update_password (passwd_handler); + } else { + /* Only add new passwords to queue */ + update_password (passwd_handler); + } + + /* Pop new password through the backend. If user has no password, popping the queue + would output current password, while 'passwd' is waiting for the new one. So wait + for io_watch_stdout() to remove current password from the queue, and output + the new one for us.*/ + //如果密码为空,将新进队列的密码,作为current_passwd弹出 + if (passwd_handler->current_password) + { + io_queue_pop (passwd_handler->backend_stdin_queue, passwd_handler->backend_stdin); + } + + /* Our IO watcher should now handle the rest */ + + return TRUE; +} + +void passwd_authenticate (PasswdHandler *passwd_handler, + const char *current_password, + PasswdCallback cb, + const gpointer user_data) +{ + GError *error = NULL; + + /* Don't stop if we've already started chaging password */ + if (passwd_handler->changing_password) + return; + + /* Clear data from possible previous attempts to change password */ + passwd_handler->new_password = NULL; + passwd_handler->chpasswd_cb = NULL; + passwd_handler->chpasswd_cb_data = NULL; + g_queue_foreach (passwd_handler->backend_stdin_queue, (GFunc) g_free, NULL); + g_queue_clear (passwd_handler->backend_stdin_queue); + + passwd_handler->current_password = current_password; + passwd_handler->auth_cb = cb; + passwd_handler->auth_cb_data = user_data; + + /* Spawn backend */ + //重新启动后台passwd + stop_passwd (passwd_handler); + + if (!spawn_passwd (passwd_handler, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + return; + } + + //将current passwd从尾部插入队列 + authenticate (passwd_handler); + + /* Our IO watcher should now handle the rest */ +} + + +PasswdHandler * passwd_init () +{ + PasswdHandler *passwd_handler; + + passwd_handler = g_new0 (PasswdHandler, 1); + + /* Initialize backend_pid. -1 means the backend is not running */ + //-1代表后台还没启动 + passwd_handler->backend_pid = -1; + + /* Initialize IO Channels */ + passwd_handler->backend_stdin = NULL; + passwd_handler->backend_stdout = NULL; + + /* Initialize write queue */ + passwd_handler->backend_stdin_queue = g_queue_new (); + + /* Initialize watchers */ + passwd_handler->backend_child_watch_id = 0; + passwd_handler->backend_stdout_watch_id = 0; + + /* Initialize backend state */ + passwd_handler->backend_state = PASSWD_STATE_NONE; + passwd_handler->changing_password = FALSE; + + return passwd_handler; +} + + +void passwd_destroy (PasswdHandler *passwd_handler) +{ + g_queue_free (passwd_handler->backend_stdin_queue); + stop_passwd (passwd_handler); + g_free (passwd_handler); +} diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/run-passwd.h ukui-control-center-3.0.3/plugins/account/userinfo/run-passwd.h --- ukui-control-center-2.0.3/plugins/account/userinfo/run-passwd.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/run-passwd.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,34 @@ +#ifndef RUNPASSWD_H +#define RUNPASSWD_H + + +struct PasswdHandler; + +typedef struct PasswdHandler PasswdHandler; + +typedef void (*PasswdCallback) (PasswdHandler * passwd_handler, GError * error, const gpointer user_data); + +/* Error codes */ +typedef enum { + PASSWD_ERROR_REJECTED, /* New password is not secure enough */ + PASSWD_ERROR_AUTH_FAILED, /* Wrong old password, or PAM failure */ + PASSWD_ERROR_REAUTH_FAILED, /* Password has changed since first authentication */ + PASSWD_ERROR_BACKEND, /* Backend error */ + PASSWD_ERROR_UNKNOWN /* General error */ +} PasswdError; + +PasswdHandler *passwd_init (); + +void passwd_destroy (PasswdHandler *passwd_handler); + +void passwd_authenticate (PasswdHandler *passwd_handler, + const char *current_password, + PasswdCallback cb, + gpointer user_data); + +gboolean passwd_change_password (PasswdHandler *passwd_handler, + const char *new_password, + PasswdCallback cb, + const gpointer user_data); + +#endif // RUNPASSWD_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/servicemanager.cpp ukui-control-center-3.0.3/plugins/account/userinfo/servicemanager.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/servicemanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/servicemanager.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,102 @@ +/* + * 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 "servicemanager.h" +#include +#include "biometricdeviceinfo.h" + +#define SERVICE "biometric-authentication.service" +#define DBUS_SERVICE "org.ukui.Biometric" +#define DBUS_PATH "/org/ukui/Biometric" +#define DBUS_INTERFACE "org.ukui.Biometric" + +#define FD_DBUS_SERVICE "org.freedesktop.DBus" +#define FD_DBUS_PATH "/org/freedesktop/DBus" +#define FD_DBUS_INTERFACE "org.freedesktop.DBus" + +ServiceManager *ServiceManager::instance_ = nullptr; + +ServiceManager::ServiceManager(QObject *parent) + : QObject(parent), + dbusService(nullptr), + bioService(nullptr) +{ + init(); +} + +void ServiceManager::init() +{ + if(!dbusService) + { + dbusService = new QDBusInterface(FD_DBUS_SERVICE, + FD_DBUS_PATH, + FD_DBUS_INTERFACE, + QDBusConnection::systemBus()); + connect(dbusService, SIGNAL(NameOwnerChanged(QString, QString, QString)), + this, SLOT(onDBusNameOwnerChanged(QString,QString,QString))); + } +} + +ServiceManager *ServiceManager::instance() +{ + if(!instance_) + { + instance_ = new ServiceManager; + } + return instance_; +} + +bool ServiceManager::connectToService() +{ + if(!bioService) + { + bioService = new QDBusInterface(DBUS_SERVICE, + DBUS_PATH, + DBUS_INTERFACE, + QDBusConnection::systemBus()); + } + return bioService->isValid(); +} + +void ServiceManager::onDBusNameOwnerChanged(const QString &name, + const QString &oldOwner, + const QString &newOwner) +{ + if(name == DBUS_SERVICE) + { + qDebug() << "service status changed:" + << (newOwner.isEmpty() ? "inactivate" : "activate"); + Q_EMIT serviceStatusChanged(!newOwner.isEmpty()); + } +} + +/*! + * \brief checkServiceExist + * 检查生物识别后台服务是否已启动 + */ +bool ServiceManager::serviceExists() +{ + QDBusReply reply = dbusService->call("NameHasOwner", DBUS_SERVICE); + if(!reply.isValid()) + { + qDebug() << "check service exists error:" << reply.error(); + return false; + } + return reply.value(); +} + diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/servicemanager.h ukui-control-center-3.0.3/plugins/account/userinfo/servicemanager.h --- ukui-control-center-2.0.3/plugins/account/userinfo/servicemanager.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/servicemanager.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,52 @@ +/* + * 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 SERVICEMANAGER_H +#define SERVICEMANAGER_H + +#include +#include + +class ServiceManager : public QObject +{ + Q_OBJECT +public: + static ServiceManager *instance(); + bool serviceExists(); + +private: + explicit ServiceManager(QObject *parent = nullptr); + void init(); + bool connectToService(); + +signals: + void serviceStatusChanged(bool activate); + +public slots: + void onDBusNameOwnerChanged(const QString &name, + const QString &oldOwner, + const QString &newOwner); + +private: + static ServiceManager *instance_; + QDBusInterface *dbusService; + QDBusInterface *bioService; + bool serviceStatus; +}; + +#endif // SERVICEMANAGER_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/userinfo.cpp ukui-control-center-3.0.3/plugins/account/userinfo/userinfo.cpp --- ukui-control-center-2.0.3/plugins/account/userinfo/userinfo.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/userinfo.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -24,12 +24,22 @@ #include #include #include - +#include +#include +#include +#include +#include #include +#include +#include + +#include #include "SwitchButton/switchbutton.h" #include "ImageUtil/imageutil.h" #include "elipsemaskwidget.h" +#include "passwdcheckutil.h" +#include "loginedusers.h" /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 @@ -43,80 +53,98 @@ #include } +#ifdef WITHKYSEC +#include +#include +#endif #define DEFAULTFACE "/usr/share/ukui/faces/default.png" #define ITEMHEIGH 52 -UserInfo::UserInfo() +UserInfo::UserInfo() : mFirstLoad(true) { - ui = new Ui::UserInfo; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - - pluginName = tr("Userinfo"); + pluginName = tr("User Info"); pluginType = ACCOUNT; - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - //构建System dbus调度对象 - sysdispatcher = new SystemDbusDispatcher; - - - //获取系统全部用户信息,用户Uid大于等于1000的 - _acquireAllUsersInfo(); - - - readCurrentPwdConf(); - initComponent(); - initAllUserStatus(); - //设置界面用户信息 - _refreshUserInfoUI(); - - -// pwdSignalMapper = new QSignalMapper(this); -// faceSignalMapper = new QSignalMapper(this); -// typeSignalMapper = new QSignalMapper(this); -// delSignalMapper = new QSignalMapper(this); - -// faceSize = QSize(64, 64); -// itemSize = QSize(230, 106); //?需要比btnsize大多少?否则显示不全 -// btnSize = QSize(222, 92); - - -// get_all_users(); -// ui_component_init(); -// ui_status_init(); - } UserInfo::~UserInfo() { - delete ui; - delete autoSettings; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + delete autoSettings; + autoSettings = nullptr; + } } -QString UserInfo::get_plugin_name(){ +QString UserInfo::get_plugin_name() { return pluginName; } -int UserInfo::get_plugin_type(){ +int UserInfo::get_plugin_type() { return pluginType; } -QWidget *UserInfo::get_plugin_ui(){ +QWidget *UserInfo::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::UserInfo; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + // 构建System dbus调度对象 + sysdispatcher = new SystemDbusDispatcher(this); + + // 获取系统全部用户信息,用户Uid大于等于1000的 + _acquireAllUsersInfo(); + + initTitleLabel(); + initSearchText(); + readCurrentPwdConf(); + initComponent(); + initAllUserStatus(); + // 设置界面用户信息 + _refreshUserInfoUI(); + } return pluginWidget; } -void UserInfo::plugin_delay_control(){ +void UserInfo::plugin_delay_control() { + +} + +const QString UserInfo::name() const { + + return QStringLiteral("userinfo"); +} +void UserInfo::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); + ui->bioPasswordLabel->setFont(font); +} + +void UserInfo::initSearchText() { + //~ contents_path /userinfo/Password + ui->changePwdBtn->setText(tr("Password")); + //~ contents_path /userinfo/Type + ui->changeTypeBtn->setText(tr("Type")); + //~ contents_path /userinfo/Login no passwd + ui->loginpwdLabel->setText(tr("Login no passwd")); + //~ contents_path /userinfo/enable autoLogin + ui->autologinLabel->setText(tr("enable autoLogin")); } QString UserInfo::_accountTypeIntToString(int type){ QString atype; if (type == STANDARDUSER) - atype = tr("standard user"); + atype = tr("Standard"); else if (type == ADMINISTRATOR) - atype = tr("administrator"); + atype = tr("Admin"); else if (type == ROOT) atype = tr("root"); @@ -124,12 +152,32 @@ } void UserInfo::_acquireAllUsersInfo(){ + + mUserName = qgetenv("USER"); + if (mUserName.isEmpty()) { + mUserName = qgetenv("USERNAME"); + } + QStringList objectpaths = sysdispatcher->list_cached_users(); //初始化用户信息QMap allUserInfoMap.clear(); //初始化管理员数目为0 - adminnum = 0; +// adminnum = 0; + + //root + if (!getuid()){ + UserInfomation root; + root.username = g_get_user_name(); + root.realname = g_get_real_name(); + root.current = true; + root.logined = true; + root.autologin = false; + root.uid = 0; + root.accounttype = ADMINISTRATOR; + root.iconfile = DEFAULTFACE; + allUserInfoMap.insert(root.username, root); + } for (QString objectpath : objectpaths){ UserInfomation user; @@ -137,8 +185,47 @@ allUserInfoMap.insert(user.username, user); } - //处理root登录 + if (allUserInfoMap.isEmpty()) { + ui->currentUserFrame->setVisible(false); + ui->autoLoginFrame->setVisible(false); + ui->liveFrame->setVisible(true); + } else { + ui->currentUserFrame->setVisible(true); + ui->autoLoginFrame->setVisible(true); + ui->liveFrame->setVisible(false); + } + initUserPropertyConnection(objectpaths); +} + +int UserInfo::_userCanDel(QString user){ + QString cmd = QString("cat /etc/group | grep sudo | awk -F: '{ print $NF}'"); + QString output; + FILE *stream; + char buf[256]; + + if ((stream = popen(cmd.toLatin1().data(), "r" )) == NULL){ + return -1; + } + + while(fgets(buf, 256, stream) != NULL){ + output = QString(buf).simplified(); + } + + pclose(stream); + + QStringList users = output.split(","); + int num = users.length(); + + if (users.contains(user)){ + if (num > 1){ + return 1; + } else { + return 0; + } + } else { + return 1; + } } UserInfomation UserInfo::_acquireUserInfo(QString objpath){ @@ -158,40 +245,29 @@ QMap propertyMap; propertyMap = reply.value(); user.username = propertyMap.find("UserName").value().toString(); - if (user.username == QString(g_get_user_name())){ - user.current = true; - user.logined = true; + user.realname = propertyMap.find("RealName").value().toString(); - //获取当前用户免密登录属性 - QDBusInterface *tmpSysinterface = new QDBusInterface("com.control.center.qt.systemdbus", - "/", - "com.control.center.interface", - QDBusConnection::systemBus()); - //获取免密登录状态 - QDBusReply noPwdres; - noPwdres = tmpSysinterface ->call("getNoPwdLoginStatus"); - //const QString &tmp=noPwdres; - if(!noPwdres.isValid()){ - qDebug()<<"获取tmpSysinterface状态不合法---->"<< noPwdres.error(); - } - delete tmpSysinterface; + if (user.realname.isEmpty()){ + user.realname = propertyMap.find("UserName").value().toString(); + } - user.noPwdLogin = noPwdres.value().contains(user.username) ? true : false; + if (user.username == QString(g_get_user_name())) { + user.current = true; + user.logined = true; + user.noPwdLogin = getNoPwdStatus(); } user.accounttype = propertyMap.find("AccountType").value().toInt(); - if (user.accounttype == ADMINISTRATOR) - adminnum++; user.iconfile = propertyMap.find("IconFile").value().toString(); user.passwdtype = propertyMap.find("PasswordMode").value().toInt(); user.uid = propertyMap.find("Uid").value().toInt(); -// user.autologin = propertyMap.find("AutomaticLogin").value().toBool(); - user.autologin = this->getAutomaticLogin(user.username); + user.autologin = getAutomaticLogin().contains(user.username, Qt::CaseSensitive); user.objpath = objpath; } else qDebug() << "reply failed"; delete iproperty; + iproperty = nullptr; return user; } @@ -220,6 +296,12 @@ enablePwdQuality = true; } + if (PasswdCheckUtil::getCurrentPamState()){ + enablePwdQuality = true; + } else { + enablePwdQuality = false; + } + if (enablePwdQuality){ int minLen; status = pwquality_get_int_value(pwdconf, PWQ_SETTING_MIN_LENGTH, &minLen); @@ -311,20 +393,26 @@ } void UserInfo::initComponent(){ - //样式表 -// pluginWidget->setStyleSheet("background: #ffffff;"); - -// ui->currentUserWidget->setStyleSheet("QWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); -// ui->autoLoginWidget->setStyleSheet("QWidget{background: #F4F4F4; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); -// QString btnQss = QString("QPushButton{background: #FFFFFF; border-radius: 4px;}"); -// ui->changePwdBtn->setStyleSheet(btnQss); -// ui->changeTypeBtn->setStyleSheet(btnQss); + //root需要屏蔽部分功能 + if (!getuid()){ + ui->changeTypeBtn->setEnabled(false); +// ui->changeGroupBtn->setEnabled(false); + ui->autoLoginFrame->setVisible(false); + ui->noPwdLoginFrame->setVisible(false); + } -// ui->addUserWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); +#ifdef WITHKYSEC + if (!kysec_is_disabled() && kysec_get_3adm_status() && (getuid() || geteuid())){ + ui->addUserWidget->hide(); + } +#endif -// QString filename = "/etc/lightdm/lightdm.conf"; -// autoSettings = new QSettings(filename, QSettings::IniFormat); +#ifdef __sw_64__ + ui->changeValidBtn->show(); +#else + ui->changeValidBtn->hide(); +#endif ui->listWidget->setStyleSheet("QListWidget::Item:hover{background:palette(base);}"); @@ -340,53 +428,38 @@ QLabel * textLabel = new QLabel(tr("Add new user")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); + iconLabel->setProperty("useIconHighlightEffect", true); + iconLabel->setProperty("iconHighlightEffectMode", 1); addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); addWgt->setLayout(addLyt); - // 悬浮改变Widget状态 - connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(base);"); - - }); - // 还原状态 - connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(windowText);"); - }); - - connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname){ + connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname) { + Q_UNUSED(mname); showCreateUserDialog(); }); ui->addLyt->addWidget(addWgt); - nopwdSwitchBtn = new SwitchButton(ui->nopwdLoginFrame); + ui->nopwdHorLayout->setSpacing(0); + ui->nopwdHorLayout->setMargin(0); + + nopwdSwitchBtn = new SwitchButton(ui->noPwdLoginFrame); ui->nopwdHorLayout->addWidget(nopwdSwitchBtn); autoLoginSwitchBtn = new SwitchButton(ui->autoLoginFrame); ui->autoLoginHorLayout->addWidget(autoLoginSwitchBtn); - -// ui->listWidget->setStyleSheet("QListWidget{border: none}"); -// ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -// ui->listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->listWidget->setSpacing(0); ElipseMaskWidget * mainElipseMaskWidget = new ElipseMaskWidget(ui->currentUserFaceLabel); mainElipseMaskWidget->setGeometry(0, 0, ui->currentUserFaceLabel->width(), ui->currentUserFaceLabel->height()); - //设置添加用户的图标 -// ui->addBtn->setIcon(QIcon("://img/plugins/userinfo/add.png")); -// ui->addBtn->setIconSize(ui->addBtn->size()); -// ui->addBtn->setStyleSheet("QPushButton{background-color:transparent;}"); - - ui->currentUserFaceLabel->installEventFilter(this); -// ui->addUserFrame->installEventFilter(this); + if (getuid()){ + ui->currentUserFaceLabel->installEventFilter(this); + ui->nameChangeWidget->installEventFilter(this); + } //修改当前用户密码的回调 connect(ui->changePwdBtn, &QPushButton::clicked, this, [=](bool checked){ @@ -397,11 +470,17 @@ }); //修改当前用户类型的回调 - connect(ui->changeTypeBtn, &QPushButton::clicked, this, [=](bool checked){ - Q_UNUSED(checked) - UserInfomation user = allUserInfoMap.value(g_get_user_name()); + if (getuid()) + connect(ui->changeTypeBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + UserInfomation user = allUserInfoMap.value(g_get_user_name()); - showChangeTypeDialog(user.username); + showChangeTypeDialog(user.username); + }); + + connect(ui->changeGroupBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + showChangeGroupDialog(); }); connect(ui->changeValidBtn, &QPushButton::clicked, this, [=](bool checked){ @@ -413,52 +492,53 @@ }); //修改当前用户免密登录 - connect(nopwdSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ - - UserInfomation user = allUserInfoMap.value(g_get_user_name()); - //免密登录状态改变 + if (getuid()) + connect(nopwdSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ - QDBusInterface * tmpSysinterface = new QDBusInterface("com.control.center.qt.systemdbus", - "/", - "com.control.center.interface", - QDBusConnection::systemBus()); + UserInfomation user = allUserInfoMap.value(g_get_user_name()); + //免密登录状态改变 - if (!tmpSysinterface->isValid()){ - qCritical() << "Create Client Interface Failed When execute gpasswd: " << QDBusConnection::systemBus().lastError(); - return; - } - tmpSysinterface->call("setNoPwdLoginStatus", checked, user.username); + QDBusInterface * tmpSysinterface = new QDBusInterface("com.control.center.qt.systemdbus", + "/", + "com.control.center.interface", + QDBusConnection::systemBus()); + + if (!tmpSysinterface->isValid()){ + qCritical() << "Create Client Interface Failed When execute gpasswd: " << QDBusConnection::systemBus().lastError(); + return; + } + tmpSysinterface->call("setNoPwdLoginStatus", checked, user.username); - delete tmpSysinterface; + delete tmpSysinterface; + tmpSysinterface = nullptr; - }); + }); //修改当前用户自动登录 - connect(autoLoginSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ - UserInfomation user = allUserInfoMap.value(g_get_user_name()); + if (getuid()) + connect(autoLoginSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked) { + UserInfomation user = allUserInfoMap.value(g_get_user_name()); - UserDispatcher * userdispatcher = new UserDispatcher(user.objpath); + UserDispatcher * userdispatcher = new UserDispatcher(user.objpath); + bool status = getAutomaticLogin().contains(user.username, Qt::CaseSensitive); -// bool status = userdispatcher->get_autoLogin_status(); - - bool status = this->getAutomaticLogin(user.username); - - - if ((checked != status)) { - if (checked) { - userdispatcher->change_user_autologin(user.username); - } else { - userdispatcher->change_user_autologin(""); + if (checked && !isOpenAutoLogin(user.username)) { + autoLoginSwitchBtn->blockSignals(true); + autoLoginSwitchBtn->setChecked(false); + autoLoginSwitchBtn->blockSignals(false); + return ; } - } - -// bool lstStatus = userdispatcher->get_autoLogin_status(); -// bool lstStatus = this->getAutomaticLogin(user.username); -// autoLoginSwitchBtn->setChecked(lstStatus); - }); + if ((checked != status)) { + if (checked) { + userdispatcher->change_user_autologin(user.username); + } else { + userdispatcher->change_user_autologin(""); + } + } + }); //成功删除用户的回调 connect(sysdispatcher, &SystemDbusDispatcher::deleteuserdone, this, [=](QString objPath){ @@ -475,11 +555,17 @@ connect(sysdispatcher, &SystemDbusDispatcher::createuserdone, this, [=](QString objPath){ createUserDone(objPath); }); + + //初始化生物密码控件 + if(isShowBiometric()) + initBioComonent(); + else + setBiometricDeviceVisible(false); } void UserInfo::_resetListWidgetHeigh(){ //设置其他用户控件的总高度 - ui->listWidget->setFixedHeight((allUserInfoMap.count()) * ITEMHEIGH); + ui->listWidget->setFixedHeight((allUserInfoMap.count() - 1 ) * (ITEMHEIGH) + 4); } void UserInfo::initAllUserStatus(){ @@ -502,6 +588,54 @@ } } +QStringList UserInfo::getLoginedUsers() { + m_loginedUser.clear(); + qRegisterMetaType("LoginedUsers"); + qDBusRegisterMetaType(); + QDBusInterface loginInterface("org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + QDBusConnection::systemBus()); + + if (loginInterface.isValid()) { + qDebug() << "create interface sucess"; + } + + 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()) { + LoginedUsers user; + dbusArgs >> user; + loginedUsers.push_back(user); + } + dbusArgs.endArray(); + + for (LoginedUsers user : loginedUsers) { + + QDBusInterface userPertyInterface("org.freedesktop.login1", + user.objpath.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); + } + } + } + return m_loginedUser; +} + void UserInfo::_refreshUserInfoUI(){ QMap::iterator it = allUserInfoMap.begin(); for (; it != allUserInfoMap.end(); it++){ @@ -519,15 +653,17 @@ if (user.username == QString(g_get_user_name())){ //设置用户头像 QPixmap iconPixmap = QPixmap(user.iconfile).scaled(ui->currentUserFaceLabel->size()); -// ui->currentUserFaceLabel->setScaledContents(true); ui->currentUserFaceLabel->setPixmap(iconPixmap); //设置用户名 - ui->userNameLabel->setText(user.username); + ui->userNameLabel->setText(user.realname); + ui->userNameChangeLabel->setPixmap(QIcon::fromTheme("document-edit-symbolic").pixmap(ui->userNameChangeLabel->size())); //设置用户类型 ui->userTypeLabel->setText(_accountTypeIntToString(user.accounttype)); //设置登录状态 + autoLoginSwitchBtn->blockSignals(true); autoLoginSwitchBtn->setChecked(user.autologin); + autoLoginSwitchBtn->blockSignals(false); //设置免密登录状态 nopwdSwitchBtn->setChecked(user.noPwdLogin); @@ -549,6 +685,8 @@ baseWidget->setMaximumSize(960,50); baseWidget->setAttribute(Qt::WA_DeleteOnClose); + //ui->currentUserFrame->setContentsMargins(16,0,16,0); + QHBoxLayout * baseVerLayout = new QHBoxLayout(baseWidget); baseVerLayout->setSpacing(0); baseVerLayout->setMargin(0); @@ -567,25 +705,31 @@ QPushButton * faceBtn = new QPushButton(widget); faceBtn->setObjectName("faceBtn"); - faceBtn->setFixedSize(32, 32); + faceBtn->setFixedSize(40, 40); faceBtn->setIcon(QIcon(user.iconfile)); - faceBtn->setIconSize(faceBtn->size()); + faceBtn->setIconSize(QSize(32, 32)); connect(faceBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) showChangeFaceDialog(user.username); }); + ElipseMaskWidget * otherElipseMaskWidget = new ElipseMaskWidget(faceBtn); + otherElipseMaskWidget->setGeometry(0, 0, faceBtn->width(), faceBtn->height()); + QLabel * nameLabel = new QLabel(widget); QSizePolicy nameSizePolicy = nameLabel->sizePolicy(); nameSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); nameSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); nameLabel->setSizePolicy(nameSizePolicy); - nameLabel->setText(user.username); + nameLabel->setText(user.realname); QString btnQss = QString("QPushButton{background: #ffffff; border-radius: 4px;}"); QPushButton * typeBtn = new QPushButton(widget); - typeBtn->setFixedSize(88, 36); +// typeBtn->setFixedSize(88, 36); + typeBtn->setFixedHeight(36); + typeBtn->setMinimumWidth(88); + typeBtn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); typeBtn->setText(tr("Change type")); // typeBtn->setStyleSheet(btnQss); connect(typeBtn, &QPushButton::clicked, this, [=](bool checked){ @@ -595,7 +739,10 @@ typeBtn->hide(); QPushButton * pwdBtn = new QPushButton(widget); - pwdBtn->setFixedSize(88, 36); +// pwdBtn->setFixedSize(88, 36); + pwdBtn->setFixedHeight(36); + pwdBtn->setMinimumWidth(88); + pwdBtn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); pwdBtn->setText(tr("Change pwd")); // pwdBtn->setStyleSheet(btnQss); connect(pwdBtn, &QPushButton::clicked, this, [=](bool checked){ @@ -614,7 +761,7 @@ QPushButton * delBtn = new QPushButton(baseWidget); delBtn->setFixedSize(60, 36); - delBtn->setText(tr("Delete")); + delBtn->setText(tr("Del")); // delBtn->setStyleSheet("QPushButton{background: #FA6056; border-radius: 4px}"); delBtn->hide(); connect(delBtn, &QPushButton::clicked, this, [=](bool checked){ @@ -623,7 +770,22 @@ }); connect(baseWidget, &HoverWidget::enterWidget, this, [=](QString name){ - Q_UNUSED(name) + + //不允许删除最后一个管理员 + if (_userCanDel(name) == 1){ + delBtn->setEnabled(true); + } else if (_userCanDel(name) == 0) { + delBtn->setEnabled(false); + } + +#ifdef WITHKYSEC + if (!kysec_is_disabled() && kysec_get_3adm_status()){ + if (user.username == "secadm" || user.username == "auditadm"){ + delBtn->setEnabled(false); + } + } +#endif + typeBtn->show(); pwdBtn->show(); delBtn->show(); @@ -637,16 +799,25 @@ baseHorLayout->addWidget(widget); baseHorLayout->addWidget(delBtn, Qt::AlignVCenter); - baseHorLayout->addSpacing(4); - + //baseHorLayout->addSpacing(4); baseVerLayout->addLayout(baseHorLayout); // baseVerLayout->addStretch(); baseWidget->setLayout(baseVerLayout); +#ifdef WITHKYSEC + if (!kysec_is_disabled() && kysec_get_3adm_status()){ + if (user.username == "secadm" || user.username == "auditadm"){ + pwdBtn->setEnabled(false); + typeBtn->setEnabled(false); + } + } +#endif + QListWidgetItem * item = new QListWidgetItem(ui->listWidget); - item->setSizeHint(QSize(ui->listWidget->width() - 4, ITEMHEIGH)); +// item->setSizeHint(QSize(ui->listWidget->width() - 4, ITEMHEIGH)); + item->setSizeHint(QSize(QSizePolicy::Expanding, ITEMHEIGH)); item->setData(Qt::UserRole, QVariant(user.objpath)); ui->listWidget->setItemWidget(item, baseWidget); @@ -669,6 +840,15 @@ dialog->exec(); } +QStringList UserInfo::getUsersList() +{ + QStringList usersStringList; + for (QVariant tmp : allUserInfoMap.keys()){ + usersStringList << tmp.toString(); + } + return usersStringList; +} + void UserInfo::createUser(QString username, QString pwd, QString pin, int atype){ Q_UNUSED(pin); sysdispatcher->create_user(username, "", atype); @@ -698,14 +878,19 @@ } void UserInfo::showDeleteUserDialog(QString username){ + + QStringList loginedusers = getLoginedUsers(); + if (loginedusers.contains(username)) { + QMessageBox::warning(pluginWidget, tr("Warning"), tr("The user is logged in, please delete the user after logging out")); + return; + } UserInfomation user = (UserInfomation)(allUserInfoMap.find(username).value()); DelUserDialog * dialog = new DelUserDialog; dialog->setAttribute(Qt::WA_DeleteOnClose); - dialog->setFace(user.iconfile); dialog->setUsername(user.username); - connect(dialog, &DelUserDialog::removefile_send, this, [=](bool removeFile, QString userName){ - deleteUser(removeFile, userName); + connect(dialog, &DelUserDialog::removefile_send, this, [=](bool removeFile){ + deleteUser(removeFile, user.username); }); dialog->exec(); } @@ -716,8 +901,8 @@ UserInfomation user = (UserInfomation)(allUserInfoMap.find(username).value()); // hidden the item when click delete user button - QListWidgetItem *item = otherUserItemMap.find(user.objpath).value(); - ui->listWidget->setItemHidden(item, true); +// QListWidgetItem *item = otherUserItemMap.find(user.objpath).value(); +// ui->listWidget->setItemHidden(item, true); sysdispatcher->delete_user(user.uid, removefile); } @@ -728,6 +913,33 @@ sysdispatcher->delete_user(user.uid, removefile); } +void UserInfo::pwdAndAutoChangedSlot(QString key) { + if ("option" == key) { + autoLoginSwitchBtn->blockSignals(true); + autoLoginSwitchBtn->setChecked(getAutomaticLogin().contains(mUserName, Qt::CaseSensitive)); + autoLoginSwitchBtn->blockSignals(false); + nopwdSwitchBtn->setChecked(getNoPwdStatus()); + } else if( "avatar" == key) { + //重新获取全部用户QMap + _acquireAllUsersInfo(); + + //更新界面显示 + _refreshUserInfoUI(); + } +} + +void UserInfo::propertyChangedSlot(QString property, QMap propertyMap, QStringList propertyList) { + Q_UNUSED(property); + Q_UNUSED(propertyList); + if (propertyMap.keys().contains("IconFile") && getuid() && + propertyMap.value("RealName").toString() == mUserName) { + if (propertyMap.keys().contains("AccountType")) { + int type = propertyMap.value("AccountType").toInt(); + ui->userTypeLabel->setText(_accountTypeIntToString(type)); + } + } +} + void UserInfo::deleteUserDone(QString objpath){ QListWidgetItem * item = otherUserItemMap.value(objpath); @@ -744,6 +956,11 @@ _resetListWidgetHeigh(); } +void UserInfo::showChangeGroupDialog(){ + ChangeGroupDialog * dialog = new ChangeGroupDialog(); + dialog->exec(); +} + void UserInfo::showChangeValidDialog(QString username){ if (allUserInfoMap.keys().contains(username)){ UserInfomation user = allUserInfoMap.value(username); @@ -766,13 +983,13 @@ ChangeTypeDialog * dialog = new ChangeTypeDialog; dialog->setFace(user.iconfile); - dialog->setUsername(user.username); + dialog->setUsername(user.realname); dialog->setCurrentAccountTypeLabel(_accountTypeIntToString(user.accounttype)); dialog->setCurrentAccountTypeBtn(user.accounttype); - dialog->forbidenChange(adminnum); + dialog->forbidenChange(_userCanDel(username)); // connect(dialog, SIGNAL(type_send(int,QString,bool)), this, SLOT(change_accounttype_slot(int,QString,bool))); - connect(dialog, &ChangeTypeDialog::type_send, this, [=](int atype, QString userName){ - changeUserType(atype, userName); + connect(dialog, &ChangeTypeDialog::type_send, this, [=](int atype){ + changeUserType(atype, username); }); dialog->exec(); @@ -797,19 +1014,46 @@ _refreshUserInfoUI(); } +void UserInfo::showChangeNameDialog(){ + ChangeUserName * dialog = new ChangeUserName; + connect(dialog, &ChangeUserName::sendNewName, [=](QString name){ + changeUserName(name); + }); + dialog->exec(); +} + +void UserInfo::changeUserName(QString newName){ + UserInfomation user = (UserInfomation)(allUserInfoMap.find(QString(g_get_user_name())).value()); + + UserDispatcher * userdispatcher = new UserDispatcher(user.objpath); + + userdispatcher->change_user_name(newName); + + //重新获取全部用户QMap + _acquireAllUsersInfo(); + + //更新界面显示 + _refreshUserInfoUI(); +} + void UserInfo::showChangeFaceDialog(QString username){ - UserInfomation user = (UserInfomation)(allUserInfoMap.find(username).value()); + if (allUserInfoMap.keys().contains(username)){ + UserInfomation user = allUserInfoMap.value(username); + + ChangeFaceDialog * dialog = new ChangeFaceDialog; + dialog->setFace(user.iconfile); + dialog->setUsername(user.realname); + dialog->setAccountType(_accountTypeIntToString(user.accounttype)); + // dialog->set_face_list_status(user.iconfile); + connect(dialog, &ChangeFaceDialog::face_file_send, [=](QString faceFile){ + changeUserFace(faceFile, user.username); + }); + dialog->exec(); + } else { + qDebug() << "User Data Error When Change User Face!"; + } - ChangeFaceDialog * dialog = new ChangeFaceDialog; - dialog->setFace(user.iconfile); - dialog->setUsername(user.username); - dialog->setAccountType(_accountTypeIntToString(user.accounttype)); -// dialog->set_face_list_status(user.iconfile); - connect(dialog, &ChangeFaceDialog::face_file_send, [=](QString faceFile, QString userName){ - changeUserFace(faceFile, userName); - }); - dialog->exec(); } void UserInfo::changeUserFace(QString facefile, QString username){ @@ -817,7 +1061,6 @@ UserDispatcher * userdispatcher = new UserDispatcher(user.objpath); userdispatcher->change_user_face(facefile); -// userdispatcher->change_user_face(QString("/home/%1/.face").arg(user.username)); //拷贝设置的头像文件到~/.face sysinterface = new QDBusInterface("com.control.center.qt.systemdbus", @@ -832,28 +1075,45 @@ QString cmd = QString("cp %1 /home/%2/.face").arg(facefile).arg(user.username); - QDBusReply reply = sysinterface->call("systemRun", QVariant(cmd)); - + QProcess::execute(cmd); //重新获取全部用户QMap _acquireAllUsersInfo(); //更新界面显示 _refreshUserInfoUI(); - - Q_UNUSED(reply) } void UserInfo::showChangePwdDialog(QString username){ + if (allUserInfoMap.keys().contains(username)){ UserInfomation user = allUserInfoMap.value(username); - - ChangePwdDialog * dialog = new ChangePwdDialog; + ChangePwdDialog * dialog = new ChangePwdDialog(user.current, user.username); dialog->setFace(user.iconfile); - dialog->setUsername(user.username); + dialog->setUsername(user.realname); dialog->setAccountType(_accountTypeIntToString(user.accounttype)); - connect(dialog, &ChangePwdDialog::passwd_send, this, [=](QString pwd, QString userName){ - changeUserPwd(pwd, userName); + if (!getuid() || !user.current) + dialog->haveCurrentPwdEdit(false); + + connect(dialog, &ChangePwdDialog::passwd_send, this, [=](QString pwd){ + + changeUserPwd(pwd, username); + + }); + connect(dialog, &ChangePwdDialog::passwd_send2, this, [=](QString pwd){ + + PolkitQt1::Authority::Result result; + + result = PolkitQt1::Authority::instance()->checkAuthorizationSync( + "org.control.center.qt.systemdbus.action", + PolkitQt1::UnixProcessSubject(QCoreApplication::applicationPid()), + PolkitQt1::Authority::AllowUserInteraction); + + if (result == PolkitQt1::Authority::Yes){ + changeUserPwd(pwd, username); + } + + }); dialog->exec(); @@ -867,10 +1127,22 @@ //上层已做判断,这里不去判断而直接获取 UserInfomation user = allUserInfoMap.value(username); - UserDispatcher * userdispatcher = new UserDispatcher(user.objpath); //继承QObject不再删除 - QString result = userdispatcher->change_user_pwd(pwd, ""); +// UserDispatcher * userdispatcher = new UserDispatcher(user.objpath); //继承QObject不再删除 +// QString result = userdispatcher->change_user_pwd(pwd, ""); + + QDBusInterface * tmpSysinterface = new QDBusInterface("com.control.center.qt.systemdbus", + "/", + "com.control.center.interface", + QDBusConnection::systemBus()); + + if (!tmpSysinterface->isValid()){ + qCritical() << "Create Client Interface Failed When : " << QDBusConnection::systemBus().lastError(); + return; + } + tmpSysinterface->call("changeOtherUserPasswd", username, pwd); - Q_UNUSED(result) + delete tmpSysinterface; + tmpSysinterface = nullptr; } @@ -880,19 +1152,26 @@ QMouseEvent * mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::LeftButton ){ if(watched == ui->currentUserFaceLabel){ - showChangeFaceDialog(ui->userNameLabel->text()); + showChangeFaceDialog(g_get_user_name()); } return true; } else { return false; } } + } else if (watched == ui->nameChangeWidget){ + if (event->type() == QEvent::MouseButtonPress){ + QMouseEvent * mouseEvent = static_cast(event); + if (mouseEvent->button() == Qt::LeftButton ){ + showChangeNameDialog(); + } + } } return QObject::eventFilter(watched, event); } -bool UserInfo::getAutomaticLogin(QString username) { +QString UserInfo::getAutomaticLogin() { QString filename = "/etc/lightdm/lightdm.conf"; autoSettings = new QSettings(filename, QSettings::IniFormat); @@ -902,5 +1181,639 @@ autoSettings->endGroup(); - return autoUser == username ? true : false; + return autoUser; +} + +bool UserInfo::getNoPwdStatus() { + // 获取当前用户免密登录属性 + QDBusInterface tmpSysinterface("com.control.center.qt.systemdbus", + "/", + "com.control.center.interface", + QDBusConnection::systemBus()); + // 获取免密登录状态 + QDBusReply noPwdres; + noPwdres = tmpSysinterface.call("getNoPwdLoginStatus"); + if (!noPwdres.isValid()) { + qDebug() << noPwdres.error(); + } + return (noPwdres.value().contains(mUserName) ? true : false); +} + +bool UserInfo::isOpenAutoLogin(const QString &userName) { + QString autoLoginedUser = this->getAutomaticLogin(); + bool res = true; + int ret; + if (!autoLoginedUser.isEmpty() && userName != autoLoginedUser) { + QMessageBox msg(this->pluginWidget); + msg.setWindowTitle(tr("Hint")); + msg.setText(tr("The system only allows one user to log in automatically." + "After it is turned on, the automatic login of other users will be turned off." + "Is it turned on?")); + msg.addButton(tr("Trun on"), QMessageBox::AcceptRole); + msg.addButton(tr("Close on"), QMessageBox::RejectRole); + + ret = msg.exec(); + + switch (ret) { + case QMessageBox::AcceptRole: + res = true; + break; + case QMessageBox::RejectRole: + res = false; + break; + } + } + return res; +} + +void UserInfo::initUserPropertyConnection(const QStringList &objPath) { + + foreach (QString userPath, objPath) { + QDBusInterface iproperty("org.freedesktop.Accounts", + userPath, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + + iproperty.connection().connect("org.freedesktop.Accounts", userPath, "org.freedesktop.DBus.Properties", "PropertiesChanged", + this, SLOT(propertyChangedSlot(QString, QMap, QStringList))); + } + + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), "org.freedesktop.kylinssoclient.interface", "keyChanged", this, SLOT(pwdAndAutoChangedSlot(QString))); +} + +bool UserInfo::isShowBiometric() +{ + + QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat); + + return sysSettings.value("isShownInControlCenter").toString() == "true"; + +} + +void UserInfo::initBioComonent() +{ + m_biometricProxy = new BiometricProxy(this); + + + serviceInterface = new QDBusInterface(DBUS_SERVICE, + DBUS_PATH, + DBUS_INTERFACE + , QDBusConnection::systemBus()); + serviceInterface->setTimeout(2147483647); /* 微秒 */ + + addBioFeatureWidget = new HoverWidget(""); + addBioFeatureWidget->setObjectName("addBioFeatureWidget"); + addBioFeatureWidget->setMinimumSize(QSize(580, 50)); + addBioFeatureWidget->setMaximumSize(QSize(960, 50)); + addBioFeatureWidget->setStyleSheet("HoverWidget#addBioFeatureWidget{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addBioFeatureWidget{background: #3D6BE5; border-radius: 4px;}"); + + QHBoxLayout *addBioFeatureLayout = new QHBoxLayout; + + QLabel * iconLabel = new QLabel(); + QLabel * textLabel = new QLabel(tr("Add biometric feature")); + QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); + iconLabel->setPixmap(pixgray); + addBioFeatureLayout->addWidget(iconLabel); + addBioFeatureLayout->addWidget(textLabel); + addBioFeatureLayout->addStretch(); + addBioFeatureWidget->setLayout(addBioFeatureLayout); + + // 悬浮改变Widget状态 + connect(addBioFeatureWidget, &HoverWidget::enterWidget, this, [=](QString mname) { + Q_UNUSED(mname); + QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); + iconLabel->setPixmap(pixgray); + textLabel->setStyleSheet("color: palette(base);"); + + }); + // 还原状态 + connect(addBioFeatureWidget, &HoverWidget::leaveWidget, this, [=](QString mname) { + Q_UNUSED(mname); + QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); + iconLabel->setPixmap(pixgray); + textLabel->setStyleSheet("color: palette(windowText);"); + }); + + connect(addBioFeatureWidget, &HoverWidget::widgetClicked, this, [=](QString mname) { + Q_UNUSED(mname); + showEnrollDialog(); + }); + + ui->addFeatureLayout->addWidget(addBioFeatureWidget); + + ui->bioFeatureListWidget->setStyleSheet("QListWidget::Item:hover{background:palette(base);}"); + ui->bioFeatureListWidget->setSpacing(0); + + ui->bioFeatureListWidget->setFixedHeight(biometricFeatureMap.count()*ITEMHEIGH - biometricFeatureMap.count()*6); + + connect(ui->biometrictypeBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(onbiometricTypeBoxCurrentIndexChanged(int))); + + connect(ui->biometricDeviceBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(onbiometricDeviceBoxCurrentIndexChanged(int))); + + connect(ui->bioSettings, &QPushButton::clicked, this, [=](){ + QProcess process(this); + process.startDetached("/usr/bin/biometric-manager"); + }); + + ui->biometricMoreBtn->setText("..."); + connect(ui->biometricMoreBtn, &QPushButton::clicked, this, [=](){ + biometricShowMoreInfoDialog(); + }); + + updateDevice(); + + if(m_biometricProxy && m_biometricProxy->isValid()) + { + connect(m_biometricProxy, &BiometricProxy::USBDeviceHotPlug, + this, &UserInfo::onBiometricUSBDeviceHotPlug); + } + + enableBiometricBtn = new SwitchButton(ui->enableBiometricFrame); + enableBiometricBtn->setChecked(getBioStatus()); + ui->enableBiometricLayout->addWidget(enableBiometricBtn); + connect(enableBiometricBtn, &SwitchButton::checkedChanged, [=](bool checked){ + QProcess process; + if(checked){ + process.start("bioctl enable"); + process.waitForFinished(3000); + }else{ + process.start("bioctl disable"); + process.waitForFinished(3000); + } + }); + + mBiometricWatcher = nullptr; + if(!mBiometricWatcher){ + mBiometricWatcher = new QFileSystemWatcher(this); + mBiometricWatcher->addPath(UKUI_BIOMETRIC_SYS_CONFIG_PATH); + connect(mBiometricWatcher,&QFileSystemWatcher::fileChanged,this,[=](const QString &path){ + mBiometricWatcher->addPath(UKUI_BIOMETRIC_SYS_CONFIG_PATH); + enableBiometricBtn->blockSignals(true); + enableBiometricBtn->setChecked(getBioStatus()); + enableBiometricBtn->blockSignals(false); + }); + } + +} + +bool UserInfo::getBioStatus() +{ + QProcess process; + process.start("bioctl status"); + process.waitForFinished(); + QString output = process.readAllStandardOutput(); + if (output.contains("enable", Qt::CaseInsensitive)) { + return true; + } + else { + return false; + } +} + +void UserInfo::setBioStatus(bool status) +{ + enableBiometricBtn->setChecked(true); +} + +void UserInfo::onBiometricUSBDeviceHotPlug(int drvid, int action, int deviceNum) +{ + int savedDeviceId = -1; + if(currentDevice) + savedDeviceId = currentDevice->id; + + int savedCount = 0; + for(int type : deviceMap.keys()) + savedCount += deviceMap.value(type).count(); + + switch(action) + { + case ACTION_ATTACHED: + { + //插入设备后,需要更新设备列表 + updateDevice(); + if(savedDeviceId >= 0) + setCurrentDevice(savedDeviceId); + break; + } + case ACTION_DETACHED: + { + updateDevice(); + } + + } +} + +void UserInfo::setBiometricDeviceVisible(bool visible) +{ + if(!visible) + { + ui->bioTitleWidget->hide(); + ui->biometricWidget->hide(); + }else{ + ui->bioTitleWidget->show(); + ui->biometricWidget->show(); + } +} + +void UserInfo::updateDevice() +{ + deviceMap.clear(); + DeviceList deviceList = m_biometricProxy->GetDevList(); + + QString default_name = GetDefaultDevice(QString(qgetenv("USER"))); + + for(auto pDeviceInfo : deviceList) + { + deviceMap[pDeviceInfo->deviceType].push_back(pDeviceInfo); + } + ui->biometrictypeBox->clear(); + for(int type : deviceMap.keys()) + { + ui->biometrictypeBox->addItem(DeviceType::getDeviceType_tr(type), type); + } + if(deviceMap.size() > 0) + { + DeviceInfoPtr ptr = findDeviceByName(default_name); + if(ptr) + { + setCurrentDevice(default_name); + }else{ + int index = deviceMap.keys().at(0); + setCurrentDevice(deviceMap[index].at(0)); + } + } + + if(deviceMap.size()<=0) + setBiometricDeviceVisible(false); + else + setBiometricDeviceVisible(true); +} + +void UserInfo::setCurrentDevice(int drvid) +{ + DeviceInfoPtr pDeviceInfo = findDeviceById(drvid); + if(pDeviceInfo) + { + setCurrentDevice(pDeviceInfo); + } +} + +void UserInfo::setCurrentDevice(const QString &deviceName) +{ + DeviceInfoPtr pDeviceInfo = findDeviceByName(deviceName); + if(pDeviceInfo) + { + setCurrentDevice(pDeviceInfo); + } +} + +void UserInfo::setCurrentDevice(const DeviceInfoPtr &pDeviceInfo) +{ + this->currentDevice = pDeviceInfo; + ui->biometrictypeBox->setCurrentText(DeviceType::getDeviceType_tr(pDeviceInfo->deviceType)); + ui->biometricDeviceBox->setCurrentText(pDeviceInfo->shortName); + +} + +DeviceInfoPtr UserInfo::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 UserInfo::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(); +} + +bool UserInfo::deviceExists(int drvid) +{ + return (findDeviceById(drvid) != nullptr); +} + +bool UserInfo::deviceExists(const QString &deviceName) +{ + return (findDeviceByName(deviceName) != nullptr); +} + +void UserInfo::onbiometricTypeBoxCurrentIndexChanged(int index) +{ + if(index < 0 || index >= deviceMap.keys().size()) + { + return; + } + + int type = ui->biometrictypeBox->itemData(index).toInt(); + ui->biometricDeviceBox->clear(); + + for(auto &deviceInfo : deviceMap.value(type)) + { + ui->biometricDeviceBox->addItem(deviceInfo->shortName); + } +} + +void UserInfo::onbiometricDeviceBoxCurrentIndexChanged(int index) +{ + if(index < 0) + { + return; + } + + int type = ui->biometrictypeBox->currentData().toInt(); + + DeviceInfoPtr deviceInfo = deviceMap.value(type).at(index); + QList args; + + currentDevice = deviceInfo; + + args << QVariant(deviceInfo->id) + << QVariant((int)getuid()) << QVariant(0) << QVariant(-1); + serviceInterface->callWithCallback("GetFeatureList", args, this, + SLOT(updateFeatureListCallback(QDBusMessage)), + SLOT(errorCallback(QDBusError))); +} + +void UserInfo::updateFeatureListCallback(QDBusMessage callbackReply) +{ + QList qlist; + FeatureInfo *featureInfo; + int listsize; + + ui->bioFeatureListWidget->clear(); + biometricFeatureMap.clear(); + + QList variantList = callbackReply.arguments(); + listsize = variantList[0].value(); + variantList[1].value() >> qlist; + for (int i = 0; i < listsize; i++) { + featureInfo = new FeatureInfo; + qlist[i].variant().value() >> *featureInfo; + addFeature(featureInfo); + } + updateFeatureList(); +} + +void UserInfo::updateFeatureList() +{ + ui->bioFeatureListWidget->setFixedHeight(biometricFeatureMap.count()*ITEMHEIGH + biometricFeatureMap.count()*6); +} + +void UserInfo::errorCallback(QDBusError error) +{ + +} + +void UserInfo::showEnrollDialog() +{ + if(ui->biometricDeviceBox->count() <= 0 || ui->biometrictypeBox->count() <= 0) + return ; + + int index = ui->biometricDeviceBox->currentIndex(); + int type = ui->biometrictypeBox->currentData().toInt(); + + if(index < 0|| type < 0) + return ; + + DeviceInfoPtr deviceInfo = deviceMap.value(type).at(index); + + if(!deviceInfo) + return ; + + BiometricEnrollDialog * dialog = new BiometricEnrollDialog(serviceInterface,deviceInfo->deviceType,deviceInfo->id,getuid()); + //gdxfp显示指纹图片 + if(deviceInfo->shortName == "gdxfp") + dialog->setProcessed(true); + + int num=1; + QStringList list = m_biometricProxy->getFeaturelist(deviceInfo->id,getuid(),0,-1); + QString featurename; + while(1){ + featurename = DeviceType::getDeviceType_tr(deviceInfo->deviceType) + QString::number(num); + if(!list.contains(featurename)) + break; + num++; + } + dialog->enroll(deviceInfo->id,getuid(),-1,featurename); + + onbiometricDeviceBoxCurrentIndexChanged(ui->biometricDeviceBox->currentIndex()); + +} + +void UserInfo::showVerifyDialog(FeatureInfo *featureinfo) +{ + DeviceInfoPtr deviceInfoPtr = findDeviceByName(featureinfo->device_shortname); + if(!deviceInfoPtr) + return ; + + BiometricEnrollDialog * dialog = new BiometricEnrollDialog(serviceInterface,deviceInfoPtr->deviceType,deviceInfoPtr->id,getuid()); + + if(deviceInfoPtr->shortName == "huawei") + dialog->setProcessed(true); + + dialog->verify(deviceInfoPtr->id,getuid(),featureinfo->index); +} + +void UserInfo::biometricShowMoreInfoDialog() +{ + if(ui->biometricDeviceBox->count() <= 0 || ui->biometrictypeBox->count() <= 0) + return ; + + int index = ui->biometricDeviceBox->currentIndex(); + int type = ui->biometrictypeBox->currentData().toInt(); + + if(index < 0|| type < 0) + return ; + + DeviceInfoPtr deviceInfo = deviceMap.value(type).at(index); + + if(!deviceInfo) + return ; + + BiometricMoreInfoDialog * dialog = new BiometricMoreInfoDialog(deviceInfo); + dialog->exec(); +} + +void UserInfo::renameFeaturedone(FeatureInfo *featureinfo ,QString newname) +{ + QListWidgetItem *item = biometricFeatureMap.value(featureinfo->index_name); + ui->bioFeatureListWidget->takeItem(ui->bioFeatureListWidget->row(item)); + biometricFeatureMap.remove(featureinfo->index_name); + + + featureinfo->index_name = newname; + addFeature(featureinfo); + +} + +void UserInfo::deleteFeaturedone(FeatureInfo *featureinfo) +{ + + QListWidgetItem *item = biometricFeatureMap.value(featureinfo->index_name); + + ui->bioFeatureListWidget->takeItem(ui->bioFeatureListWidget->row(item)); + biometricFeatureMap.remove(featureinfo->index_name); + + updateFeatureList(); +} + +void UserInfo::addFeature(FeatureInfo *featureinfo) +{ + HoverWidget * baseWidget = new HoverWidget(featureinfo->index_name); + baseWidget->setMinimumSize(550,50); + baseWidget->setMaximumSize(960,50); + baseWidget->setAttribute(Qt::WA_DeleteOnClose); + + //ui->currentUserFrame->setContentsMargins(16,0,16,0); + + QHBoxLayout * baseVerLayout = new QHBoxLayout(baseWidget); + baseVerLayout->setSpacing(0); + baseVerLayout->setMargin(0); + + QHBoxLayout * baseHorLayout = new QHBoxLayout(); + baseHorLayout->setSpacing(16); + baseHorLayout->setMargin(0); + + QFrame * widget = new QFrame(baseWidget); + widget->setFrameShape(QFrame::Shape::Box); + widget->setFixedHeight(50); + + QHBoxLayout * mainHorLayout = new QHBoxLayout(widget); + mainHorLayout->setSpacing(16); + mainHorLayout->setContentsMargins(16, 0, 16, 0); + + QLabel * nameLabel = new QLabel(widget); + QSizePolicy nameSizePolicy = nameLabel->sizePolicy(); + nameSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); + nameSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); + nameLabel->setSizePolicy(nameSizePolicy); + nameLabel->setText(featureinfo->index_name); + + QString btnQss = QString("QPushButton{background: #ffffff; border-radius: 4px;}"); + + QLineEdit *renameEdit = new QLineEdit(widget); + renameEdit->setFixedWidth(240); + renameEdit->setText(featureinfo->index_name); + renameEdit->hide(); + + connect(renameEdit, &QLineEdit::editingFinished, this, [=](){ + renameEdit->hide(); + nameLabel->show(); + QString rename = renameEdit->text(); + if(rename == "" || rename == featureinfo->index_name) + return; + + DeviceInfoPtr deviceInfoPtr = findDeviceByName(featureinfo->device_shortname); + if(!deviceInfoPtr) + return ; + bool res = m_biometricProxy->renameFeature(deviceInfoPtr->id,getuid(),featureinfo->index,rename); + renameFeaturedone(featureinfo,rename); + }); + + QPushButton * renameBtn = new QPushButton(widget); + + renameBtn->setFixedHeight(36); + renameBtn->setMinimumWidth(88); + renameBtn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + renameBtn->setText(tr("Rename")); + + connect(renameBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + nameLabel->hide(); + renameEdit->show(); + }); + renameBtn->hide(); + + QPushButton * verifyBtn = new QPushButton(widget); + + verifyBtn->setFixedHeight(36); + verifyBtn->setMinimumWidth(88); + verifyBtn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + verifyBtn->setText(tr("Verify")); + + connect(verifyBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + showVerifyDialog(featureinfo); + }); + + renameBtn->hide(); + verifyBtn->hide(); + + mainHorLayout->addWidget(nameLabel); + mainHorLayout->addWidget(renameEdit); + mainHorLayout->addStretch(); + mainHorLayout->addWidget(renameBtn); + mainHorLayout->addWidget(verifyBtn); + + widget->setLayout(mainHorLayout); + + QPushButton * delBtn = new QPushButton(baseWidget); + delBtn->setFixedSize(60, 36); + delBtn->setText(tr("Delete")); +// delBtn->setStyleSheet("QPushButton{background: #FA6056; border-radius: 4px}"); + delBtn->hide(); + connect(delBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + DeviceInfoPtr deviceInfoPtr = findDeviceByName(featureinfo->device_shortname); + if(!deviceInfoPtr) + return ; + bool res = m_biometricProxy->deleteFeature(deviceInfoPtr->id,getuid(),featureinfo->index,featureinfo->index); + if(!res){ + deleteFeaturedone(featureinfo); + } + }); + + connect(baseWidget, &HoverWidget::enterWidget, this, [=](QString name){ + Q_UNUSED(name) + renameBtn->show(); + //驱动gdxfp不支持验证 + if(featureinfo->device_shortname != "gdxfp") + verifyBtn->show(); + delBtn->show(); + }); + connect(baseWidget, &HoverWidget::leaveWidget, this, [=](QString name){ + Q_UNUSED(name) + renameBtn->hide(); + verifyBtn->hide(); + delBtn->hide(); + }); + + baseHorLayout->addWidget(widget); + baseHorLayout->addWidget(delBtn, Qt::AlignVCenter); + baseHorLayout->addSpacing(4); + + baseVerLayout->addLayout(baseHorLayout); + + baseWidget->setLayout(baseVerLayout); + + QListWidgetItem * item = new QListWidgetItem(ui->bioFeatureListWidget); + item->setSizeHint(QSize(QSizePolicy::Expanding, ITEMHEIGH)); + item->setData(Qt::UserRole, QVariant(featureinfo->index_name)); + ui->bioFeatureListWidget->setItemWidget(item, baseWidget); + + biometricFeatureMap.insert(featureinfo->index_name, item); } diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/userinfo.h ukui-control-center-3.0.3/plugins/account/userinfo/userinfo.h --- ukui-control-center-2.0.3/plugins/account/userinfo/userinfo.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/userinfo.h 2021-05-20 13:08:14.000000000 +0000 @@ -22,10 +22,7 @@ #include #include - -//#include -//#include -//#include +#include #include #include #include @@ -35,13 +32,19 @@ #include "qtdbus/systemdbusdispatcher.h" #include "qtdbus/userdispatcher.h" +#include "changegroupdialog.h" #include "changepwddialog.h" #include "changefacedialog.h" #include "changetypedialog.h" #include "changevaliddialog.h" +#include "changeusername.h" #include "deluserdialog.h" #include "createuserdialog.h" #include "HoverWidget/hoverwidget.h" +#include "biometricdeviceinfo.h" +#include "biometricproxy.h" +#include "biometricenroll.h" +#include "biometricmoreinfo.h" #ifdef ENABLEPQ extern "C" { @@ -58,6 +61,7 @@ typedef struct _UserInfomation { QString objpath; QString username; + QString realname; QString iconfile; QString passwd; int accounttype; @@ -116,17 +120,48 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); + void initSearchText(); void initComponent(); void initAllUserStatus(); + //初始化生物特征组件 + void initBioComonent(); + //添加生物特征 + void addFeature(FeatureInfo *featureinfo); + //更新生物特征设备 + void updateDevice(); + void updateFeatureList(); + 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 showEnrollDialog(); + void showVerifyDialog(FeatureInfo *featureinfo); + void deleteFeature(); + void deleteFeaturedone(FeatureInfo *feature); + void renameFeaturedone(FeatureInfo *feature,QString newname); + void setBiometricDeviceVisible(bool visible); + void setBioStatus(bool status); + bool getBioStatus(); + void biometricShowMoreInfoDialog(); + bool isShowBiometric(); + + QStringList getLoginedUsers(); void _acquireAllUsersInfo(); UserInfomation _acquireUserInfo(QString objpath); QString _accountTypeIntToString(int type); void _buildWidgetForItem(UserInfomation user); void _resetListWidgetHeigh(); + int _userCanDel(QString user); + void _refreshUserInfoUI(); void showCreateUserDialog(); @@ -148,6 +183,11 @@ void showChangeValidDialog(QString username); + void showChangeGroupDialog(); + + void showChangeNameDialog(); + void changeUserName(QString newName); + void get_all_users(); UserInfomation init_user_info(QString objpath); void setup_otherusers_ui(); @@ -157,8 +197,8 @@ QString accounttype_enum_to_string(int id); QString login_status_bool_to_string(bool status); - void readCurrentPwdConf(); + QStringList getUsersList(); protected: bool eventFilter(QObject *watched, QEvent *event); @@ -171,26 +211,26 @@ QWidget * pluginWidget; HoverWidget *addWgt; -private: + //增加生物密码 + HoverWidget *addBioFeatureWidget; + BiometricProxy *proxy; + DeviceMap deviceMap; + DeviceInfoPtr currentDevice; + BiometricProxy *m_biometricProxy; + QDBusInterface *serviceInterface; + QFileSystemWatcher *mBiometricWatcher; + SwitchButton * nopwdSwitchBtn; SwitchButton * autoLoginSwitchBtn; + SwitchButton * enableBiometricBtn; SystemDbusDispatcher * sysdispatcher; QSettings * autoSettings = nullptr; - -private: - bool getAutomaticLogin(QString username); - -private: QMap allUserInfoMap; QMap otherUserItemMap; + QMap biometricFeatureMap; - int adminnum; - - QString _newUserPwd; - -// QMap otherbtnMap; QMap otherItemMap; QSignalMapper * pwdSignalMapper; @@ -202,12 +242,18 @@ QSize itemSize; QSize btnSize; - QString pwdcreate; + QString _newUserPwd; + QString mUserName; - QDBusInterface * sysinterface; + QStringList m_loginedUser; + QDBusInterface *sysinterface; + QDBusInterface *mUserproperty; + + int adminnum; bool enablePwdQuality; + bool mFirstLoad; #ifdef ENABLEPQ pwquality_settings_t * pwdconf; @@ -217,26 +263,29 @@ QString pwdMsg; -private slots: -// void show_change_pwd_dialog_slot(QString username); -// void change_pwd_slot(QString pwd, QString username); -// void change_pwd_done_slot(); - -// void show_change_face_dialog_slot(QString username); -// void change_face_slot(QString facefile, QString username); -// void change_face_done_slot(); - -// void show_change_accounttype_dialog_slot(QString username); -// void change_accounttype_slot(int atype, QString username, bool status); -// void change_accounttype_done_slot(); +private: + QString getAutomaticLogin(); + bool getNoPwdStatus(); + bool isOpenAutoLogin(const QString &userName); + void initUserPropertyConnection(const QStringList &objPath); -// void show_del_user_dialog_slot(QString username); +private slots: void delete_user_slot(bool removefile, QString username); -// void delete_user_done_slot(QString objpath); + void propertyChangedSlot(QString, QMap, QStringList); + void pwdAndAutoChangedSlot(QString key); + + void onbiometricTypeBoxCurrentIndexChanged(int index); + void onbiometricDeviceBoxCurrentIndexChanged(int index); + void updateFeatureListCallback(QDBusMessage callbackReply); + void errorCallback(QDBusError error); + /** + * @brief USB设备热插拔 + * @param drvid 设备id + * @param action 插拔动作(1:插入,-1:拔出) + * @param deviceNum 插拔动作后该驱动拥有的设备数量 + */ + void onBiometricUSBDeviceHotPlug(int drvid, int action, int deviceNum); -// void show_create_user_dialog_slot(); -// void create_user_slot(QString username, QString pwd, QString pin, int atype, bool autologin); -// void create_user_done_slot(QString objpath); }; #endif // USERINFO_H diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/userinfo.pro ukui-control-center-3.0.3/plugins/account/userinfo/userinfo.pro --- ukui-control-center-2.0.3/plugins/account/userinfo/userinfo.pro 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/userinfo.pro 2021-05-20 13:08:14.000000000 +0000 @@ -8,8 +8,9 @@ include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/flowlayout.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) -QT += widgets dbus +QT += widgets dbus gui TEMPLATE = lib CONFIG += plugin @@ -22,20 +23,29 @@ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ -LIBS += -L$$[QT_INSTALL_LIBS] -lcrypt +LIBS += -L$$[QT_INSTALL_LIBS] -lcrypt -lpolkit-qt5-core-1 -lpam ##加载gio库和gio-unix库 CONFIG += link_pkgconfig \ C++11 PKGCONFIG += gio-2.0 \ - gio-unix-2.0 + gio-unix-2.0 \ + gsettings-qt #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ + changegroupdialog.cpp \ + changeusername.cpp \ changevaliddialog.cpp \ + creategroupdialog.cpp \ + definegroupitem.cpp \ + delgroupdialog.cpp \ + editgroupdialog.cpp \ elipsemaskwidget.cpp \ + pwdcheckthread.cpp \ + run-passwd.cpp \ userinfo.cpp \ qtdbus/systemdbusdispatcher.cpp \ changepwddialog.cpp \ @@ -43,11 +53,26 @@ changetypedialog.cpp \ changefacedialog.cpp \ deluserdialog.cpp \ - createuserdialog.cpp + createuserdialog.cpp \ + passwdcheckutil.cpp \ + biometricdeviceinfo.cpp \ + biometricproxy.cpp \ + biometricenroll.cpp \ + biometricmoreinfo.cpp \ + servicemanager.cpp HEADERS += \ + changegroupdialog.h \ + changeusername.h \ changevaliddialog.h \ + creategroupdialog.h \ + definegroupitem.h \ + delgroupdialog.h \ + editgroupdialog.h \ elipsemaskwidget.h \ + loginedusers.h \ + pwdcheckthread.h \ + run-passwd.h \ userinfo.h \ qtdbus/systemdbusdispatcher.h \ changepwddialog.h \ @@ -55,15 +80,28 @@ changetypedialog.h \ changefacedialog.h \ deluserdialog.h \ - createuserdialog.h + createuserdialog.h \ + passwdcheckutil.h \ + biometricdeviceinfo.h \ + biometricproxy.h \ + biometricenroll.h \ + biometricmoreinfo.h \ + servicemanager.h FORMS += \ + changegroupdialog.ui \ + changeusername.ui \ changevaliddialog.ui \ + creategroupdialog.ui \ + delgroupdialog.ui \ + editgroupdialog.ui \ userinfo.ui \ changepwddialog.ui \ changetypedialog.ui \ changefacedialog.ui \ deluserdialog.ui \ - createuserdialog.ui + createuserdialog.ui \ + biometricmoreinfo.ui \ + biometricenroll.ui INSTALLS += target diff -Nru ukui-control-center-2.0.3/plugins/account/userinfo/userinfo.ui ukui-control-center-3.0.3/plugins/account/userinfo/userinfo.ui --- ukui-control-center-2.0.3/plugins/account/userinfo/userinfo.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/account/userinfo/userinfo.ui 2021-05-20 13:08:14.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 800 - 710 + 1124 @@ -25,13 +25,7 @@ UserInfo - - - 0 - - - 0 - + 32 @@ -62,7 +56,7 @@ 20 - 14 + 12 @@ -72,13 +66,13 @@ 550 - 202 + 122 960 - 202 + 150 @@ -115,15 +109,12 @@ 16 - 9 + 0 - + - 16 - - - 0 + 10 24 @@ -138,14 +129,14 @@ - 112 - 112 + 88 + 88 - 112 - 112 + 88 + 88 @@ -163,118 +154,167 @@ - 8 + 13 20 - - - 8 + + + 0 + + + 0 + + 0 + + + + + 8 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 0 + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + + + + + + 15 + 22 + + + + + 15 + 22 + + + + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - + - Qt::Vertical + Qt::Horizontal - 20 - 40 + 40 + 20 - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - - 120 + 100 36 - 120 + 16777215 36 - Change pwd - - - - - - - - - 8 - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - + Password @@ -282,182 +322,70 @@ - 120 + 100 36 - 120 + 16777215 36 - Change type + Type - - - - - - 8 - - - - Qt::Vertical - - + + - 20 - 40 + 100 + 36 - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - + + + 16777215 + 36 + - + Valid - + - 120 + 100 36 - 120 + 16777215 36 - Change valid + Group - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 50 - - - - - 16777215 - 50 - - - - QFrame::Box - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 0 - - - - Login no passwd - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - + 550 @@ -473,7 +401,7 @@ QFrame::Box - + 0 @@ -490,7 +418,7 @@ 0 - + 0 @@ -501,7 +429,7 @@ 0 - + 0 @@ -509,7 +437,7 @@ - enable autoLogin + Login no passwd true @@ -517,7 +445,7 @@ - + Qt::Horizontal @@ -535,113 +463,701 @@ - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 46 - - - - - - - - - 0 - 0 - - - - Other Users - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 14 - - - - - - + 550 - 0 + 50 960 - 16777215 - - - - - - - - - 550 - 60 + 50 - - - 960 - 60 - + + QFrame::Box - + 0 - 0 + 16 0 - 0 + 16 0 - + - 8 + 0 0 + + 0 + + + + + + 0 + 0 + + + + Automatic login at boot + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 550 + 50 + + + + + 960 + 50 + + + + QFrame::Box + + + + 0 + + + 16 + + + 0 + + + 16 + + + 0 + + + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + Currently in Live mode, please create a new user and log out + + + true + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 46 + + + + + + + + + 550 + 0 + + + + + 950 + 16777215 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Biometric Password + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + advanced settings + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 0 + + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 8 + + + 30 + + + + + + 550 + 50 + + + + + 960 + 50 + + + + + 0 + 0 + + + + QFrame::Box + + + QFrame::Plain + + + + 0 + + + 16 + + + 0 + + + 16 + + + 0 + + + + + 8 + + + + + enable biometrics + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + 550 + 50 + + + + + 960 + 50 + + + + QFrame::Box + + + QFrame::Plain + + + + 0 + + + 16 + + + 0 + + + 16 + + + 0 + + + + + 0 + + + 0 + + + + + types of biometric password + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 444 + 0 + + + + + + + + + + + + + + 550 + 50 + + + + + 960 + 50 + + + + QFrame::Box + + + QFrame::Plain + + + + 0 + + + 16 + + + 0 + + + 16 + + + 0 + + + + + 0 + + + 0 + + + + + biometric device + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 400 + 0 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 8 + 20 + + + + + + + + + 36 + 36 + + + + + 36 + 36 + + + + + + + + + + + + + + + 550 + 0 + + + + + 960 + 16777215 + + + + + + + + + 550 + 60 + + + + + 960 + 60 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + + + + + + + + + + + + + 0 + 0 + + + + Other Users + + + true + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 8 + + + + + + + + 0 + + + + + + 550 + 0 + + + + + 960 + 16777215 + + + + + + + + + 550 + 60 + + + + + 960 + 60 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 0 + + + + + + + + + Qt::Vertical diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/audio.cpp ukui-control-center-3.0.3/plugins/devices/audio/audio.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/audio.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/audio.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -22,36 +22,43 @@ #include -Audio::Audio() +Audio::Audio() : mFirstLoad(true) { - ui = new Ui::Audio; - pluginWidget = new UkmediaMainWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); -// pluginWidget->setStyleSheet("background: #ffffff;"); - ui->setupUi(pluginWidget); - pluginName = tr("Audio"); pluginType = DEVICES; } Audio::~Audio() { - delete ui; + if (!mFirstLoad) { + delete ui; + } } -QString Audio::get_plugin_name(){ +QString Audio::get_plugin_name() { return pluginName; } -int Audio::get_plugin_type(){ +int Audio::get_plugin_type() { return pluginType; } -QWidget *Audio::get_plugin_ui(){ - return pluginWidget; +QWidget *Audio::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + ui = new Ui::Audio; + pluginWidget = new UkmediaMainWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + } + return pluginWidget; } void Audio::plugin_delay_control(){ } +const QString Audio::name() const { + return QStringLiteral("audio"); +} + diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/audio.h ukui-control-center-3.0.3/plugins/devices/audio/audio.h --- ukui-control-center-2.0.3/plugins/devices/audio/audio.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/audio.h 2021-04-14 01:27:20.000000000 +0000 @@ -24,7 +24,6 @@ #include #include #include - #include "shell/interface.h" #include "ukmedia_main_widget.h" @@ -46,6 +45,7 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; private: Ui::Audio *ui; @@ -53,6 +53,8 @@ int pluginType; UkmediaMainWidget *pluginWidget; + bool mFirstLoad; + }; #endif // AUDIO_H diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/audio.pro ukui-control-center-3.0.3/plugins/devices/audio/audio.pro --- ukui-control-center-2.0.3/plugins/devices/audio/audio.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/audio.pro 2021-05-20 13:08:14.000000000 +0000 @@ -11,6 +11,8 @@ TEMPLATE = lib CONFIG += plugin +include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) + INCLUDEPATH += ../../.. \ $$PROJECT_COMPONENTSOURCE \ @@ -27,7 +29,9 @@ Qt5Multimedia \ gsettings-qt \ libcanberra \ - dconf + dconf \ + libpulse \ + libpulse-mainloop-glib #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ @@ -37,9 +41,9 @@ ukmedia_output_widget.cpp \ ukmedia_sound_effects_widget.cpp \ ukui_custom_style.cpp \ - switchbutton.cpp \ customstyle.cpp \ - ukmedia_slider_tip_label_helper.cpp + ukmedia_slider_tip_label_helper.cpp \ + ukui_list_widget_item.cpp HEADERS += \ audio.h \ @@ -48,9 +52,9 @@ ukmedia_output_widget.h \ ukmedia_sound_effects_widget.h \ ukui_custom_style.h \ - switchbutton.h \ customstyle.h \ - ukmedia_slider_tip_label_helper.h + ukmedia_slider_tip_label_helper.h \ + ukui_list_widget_item.h FORMS += \ audio.ui diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/customstyle.cpp ukui-control-center-3.0.3/plugins/devices/audio/customstyle.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/customstyle.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/customstyle.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -28,6 +28,110 @@ void CustomStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { + switch (element) { + case CE_ProgressBar: + { + if (const QStyleOptionProgressBar *pb = qstyleoption_cast(option)) { + QStyleOptionProgressBar subopt = *pb; + subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget); + proxy()->drawControl(CE_ProgressBarGroove, &subopt, painter, widget); + subopt.rect = subElementRect(SE_ProgressBarContents, pb, widget); + proxy()->drawControl(CE_ProgressBarContents, &subopt, painter, widget); + + //这是这个控件的当前进度的文字,你那边看情况是否需要绘制 + // if (pb->textVisible) { + // subopt.rect = subElementRect(SE_ProgressBarLabel, pb, widget); + // proxy()->drawControl(CE_ProgressBarLabel, &subopt, painter, widget); + // } + return; + } + break; + } + + case CE_ProgressBarGroove: + { + //这是这个控件的背景,你那边看情况是否绘制 + return; + if (const QStyleOptionProgressBar *pbg = qstyleoption_cast(option)) { + const bool enable = pbg->state &State_Enabled; + painter->save(); + painter->setRenderHint(QPainter::Antialiasing, true); + painter->setPen(Qt::NoPen); + painter->setBrush(pbg->palette.brush(enable ? QPalette::Active : QPalette::Disabled, QPalette::Window)); + painter->drawRect(pbg->rect); + painter->restore(); + return; + } + break; + } + + case CE_ProgressBarContents: + { + if (const QStyleOptionProgressBar *bar = qstyleoption_cast(option)) { + if (bar->progress == bar->maximum) + return; + + const bool enable = bar->state & QStyle::State_Enabled; + const bool vertical = bar->orientation == Qt::Vertical; + const bool inverted = bar->invertedAppearance; + qint64 minimum = qint64(bar->minimum); + qint64 maximum = qint64(bar->maximum); + qint64 progress = qint64(bar->progress); + qint64 totalSteps = qMax(Q_INT64_C(1), maximum - minimum); + qint64 progressSteps = progress - bar->minimum; + qint64 progressBarWidth = progressSteps * (vertical ? bar->rect.height() : bar->rect.width()) / totalSteps; + + int ProgressBarItem_Width = 4; + int ProgressBarItem_Distance = 16; + int distance = ProgressBarItem_Distance + ProgressBarItem_Width; + int num = progressBarWidth / distance; + int totalnum = (vertical ? bar->rect.height() : bar->rect.width()) / distance; + + bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical; + if (inverted) + reverse = !reverse; + + int ProgressBarItem_Hight = 16; + QRect drawRect(bar->rect); + if (vertical) { + drawRect.setWidth(ProgressBarItem_Hight); + } else { + drawRect.setHeight(ProgressBarItem_Hight); + } + drawRect.moveCenter(bar->rect.center()); + + QRect itemRect(drawRect); + painter->save(); + painter->setPen(Qt::NoPen); + painter->setRenderHints(QPainter::Antialiasing, true); + for (int var = 0; var < totalnum; ++var) { + if (var < num) { + if (enable) + painter->setBrush(bar->palette.brush(QPalette::Active, QPalette::Highlight)); + else + painter->setBrush(bar->palette.color(QPalette::Active, QPalette::Highlight).light(150)); + } else { + painter->setBrush(bar->palette.brush(enable ? QPalette::Active : QPalette::Disabled, QPalette::Button)); + } + + if (vertical) + itemRect.setRect(drawRect.left(), !reverse ? drawRect.top() + var * distance : drawRect.bottom() - ProgressBarItem_Width - var * distance, + drawRect.width(), ProgressBarItem_Width); + else + itemRect.setRect(reverse ? drawRect.right() - ProgressBarItem_Width - var * distance : drawRect.left() + var * distance, drawRect.top(), + ProgressBarItem_Width, drawRect.height()); + painter->drawRoundedRect(itemRect, ProgressBarItem_Width/2, ProgressBarItem_Width/2); + } + painter->restore();; + return; + } + break; + } + + default: + break; + } + return QProxyStyle::drawControl(element, option, painter, widget); } @@ -128,6 +232,12 @@ int CustomStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const { switch (metric){ + case PM_ProgressBarChunkWidth: + { + int ProgressBarItem_Width = 4; + int ProgressBarItem_Distance = 16; + return ProgressBarItem_Width + ProgressBarItem_Distance; + } case PM_ToolBarIconSize:{ return (int)48*qApp->devicePixelRatio(); } @@ -198,6 +308,19 @@ QSize CustomStyle::sizeFromContents(QStyle::ContentsType type, const QStyleOption *option, const QSize &contentsSize, const QWidget *widget) const { + QSize newSize = contentsSize; + switch (type) { + case CT_ProgressBar: + { + qDebug()<pixelMetric(QStyle::PM_ProgressBarChunkWidth, option, widget); + newSize.setWidth(cw * ProgressBarItem_Num); + return newSize; + } + default: + break; + } return QProxyStyle::sizeFromContents(type, option, contentsSize, widget); } @@ -236,5 +359,13 @@ QRect CustomStyle::subElementRect(QStyle::SubElement element, const QStyleOption *option, const QWidget *widget) const { + switch (element) { + case SE_ProgressBarGroove: + case SE_ProgressBarContents: + return option->rect; + + default: + break; + } return QProxyStyle::subElementRect(element, option, widget); } diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/switchbutton.cpp ukui-control-center-3.0.3/plugins/devices/audio/switchbutton.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/switchbutton.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/switchbutton.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,182 +0,0 @@ -/* -*- 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 "switchbutton.h" - -#include - -SwitchButton::SwitchButton(QWidget *parent) : - QWidget(parent) -{ -// this->resize(QSize(52, 24)); - this->setFixedSize(QSize(52, 24)); - - checked = false; - borderColorOff = QColor("#cccccc"); - - bgColorOff = QColor("#cccccc"); - bgColorOn = QColor("#3D6BE5"); - - sliderColorOff = QColor("#ffffff"); - sliderColorOn = QColor("#ffffff"); - - space = 2; - step = width() / 50; - startX = 0; - endX= 0; - - timer = new QTimer(this); - timer->setInterval(5); - connect(timer, SIGNAL(timeout()), this, SLOT(updatevalue())); -} - -SwitchButton::~SwitchButton() -{ -} - -void SwitchButton::paintEvent(QPaintEvent *){ - //启用反锯齿 - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing, true); - - drawBg(&painter); - drawSlider(&painter); -} - -void SwitchButton::drawBg(QPainter *painter){ - painter->save(); -// painter->setPen(Qt::NoPen); - - if (!checked){ - painter->setPen(borderColorOff); - painter->setBrush(bgColorOff); - } - else{ - painter->setPen(Qt::NoPen); - painter->setBrush(bgColorOn); - } - - 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 SwitchButton::drawSlider(QPainter *painter){ - painter->save(); - painter->setPen(Qt::NoPen); - - if (!checked){ - painter->setBrush(sliderColorOff); - } - else - painter->setBrush(sliderColorOn); - - 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 SwitchButton::mousePressEvent(QMouseEvent *){ - checked = !checked; - Q_EMIT checkedChanged(checked); - - step = width() / 50; - - if (checked){ - endX = width() - height(); - } - else{ - endX = 0; - } - timer->start(); -} - -void SwitchButton::resizeEvent(QResizeEvent *){ - // - step = width() / 50; - - if (checked){ - startX = width() - height(); - } - else - startX = 0; - - update(); -} - -void SwitchButton::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 SwitchButton::setChecked(bool checked){ - if (this->checked != checked){ - this->checked = checked; - Q_EMIT checkedChanged(checked); - update(); - } - - step = width() / 50; - - if (checked){ - endX = width() - height(); - } - else{ - endX = 0; - } - timer->start(); -} - -bool SwitchButton::isChecked(){ - return this->checked; -} - - diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/switchbutton.h ukui-control-center-3.0.3/plugins/devices/audio/switchbutton.h --- ukui-control-center-2.0.3/plugins/devices/audio/switchbutton.h 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/switchbutton.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ -/* -*- 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 SWITCHBUTTON_H -#define SWITCHBUTTON_H - -#include -#include -#include -#include -#include -class SwitchButton : public QWidget -{ - Q_OBJECT - -public: - SwitchButton(QWidget *parent = 0); - ~SwitchButton(); - - void setChecked(bool checked); - - bool isChecked(); - -protected: - void mousePressEvent(QMouseEvent *); - void resizeEvent(QResizeEvent *); - void paintEvent(QPaintEvent *); - void drawBg(QPainter * painter); - void drawSlider(QPainter * painter); - -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; - - -private Q_SLOTS: - void updatevalue(); - - -Q_SIGNALS: - void checkedChanged(bool checked); - -}; - -#endif // SWITCHBUTTON_H diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_input_widget.cpp ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_input_widget.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_input_widget.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_input_widget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -30,16 +30,36 @@ m_pInputLevelWidget = new QFrame(m_pInputWidget); m_pInputPortWidget = new QFrame(m_pInputWidget); + m_pInputListWidget = new QListWidget(this); + m_pInputListWidget->setFixedHeight(250); + + m_pInputListWidget->setStyleSheet( + + "QListWidget{" + "background-color:palette(base);" + "padding-left:8;" + "padding-right:20;" + "padding-top:8;" + "padding-bottom:8;}" + "QListWidget::item{" + "border-radius:6px;}" + /**列表项扫过*/ + "QListWidget::item:hover{" + "background-color:rgba(55,144,250,0.5);}" + /**列表项选中*/ + "QListWidget::item::selected{" + "background-color:rgba(55,144,250,1);" + "border-width:0;}"); m_pInputDeviceWidget->setFrameShape(QFrame::Shape::Box); m_pVolumeWidget->setFrameShape(QFrame::Shape::Box); m_pInputLevelWidget->setFrameShape(QFrame::Shape::Box); m_pInputPortWidget->setFrameShape(QFrame::Shape::Box); //设置大小 - m_pInputWidget->setMinimumSize(550,152); - m_pInputWidget->setMaximumSize(960,152); - m_pInputDeviceWidget->setMinimumSize(550,50); - m_pInputDeviceWidget->setMaximumSize(960,50); + m_pInputWidget->setMinimumSize(550,422); + m_pInputWidget->setMaximumSize(960,422); + m_pInputDeviceWidget->setMinimumSize(550,319); + m_pInputDeviceWidget->setMaximumSize(960,319); m_pVolumeWidget->setMinimumSize(550,50); m_pVolumeWidget->setMaximumSize(960,50); m_pInputLevelWidget->setMinimumSize(550,50); @@ -49,79 +69,79 @@ m_pInputLabel = new QLabel(tr("Input"),this); m_pInputLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - m_pInputDeviceLabel = new QLabel(tr("Input Device"),m_pInputWidget); + //~ contents_path /audio/Input Device + m_pInputDeviceLabel = new QLabel(tr("Input Device:"),m_pInputWidget); m_pInputDeviceCombobox = new QComboBox(m_pInputDeviceWidget); + m_pInputDeviceCombobox->hide(); + //~ contents_path /audio/Volume m_pIpVolumeLabel = new QLabel(tr("Volume"),m_pVolumeWidget); m_pInputIconBtn = new UkuiButtonDrawSvg(m_pVolumeWidget); m_pIpVolumeSlider = new AudioSlider(m_pVolumeWidget); m_pIpVolumePercentLabel = new QLabel(m_pVolumeWidget); + //~ contents_path /audio/Input Level m_pInputLevelLabel = new QLabel(tr("Input Level"),m_pInputLevelWidget); - m_pLowLevelLabel = new QLabel(tr("Low"),m_pInputLevelWidget); - m_pInputLevelSlider = new AudioSlider(m_pInputLevelWidget); - m_pHighLevelLabel = new QLabel(tr("High"),m_pInputLevelWidget); + m_pInputLevelProgressBar = new QProgressBar(m_pInputLevelWidget); + m_pInputLevelProgressBar->setStyle(new CustomStyle); m_pInputPortCombobox = new QComboBox(m_pInputPortWidget); m_pInputPortLabel = new QLabel(tr("Connector"),m_pInputPortWidget); + m_pInputLevelProgressBar->setTextVisible(false); + m_pIpVolumeSlider->setOrientation(Qt::Horizontal); - m_pInputLevelSlider->setOrientation(Qt::Horizontal); m_pIpVolumeSlider->setRange(0,100); m_pInputIconBtn->setFocusPolicy(Qt::NoFocus); //输入设备添加布局 - QHBoxLayout *m_pInputDeviceLayout = new QHBoxLayout(m_pInputDeviceWidget); + QVBoxLayout *m_pInputDeviceLayout = new QVBoxLayout(m_pInputDeviceWidget); m_pInputLabel->setFixedSize(83,24); - m_pInputDeviceCombobox->setMinimumSize(50,32); - m_pInputDeviceCombobox->setMaximumSize(900,32); - m_pInputDeviceLabel->setFixedSize(115,24); - m_pInputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + m_pInputDeviceCombobox->setFixedHeight(32); + m_pInputDeviceCombobox->setFixedSize(600,32); + m_pInputDeviceLabel->setFixedSize(150,32); + m_pInputDeviceLayout->addWidget(m_pInputDeviceLabel); - m_pInputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - m_pInputDeviceLayout->addWidget(m_pInputDeviceCombobox); - m_pInputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + m_pInputDeviceLayout->addWidget(m_pInputListWidget); m_pInputDeviceLayout->setSpacing(0); m_pInputDeviceWidget->setLayout(m_pInputDeviceLayout); - m_pInputDeviceLayout->layout()->setContentsMargins(0,0,0,0); + m_pInputDeviceLayout->layout()->setContentsMargins(16,14,16,14); + //主音量添加布局 QHBoxLayout *m_pMasterLayout = new QHBoxLayout(m_pVolumeWidget); - m_pIpVolumeLabel->setFixedSize(115,24); + m_pIpVolumeLabel->setFixedSize(150,32); m_pInputIconBtn->setFixedSize(24,24); m_pIpVolumeSlider->setFixedHeight(20); - m_pIpVolumePercentLabel->setFixedSize(40,24); + m_pIpVolumePercentLabel->setFixedSize(55,24); m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); m_pMasterLayout->addWidget(m_pIpVolumeLabel); m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); m_pMasterLayout->addWidget(m_pInputIconBtn); m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); m_pMasterLayout->addWidget(m_pIpVolumeSlider); - m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Maximum)); m_pMasterLayout->addWidget(m_pIpVolumePercentLabel); - m_pMasterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + m_pMasterLayout->addItem(new QSpacerItem(10,20,QSizePolicy::Maximum)); m_pMasterLayout->setSpacing(0); m_pVolumeWidget->setLayout(m_pMasterLayout); m_pVolumeWidget->layout()->setContentsMargins(0,0,0,0); //声道平衡添加布局 QHBoxLayout *m_pSoundLayout = new QHBoxLayout(m_pInputLevelWidget); - m_pInputLevelLabel->setFixedSize(115,24); - m_pLowLevelLabel->setFixedSize(24,24); - m_pInputLevelSlider->setFixedHeight(20); - m_pHighLevelLabel->setFixedSize(36,24); + m_pInputLevelLabel->setFixedSize(150,32); m_pSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); m_pSoundLayout->addWidget(m_pInputLevelLabel); - m_pSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - m_pSoundLayout->addWidget(m_pLowLevelLabel); - m_pSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - m_pSoundLayout->addWidget(m_pInputLevelSlider); - m_pSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - m_pSoundLayout->addWidget(m_pHighLevelLabel); - m_pSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + // m_pSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + // m_pSoundLayout->addWidget(m_pLowLevelLabel); + m_pSoundLayout->addItem(new QSpacerItem(18,20,QSizePolicy::Fixed)); + m_pSoundLayout->addWidget(m_pInputLevelProgressBar); + // m_pSoundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + // m_pSoundLayout->addWidget(m_pHighLevelLabel); + // m_pSoundLayout->addItem(new QSpacerItem(24,20,QSizePolicy::Fixed)); m_pSoundLayout->setSpacing(0); m_pInputLevelWidget->setLayout(m_pSoundLayout); m_pInputLevelWidget->layout()->setContentsMargins(0,0,0,0); //连接器添加布局 QHBoxLayout *pConnectLayout = new QHBoxLayout(m_pInputLevelWidget); - m_pInputPortLabel->setFixedSize(115,24); + m_pInputPortLabel->setFixedSize(150,32); m_pInputPortCombobox->setMinimumSize(50,32); m_pInputPortCombobox->setMaximumSize(900,32); pConnectLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); @@ -135,13 +155,13 @@ //进行整体布局 m_pVlayout = new QVBoxLayout(m_pInputWidget); + m_pVlayout->addWidget(m_pInputDeviceWidget); m_pVlayout->addWidget(m_pVolumeWidget); m_pVlayout->addWidget(m_pInputLevelWidget); m_pVlayout->setSpacing(1); m_pInputWidget->setLayout(m_pVlayout); m_pInputWidget->layout()->setContentsMargins(0,0,0,0); -// inputWidgetAddPort(); m_pInputPortWidget->hide(); QVBoxLayout *m_pVlayout1 = new QVBoxLayout(this); m_pVlayout1->addWidget(m_pInputLabel); @@ -150,57 +170,20 @@ this->setLayout(m_pVlayout1); this->layout()->setContentsMargins(0,0,0,0); - //设置样式 - m_pIpVolumeSlider->setStyleSheet("QSlider::groove:horizontal {" - "border: 0px solid #bbb; }" - "QSlider::sub-page:horizontal {" - "background: #3D6BE5;border-radius: 2px;" - "margin-top:8px;margin-bottom:9px;}" - "QSlider::add-page:horizontal {" - "background: rgba(52,70,80,90%);" - "border: 0px solid #777;" - "border-radius: 2px;" - "margin-top:8px;" - "margin-bottom:9px;}" - "QSlider::handle:horizontal {" - "width: 20px;" - "height: 20px;" - "background: rgb(61,107,229);" - "border-radius:10px;}"); - m_pInputLevelSlider->setStyleSheet("QSlider::groove:horizontal {" - "border: 0px solid #bbb; }" - "QSlider::sub-page:horizontal {" - "background: #3D6BE5;border-radius: 2px;" - "margin-top:8px;margin-bottom:9px;}" - "QSlider::add-page:horizontal {" - "background: rgba(52,70,80,90%);" - "border: 0px solid #777;" - "border-radius: 2px;" - "margin-top:8px;" - "margin-bottom:9px;}" - "QSlider::handle:horizontal {" - "width: 20px;" - "height: 20px;" - "background: rgb(61,107,229);" - "border-radius:10px;}"); - - } void UkmediaInputWidget::inputWidgetAddPort() { - m_pInputWidget->setMinimumSize(550,203); - m_pInputWidget->setMaximumSize(960,203); -// m_pVlayout->addSpacing(1); + m_pInputWidget->setMinimumSize(550,505); + m_pInputWidget->setMaximumSize(960,505); m_pVlayout->addWidget(m_pInputPortWidget); m_pInputPortWidget->show(); } void UkmediaInputWidget::inputWidgetRemovePort() { -// m_pVlayout->addSpacing(1); - m_pInputWidget->setMinimumSize(550,152); - m_pInputWidget->setMaximumSize(960,152); + m_pInputWidget->setMinimumSize(550,454); + m_pInputWidget->setMaximumSize(960,454); m_pVlayout->removeWidget(m_pInputPortWidget); m_pInputPortWidget->hide(); } diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_input_widget.h ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_input_widget.h --- ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_input_widget.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_input_widget.h 2021-04-14 01:27:20.000000000 +0000 @@ -27,6 +27,8 @@ #include "ukmedia_output_widget.h" #include #include +#include +#include #include "ukui_custom_style.h" class UkmediaInputWidget : public QWidget @@ -48,19 +50,18 @@ QFrame *m_pVolumeWidget; QFrame *m_pInputLevelWidget; QFrame *m_pInputPortWidget; + QListWidget *m_pInputListWidget; QLabel *m_pInputLabel; QLabel *m_pInputDeviceLabel; QLabel *m_pIpVolumeLabel; QLabel *m_pInputLevelLabel; - QLabel *m_pLowLevelLabel; - QLabel *m_pHighLevelLabel; QLabel *m_pIpVolumePercentLabel; QLabel *m_pInputPortLabel; UkuiButtonDrawSvg *m_pInputIconBtn; AudioSlider *m_pIpVolumeSlider; - AudioSlider *m_pInputLevelSlider; + QProgressBar *m_pInputLevelProgressBar; QComboBox *m_pInputDeviceCombobox; QComboBox *m_pInputPortCombobox; diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_main_widget.cpp ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_main_widget.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_main_widget.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_main_widget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -27,11 +27,12 @@ #include #include #include +#include #include #define MATE_DESKTOP_USE_UNSTABLE_API #define VERSION "1.12.1" #define GVC_DIALOG_DBUS_NAME "org.mate.VolumeControl" -#define KEY_SOUNDS_SCHEMA "org.mate.sound" +#define KEY_SOUNDS_SCHEMA "org.ukui.sound" #define GVC_SOUND_SOUND (xmlChar *) "sound" #define GVC_SOUND_NAME (xmlChar *) "name" #define GVC_SOUND_FILENAME (xmlChar *) "filename" @@ -59,6 +60,17 @@ SOUND_TYPE_BUILTIN, SOUND_TYPE_CUSTOM }; + +struct profile_prio_compare { + bool operator() (pa_card_profile_info2 const * const lhs, pa_card_profile_info2 const * const rhs) const { + + if (lhs->priority == rhs->priority) + return strcmp(lhs->name, rhs->name) > 0; + + return lhs->priority > rhs->priority; + } +}; + static void callback(ca_context *c, uint32_t id, int error, void *userdata) { fprintf(stderr, "callback called for id %u, error '%s', userdata=%p\n", id, ca_strerror(error), userdata); } @@ -68,7 +80,7 @@ m_pOutputWidget = new UkmediaOutputWidget(); m_pInputWidget = new UkmediaInputWidget(); m_pSoundWidget = new UkmediaSoundEffectsWidget(); - + firstEntry = true; mThemeName = UKUI_THEME_WHITE; QVBoxLayout *m_pvLayout = new QVBoxLayout(); m_pvLayout->addWidget(m_pOutputWidget); @@ -91,7 +103,9 @@ m_pThemeNameList = new QStringList; m_pThemeDisplayNameList = new QStringList; m_pDeviceNameList = new QStringList; + m_pDeviceLabelList = new QStringList; m_pOutputStreamList = new QStringList; + m_pPrivOutputStreamList = new QStringList; m_pInputStreamList = new QStringList; m_pAppVolumeList = new QStringList; m_pStreamControlList = new QStringList; @@ -100,58 +114,75 @@ m_pOutputPortList = new QStringList; m_pSoundNameList = new QStringList; m_pProfileNameList = new QStringList; - + m_pSoundThemeList = new QStringList; + m_pSoundThemeDirList = new QStringList; + m_pSoundThemeXmlNameList = new QStringList; + + m_pOutputPortLabelList = new QStringList; + m_pInputPortLabelList = new QStringList; + m_pListWidgetLabelList = new QStringList; + m_pCurrentOutputPortLabelList = new QStringList; + m_pCurrentInputPortLabelList = new QStringList; + m_pCurrentOutputCardList = new QStringList; + m_pOutputCardList = new QStringList; + m_pInputCardList = new QStringList; + m_pCurrentInputCardList = new QStringList; + m_pInputDeviceLabelList = new QStringList; eventList = new QStringList; eventIdNameList = new QStringList; + m_pCardNameList = new QStringList; + m_pInputCardNameList = new QStringList; eventList->append("window-close"); eventList->append("system-setting"); eventList->append("volume-changed"); + eventList->append("alert-sound"); eventIdNameList->append("dialog-warning"); eventIdNameList->append("bell"); - eventIdNameList->append("audio-volume-change"); + eventIdNameList->append("flop"); + eventIdNameList->append("gudou"); for (int i=0;icount();i++) { // getValue(); addValue(eventList->at(i),eventIdNameList->at(i)); } - //创建context - m_pContext = mate_mixer_context_new(); - - mate_mixer_context_set_app_name (m_pContext,_("Volume Control"));//设置app名 - mate_mixer_context_set_app_icon(m_pContext,"multimedia-volume-control"); - - //打开context - if G_UNLIKELY (mate_mixer_context_open(m_pContext) == FALSE) { - g_warning ("Failed to connect to a sound system**********************"); - } - - g_param_spec_object ("context", - "Context", - "MateMixer context", - MATE_MIXER_TYPE_CONTEXT, - (GParamFlags)(G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); - - if (mate_mixer_context_get_state (m_pContext) == MATE_MIXER_STATE_CONNECTING) { - - } - - //当出现获取输入输出异常时,使用默认的输入输出stream - m_pInputStream = mate_mixer_context_get_default_input_stream(m_pContext); - m_pOutputStream = mate_mixer_context_get_default_output_stream(m_pContext); - contextSetProperty(this); -// 点击输出设备 - connect(m_pOutputWidget->m_pOutputDeviceCombobox,SIGNAL(currentIndexChanged(QString)),this,SLOT(outputDeviceComboxIndexChangedSlot(QString))); -// 点击输入设备 - connect(m_pInputWidget->m_pInputDeviceCombobox,SIGNAL(currentIndexChanged(QString)),this,SLOT(inputDeviceComboxIndexChangedSlot(QString))); - - g_signal_connect (G_OBJECT (m_pContext), - "notify::state", - G_CALLBACK (onContextStateNotify), - this); + connectContext(this); +// //创建context +// m_pContext = mate_mixer_context_new(); + +// mate_mixer_context_set_app_name (m_pContext,_("Volume Control"));//设置app名 +// mate_mixer_context_set_app_icon(m_pContext,"multimedia-volume-control"); + +// //打开context +// if G_UNLIKELY (mate_mixer_context_open(m_pContext) == FALSE) { +// g_warning ("Failed to connect to a sound system**********************"); +// } + +// g_param_spec_object ("context", +// "Context", +// "MateMixer context", +// MATE_MIXER_TYPE_CONTEXT, +// (GParamFlags)(G_PARAM_READWRITE | +// G_PARAM_CONSTRUCT_ONLY | +// G_PARAM_STATIC_STRINGS)); + +// MateMixerState state = mate_mixer_context_get_state(m_pContext); +// if (mate_mixer_context_get_state (m_pContext) != MATE_MIXER_STATE_CONNECTING) { +// g_timeout_add_seconds(3,connectContext,this); +// } + +// //当出现获取输入输出异常时,使用默认的输入输出stream +// contextSetProperty(this); +// m_pInputStream = mate_mixer_context_get_default_input_stream(m_pContext); +// m_pOutputStream = mate_mixer_context_get_default_output_stream(m_pContext); + +// connect(m_pInputWidget->m_pInputIconBtn,SIGNAL(clicked()),this,SLOT(inputMuteButtonSlot())); +// connect(m_pOutputWidget->m_pOutputIconBtn,SIGNAL(clicked()),this,SLOT(outputMuteButtonSlot())); +// g_signal_connect (G_OBJECT (m_pContext), +// "notify::state", +// G_CALLBACK (onContextStateNotify), +// this); //设置滑动条的最大值为100 m_pInputWidget->m_pIpVolumeSlider->setMaximum(100); @@ -159,22 +190,28 @@ m_pOutputWidget->m_pOpBalanceSlider->setMaximum(100); m_pOutputWidget->m_pOpBalanceSlider->setMinimum(-100); m_pOutputWidget->m_pOpBalanceSlider->setSingleStep(100); - m_pInputWidget->m_pInputLevelSlider->setMaximum(100); - m_pInputWidget->m_pInputLevelSlider->setEnabled(false); + m_pInputWidget->m_pInputLevelProgressBar->setMaximum(100); //设置声音主题 - //获取声音gsettings值 - m_pSoundSettings = g_settings_new (KEY_SOUNDS_SCHEMA); +// //获取声音gsettings值 +// m_pSoundSettings = g_settings_new (KEY_SOUNDS_SCHEMA); - g_signal_connect (G_OBJECT (m_pSoundSettings), - "changed", - G_CALLBACK (onKeyChanged), - this); - setupThemeSelector(this); - updateTheme(this); - //报警声音,从指定路径获取报警声音文件 - populateModelFromDir(this,SOUND_SET_DIR); - //初始化combobox的值 - comboboxCurrentTextInit(); +// g_signal_connect (G_OBJECT (m_pSoundSettings), +// "changed", +// G_CALLBACK (onKeyChanged), +// this); +// //连接到pulseaudio +// pa_glib_mainloop *m = pa_glib_mainloop_new(g_main_context_default()); +// api = pa_glib_mainloop_get_api(m); + +// role = "sink-input-by-media-role:event"; + +// setupThemeSelector(this); +// updateTheme(this); +// //报警声音,从指定路径获取报警声音文件 +// populateModelFromDir(this,SOUND_SET_DIR); +// //初始化combobox的值 +// comboboxCurrentTextInit(); + time = new QTimer(); //检测系统主题 if (QGSettings::isSchemaInstalled(UKUI_THEME_SETTING)){ m_pThemeSetting = new QGSettings(UKUI_THEME_SETTING); @@ -187,16 +224,39 @@ //检测设计开关机音乐 if (QGSettings::isSchemaInstalled(UKUI_SWITCH_SETTING)) { m_pBootSetting = new QGSettings(UKUI_SWITCH_SETTING); - if (m_pBootSetting->keys().contains("bootMusic")) { - m_hasMusic = m_pBootSetting->get(UKUI_BOOT_MUSIC_KEY).toBool(); - m_pSoundWidget->m_pBootButton->setChecked(m_hasMusic); + if (m_pBootSetting->keys().contains("startupMusic")) { + bool startup = m_pBootSetting->get(UKUI_STARTUP_MUSIC_KEY).toBool(); + m_pSoundWidget->m_pStartupButton->setChecked(startup); + } + if (m_pBootSetting->keys().contains("poweroffMusic")) { + bool poweroff = m_pBootSetting->get(UKUI_POWEROFF_MUSIC_KEY).toBool(); + m_pSoundWidget->m_pPoweroffButton->setChecked(poweroff); + } + if (m_pBootSetting->keys().contains("logoutMusic")) { + bool logout = m_pBootSetting->get(UKUI_LOGOUT_MUSIC_KEY).toBool(); + m_pSoundWidget->m_pWakeupMusicButton->setChecked(logout); + } + if (m_pBootSetting->keys().contains("weakupMusic")) { + bool m_hasMusic = m_pBootSetting->get(UKUI_WAKEUP_MUSIC_KEY).toBool(); + m_pSoundWidget->m_pWakeupMusicButton->setChecked(m_hasMusic); } - connect(m_pBootSetting,SIGNAL(changed(const QString &)),this,SLOT(bootMusicSettingsChanged())); } bool status = g_settings_get_boolean(m_pSoundSettings, EVENT_SOUNDS_KEY); m_pSoundWidget->m_pAlertSoundSwitchButton->setChecked(status); - connect(m_pSoundWidget->m_pBootButton,SIGNAL(checkedChanged(bool)),this,SLOT(bootButtonSwitchChangedSlot(bool))); + /* + if (status) { + m_pSoundWidget->m_pSoundLayout->insertWidget(5,m_pSoundWidget->m_pAlertSoundVolumeWidget); + } + else { + m_pSoundWidget->m_pAlertSoundVolumeWidget->hide(); + } + */ + connect(m_pSoundWidget->m_pAlertIconBtn,SIGNAL(clicked()),this,SLOT(alertSoundVolumeChangedSlot())); + connect(m_pSoundWidget->m_pStartupButton,SIGNAL(checkedChanged(bool)),this,SLOT(startupButtonSwitchChangedSlot(bool))); + connect(m_pSoundWidget->m_pPoweroffButton,SIGNAL(checkedChanged(bool)),this,SLOT(poweroffButtonSwitchChangedSlot(bool))); + connect(m_pSoundWidget->m_pLogoutButton,SIGNAL(checkedChanged(bool)),this,SLOT(logoutMusicButtonSwitchChangedSlot(bool))); + connect(m_pSoundWidget->m_pWakeupMusicButton,SIGNAL(checkedChanged(bool)),this,SLOT(wakeButtonSwitchChangedSlot(bool))); connect(m_pSoundWidget->m_pAlertSoundSwitchButton,SIGNAL(checkedChanged(bool)),this,SLOT(alertSoundButtonSwitchChangedSlot(bool))); //输出音量控制 //输出滑动条音量控制 @@ -205,20 +265,211 @@ connect(m_pInputWidget->m_pIpVolumeSlider,SIGNAL(valueChanged(int)),this,SLOT(inputWidgetSliderChangedSlot(int))); //点击报警音量时播放报警声音 - connect(m_pSoundWidget->m_pShutdownCombobox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboxIndexChangedSlot(int))); + connect(m_pSoundWidget->m_pAlertSlider,SIGNAL(valueChanged(int)),this,SLOT(alertVolumeSliderChangedSlot(int))); + connect(m_pSoundWidget->m_pAlertSoundCombobox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboxIndexChangedSlot(int))); connect(m_pSoundWidget->m_pLagoutCombobox ,SIGNAL(currentIndexChanged(int)),this,SLOT(comboxIndexChangedSlot(int))); connect(m_pSoundWidget->m_pSoundThemeCombobox,SIGNAL(currentIndexChanged(int)),this,SLOT(themeComboxIndexChangedSlot(int))); - connect(m_pInputWidget->m_pInputLevelSlider,SIGNAL(valueChanged(int)),this,SLOT(inputLevelValueChangedSlot())); + connect(m_pInputWidget->m_pInputLevelProgressBar,SIGNAL(valueChanged(int)),this,SLOT(inputLevelValueChangedSlot())); // connect(m_pInputWidget->m_pInputPortCombobox,SIGNAL(currentIndexChanged(int)),this,SLOT(inputPortComboxChangedSlot(int))); - connect(m_pSoundWidget->m_pWindowClosedCombobox,SIGNAL(currentIndexChanged (int)),this,SLOT(windowClosedComboboxChangedSlot(int))); connect(m_pSoundWidget->m_pVolumeChangeCombobox,SIGNAL(currentIndexChanged (int)),this,SLOT(volumeChangedComboboxChangeSlot(int))); - connect(m_pSoundWidget->m_pSettingSoundCombobox,SIGNAL(currentIndexChanged (int)),this,SLOT(settingMenuComboboxChangedSlot(int))); // connect(m_pOutputWidget->m_pProfileCombobox,SIGNAL(currentIndexChanged (int)),this,SLOT(profileComboboxChangedSlot(int))); -// connect(m_pOutputWidget->m_pSelectCombobox,SIGNAL(currentIndexChanged (int)),this,SLOT(selectComboboxChangedSlot(int))); + connect(m_pOutputWidget->m_pSelectCombobox,SIGNAL(currentIndexChanged (int)),this,SLOT(selectComboboxChangedSlot(int))); + + connect(m_pOutputWidget->m_pOutputListWidget,SIGNAL(currentRowChanged(int )),this,SLOT(outputListWidgetCurrentRowChangedSlot(int))); + connect(m_pInputWidget->m_pInputListWidget,SIGNAL(currentRowChanged(int )),this,SLOT(inputListWidgetCurrentRowChangedSlot(int))); + //输入等级 +// ukuiInputLevelSetProperty(this); +} + +int UkmediaMainWidget::connectContext(gpointer userdata) +{ + UkmediaMainWidget *w = static_cast(userdata); + //创建context + w->m_pContext = mate_mixer_context_new(); + + mate_mixer_context_set_app_name (w->m_pContext,_("Volume Control"));//设置app名 + mate_mixer_context_set_app_icon(w->m_pContext,"multimedia-volume-control"); + + //打开context + if G_UNLIKELY (mate_mixer_context_open(w->m_pContext) == FALSE) { + g_warning ("Failed to connect to a sound system**********************"); + } + + g_param_spec_object ("context", + "Context", + "MateMixer context", + MATE_MIXER_TYPE_CONTEXT, + (GParamFlags)(G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + MateMixerState state = mate_mixer_context_get_state(w->m_pContext); + + //当出现获取输入输出异常时,使用默认的输入输出stream + contextSetProperty(w); + w->m_pInputStream = mate_mixer_context_get_default_input_stream(w->m_pContext); + w->m_pOutputStream = mate_mixer_context_get_default_output_stream(w->m_pContext); + + connect(w->m_pInputWidget->m_pInputIconBtn,SIGNAL(clicked()),w,SLOT(inputMuteButtonSlot())); + connect(w->m_pOutputWidget->m_pOutputIconBtn,SIGNAL(clicked()),w,SLOT(outputMuteButtonSlot())); + g_signal_connect (G_OBJECT (w->m_pContext), + "notify::state", + G_CALLBACK (onContextStateNotify), + w); + + //获取声音gsettings值 + w->m_pSoundSettings = g_settings_new (KEY_SOUNDS_SCHEMA); + + g_signal_connect (G_OBJECT (w->m_pSoundSettings), + "changed", + G_CALLBACK (onKeyChanged), + w); + //连接到pulseaudio + pa_glib_mainloop *m = pa_glib_mainloop_new(g_main_context_default()); + w->api = pa_glib_mainloop_get_api(m); + + w->role = "sink-input-by-media-role:event"; + + w->setupThemeSelector(w); + w->updateTheme(w); + //报警声音,从指定路径获取报警声音文件 + w->populateModelFromDir(w,SOUND_SET_DIR); + //初始化combobox的值 + w->comboboxCurrentTextInit(); //输入等级 - ukuiInputLevelSetProperty(this); + w->ukuiInputLevelSetProperty(w); + w->reconnectTime = 5; + + if (mate_mixer_context_get_state (w->m_pContext) != MATE_MIXER_STATE_CONNECTING) { + qDebug() << "prety reconnect pulseaudio after 5s" ; + g_timeout_add_seconds(w->reconnectTime,connectContext,userdata); + } + else { + + return 0; + } + +} + +QPixmap UkmediaMainWidget::drawDarkColoredPixmap(const QPixmap &source) +{ +// QColor currentcolor=HighLightEffect::getCurrentSymbolicColor(); + QColor gray(255,255,255); + 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 (qAbs(color.red()-gray.red())<20 && qAbs(color.green()-gray.green())<20 && qAbs(color.blue()-gray.blue())<20) { + color.setRed(0); + color.setGreen(0); + color.setBlue(0); + img.setPixelColor(x, y, color); + } + else { + color.setRed(0); + color.setGreen(0); + color.setBlue(0); + img.setPixelColor(x, y, color); + } + } + } + } + return QPixmap::fromImage(img); +} + +QPixmap UkmediaMainWidget::drawLightColoredPixmap(const QPixmap &source) +{ +// QColor currentcolor=HighLightEffect::getCurrentSymbolicColor(); + QColor gray(255,255,255); + QColor standard (0,0,0); + 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 (qAbs(color.red()-gray.red())<20 && qAbs(color.green()-gray.green())<20 && qAbs(color.blue()-gray.blue())<20) { + color.setRed(255); + color.setGreen(255); + color.setBlue(255); + img.setPixelColor(x, y, color); + } + else { + color.setRed(255); + color.setGreen(255); + color.setBlue(255); + img.setPixelColor(x, y, color); + } + } + } + } + return QPixmap::fromImage(img); +} + +void UkmediaMainWidget::alertIconButtonSetIcon(bool state,int value) +{ + QImage image; + QColor color = QColor(0,0,0,216); + if (mThemeName == UKUI_THEME_WHITE) { + color = QColor(0,0,0,216); + } + else if (mThemeName == UKUI_THEME_BLACK) { + color = QColor(255,255,255,216); + } + m_pSoundWidget->m_pAlertIconBtn->mColor = color; + if (state) { + image = QImage("/usr/share/ukui-media/img/audio-volume-muted.svg"); + m_pSoundWidget->m_pAlertIconBtn->mImage = image; + } + else if (value <= 0) { + image = QImage("/usr/share/ukui-media/img/audio-volume-muted.svg"); + m_pSoundWidget->m_pAlertIconBtn->mImage = image; + } + else if (value > 0 && value <= 33) { + image = QImage("/usr/share/ukui-media/img/audio-volume-low.svg"); + m_pSoundWidget->m_pAlertIconBtn->mImage = image; + } + else if (value >33 && value <= 66) { + image = QImage("/usr/share/ukui-media/img/audio-volume-medium.svg"); + m_pSoundWidget->m_pAlertIconBtn->mImage = image; + } + else { + image = QImage("/usr/share/ukui-media/img/audio-volume-high.svg"); + m_pSoundWidget->m_pAlertIconBtn->mImage = image; + } + +} + +void UkmediaMainWidget::createAlertSound(UkmediaMainWidget *pWidget) +{ + const GList *list; + connect_to_pulse(this); + + /* Find an event role stored control */ + list = mate_mixer_context_list_stored_controls (pWidget->m_pContext); + while (list != NULL) { + MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (list->data); + MateMixerStreamControlMediaRole media_role; + MateMixerStream *stream = mate_mixer_stream_control_get_stream(control); + media_role = mate_mixer_stream_control_get_media_role (control); + if (media_role == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT) { + pWidget->m_pMediaRoleControl = control; + //初始化提示音量的值 + int volume = mate_mixer_stream_control_get_volume(m_pMediaRoleControl); + volume = int(volume*100/65536.0+0.5); + pWidget->m_pSoundWidget->m_pAlertSlider->setValue(volume); + pWidget->m_pSoundWidget->m_pAlertVolumeLabel->setText(QString::number(volume).append("%")); + qDebug() << "media role : " << mate_mixer_stream_control_get_name(control) <<"提示音量值为:" <next; + } } /* @@ -248,9 +499,13 @@ break; } } + if (nameStr == "alert-sound") { + QString displayName = m_pSoundNameList->at(index); + m_pSoundWidget->m_pAlertSoundCombobox->setCurrentText(displayName); + continue; + } if (nameStr == "window-close") { QString displayName = m_pSoundNameList->at(index); - m_pSoundWidget->m_pWindowClosedCombobox->setCurrentText(displayName); continue; } else if (nameStr == "volume-changed") { @@ -260,7 +515,6 @@ } else if (nameStr == "system-setting") { QString displayName = m_pSoundNameList->at(index); - m_pSoundWidget->m_pSettingSoundCombobox->setCurrentText(displayName); continue; } } @@ -271,15 +525,57 @@ } /* - 是否播放开关机音乐 + 是否播放开机音乐 +*/ +void UkmediaMainWidget::startupButtonSwitchChangedSlot(bool status) +{ + bool bBootStatus = true; + if (m_pBootSetting->keys().contains("startupMusic")) { + bBootStatus = m_pBootSetting->get(UKUI_STARTUP_MUSIC_KEY).toBool(); + if (bBootStatus != status) { + m_pBootSetting->set(UKUI_STARTUP_MUSIC_KEY,status); + } + } +} + +/* + 是否播放关机音乐 +*/ +void UkmediaMainWidget::poweroffButtonSwitchChangedSlot(bool status) +{ + bool bBootStatus = true; + if (m_pBootSetting->keys().contains("poweroffMusic")) { + bBootStatus = m_pBootSetting->get(UKUI_POWEROFF_MUSIC_KEY).toBool(); + if (bBootStatus != status) { + m_pBootSetting->set(UKUI_POWEROFF_MUSIC_KEY,status); + } + } +} + +/* + 是否播放注销音乐 +*/ +void UkmediaMainWidget::logoutMusicButtonSwitchChangedSlot(bool status) +{ + bool bBootStatus = true; + if (m_pBootSetting->keys().contains("logoutMusic")) { + bBootStatus = m_pBootSetting->get(UKUI_LOGOUT_MUSIC_KEY).toBool(); + if (bBootStatus != status) { + m_pBootSetting->set(UKUI_LOGOUT_MUSIC_KEY,status); + } + } +} + +/* + 是否播放唤醒音乐 */ -void UkmediaMainWidget::bootButtonSwitchChangedSlot(bool status) +void UkmediaMainWidget::wakeButtonSwitchChangedSlot(bool status) { bool bBootStatus = true; - if (m_pBootSetting->keys().contains("bootMusic")) { - bBootStatus = m_pBootSetting->get(UKUI_BOOT_MUSIC_KEY).toBool(); + if (m_pBootSetting->keys().contains("weakupMusic")) { + bBootStatus = m_pBootSetting->get(UKUI_WAKEUP_MUSIC_KEY).toBool(); if (bBootStatus != status) { - m_pBootSetting->set(UKUI_BOOT_MUSIC_KEY,status); + m_pBootSetting->set(UKUI_WAKEUP_MUSIC_KEY,status); } } } @@ -290,16 +586,44 @@ void UkmediaMainWidget::alertSoundButtonSwitchChangedSlot(bool status) { g_settings_set_boolean (m_pSoundSettings, EVENT_SOUNDS_KEY, status); + /* + if (status == true) { + m_pSoundWidget->m_pAlertSoundVolumeWidget->show(); + m_pSoundWidget->m_pSoundLayout->insertWidget(5,m_pSoundWidget->m_pAlertSoundVolumeWidget); + } + else { + m_pSoundWidget->m_pAlertSoundVolumeWidget->hide(); + m_pSoundWidget->m_pSoundLayout->removeWidget(m_pSoundWidget->m_pAlertSoundVolumeWidget); + } + */ } void UkmediaMainWidget::bootMusicSettingsChanged() { bool bBootStatus = true; - bool status = m_pSoundWidget->m_pBootButton->isChecked(); - if (m_pBootSetting->keys().contains("bootMusic")) { - bBootStatus = m_pBootSetting->get(UKUI_BOOT_MUSIC_KEY).toBool(); + bool status; + if (m_pBootSetting->keys().contains("startupMusic")) { + bBootStatus = m_pBootSetting->get(UKUI_STARTUP_MUSIC_KEY).toBool(); + if (status != bBootStatus ) { + m_pSoundWidget->m_pStartupButton->setChecked(bBootStatus); + } + } + if (m_pBootSetting->keys().contains("poweroffMusic")) { + bBootStatus = m_pBootSetting->get(UKUI_POWEROFF_MUSIC_KEY).toBool(); + if (status != bBootStatus ) { + m_pSoundWidget->m_pPoweroffButton->setChecked(bBootStatus); + } + } + if (m_pBootSetting->keys().contains("logoutMusic")) { + bBootStatus = m_pBootSetting->get(UKUI_LOGOUT_MUSIC_KEY).toBool(); if (status != bBootStatus ) { - m_pSoundWidget->m_pBootButton->setChecked(bBootStatus); + m_pSoundWidget->m_pLogoutButton->setChecked(bBootStatus); + } + } + if (m_pBootSetting->keys().contains("weakupMusic")) { + bBootStatus = m_pBootSetting->get(UKUI_WAKEUP_MUSIC_KEY).toBool(); + if (status != bBootStatus ) { + m_pSoundWidget->m_pWakeupMusicButton->setChecked(bBootStatus); } } } @@ -320,6 +644,7 @@ inputVolumeDarkThemeImage(nInputValue,inputStatus); outputVolumeDarkThemeImage(nOutputValue,outputStatus); m_pOutputWidget->m_pOutputIconBtn->repaint(); + m_pSoundWidget->m_pAlertIconBtn->repaint(); m_pInputWidget->m_pInputIconBtn->repaint(); } @@ -331,9 +656,9 @@ Q_UNUSED(pspec); g_debug("on context state notify"); MateMixerState state = mate_mixer_context_get_state (m_pContext); + listDevice(m_pWidget,m_pContext); if (state == MATE_MIXER_STATE_READY) { - updateDefaultInputStream (m_pWidget); updateIconOutput(m_pWidget); updateIconInput(m_pWidget); } @@ -341,6 +666,9 @@ UkuiMessageBox::critical(m_pWidget,tr("sound error"),tr("load sound failed"),UkuiMessageBox::Yes | UkuiMessageBox::No,UkuiMessageBox::Yes); g_debug(" mate mixer state failed"); } + m_pWidget->createAlertSound(m_pWidget); + + // 点击输出设备 connect(m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox,SIGNAL(currentIndexChanged(QString)),m_pWidget,SLOT(outputDeviceComboxIndexChangedSlot(QString))); // 点击输入设备 @@ -358,7 +686,8 @@ m_pControl = MATE_MIXER_STREAM_CONTROL (mate_mixer_context_get_stored_control (m_pContext, m_pName)); if (G_UNLIKELY (m_pControl == nullptr)) return; - + qDebug() << "on context stored control add" << mate_mixer_stream_control_get_name(m_pControl); + m_pWidget->m_pMediaRoleControl = m_pControl; mediaRole = mate_mixer_stream_control_get_media_role (m_pControl); if (mediaRole == MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT) ukuiBarSetStreamControl (m_pWidget,MATE_MIXER_DIRECTION_UNKNOWN, m_pControl); @@ -369,7 +698,7 @@ */ void UkmediaMainWidget::onContextStreamAdded (MateMixerContext *m_pContext,const gchar *m_pName,UkmediaMainWidget *m_pWidget) { - g_debug("on context stream added"); + qDebug() <<"on context stream added" << m_pName; MateMixerStream *m_pStream; m_pStream = mate_mixer_context_get_stream (m_pContext, m_pName); if (G_UNLIKELY (m_pStream == nullptr)) @@ -385,12 +714,74 @@ g_debug("list device"); const GList *m_pList; m_pList = mate_mixer_context_list_streams (m_pContext); - qDebug() << "list device"; while (m_pList != nullptr) { addStream (m_pWidget, MATE_MIXER_STREAM (m_pList->data),m_pContext); m_pList = m_pList->next; } + //初始化输入输出设备 + MateMixerStream *inputStream = mate_mixer_context_get_default_input_stream(m_pContext); + MateMixerStream *outputStream = mate_mixer_context_get_default_output_stream(m_pContext); + QString inputDeviceName = mate_mixer_stream_get_name(inputStream); + QString outputDeviceName = mate_mixer_stream_get_name(outputStream); + + MateMixerDevice *device = mate_mixer_stream_get_device(outputStream); + QString deviceName = mate_mixer_device_get_name(device); + int index = m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->findText(outputDeviceName); + if (index >= 0 ) { + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->blockSignals(true); + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->setCurrentIndex(index); + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->blockSignals(false); + qDebug() << "初始化输出设备:" << m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->currentText(); + QTimer *time = new QTimer; + time->start(100); + connect(time,&QTimer::timeout,[=](){ + int devIndex = m_pWidget->m_pCardNameList->indexOf(deviceName); + + qDebug() << "output device combobox index changed *******************" << m_pWidget->m_pOutputWidget->m_pOutputListWidget->count() << outputDeviceName << deviceName; + m_pWidget->findOutputListWidgetItem(m_pWidget->m_pCardNameList->at(devIndex),outputStream); + + delete time; + }); +// if (index < m_pWidget->m_pOutputPortLabelList->count()) { +// m_pWidget->m_pOutputPortLabelList->at(index); +// int i =0; +// if (index >= 0) { +// for (i=0;i m_pOutputWidget->m_pOutputListWidget->count();i++) { + +// QListWidgetItem *item = m_pWidget->m_pOutputWidget->m_pOutputListWidget->item(i); +// UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pWidget->m_pOutputWidget->m_pOutputListWidget->itemWidget(item); +// // wid->portLabel +// if(m_pWidget->m_pOutputPortLabelList->at(index) == wid->portLabel->text()) { +// m_pWidget->m_pOutputWidget->m_pOutputListWidget->blockSignals(true); +// m_pWidget->m_pOutputWidget->m_pOutputListWidget->setCurrentItem(item); +// m_pWidget->m_pOutputWidget->m_pOutputListWidget->blockSignals(false); +// } + +// } +// } +// } + } + device = mate_mixer_stream_get_device(inputStream); + deviceName = mate_mixer_device_get_name(device); + int devIndex = m_pWidget->m_pInputCardNameList->indexOf(deviceName); + index = m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->findText(inputDeviceName); + qDebug() << "input combobox index:" << index << inputDeviceName; + if (index >= 0 && devIndex >= 0) { + m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->setCurrentIndex(index); + QTimer *time = new QTimer; + time->start(100); + connect(time,&QTimer::timeout,[=](){ + qDebug() << "input device combobox index changed *******************" << m_pWidget->m_pInputWidget->m_pInputListWidget->count() << inputDeviceName << "index:" << devIndex;// m_pWidget->m_pInputCardNameList->at(devIndex); + m_pWidget->findInputListWidgetItem(m_pWidget->m_pInputCardNameList->at(devIndex),inputStream); + + delete time; + }); + } + else { + qDebug() << "input device index or input card index <= 0"; + } + const GList *pDeviceList; const GList *switches; const gchar *profileName; @@ -403,16 +794,10 @@ MateMixerDeviceSwitch *swtch = MATE_MIXER_DEVICE_SWITCH (switches->data); const GList *options; options = mate_mixer_switch_list_options ( MATE_MIXER_SWITCH(swtch)); - while (options != NULL) { + while (options != NULL) { MateMixerSwitchOption *option = MATE_MIXER_SWITCH_OPTION (options->data); profileLabel = mate_mixer_switch_option_get_label (option); profileName = mate_mixer_switch_option_get_name(option); - if (!m_pWidget->m_pProfileNameList->contains(profileName)) { - - m_pWidget->m_pProfileNameList->append(profileName); - m_pWidget->m_pOutputWidget->m_pProfileCombobox->addItem(profileLabel); - } - qDebug() << "profile name:" << profileName << "profile label :" << profileLabel; /* Select the currently active option of the switch */ options = options->next; } @@ -431,17 +816,14 @@ const gchar *m_pName; const gchar *m_pLabel; MateMixerStreamControl *m_pControl; - + qDebug() << "add stream ,stream name is :" << mate_mixer_stream_get_name(m_pStream); const GList *switchList; MateMixerSwitch *swt; switchList = mate_mixer_stream_list_switches(m_pStream); while (switchList != nullptr) { swt = MATE_MIXER_SWITCH(switchList->data); - // MateMixerSwitchOption *opt = MATE_MIXER_SWITCH_OPTION(optionList->data); MateMixerSwitchOption *opt = mate_mixer_switch_get_active_option(swt); const char *name = mate_mixer_switch_option_get_name(opt); - const char *label = mate_mixer_switch_option_get_label(opt); - qDebug() << "opt name:" << name << "opt label:" << label; m_pWidget->m_pDeviceStr = name; switchList = switchList->next; } @@ -457,8 +839,23 @@ } m_pName = mate_mixer_stream_get_name (m_pStream); m_pLabel = mate_mixer_stream_get_label (m_pStream); - m_pWidget->m_pInputStreamList->append(m_pName); - m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->addItem(m_pLabel); + QString deviceName = m_pName; + MateMixerDevice *device = mate_mixer_stream_get_device(m_pStream); + QString devName; + if (!deviceName.contains("monitor",Qt::CaseInsensitive) /*&& !m_pWidget->m_pInputStreamList->contains(m_pName)*/) { + m_pWidget->m_pInputStreamList->append(m_pName); + m_pWidget->m_pInputDeviceLabelList->append(m_pLabel); + m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->addItem(m_pName); + if (MATE_MIXER_IS_DEVICE(device)) { + devName = mate_mixer_device_get_name(device); + m_pWidget->inputStreamMapCardName(m_pName,devName); + } + else { + devName = m_pWidget->findInputStreamCardName(m_pName); + } + qDebug() << "input card name append :" << devName << "stream name :" << mate_mixer_stream_get_name(m_pStream); + m_pWidget->m_pInputCardNameList->append(devName); + } } else if (direction == MATE_MIXER_DIRECTION_OUTPUT) { MateMixerStream *m_pOutput; @@ -467,10 +864,8 @@ m_pControl = mate_mixer_stream_get_default_control (m_pStream); m_pName = mate_mixer_stream_get_name (m_pStream); m_pLabel = mate_mixer_stream_get_label (m_pStream); - if (m_pStream == m_pOutput) { - updateOutputSettings(m_pWidget,m_pControl); - ukuiBarSetStream (m_pWidget, m_pStream); - } + MateMixerDevice *device = mate_mixer_stream_get_device(m_pStream); + QString devName; if (m_pStream == m_pOutput) { updateOutputSettings(m_pWidget,m_pControl); @@ -478,8 +873,23 @@ } m_pName = mate_mixer_stream_get_name (m_pStream); m_pLabel = mate_mixer_stream_get_label (m_pStream); - m_pWidget->m_pOutputStreamList->append(m_pName); - m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->addItem(m_pLabel); + if (!strstr(m_pName,".echo-cancel") && !strstr(m_pName,"auto_null")/* && !(m_pWidget->m_pOutputStreamList->contains(m_pName))*/) { + m_pWidget->m_pOutputStreamList->append(m_pName); + m_pWidget->m_pDeviceLabelList->append(m_pLabel); + + if (MATE_MIXER_IS_DEVICE(device)) { + devName = mate_mixer_device_get_name(device); + m_pWidget->outputStreamMapCardName(m_pName,devName); + } + else { + devName = m_pWidget->findOutputStreamCardName(m_pName); + } + + m_pWidget->m_pCardNameList->append(devName); + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->addItem(m_pName); + qDebug() << "card name list apppend : "<< devName << m_pName << m_pLabel; + } + } m_pControls = mate_mixer_stream_list_controls (m_pStream); while (m_pControls != nullptr) { @@ -514,6 +924,8 @@ m_pWidget); } + + /* 添加应用音量控制 */ @@ -529,7 +941,6 @@ const gchar *m_pAppIcon; appnum++; mediaRole = mate_mixer_stream_control_get_media_role (m_pControl); - /* Add stream to the applications page, but make sure the stream qualifies * for the inclusion */ m_pInfo = mate_mixer_stream_control_get_app_info (m_pControl); @@ -587,6 +998,8 @@ g_debug("on stream control added"); MateMixerStreamControl *m_pControl; MateMixerStreamControlRole role; + + m_pWidget->updatePort = true; m_pControl = mate_mixer_stream_get_control (m_pStream, m_pName); if G_UNLIKELY (m_pControl == nullptr) return; @@ -614,6 +1027,7 @@ { Q_UNUSED(m_pStream); g_debug("on stream control removed"); + m_pWidget->updatePort = true; if (m_pWidget->m_pStreamControlList->count() > 0 && m_pWidget->m_pAppNameList->count() > 0) { int i = m_pWidget->m_pStreamControlList->indexOf(m_pName); @@ -663,6 +1077,7 @@ G_CALLBACK (onContextDefaultOutputStreamNotify), m_pWidget); + g_signal_connect (G_OBJECT (m_pContext), "stored-control-added", G_CALLBACK (onContextStoredControlAdded), @@ -691,23 +1106,31 @@ */ void UkmediaMainWidget::removeStream (UkmediaMainWidget *m_pWidget, const gchar *m_pName) { - g_debug("remove stream"); + qDebug() << "remove stream" <m_pInputStreamList->indexOf(m_pName); if (index >= 0) { m_pWidget->m_pInputStreamList->removeAt(index); + m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->blockSignals(true); m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->removeItem(index); + m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->blockSignals(false); + m_pWidget->m_pInputCardNameList->removeAt(index); } else { index = m_pWidget->m_pOutputStreamList->indexOf(m_pName); if (index >= 0) { m_pWidget->m_pOutputStreamList->removeAt(index); + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->blockSignals(true); m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->removeItem(index); + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->blockSignals(false); + m_pWidget->m_pCardNameList->removeAt(index); + m_pWidget->m_pDeviceLabelList->removeAt(index); } } if (m_pWidget->m_pAppVolumeList != nullptr) { ukuiBarSetStream(m_pWidget,nullptr); } + m_pWidget->m_pInputWidget->m_pInputLevelProgressBar->setValue(0); } /* @@ -722,45 +1145,70 @@ if (G_UNLIKELY (m_pDevice == nullptr)) return; addDevice (m_pWidget, m_pDevice); + + int index = m_pWidget->m_pDeviceNameList->indexOf(m_pName); + if (index >= 0 && index < m_pWidget->m_pOutputWidget->m_pSelectCombobox->count()) { + m_pWidget->m_pOutputWidget->m_pSelectCombobox->setCurrentIndex(index); + } } /* 添加设备 */ -void UkmediaMainWidget::addDevice (UkmediaMainWidget *m_pWidget, MateMixerDevice *pDevice) +void UkmediaMainWidget::addDevice(UkmediaMainWidget *m_pWidget, MateMixerDevice *pDevice) { g_debug("add device"); const gchar *pName; - const gchar *pLabel; + const gchar *profileLabel = NULL; /* - * const gchar *m_pLabel; - * m_pLabel = mate_mixer_device_get_label (m_pDevice); - */ + * const gchar *m_pLabel; + * m_pLabel = mate_mixer_device_get_label (m_pDevice); + */ m_pWidget->m_pDevice = pDevice; pName = mate_mixer_device_get_name (pDevice); - pLabel = mate_mixer_device_get_label(pDevice); - if (m_pWidget->m_pDeviceNameList->contains(pName) == false) { - m_pWidget->m_pDeviceNameList->append(pName); - m_pWidget->m_pOutputWidget->m_pSelectCombobox->addItem(pLabel); + const char *pLabel = mate_mixer_device_get_label(pDevice); + QString sLabel(pLabel); + m_pWidget->m_pDeviceNameList->append(pName); + + if (m_pWidget->m_pOutputWidget->m_pSelectCombobox->findText(pLabel)) { + + if (strstr(pName,"hdmi")) { + sLabel+=" (HDMI)"; + } + else if (strstr(pName,"dp")) { + sLabel+=" (DP)"; + } + else if (strstr(pName,"usb")) { + sLabel+=" (USB)"; + } + } + m_pWidget->m_pOutputWidget->m_pSelectCombobox->addItem(pLabel); + + qDebug() << "add device name,device name" << pName << pLabel ; MateMixerSwitch *profileSwitch; - qDebug() << "device name " << pName << "device label :" << pLabel; + profileSwitch = findDeviceProfileSwitch(m_pWidget,pDevice); - m_pWidget->m_pSwitch = profileSwitch; + MateMixerSwitchOption *activeProfile; + activeProfile = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH (profileSwitch)); + if (G_LIKELY (activeProfile != NULL)) + profileLabel = mate_mixer_switch_option_get_label(activeProfile); + if (profileSwitch != NULL) { - MateMixerSwitchOption *active; - active = mate_mixer_switch_get_active_option (profileSwitch); - if (G_LIKELY (active != NULL)) - profileLabel = mate_mixer_switch_option_get_label (active); -// qDebug() << "profilelabel :" << profileLabel; + activeProfile = mate_mixer_switch_get_active_option(profileSwitch); + if (G_LIKELY (activeProfile != NULL)) + profileLabel = mate_mixer_switch_option_get_label(activeProfile); g_signal_connect (G_OBJECT (profileSwitch), "notify::active-option", G_CALLBACK (onDeviceProfileActiveOptionNotify), m_pWidget); } + m_pWidget->updateInputDevicePort(); + m_pWidget->updateOutputDevicePort(); + } /* @@ -771,8 +1219,13 @@ Q_UNUSED(m_pContext); g_debug("on context device removed"); int index = m_pWidget->m_pDeviceNameList->indexOf(m_pName); - if (index >= 0) + + if (index >= 0) { + qDebug() << "device remove " << m_pWidget->m_pDeviceNameList->at(index) << m_pWidget->m_pOutputWidget->m_pSelectCombobox->itemText(index); m_pWidget->m_pDeviceNameList->removeAt(index); + m_pWidget->m_pOutputWidget->m_pSelectCombobox->removeItem(index); + m_pWidget->m_pOutputWidget->m_pSelectCombobox->update(); + } } /* @@ -783,31 +1236,63 @@ Q_UNUSED(pspec); g_debug ("on context default input stream notify"); MateMixerStream *m_pStream; - m_pStream = mate_mixer_context_get_default_input_stream (m_pContext); - if (m_pStream == nullptr) { - //当输入流更改异常时,使用默认的输入流,不应该发生这种情况 - m_pStream = m_pWidget->m_pInputStream; - } - QString deviceName = mate_mixer_stream_get_label(m_pStream); + m_pStream = mate_mixer_context_get_default_input_stream (m_pWidget->m_pContext); + qDebug() << "onContextDefaultInputStreamNotify" << mate_mixer_stream_get_name(m_pStream); + + if(!MATE_MIXER_IS_STREAM(m_pStream)) + return; + QString deviceName = mate_mixer_stream_get_name(m_pStream); int index = m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->findText(deviceName); - if (index < 0) + if (index < 0) { + //if input stream is monitor stream,set input list widget select null + m_pWidget->m_pInputWidget->m_pInputListWidget->setCurrentRow(-1); return; + } + else { + if (index < m_pWidget->m_pInputPortLabelList->count()) { + m_pWidget->m_pInputPortLabelList->at(index); + int i =0; + + for (i=0;i m_pInputWidget->m_pInputListWidget->count();i++) { + + QListWidgetItem *item = m_pWidget->m_pInputWidget->m_pInputListWidget->item(i); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pWidget->m_pInputWidget->m_pInputListWidget->itemWidget(item); + // wid->portLabel + if(m_pWidget->m_pInputPortLabelList->at(index) == wid->portLabel->text()) { + m_pWidget->m_pInputWidget->m_pInputListWidget->blockSignals(true); + m_pWidget->m_pInputWidget->m_pInputListWidget->setCurrentItem(item); + m_pWidget->m_pInputWidget->m_pInputListWidget->blockSignals(false); + } + } + } + } m_pWidget->m_pInputWidget->m_pInputDeviceCombobox->setCurrentIndex(index); updateIconInput(m_pWidget); - + m_pWidget->updateInputDevicePort(); setInputStream(m_pWidget, m_pStream); } void UkmediaMainWidget::setInputStream(UkmediaMainWidget *m_pWidget, MateMixerStream *m_pStream) { g_debug("set input stream"); - if (m_pStream == nullptr) { + if (!MATE_MIXER_IS_STREAM(m_pStream)) { return; } + qDebug() << "set input stream" << mate_mixer_stream_get_name(m_pStream); + if (m_pWidget->m_pPrivInputControl != nullptr) { + /* Disable monitoring of the previous control */ +// g_signal_handlers_disconnect_by_func (G_OBJECT (m_pWidget->m_pPrivInputControl), +// G_CALLBACK (onStreamControlMonitorValue), +// m_pWidget); + g_signal_handlers_disconnect_by_data (G_OBJECT (m_pWidget->m_pPrivInputControl), +// G_CALLBACK (onStreamControlMonitorValue), + m_pWidget); + mate_mixer_stream_control_set_monitor_enabled(m_pWidget->m_pPrivInputControl,false); + } MateMixerStreamControl *m_pControl = mate_mixer_stream_get_default_control(m_pStream); if (m_pControl != nullptr) { - mate_mixer_stream_control_set_monitor_enabled (m_pControl, false); +// mate_mixer_stream_control_set_monitor_enabled (m_pControl, false); } ukuiBarSetStream (m_pWidget, m_pStream); @@ -859,7 +1344,7 @@ g_debug("on stream control mute notifty"); /* Stop monitoring the input stream when it gets muted */ if (mate_mixer_stream_control_get_mute (m_pControl) == TRUE) { - mate_mixer_stream_control_set_monitor_enabled (m_pControl, false); +// mate_mixer_stream_control_set_monitor_enabled (m_pControl, false); } else { if (m_pWidget->m_pDeviceStr == UKUI_INPUT_REAR_MIC || m_pWidget->m_pDeviceStr == UKUI_INPUT_FRONT_MIC || m_pWidget->m_pDeviceStr == UKUI_OUTPUT_HEADPH) { @@ -876,22 +1361,95 @@ Q_UNUSED(pspec); g_debug("on context default output stream notify"); MateMixerStream *m_pStream; + const gchar *portLabel; + const gchar *portName; m_pStream = mate_mixer_context_get_default_output_stream (m_pContext); - if (m_pStream == nullptr) { - qDebug() << "on context default output steam notify:" << "stream is null"; - //当输出流更改异常时,使用默认的输入流,不应该发生这种情况 - m_pStream = m_pWidget->m_pOutputStream; + //修改输出设备时跟随输出设备改变 + MateMixerDevice *pDevice = mate_mixer_stream_get_device(m_pStream); + const gchar *cardName = mate_mixer_device_get_name(pDevice); + + if (!(MATE_MIXER_IS_STREAM(m_pStream))) { + return; } - QString deviceName = mate_mixer_stream_get_label(m_pStream); + +// /* Enable the port selector if the stream has one */ +// MateMixerSwitch *portSwitch; +// portSwitch = findStreamPortSwitch (m_pWidget,m_pStream); +// //拔插耳机时设置输出端口名 +// m_pWidget->m_pOutputPortList->clear(); +// m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->clear(); +// MateMixerDirection direction = mate_mixer_stream_get_direction(MATE_MIXER_STREAM(m_pStream)); +// if (MATE_MIXER_IS_STREAM(m_pStream)) { +// if (direction == MATE_MIXER_DIRECTION_OUTPUT) { +// if (portSwitch != nullptr) { +// const GList *options; +// options = mate_mixer_switch_list_options(MATE_MIXER_SWITCH(portSwitch)); +// MateMixerSwitchOption *activePort = mate_mixer_switch_get_active_option(portSwitch); +// while (options != nullptr) { +// portName = mate_mixer_switch_option_get_name(activePort); +// portLabel = mate_mixer_switch_option_get_label(activePort); +// MateMixerSwitchOption *opt = MATE_MIXER_SWITCH_OPTION(options->data); +// QString label = mate_mixer_switch_option_get_label(opt); +// QString name = mate_mixer_switch_option_get_name(opt); +// if (!m_pWidget->m_pOutputPortList->contains(name)) { +// m_pWidget->m_pOutputPortList->append(name); +// m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->addItem(label); +// } +// options = options->next; +// } +// } +// } +// } +// int portIndex = m_pWidget->m_pOutputPortList->indexOf(portName); +// if (portIndex < 0) { +// m_pWidget->m_pOutputWidget->m_pOutputPortWidget->hide(); +// m_pWidget->m_pOutputWidget->outputWidgetRemovePort(); +// return; +// } +// if (m_pStream == nullptr) { +// //当输出流更改异常时,使用默认的输入流,不应该发生这种情况 +// m_pStream = m_pWidget->m_pOutputStream; +// } + QString deviceName = mate_mixer_stream_get_name(m_pStream); int index = m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->findText(deviceName); - if (index < 0) + qDebug() << "on context default output steam notify:" << mate_mixer_stream_get_name(m_pStream) << cardName <m_pOutputWidget->m_pOutputListWidget->setCurrentRow(-1); return; - m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->setCurrentIndex(index); + } - updateIconOutput(m_pWidget); - setOutputStream (m_pWidget, m_pStream); -} + if (index >= 0) { + + if (index < m_pWidget->m_pOutputPortLabelList->count()) { + m_pWidget->m_pOutputPortLabelList->at(index); + int i =0; + + for (i=0;i m_pOutputWidget->m_pOutputListWidget->count();i++) { + + QListWidgetItem *item = m_pWidget->m_pOutputWidget->m_pOutputListWidget->item(i); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pWidget->m_pOutputWidget->m_pOutputListWidget->itemWidget(item); + // wid->portLabel + if(m_pWidget->m_pOutputPortLabelList->at(index) == wid->portLabel->text()) { + m_pWidget->m_pOutputWidget->m_pOutputListWidget->blockSignals(true); + m_pWidget->m_pOutputWidget->m_pOutputListWidget->setCurrentItem(item); + m_pWidget->m_pOutputWidget->m_pOutputListWidget->blockSignals(false); + } + } + } + } + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->blockSignals(true); + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->setCurrentIndex(index); + m_pWidget->m_pOutputWidget->m_pOutputDeviceCombobox->blockSignals(false); + m_pWidget->setOutputListWidgetRow(); + m_pWidget->setDefaultstream = false; + + updateIconOutput(m_pWidget); + setOutputStream (m_pWidget, m_pStream); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(true); +// m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->setCurrentIndex(portIndex); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(false); +} /* 移除存储control @@ -958,33 +1516,29 @@ { QImage image; QColor color = QColor(0,0,0,216); - if (mThemeName == UKUI_THEME_WHITE) { + if (mThemeName == UKUI_THEME_WHITE || mThemeName == "ukui-default") { color = QColor(0,0,0,216); } - else if (mThemeName == UKUI_THEME_BLACK) { + else if (mThemeName == UKUI_THEME_BLACK || mThemeName == "ukui-dark") { color = QColor(255,255,255,216); } m_pOutputWidget->m_pOutputIconBtn->mColor = color; if (status) { - image = QImage("/usr/share/ukui-media/img/audio-volume-muted.svg"); - m_pOutputWidget->m_pOutputIconBtn->mImage = image; + image = QIcon::fromTheme("audio-volume-muted-symbolic").pixmap(24,24).toImage(); } else if (value <= 0) { - image = QImage("/usr/share/ukui-media/img/audio-volume-muted.svg"); - m_pOutputWidget->m_pOutputIconBtn->mImage = image; + image = QIcon::fromTheme("audio-volume-muted-symbolic").pixmap(24,24).toImage(); } else if (value > 0 && value <= 33) { - image = QImage("/usr/share/ukui-media/img/audio-volume-low.svg"); - m_pOutputWidget->m_pOutputIconBtn->mImage = image; + image = QIcon::fromTheme("audio-volume-low-symbolic").pixmap(24,24).toImage(); } else if (value >33 && value <= 66) { - image = QImage("/usr/share/ukui-media/img/audio-volume-medium.svg"); - m_pOutputWidget->m_pOutputIconBtn->mImage = image; + image = QIcon::fromTheme("audio-volume-medium-symbolic").pixmap(24,24).toImage(); } else { - image = QImage("/usr/share/ukui-media/img/audio-volume-high.svg"); - m_pOutputWidget->m_pOutputIconBtn->mImage = image; + image = QIcon::fromTheme("audio-volume-high-symbolic").pixmap(24,24).toImage(); } + m_pOutputWidget->m_pOutputIconBtn->mImage = image; } @@ -995,33 +1549,29 @@ { QImage image; QColor color = QColor(0,0,0,190); - if (mThemeName == UKUI_THEME_WHITE) { + if (mThemeName == UKUI_THEME_WHITE || mThemeName == "ukui-default") { color = QColor(0,0,0,190); } - else if (mThemeName == UKUI_THEME_BLACK) { + else if (mThemeName == UKUI_THEME_BLACK || mThemeName == "ukui-dark") { color = QColor(255,255,255,190); } m_pInputWidget->m_pInputIconBtn->mColor = color; if (status) { - image = QImage("/usr/share/ukui-media/img/microphone-mute.svg"); - m_pInputWidget->m_pInputIconBtn->mImage = image; + image = QIcon::fromTheme("microphone-sensitivity-muted-symbolic").pixmap(24,24).toImage(); } else if (value <= 0) { - image = QImage("/usr/share/ukui-media/img/microphone-mute.svg"); - m_pInputWidget->m_pInputIconBtn->mImage = image; + image = QIcon::fromTheme("microphone-sensitivity-muted-symbolic").pixmap(24,24).toImage(); } else if (value > 0 && value <= 33) { - image = QImage("/usr/share/ukui-media/img/microphone-low.svg"); - m_pInputWidget->m_pInputIconBtn->mImage = image; + image = QIcon::fromTheme("microphone-sensitivity-low-symbolic").pixmap(24,24).toImage(); } else if (value >33 && value <= 66) { - image = QImage("/usr/share/ukui-media/img/microphone-medium.svg"); - m_pInputWidget->m_pInputIconBtn->mImage = image; + image = QIcon::fromTheme("microphone-sensitivity-medium-symbolic").pixmap(24,24).toImage(); } else { - image = QImage("/usr/share/ukui-media/img/microphone-high.svg"); - m_pInputWidget->m_pInputIconBtn->mImage = image; + image = QIcon::fromTheme("microphone-sensitivity-high-symbolic").pixmap(24,24).toImage(); } + m_pInputWidget->m_pInputIconBtn->mImage = image; } /* @@ -1036,20 +1586,36 @@ const gchar *m_pAppId; gboolean show = FALSE; m_pStream = mate_mixer_context_get_default_input_stream (m_pWidget->m_pContext); + + qDebug() << "update icon input" << mate_mixer_stream_get_name(m_pStream); + if (!MATE_MIXER_IS_STREAM(m_pStream)) { + return; + } const GList *m_pInputs =mate_mixer_stream_list_controls(m_pStream); m_pControl = mate_mixer_stream_get_default_control(m_pStream); + const gchar *inputControlName = mate_mixer_stream_control_get_name(m_pControl); + + if (inputControlName != nullptr && inputControlName != "auto_null.monitor") { + if (strstr(inputControlName,"alsa_input") || strstr(inputControlName,"3a_source") || strstr(inputControlName,"bluez_source") || strstr(inputControlName,"bt_sco_source")) + show = true; + } + + if (strstr(inputControlName,".monitor")) { + m_pWidget->m_pInputWidget->m_pInputListWidget->setCurrentRow(-1); + } m_pWidget->m_pStream = m_pStream; //初始化滑动条的值 int volume = mate_mixer_stream_control_get_volume(m_pControl); bool status = mate_mixer_stream_control_get_mute(m_pControl); int value = volume *100 /65536.0+0.5; + m_pWidget->m_pInputWidget->m_pIpVolumeSlider->blockSignals(true); m_pWidget->m_pInputWidget->m_pIpVolumeSlider->setValue(value); + m_pWidget->m_pInputWidget->m_pIpVolumeSlider->blockSignals(false); QString percent = QString::number(value); percent.append("%"); m_pWidget->m_pInputWidget->m_pIpVolumePercentLabel->setText(percent); m_pWidget->m_pInputWidget->m_pInputIconBtn->setFocusPolicy(Qt::NoFocus); -// m_pWidget->m_pInputWidget->m_pInputIconBtn->setStyleSheet("QPushButton{background:transparent;border:0px;padding-left:0px;}"); const QSize icon_size = QSize(24,24); m_pWidget->m_pInputWidget->m_pInputIconBtn->setIconSize(icon_size); @@ -1074,7 +1640,7 @@ * control for the icon */ m_pControl = input; } - show = TRUE; + show = true; break; } if (strcmp (m_pAppId, "org.mate.VolumeControl") != 0 && @@ -1085,17 +1651,19 @@ if G_UNLIKELY (m_pControl == nullptr) m_pControl = input; - show = TRUE; + show = true; break; } } m_pInputs = m_pInputs->next; } - - if (show == TRUE) { + //当前的麦克风可用开始监听输入等级 + if (show == true) { + mate_mixer_stream_control_set_monitor_enabled(m_pControl,true); g_debug ("Input icon enabled"); } else { + mate_mixer_stream_control_set_monitor_enabled(m_pControl,false); g_debug ("There is no recording application, input icon disabled"); } streamStatusIconSetControl(m_pWidget, m_pControl); @@ -1106,19 +1674,7 @@ else { g_debug ("There is no output stream/control, output icon disabled"); } - //开始监听输入等级 - if (show == TRUE ) { - flags = mate_mixer_stream_control_get_flags(m_pControl); - if (m_pWidget->m_pDeviceStr == UKUI_INPUT_REAR_MIC || m_pWidget->m_pDeviceStr == UKUI_INPUT_FRONT_MIC || m_pWidget->m_pDeviceStr == UKUI_OUTPUT_HEADPH) { - mate_mixer_stream_control_set_monitor_enabled(m_pControl,true); - } - /* Enable level bar only if supported by the control */ - if (flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR) { - } - } - else if(show == FALSE) { - mate_mixer_stream_control_set_monitor_enabled(m_pControl,false); - } + } /* @@ -1133,14 +1689,16 @@ m_Stream = mate_mixer_context_get_default_output_stream (m_pWidget->m_pContext); if (m_Stream != nullptr) m_pControl = mate_mixer_stream_get_default_control (m_Stream); - + qDebug() << "update icon output " << mate_mixer_stream_get_name(m_Stream); streamStatusIconSetControl(m_pWidget, m_pControl); //初始化滑动条的值 int volume = mate_mixer_stream_control_get_volume(m_pControl); bool status = mate_mixer_stream_control_get_mute(m_pControl); int value = volume *100 /65536.0+0.5; + m_pWidget->m_pOutputWidget->m_pOpVolumeSlider->blockSignals(true); m_pWidget->m_pOutputWidget->m_pOpVolumeSlider->setValue(value); + m_pWidget->m_pOutputWidget->m_pOpVolumeSlider->blockSignals(false); QString percent = QString::number(value); percent.append("%"); m_pWidget->m_pOutputWidget->m_pOpVolumePercentLabel->setText(percent); @@ -1236,6 +1794,8 @@ { Q_UNUSED(pspec); g_debug("on stream control volume notify"); + qDebug() << "on stream control volume notify" << mate_mixer_stream_control_get_name(m_pControl); + bool status = mate_mixer_stream_control_get_mute(m_pControl); MateMixerStreamControlFlags flags; guint volume = 0; QString decscription; @@ -1246,26 +1806,75 @@ if (flags&MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { volume = mate_mixer_stream_control_get_volume(m_pControl); } + MateMixerStream *outputStream = mate_mixer_context_get_default_output_stream(m_pWidget->m_pContext); + MateMixerStream *inputStream = mate_mixer_context_get_default_input_stream(m_pWidget->m_pContext); decscription = mate_mixer_stream_control_get_label(m_pControl); MateMixerDirection direction; MateMixerStream *m_pStream = mate_mixer_stream_control_get_stream(m_pControl); - if (MATE_MIXER_IS_STREAM(m_pStream)) { + if (outputStream != m_pStream && inputStream != m_pStream) { + return; + } + + MateMixerSwitch *portSwitch; + MateMixerStream *stream = mate_mixer_stream_control_get_stream(m_pControl); + /* Enable the port selector if the stream has one */ + portSwitch = findStreamPortSwitch (m_pWidget,stream); + direction = mate_mixer_stream_get_direction(MATE_MIXER_STREAM(m_pStream)); - qDebug() << "get stream correct" << mate_mixer_stream_control_get_label(m_pControl) << mate_mixer_stream_get_label(m_pStream); + if (MATE_MIXER_IS_STREAM(m_pStream)) { + if (direction == MATE_MIXER_DIRECTION_OUTPUT) { + /* + if (portSwitch != nullptr) { + const GList *options; + options = mate_mixer_switch_list_options(MATE_MIXER_SWITCH(portSwitch)); + if (options != nullptr) { + //拔插耳机时设置输出端口名 + m_pWidget->m_pOutputPortList->clear(); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->clear(); + } + MateMixerSwitchOption *option = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH(portSwitch)); + const gchar *outputPortLabel = mate_mixer_switch_option_get_label(option); + while (options != nullptr) { + MateMixerSwitchOption *opt = MATE_MIXER_SWITCH_OPTION(options->data); + QString label = mate_mixer_switch_option_get_label(opt); + QString name = mate_mixer_switch_option_get_name(opt); + if (!m_pWidget->m_pOutputPortList->contains(name)) { + m_pWidget->m_pOutputPortList->append(name); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->addItem(label); + } + options = options->next; + } + if (m_pWidget->m_privOutputPortLabel != "") { + if(!strcmp(m_pWidget->m_privOutputPortLabel,outputPortLabel) == 0) + } + m_pWidget->m_privOutputPortLabel; + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(true); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->setCurrentText(outputPortLabel); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(false); + qDebug() << "set output label" << outputPortLabel << mate_mixer_stream_control_get_name(m_pControl); + } + */ + } } else { m_pStream = m_pWidget->m_pStream; - direction = mate_mixer_stream_get_direction(MATE_MIXER_STREAM(m_pStream)); if (direction == MATE_MIXER_DIRECTION_OUTPUT) { -// mate_mixer_context_set_default_output_stream(m_pWidget->m_pContext,m_pStream); + /* + portSwitch = findStreamPortSwitch (m_pWidget,m_pStream); + mate_mixer_context_set_default_output_stream(m_pWidget->m_pContext,m_pStream); + if (portSwitch!= nullptr) { + MateMixerSwitchOption *option = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH(portSwitch)); + QString label = mate_mixer_switch_option_get_label(option); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->setCurrentText(label); + qDebug() << "get stream correct" << mate_mixer_stream_control_get_label(m_pControl) << mate_mixer_stream_get_label(m_pStream) <m_pContext,m_pStream); - qDebug() << "从control 获取的stream不为input stream" << mate_mixer_stream_get_label(m_pStream); setInputStream(m_pWidget,m_pStream); } } @@ -1274,17 +1883,26 @@ //设置输出滑动条的值 int value = volume*100/65536.0 + 0.5; if (direction == MATE_MIXER_DIRECTION_OUTPUT) { + m_pWidget->m_pOutputWidget->m_pOpVolumeSlider->blockSignals(true); m_pWidget->m_pOutputWidget->m_pOpVolumeSlider->setValue(value); + m_pWidget->m_pOutputWidget->m_pOpVolumeSlider->blockSignals(false); + m_pWidget->outputVolumeDarkThemeImage(value,status); + m_pWidget->m_pOutputWidget->m_pOutputIconBtn->repaint(); + QString percentStr = QString::number(value) ; + percentStr.append("%"); + m_pWidget->m_pOutputWidget->m_pOpVolumePercentLabel->setText(percentStr); } else if (direction == MATE_MIXER_DIRECTION_INPUT) { + m_pWidget->m_pInputWidget->m_pIpVolumeSlider->blockSignals(true); m_pWidget->m_pInputWidget->m_pIpVolumeSlider->setValue(value); + m_pWidget->m_pInputWidget->m_pIpVolumeSlider->blockSignals(false); } } /* 设置平衡属性 */ -void UkmediaMainWidget::ukuiBalanceBarSetProperty (UkmediaMainWidget *m_pWidget,MateMixerStreamControl *m_pControl) +void UkmediaMainWidget::ukuiBalanceBarSetProperty(UkmediaMainWidget *m_pWidget,MateMixerStreamControl *m_pControl) { g_debug("ukui balance bar set property"); ukuiBalanceBarSetControl(m_pWidget,m_pControl); @@ -1293,7 +1911,7 @@ /* 平衡设置control */ -void UkmediaMainWidget::ukuiBalanceBarSetControl (UkmediaMainWidget *m_pWidget, MateMixerStreamControl *m_pControl) +void UkmediaMainWidget::ukuiBalanceBarSetControl(UkmediaMainWidget *m_pWidget, MateMixerStreamControl *m_pControl) { g_debug("ukui balance bar set control"); g_signal_connect (G_OBJECT (m_pControl), @@ -1319,15 +1937,14 @@ void UkmediaMainWidget::updateOutputSettings (UkmediaMainWidget *m_pWidget,MateMixerStreamControl *m_pControl) { g_debug("update output settings"); + QString outputPortLabel; MateMixerStreamControlFlags flags; if (m_pControl == nullptr) { return; } if(m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->count() != 0 || m_pWidget->m_pOutputPortList->count() != 0) { - qDebug() << "下拉框的大小为:" << m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->count(); m_pWidget->m_pOutputPortList->clear(); m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->clear(); - m_pWidget->m_pOutputWidget->outputWidgetRemovePort(); } MateMixerSwitch *portSwitch; @@ -1339,31 +1956,40 @@ MateMixerStream *stream = mate_mixer_stream_control_get_stream(m_pControl); /* Enable the port selector if the stream has one */ portSwitch = findStreamPortSwitch (m_pWidget,stream); - if (portSwitch != nullptr) { - const GList *options; - options = mate_mixer_switch_list_options(MATE_MIXER_SWITCH(portSwitch)); - while (options != nullptr) { - MateMixerSwitchOption *opt = MATE_MIXER_SWITCH_OPTION(options->data); - QString label = mate_mixer_switch_option_get_label(opt); - QString name = mate_mixer_switch_option_get_name(opt); -// qDebug() << "opt label******: "<< label << "opt name :" << mate_mixer_switch_option_get_name(opt); - qDebug() << "设置组合框当前值为:" << label; - m_pWidget->m_pOutputPortList->append(name); - m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->addItem(label); - options = options->next; + MateMixerDirection direction = mate_mixer_stream_get_direction(MATE_MIXER_STREAM(stream)); + if (direction == MATE_MIXER_DIRECTION_OUTPUT) { + if (portSwitch != nullptr) { + const GList *options; + options = mate_mixer_switch_list_options(MATE_MIXER_SWITCH(portSwitch)); + MateMixerSwitchOption *option = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH(portSwitch)); + outputPortLabel = mate_mixer_switch_option_get_label(option); + while (options != nullptr) { + MateMixerSwitchOption *opt = MATE_MIXER_SWITCH_OPTION(options->data); + QString label = mate_mixer_switch_option_get_label(opt); + QString name = mate_mixer_switch_option_get_name(opt); + if (!m_pWidget->m_pOutputPortList->contains(name)) { + + m_pWidget->m_pOutputPortList->append(name); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->addItem(label); + } + options = options->next; + } } - MateMixerSwitchOption *option = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH(portSwitch)); - QString label = mate_mixer_switch_option_get_label(option); -// m_pWidget->m_pInputWidget->m_pInputPortWidget->show(); -// m_pWidget->m_pInputWidget->setMinimumSize(550,200); -// m_pWidget->m_pInputWidget->setMaximumSize(960,200); - m_pWidget->m_pOutputWidget->outputWidgetAddPort(); - m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->setCurrentText(label); - connect(m_pWidget->m_pOutputWidget->m_pOutputPortCombobox,SIGNAL(currentIndexChanged(int)),m_pWidget,SLOT(outputPortComboxChangedSlot(int))); } + + if (m_pWidget->m_pOutputPortList->count() > 0) { +// m_pWidget->m_pOutputWidget->outputWidgetAddPort(); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(true); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->setCurrentText(outputPortLabel); + m_pWidget->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(false); + } + //新需求不需要此接口 + /*connect(m_pWidget->m_pOutputWidget->m_pOutputPortCombobox,SIGNAL(currentIndexChanged(int)),m_pWidget,SLOT(outputPortComboxChangedSlot(int)));*/ connect(m_pWidget->m_pOutputWidget->m_pOpBalanceSlider,&QSlider::valueChanged,[=](int volume){ gdouble value = volume/100.0; - mate_mixer_stream_control_set_balance(m_pControl,value); + MateMixerStream *stream = mate_mixer_context_get_default_output_stream(m_pWidget->m_pContext); + MateMixerStreamControl *control = mate_mixer_stream_get_default_control(stream); + mate_mixer_stream_control_set_balance(control,value); }); } @@ -1395,7 +2021,6 @@ } else { pThemeName = g_strdup (NO_SOUNDS_THEME_NAME); } - qDebug() << "update theme,主题名" << pThemeName << eventsEnabled; //设置combox的主题 setComboxForThemeName (m_pWidget, pThemeName); updateAlertsFromThemeName (m_pWidget, pThemeName); @@ -1467,13 +2092,17 @@ if (m_pIndexName == nullptr) { continue; } + + gchar * themeName = g_settings_get_string (m_pWidget->m_pSoundSettings, SOUND_THEME_KEY); //设置主题到combox中 -// if(m_pName != NO_SOUNDS_THEME_NAME) { - qDebug() << "sound theme in dir" << "displayname:" << m_pIndexName << "theme name:" << m_pName; + qDebug() << "sound theme in dir" << "displayname:" << m_pIndexName << "theme name:" << m_pName << "theme:"<< themeName; + //屏蔽ubuntu custom 主题 + if (!strstr(m_pName,"ubuntu") && !strstr(m_pName,"freedesktop") && !strstr(m_pName,"custom")) { m_pWidget->m_pThemeDisplayNameList->append(m_pIndexName); m_pWidget->m_pThemeNameList->append(m_pName); m_pWidget->m_pSoundWidget->m_pSoundThemeCombobox->addItem(m_pIndexName); -// } + + } } g_dir_close (d); } @@ -1512,7 +2141,6 @@ void UkmediaMainWidget::setComboxForThemeName (UkmediaMainWidget *m_pWidget,const char *name) { g_debug("set combox for theme name"); -// qDebug() << "set combox for theme name" << name; gboolean found; int count = 0; /* If the name is empty, use "freedesktop" */ @@ -1532,9 +2160,6 @@ } if (m_pWidget->m_pThemeNameList->contains(name)) { index = m_pWidget->m_pThemeNameList->indexOf(name); -// if (index == -1) { -// return; -// } value = m_pWidget->m_pThemeNameList->at(index); m_pWidget->m_pSoundWidget->m_pSoundThemeCombobox->setCurrentIndex(index); } @@ -1604,7 +2229,6 @@ is_custom = strcmp (theme, CUSTOM_THEME_NAME) == 0; is_default = strcmp (alertId, DEFAULT_ALERT_ID) == 0; -// qDebug() << "namestr:" << nameStr << "themeStr:" << themeStr << "parent:" << parent << "theme:" << theme; if (! is_custom && is_default) { /* remove custom just in case */ remove_custom = TRUE; @@ -1623,10 +2247,8 @@ } if (add_custom) { - qDebug() << "add custom 设置主题"; setComboxForThemeName (pWidget, CUSTOM_THEME_NAME); } else if (remove_custom) { - qDebug() << "remove custom 设置主题"; setComboxForThemeName (pWidget, parent); } } @@ -1686,20 +2308,49 @@ g_debug("populate model from dir"); GDir *d; const char *name; + char *path; d = g_dir_open (dirname, 0, nullptr); if (d == nullptr) { return; } while ((name = g_dir_read_name (d)) != nullptr) { - char *path; if (! g_str_has_suffix (name, ".xml")) { continue; } + QString themeName = name; + QStringList temp = themeName.split("-"); + themeName = temp.at(0); + if (!m_pWidget->m_pSoundThemeList->contains(themeName)) { + m_pWidget->m_pSoundThemeList->append(themeName); + m_pWidget->m_pSoundThemeDirList->append(dirname); + m_pWidget->m_pSoundThemeXmlNameList->append(name); + } path = g_build_filename (dirname, name, nullptr); - populateModelFromFile (m_pWidget, path); - g_free (path); } + char *pThemeName = g_settings_get_string (m_pWidget->m_pSoundSettings, SOUND_THEME_KEY); + int themeIndex; + if(m_pWidget->m_pSoundThemeList->contains(pThemeName)) { + themeIndex = m_pWidget->m_pSoundThemeList->indexOf(pThemeName); + if (themeIndex < 0 ) + return; + + } + else { + themeIndex = 1; + } + + QString dirName = m_pWidget->m_pSoundThemeDirList->at(themeIndex); + QString xmlName = m_pWidget->m_pSoundThemeXmlNameList->at(themeIndex); + path = g_build_filename (dirName.toLatin1().data(), xmlName.toLatin1().data(), nullptr); + m_pWidget->m_pSoundWidget->m_pAlertSoundCombobox->blockSignals(true); + m_pWidget->m_pSoundWidget->m_pAlertSoundCombobox->clear(); + m_pWidget->m_pSoundWidget->m_pAlertSoundCombobox->blockSignals(false); + + populateModelFromFile (m_pWidget, path); + //初始化声音主题 + + g_free (path); g_dir_close (d); } @@ -1759,15 +2410,15 @@ } } + gchar * themeName = g_settings_get_string (m_pWidget->m_pSoundSettings, SOUND_THEME_KEY); + //将找到的声音文件名设置到combox中 if (filename != nullptr && name != nullptr) { m_pWidget->m_pSoundList->append((const char *)filename); m_pWidget->m_pSoundNameList->append((const char *)name); - m_pWidget->m_pSoundWidget->m_pShutdownCombobox->addItem((char *)name); + m_pWidget->m_pSoundWidget->m_pAlertSoundCombobox->addItem((char *)name); m_pWidget->m_pSoundWidget->m_pLagoutCombobox->addItem((char *)name); - m_pWidget->m_pSoundWidget->m_pWindowClosedCombobox->addItem((char *)name); m_pWidget->m_pSoundWidget->m_pVolumeChangeCombobox->addItem((char *)name); - m_pWidget->m_pSoundWidget->m_pSettingSoundCombobox->addItem((char *)name); } xmlFree (filename); xmlFree (name); @@ -1840,7 +2491,6 @@ gchar * themeName = g_settings_get_string (w->m_pSoundSettings, SOUND_THEME_KEY); - qDebug() << "主题名为:" << themeName << "id :" << path.toLatin1().data(); if (strcmp (path.toLatin1().data(), DEFAULT_ALERT_ID) == 0) { if (themeName != NULL) { caPlayForWidget (w, 0, @@ -1890,6 +2540,35 @@ updateAlert(this,sound_name.toLatin1().data()); playAlretSoundFromPath(this,sound_name); + QString fileName = m_pSoundList->at(index); + QStringList list = fileName.split("/"); + QString soundName = list.at(list.count()-1); + QStringList eventIdList = soundName.split("."); + QString eventId = eventIdList.at(0); + QList existsPath = listExistsPath(); + + for (char * path : existsPath) { + + char * prepath = QString(KEYBINDINGS_CUSTOM_DIR).toLatin1().data(); + char * allpath = strcat(prepath, path); + + const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); + const QByteArray bba(allpath); + if(QGSettings::isSchemaInstalled(ba)) + { + QGSettings * settings = new QGSettings(ba, bba); +// QString filenameStr = settings->get(FILENAME_KEY).toString(); + QString nameStr = settings->get(NAME_KEY).toString(); + if (nameStr == "alert-sound") { + settings->set(FILENAME_KEY,eventId); + return; + } + } + else { + continue; + } + } + } /* @@ -1917,7 +2596,6 @@ // QString filenameStr = settings->get(FILENAME_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); if (nameStr == "window-close") { - qDebug() << "找到窗口关闭" << nameStr << eventId; settings->set(FILENAME_KEY,eventId); return; } @@ -1933,6 +2611,10 @@ */ void UkmediaMainWidget::volumeChangedComboboxChangeSlot(int index) { + QString sound_name = m_pSoundList->at(index); +// updateAlert(this,sound_name.toLatin1().data()); + playAlretSoundFromPath(this,sound_name); + QString fileName = m_pSoundList->at(index); QStringList list = fileName.split("/"); QString soundName = list.at(list.count()-1); @@ -1951,7 +2633,6 @@ // QString filenameStr = settings->get(FILENAME_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); if (nameStr == "volume-changed") { - qDebug() << "找到音量改变volume changed event id" << eventId; settings->set(FILENAME_KEY,eventId); return; } @@ -1979,10 +2660,8 @@ if(QGSettings::isSchemaInstalled(ba)) { QGSettings * settings = new QGSettings(ba, bba); -// QString filenameStr = settings->get(FILENAME_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); if (nameStr == "system-setting") { - qDebug() << "找到设置菜单system-setting event id" << eventId; settings->set(FILENAME_KEY,eventId); return; } @@ -1993,21 +2672,113 @@ } } -//void UkmediaMainWidget::profileComboboxChangedSlot(int index) -//{ -// QString name = m_pProfileNameList->at(index); - -// MateMixerSwitchOption *opt = mate_mixer_switch_get_option(m_pSwitch,name.toLocal8Bit().data()); -// qDebug() << "combox " << name << mate_mixer_switch_option_get_name(opt); -// mate_mixer_switch_set_active_option(m_pSwitch,opt); -//} - -//void UkmediaMainWidget::selectComboboxChangedSlot(int index) -//{ -// QString deviceStr = m_pDeviceNameList->at(index); +void UkmediaMainWidget::profileComboboxChangedSlot(int index) +{ + if (index >= m_pProfileNameList->count() ) + return; + if (index < 0) + return; + QString profileName = m_pProfileNameList->at(index); + QByteArray ba = profileName.toLatin1(); + const gchar *optionName = ba.data(); + qDebug() << "profile combox changed ****************" << index << m_pProfileNameList->count() <<"option name" <m_pSelectCombobox->currentText(); + int devIndex = m_pOutputWidget->m_pSelectCombobox->currentIndex(); + QString deviceStr = m_pDeviceNameList->at(devIndex); + QByteArray bba = deviceStr.toLatin1(); + const gchar * deviceName = bba.data(); + if (m_pSwitch == nullptr) + qDebug() << "switch is null ==============="; + MateMixerDevice *mDevice = mate_mixer_context_get_device(m_pContext,deviceName); +// = mate_mixer_stream_get_device(mStream); + m_pSwitch = findDeviceProfileSwitch(this,mDevice); + + MateMixerSwitchOption *opt = mate_mixer_switch_get_option(m_pSwitch,optionName); + mate_mixer_switch_set_active_option(m_pSwitch,opt); +} + +void UkmediaMainWidget::selectComboboxChangedSlot(int index) +{ + if (index > m_pProfileNameList->count() && index < 0) + return; + QString deviceStr = m_pDeviceNameList->at(index); + QByteArray ba = deviceStr.toLatin1(); + const gchar *deviceName = ba.data(); + const gchar *profileLabel = nullptr; + const gchar *profileName = nullptr; + const gchar *setProfileLabel = nullptr; + MateMixerSwitchOption *activeOption; + MateMixerDevice *pDevice = mate_mixer_context_get_device(m_pContext,deviceName); + const GList *switches; + switches = mate_mixer_device_list_switches (MATE_MIXER_DEVICE(pDevice)); + m_pOutputWidget->m_pProfileCombobox->clear(); + m_pProfileNameList->clear(); + while (switches != nullptr) { + const GList *options; + MateMixerSwitch *swtch1 = findDeviceProfileSwitch(this,pDevice); + options = mate_mixer_switch_list_options(swtch1); + activeOption = mate_mixer_switch_get_active_option(swtch1); + setProfileLabel = mate_mixer_switch_option_get_label(activeOption) ; + + while (options != NULL) { + MateMixerSwitchOption *option = MATE_MIXER_SWITCH_OPTION (options->data); + profileLabel = mate_mixer_switch_option_get_label (option); + profileName = mate_mixer_switch_option_get_name(option); + m_pProfileNameList->append(profileName); + m_pOutputWidget->m_pProfileCombobox->addItem(profileLabel); + /* Select the currently active option of the switch */ + options = options->next; + } + switches = switches->next; + } + if (setProfileLabel != nullptr) + m_pOutputWidget->m_pProfileCombobox->setCurrentText(setProfileLabel); +// qDebug() << "设置声卡配置文件为:" << setProfileLabel; +} + +/* + 点击输入音量按钮静音 +*/ +void UkmediaMainWidget::inputMuteButtonSlot() +{ + MateMixerStreamControl *pControl; + MateMixerStream *pStream = mate_mixer_context_get_default_input_stream(m_pContext); + if (pStream != nullptr) + pControl = mate_mixer_stream_get_default_control(pStream); + int volume = int(mate_mixer_stream_control_get_volume(pControl)); + volume = int(volume*100/65536.0 + 0.5); + bool status = mate_mixer_stream_control_get_mute(pControl); + if (status) { + status = false; + mate_mixer_stream_control_set_mute(pControl,status); + } + else { + status =true; + mate_mixer_stream_control_set_mute(pControl,status); + } +} + +/* + 点击输出音量按钮静音 +*/ +void UkmediaMainWidget::outputMuteButtonSlot() +{ + MateMixerStreamControl *pControl; + MateMixerStream *pStream = mate_mixer_context_get_default_output_stream(m_pContext); + if (pStream != nullptr) + pControl = mate_mixer_stream_get_default_control(pStream); + int volume = int(mate_mixer_stream_control_get_volume(pControl)); + volume = int(volume*100/65536.0 + 0.5); + bool status = mate_mixer_stream_control_get_mute(pControl); + if (status) { + status = false; + mate_mixer_stream_control_set_mute(pControl,status); + } + else { + status =true; + mate_mixer_stream_control_set_mute(pControl,status); + } +} -// qDebug() << "device combox name :" << deviceStr; -//} /* 点击声音主题实现主题切换 @@ -2023,8 +2794,40 @@ QString theme = m_pThemeNameList->at(index); QByteArray ba = theme.toLatin1(); const char *m_pThemeName = ba.data(); - gboolean ok = g_settings_set_string (m_pSoundSettings, SOUND_THEME_KEY, m_pThemeName); - qDebug() << "index changed:" << index << m_pThemeNameList->at(index) << m_pThemeName << "设置主题是否成功" << ok; + + if (strcmp(m_pThemeName,"freedesktop") == 0) { + int index = 0; + for (int i=0;icount();i++) { + QString str = m_pSoundList->at(i); + if (str.contains("gudou",Qt::CaseSensitive)) { + index = i; + break; + } + } + + QString displayName = m_pSoundNameList->at(index); + m_pSoundWidget->m_pAlertSoundCombobox->setCurrentText(displayName); + } + + QString dirName = m_pSoundThemeDirList->at(index); + int themeIndex = m_pSoundThemeList->indexOf(m_pThemeName); + if (themeIndex < 0 ) + return; + //qDebug() << "index changed:" << m_pSoundThemeXmlNameList->at(themeIndex) << m_pThemeNameList->at(index) << m_pThemeName << dirName.toLatin1().data() ;//<< path; + QString xmlName = m_pSoundThemeXmlNameList->at(themeIndex); + const gchar *path = g_build_filename (dirName.toLatin1().data(), xmlName.toLatin1().data(), nullptr); + m_pSoundList->clear(); + m_pSoundNameList->clear(); + m_pSoundWidget->m_pAlertSoundCombobox->blockSignals(true); + m_pSoundWidget->m_pLagoutCombobox->blockSignals(true); + m_pSoundWidget->m_pVolumeChangeCombobox->blockSignals(true); + m_pSoundWidget->m_pAlertSoundCombobox->clear(); + m_pSoundWidget->m_pLagoutCombobox->clear(); + m_pSoundWidget->m_pVolumeChangeCombobox->clear(); + m_pSoundWidget->m_pAlertSoundCombobox->blockSignals(false); + m_pSoundWidget->m_pLagoutCombobox->blockSignals(false); + m_pSoundWidget->m_pVolumeChangeCombobox->blockSignals(false); + populateModelFromFile (this, path); /* special case for no sounds */ if (strcmp (m_pThemeName, NO_SOUNDS_THEME_NAME) == 0) { @@ -2042,25 +2845,68 @@ */ void UkmediaMainWidget::outputDeviceComboxIndexChangedSlot(QString str) { - g_debug("output device combox index changed slot"); MateMixerBackendFlags flags; + setOutputListWidgetRow(); int index = m_pOutputWidget->m_pOutputDeviceCombobox->findText(str); if (index == -1) return; const QString str1 = m_pOutputStreamList->at(index); const gchar *name = str1.toLocal8Bit(); MateMixerStream *stream = mate_mixer_context_get_stream(m_pContext,name); - if (G_UNLIKELY (stream == nullptr)) { - g_warn_if_reached (); -// g_free (name); - return; - } +// if (!MATE_MIXER_IS_STREAM(stream)) { +// return; +// } + +// MateMixerDevice *device = mate_mixer_stream_get_device(stream); +// QString deviceName; +// if (MATE_MIXER_IS_DEVICE(device)) +// deviceName= mate_mixer_device_get_name(device); +// else { +// QString streamName = mate_mixer_stream_get_name(stream); +// deviceName = findOutputStreamCardName(streamName); +// } +// QTimer *time = new QTimer; +// time->start(100); +// connect(time,&QTimer::timeout,[=](){ +// int devIndex = m_pCardNameList->indexOf(deviceName); +// qDebug() << "card name :" << m_pCardNameList->count() << "card index:" << devIndex << deviceName << "stream name " << mate_mixer_stream_get_name(stream)<< "card count" << m_pCardNameList->count(); +// if (devIndex != -1 && devIndex < m_pCardNameList->count()) { + +// findOutputListWidgetItem(m_pCardNameList->at(devIndex),stream); +// } +// delete time; +// }); +// index = m_pOutputWidget->m_pOutputDeviceCombobox->currentIndex(); +// if (index >= 0) { +// if (index < m_pOutputPortLabelList->count()) { +// int i =0; + +// for (i=0;i < m_pOutputWidget->m_pOutputListWidget->count();i++) { + +// QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(i); +// UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); +// if(m_pOutputPortLabelList->at(index) == wid->portLabel->text()) { +// m_pOutputWidget->m_pOutputListWidget->blockSignals(true); +// m_pOutputWidget->m_pOutputListWidget->setCurrentItem(item); +// m_pOutputWidget->m_pOutputListWidget->blockSignals(false); +// } + +// } +// } +// } flags = mate_mixer_context_get_backend_flags (m_pContext); if (flags & MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM) { - - mate_mixer_context_set_default_output_stream (m_pContext, stream); +// +// if (!strstr(mate_mixer_stream_get_name(stream),"histen")) +// if (setDefaultstream == true) { + mate_mixer_context_set_default_output_stream (m_pContext, stream); + qDebug() << "output device combox index changed slot" << str << index << name <<"stream name :" << mate_mixer_stream_get_name(stream); +// } +// else { +// setDefaultstream = true; +// } m_pStream = stream; MateMixerStreamControl *c = mate_mixer_stream_get_default_control(stream); int(mate_mixer_stream_control_get_volume(c) *100 /65536.0+0.5); @@ -2071,6 +2917,59 @@ } } +void UkmediaMainWidget::setOutputListWidgetRow() +{ + QString str = m_pOutputWidget->m_pOutputDeviceCombobox->currentText(); + int index = m_pOutputWidget->m_pOutputDeviceCombobox->findText(str); + if (index == -1) + return; + const QString str1 = m_pOutputStreamList->at(index); + const gchar *name = str1.toLocal8Bit(); + MateMixerStream *stream = mate_mixer_context_get_stream(m_pContext,name); + + if (!MATE_MIXER_IS_STREAM(stream)) { + return; + } + + MateMixerDevice *device = mate_mixer_stream_get_device(stream); + QString deviceName; + if (MATE_MIXER_IS_DEVICE(device)) + deviceName= mate_mixer_device_get_name(device); + else { + QString streamName = mate_mixer_stream_get_name(stream); + deviceName = findOutputStreamCardName(streamName); + } + QTimer *time = new QTimer; + time->start(100); + connect(time,&QTimer::timeout,[=](){ + int devIndex = m_pCardNameList->indexOf(deviceName); + qDebug() << "card name :" << m_pCardNameList->count() << "card index:" << devIndex << deviceName << "stream name " << mate_mixer_stream_get_name(stream)<< "card count" << m_pCardNameList->count(); + if (devIndex != -1 && devIndex < m_pCardNameList->count()) { + + findOutputListWidgetItem(m_pCardNameList->at(devIndex),stream); + } + delete time; + }); + index = m_pOutputWidget->m_pOutputDeviceCombobox->currentIndex(); + if (index >= 0) { + if (index < m_pOutputPortLabelList->count()) { + int i =0; + + for (i=0;i < m_pOutputWidget->m_pOutputListWidget->count();i++) { + + QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(i); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); + if(m_pOutputPortLabelList->at(index) == wid->portLabel->text()) { + m_pOutputWidget->m_pOutputListWidget->blockSignals(true); + m_pOutputWidget->m_pOutputListWidget->setCurrentItem(item); + m_pOutputWidget->m_pOutputListWidget->blockSignals(false); + } + + } + } + } +} + /* 点击输出设备combox切换 */ @@ -2084,20 +2983,57 @@ const QString str1 = m_pInputStreamList->at(index); const gchar *name = str1.toLocal8Bit(); MateMixerStream *stream = mate_mixer_context_get_stream(m_pContext,name); + if (!MATE_MIXER_IS_STREAM(stream)) + return; + MateMixerDevice *device = mate_mixer_stream_get_device(stream); + QString deviceName; + if (MATE_MIXER_IS_DEVICE(device)) + deviceName= mate_mixer_device_get_name(device); + else { + QString streamName = mate_mixer_stream_get_name(stream); + deviceName = findInputStreamCardName(streamName); + } + + qDebug() << "input device combox index changed slot" << str << index << deviceName; + QTimer *time = new QTimer; + time->start(100); + connect(time,&QTimer::timeout,[=](){ + int devIndex = m_pInputCardNameList->indexOf(deviceName); + if (devIndex != -1 && devIndex < m_pInputCardNameList->count()) { + findInputListWidgetItem(m_pInputCardNameList->at(devIndex),stream); + } + delete time; + }); + index = m_pInputWidget->m_pInputDeviceCombobox->currentIndex(); + if (index >= 0) { + if (index < m_pInputPortLabelList->count()) { + int i =0; + + for (i=0;i < m_pInputWidget->m_pInputListWidget->count();i++) { + + QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(i); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); + if(m_pInputPortLabelList->at(index) == wid->portLabel->text()) { + m_pInputWidget->m_pInputListWidget->blockSignals(true); + m_pInputWidget->m_pInputListWidget->setCurrentItem(item); + m_pInputWidget->m_pInputListWidget->blockSignals(false); + } + + } + } + } + if (G_UNLIKELY (stream == nullptr)) { g_warn_if_reached (); -// g_free (name); return; } flags = mate_mixer_context_get_backend_flags (m_pContext); - if (flags & MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM) { + if (flags & MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM) { m_pStream = stream; mate_mixer_context_set_default_input_stream (m_pContext, stream); MateMixerStreamControl *c = mate_mixer_stream_get_default_control(stream); - /*int volume = */int(mate_mixer_stream_control_get_volume(c) *100 /65536.0+0.5); -// miniWidget->masterVolumeSlider->setValue(volume); } else { setInputStream(this, stream); @@ -2185,7 +3121,6 @@ m_pWidget->m_pInputBarStreamControl = m_pControl; } m_pName = mate_mixer_stream_control_get_name (m_pControl); -// qDebug() << "ukuiBarSetStreamControl*********" << m_pName << direction; } } @@ -2223,28 +3158,33 @@ */ void UkmediaMainWidget::outputWidgetSliderChangedSlot(int value) { - m_pStream = mate_mixer_context_get_default_output_stream(m_pContext); - if (m_pStream != nullptr) - m_pControl = mate_mixer_stream_get_default_control(m_pStream); - + qDebug() << "outputWidgetSliderChangedSlot" << value; + MateMixerStream *pStream = mate_mixer_context_get_default_output_stream(m_pContext); + MateMixerStreamControl *pControl; + if (pStream != nullptr) + pControl = mate_mixer_stream_get_default_control(pStream); + else { + return; + } QString percent; bool status = false; percent = QString::number(value); int volume = value*65536/100; - mate_mixer_stream_control_set_volume(m_pControl,guint(volume)); + + mate_mixer_stream_control_set_volume(pControl,guint(volume)); if (value <= 0) { status = true; - mate_mixer_stream_control_set_mute(m_pControl,status); - mate_mixer_stream_control_set_volume(m_pControl,0); + mate_mixer_stream_control_set_mute(pControl,status); +// mate_mixer_stream_control_set_volume(m_pControl,0); percent = QString::number(0); } else { if (firstEnterSystem) { - bool status = mate_mixer_stream_control_get_mute(m_pControl); - mate_mixer_stream_control_set_mute(m_pControl,status); + bool status = mate_mixer_stream_control_get_mute(pControl); + mate_mixer_stream_control_set_mute(pControl,status); } else { - mate_mixer_stream_control_set_mute(m_pControl,status); + mate_mixer_stream_control_set_mute(pControl,status); } } firstEnterSystem = false; @@ -2260,15 +3200,15 @@ */ void UkmediaMainWidget::inputWidgetSliderChangedSlot(int value) { - m_pStream = mate_mixer_context_get_default_input_stream(m_pContext); - m_pControl = mate_mixer_stream_get_default_control(m_pStream); + MateMixerStream *pStream = mate_mixer_context_get_default_input_stream(m_pContext); + MateMixerStreamControl *pControl = mate_mixer_stream_get_default_control(pStream); QString percent; bool status = false; if (value <= 0) { status = true; - mate_mixer_stream_control_set_mute(m_pControl,status); - mate_mixer_stream_control_set_volume(m_pControl,0); + mate_mixer_stream_control_set_mute(pControl,status); + mate_mixer_stream_control_set_volume(pControl,0); percent = QString::number(0); } //输入图标修改成深色主题 @@ -2277,32 +3217,298 @@ m_pInputWidget->m_pInputIconBtn->repaint(); percent = QString::number(value); value = value * 65536 / 100; - mate_mixer_stream_control_set_mute(m_pControl,status); - mate_mixer_stream_control_set_volume(m_pControl,value); + mate_mixer_stream_control_set_mute(pControl,status); + mate_mixer_stream_control_set_volume(pControl,value); percent.append("%"); m_pInputWidget->m_pInputIconBtn->repaint(); m_pInputWidget->m_pIpVolumePercentLabel->setText(percent); } -void UkmediaMainWidget::inputPortComboxChangedSlot(int index) +/* + 设置提示音大小的值 +*/ +void UkmediaMainWidget::alertVolumeSliderChangedSlot(int value) { - if (index < 0) - return; - QString portStr = m_pInputPortList->at(index); - QByteArray ba = portStr.toLatin1(); - const char *portName = ba.data(); - MateMixerStream *stream = mate_mixer_context_get_default_input_stream(m_pContext); - MateMixerSwitch *portSwitch = findStreamPortSwitch (this,stream); - if (portSwitch != nullptr) { + if (m_pMediaRoleControl != nullptr) { + mate_mixer_stream_control_set_volume(m_pMediaRoleControl,value*65535/100); + this->m_pSoundWidget->m_pAlertVolumeLabel->setText(QString::number(value).append("%")); - MateMixerSwitchOption *opt = mate_mixer_switch_get_option(portSwitch,portName); - mate_mixer_switch_set_active_option(MATE_MIXER_SWITCH(portSwitch),opt); + alertIconButtonSetIcon(false,value); + m_pSoundWidget->m_pAlertIconBtn->repaint(); + } + else { + volume.channels = 1; + volume.values[0] = value*65536/100; + info.volume = volume; + updateRole(info); } } -void UkmediaMainWidget::outputPortComboxChangedSlot(int index) +/* + 提示音静音设置 +*/ +void UkmediaMainWidget::alertSoundVolumeChangedSlot() { - if (index < 0) + bool states = mate_mixer_stream_control_get_mute(m_pMediaRoleControl); + int volume = m_pSoundWidget->m_pAlertSlider->value(); + + mate_mixer_stream_control_set_mute(m_pMediaRoleControl,!states); + alertIconButtonSetIcon(!states,volume); + m_pSoundWidget->m_pAlertIconBtn->repaint(); +} + +void UkmediaMainWidget::outputListWidgetCurrentRowChangedSlot(int row) +{ + //当所有可用的输出设备全部移除,台式机才会出现该情况 + if (row == -1) + return; + QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(row); + if (item == nullptr) { + qDebug() <<"output current item is null"; + } + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); + QListWidgetItem *inputCurrrentItem = m_pInputWidget->m_pInputListWidget->currentItem(); + UkuiListWidgetItem *inputWid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(inputCurrrentItem); + + bool isContainBlue = inputCardListContainBluetooth(); + MateMixerStream *stream = mate_mixer_context_get_default_output_stream(m_pContext); + const gchar *streamName = mate_mixer_stream_get_name(stream); + //当输出设备从蓝牙切换到其他设备时,需将蓝牙声卡的配置文件切换为a2dp-sink + if (isContainBlue && (strstr(streamName,"headset_head_unit") || strstr(streamName,"bt_sco_sink"))) { + QString cardName = blueCardName(); + QString cmd = "pactl set-card-profile "+cardName+" a2dp_sink"; + system(cmd.toLocal8Bit().data()); + } + + QMap::iterator it; + QMap::iterator inputProfileMap; + QString endOutputProfile = ""; + QString endInputProfile = ""; + int count,i; + for (it=profileNameMap.begin(),i=0;it!= profileNameMap.end();++i) { + if (it.key() == wid->portLabel->text()) { + count = i; + endOutputProfile = it.value(); + } + + ++it; + } + + if (inputCurrrentItem != nullptr) { + + for (inputProfileMap=inputPortProfileNameMap.begin(),count=0;inputProfileMap!= inputPortProfileNameMap.end();count++) { + if (inputProfileMap.key() == inputWid->portLabel->text()) { + endInputProfile = inputProfileMap.value(); + } + if (count == inputPortProfileNameMap.count()-1) { + } + ++inputProfileMap; + } + } + //如果选择的输入输出设备为同一个声卡,则追加指定输入输出端口属于的配置文件 + if (inputCurrrentItem != nullptr && wid->deviceLabel->text() == inputWid->deviceLabel->text()) { + + QString setProfile = "pactl set-card-profile "; + setProfile += wid->deviceLabel->text(); + setProfile += " "; + setProfile += endOutputProfile; + setProfile += "+"; + setProfile +=endInputProfile; + system(setProfile.toLocal8Bit().data()); + QString deviceLabel = wid->deviceLabel->text(); + QTimer *time = new QTimer; + time->start(100); + connect(time,&QTimer::timeout,[=](){ + int index = m_pCardNameList->indexOf(deviceLabel); + if (index != -1) { + const QString str1 = m_pOutputStreamList->at(index); + const gchar *name = str1.toLocal8Bit(); + MateMixerStream *stream = mate_mixer_context_get_stream(m_pContext,name); +// mate_mixer_context_set_default_output_stream (m_pContext, stream); + m_pOutputWidget->m_pOutputDeviceCombobox->setCurrentIndex(index); + } + delete time; + }); + } + //如果选择的输入输出设备不是同一块声卡,需要设置一个优先级高的配置文件 + else { + int index = findCardIndex(wid->deviceLabel->text()); + QMap >::iterator it; + QString profileName; + for(it=cardProfileMap.begin();it!=cardProfileMap.end();) { + + if (it.key() == index) { + QStringList list= it.value(); + profileName = findHighPriorityProfile(index,endOutputProfile); + if (list.contains(endOutputProfile)) { + + } + } + ++it; + } + if (isContainBlue == false && (endOutputProfile == "headset_head_unit" || endOutputProfile == "a2dp_sink")) + profileName = "a2dp_sink"; + else if (isContainBlue == true && (endOutputProfile == "headset_head_unit" || endOutputProfile == "a2dp_sink")) + profileName = "headset_head_unit"; + QString setProfile = "pactl set-card-profile "; + setProfile += wid->deviceLabel->text(); + setProfile += " "; + setProfile += profileName; + system(setProfile.toLocal8Bit().data()); + QTimer *time = new QTimer; + time->start(100); + QString deviceLabel = wid->deviceLabel->text(); + connect(time,&QTimer::timeout,[=](){ + m_pOutputWidget->m_pOutputDeviceCombobox->update(); + int index = m_pCardNameList->indexOf(deviceLabel); + if (index >= 0) { + const QString str1 = m_pOutputStreamList->at(index); + const gchar *name = str1.toLocal8Bit(); + MateMixerStream *stream = mate_mixer_context_get_stream(m_pContext,name); +// mate_mixer_context_set_default_output_stream (m_pContext, stream); + m_pOutputWidget->m_pOutputDeviceCombobox->setCurrentIndex(index); + } + delete time; + }); + } + qDebug() << "active output port:" << wid->portLabel->text(); +} + +void UkmediaMainWidget::inputListWidgetCurrentRowChangedSlot(int row) +{ + //当所有可用的输入设备全部移除,台式机才会出现该情况 + qDebug() << "inputListWidgetCurrentRowChangedSlot" << row; + if (row == -1) + return; + QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(row); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); + QListWidgetItem *outputCurrrentItem = m_pOutputWidget->m_pOutputListWidget->currentItem(); + UkuiListWidgetItem *outputWid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(outputCurrrentItem); + + bool isContainBlue = inputCardListContainBluetooth(); + MateMixerStream *stream = mate_mixer_context_get_default_input_stream(m_pContext); + const gchar *streamName = mate_mixer_stream_get_name(stream); + //当输出设备从蓝牙切换到其他设备时,需将蓝牙声卡的配置文件切换为a2dp-sink + if (isContainBlue && (strstr(streamName,"headset_head_unit") || strstr(streamName,"bt_sco_source"))) { + QString cardName = blueCardName(); + QString cmd = "pactl set-card-profile "+cardName+" a2dp_sink"; + system(cmd.toLocal8Bit().data()); + } + + QMap::iterator it; + QString endOutputProfile = ""; + QString endInputProfile = ""; + int count,i; + for (it=inputPortProfileNameMap.begin(),i=0;it!= inputPortProfileNameMap.end();++i) { + if (it.key() == wid->portLabel->text()) { + count = i; + endInputProfile = it.value(); + } + ++it; + } + if (outputCurrrentItem != nullptr) { + for (it=profileNameMap.begin(),count=0;it!= profileNameMap.end();count++) { + if (it.key() == outputWid->portLabel->text()) { + endOutputProfile = it.value(); + } + if (count == profileNameMap.count()-1) { + } + ++it; + } + } + //如果选择的输入输出设备为同一个声卡,则追加指定输入输出端口属于的配置文件 + if (outputCurrrentItem != nullptr && wid->deviceLabel->text() == outputWid->deviceLabel->text()) { + + QString setProfile = "pactl set-card-profile "; + setProfile += wid->deviceLabel->text(); + setProfile += " "; + if (endOutputProfile == "a2dp-sink" || endInputProfile == "headset_head_unit") { + setProfile += endInputProfile; + } + else { + setProfile += endOutputProfile; + setProfile += "+"; + setProfile +=endInputProfile; + } + + QString deviceLabel = wid->deviceLabel->text(); + m_pInputWidget->m_pInputDeviceCombobox->blockSignals(true); + system(setProfile.toLocal8Bit().data()); + m_pInputWidget->m_pInputDeviceCombobox->blockSignals(false); + QTimer *time = new QTimer; + time->start(100); + connect(time,&QTimer::timeout,[=](){ + int index = m_pInputCardNameList->indexOf(deviceLabel); + if (index != -1) { + const QString str1 = m_pInputStreamList->at(index); + const gchar *name = str1.toLocal8Bit(); + MateMixerStream *stream = mate_mixer_context_get_stream(m_pContext,name); + mate_mixer_context_set_default_input_stream (m_pContext, stream); +// m_pInputWidget->m_pInputDeviceCombobox->setCurrentIndex(index); + } + delete time; + }); + } + //如果选择的输入输出设备不是同一块声卡,需要设置一个优先级高的配置文件 + else { + int index = findCardIndex(wid->deviceLabel->text()); + QMap >::iterator it; + QString profileName; + for(it=cardProfileMap.begin();it!=cardProfileMap.end();) { + + if (it.key() == index) { + QStringList list= it.value(); + profileName = findHighPriorityProfile(index,endInputProfile); + if (list.contains(endOutputProfile)) { + + } + } + ++it; + } + QString setProfile = "pactl set-card-profile "; + QString deviceLabel = wid->deviceLabel->text(); + setProfile += wid->deviceLabel->text(); + setProfile += " "; + setProfile += profileName; +// m_pInputWidget->m_pInputDeviceCombobox->blockSignals(true); + system(setProfile.toLocal8Bit().data()); + QTimer *time = new QTimer; + time->start(100); + connect(time,&QTimer::timeout,[=](){ +// m_pInputWidget->m_pInputDeviceCombobox->blockSignals(false); + int index = m_pInputCardNameList->indexOf(deviceLabel); + if (index >= 0) { + const QString str1 = m_pInputStreamList->at(index); + const gchar *name = str1.toLocal8Bit(); + MateMixerStream *stream = mate_mixer_context_get_stream(m_pContext,name); + mate_mixer_context_set_default_input_stream (m_pContext, stream); +// m_pInputWidget->m_pInputDeviceCombobox->setCurrentIndex(index); + } + delete time; + }); + } + qDebug() << "active input port:" << wid->portLabel->text(); +} + +void UkmediaMainWidget::inputPortComboxChangedSlot(int index) +{ + if (index < 0 || index >= m_pInputPortList->count()) + return; + QString portStr = m_pInputPortList->at(index); + QByteArray ba = portStr.toLatin1(); + const char *portName = ba.data(); + MateMixerStream *stream = mate_mixer_context_get_default_input_stream(m_pContext); + MateMixerSwitch *portSwitch = findStreamPortSwitch (this,stream); + if (portSwitch != nullptr) { + + MateMixerSwitchOption *opt = mate_mixer_switch_get_option(portSwitch,portName); + mate_mixer_switch_set_active_option(MATE_MIXER_SWITCH(portSwitch),opt); + } +} + +void UkmediaMainWidget::outputPortComboxChangedSlot(int index) +{ + if (index < 0) return; QString portStr = m_pOutputPortList->at(index); QByteArray ba = portStr.toLatin1(); @@ -2312,7 +3518,9 @@ if (portSwitch != nullptr) { MateMixerSwitchOption *opt = mate_mixer_switch_get_option(portSwitch,portName); + m_pOutputWidget->m_pOutputPortCombobox->blockSignals(true); mate_mixer_switch_set_active_option(MATE_MIXER_SWITCH(portSwitch),opt); + m_pOutputWidget->m_pOutputPortCombobox->blockSignals(false); } } @@ -2330,9 +3538,9 @@ gdouble min; gdouble max; - level = m_pWidget->m_pInputWidget->m_pInputLevelSlider->value(); - min = m_pWidget->m_pInputWidget->m_pInputLevelSlider->minimum(); - max = m_pWidget->m_pInputWidget->m_pInputLevelSlider->maximum(); + level = m_pWidget->m_pInputWidget->m_pInputLevelProgressBar->value(); + min = m_pWidget->m_pInputWidget->m_pInputLevelProgressBar->minimum(); + max = m_pWidget->m_pInputWidget->m_pInputLevelProgressBar->maximum(); switch (m_pWidget->scale) { case GVC_LEVEL_SCALE_LINEAR: @@ -2354,31 +3562,31 @@ MateMixerStream *stream; MateMixerStreamControlFlags flags; MateMixerSwitch *portSwitch; + /* Get the control currently associated with the input slider */ + if (m_pControl == nullptr) + return; + /* Get owning stream of the control */ + qDebug() << "control name is :" << mate_mixer_stream_control_get_label(m_pControl) << mate_mixer_stream_control_get_name(m_pControl); + stream = mate_mixer_stream_control_get_stream (m_pControl); + if (G_UNLIKELY (stream == nullptr)) + return; if(m_pWidget->m_pInputWidget->m_pInputPortCombobox->count() != 0 || m_pWidget->m_pInputPortList->count() != 0) { m_pWidget->m_pInputPortList->clear(); m_pWidget->m_pInputWidget->m_pInputPortCombobox->clear(); - m_pWidget->m_pInputWidget->inputWidgetRemovePort(); +// m_pWidget->m_pInputWidget->inputWidgetRemovePort(); } - /* Get the control currently associated with the input slider */ - if (m_pControl == nullptr) - return; flags = mate_mixer_stream_control_get_flags (m_pControl); - /* Enable level bar only if supported by the control */ if (flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR) { + m_pWidget->m_pPrivInputControl = m_pControl; g_signal_connect (G_OBJECT (m_pControl), "monitor-value", G_CALLBACK (onStreamControlMonitorValue), m_pWidget); } - /* Get owning stream of the control */ - qDebug() << "control name is :" << mate_mixer_stream_control_get_label(m_pControl); - stream = mate_mixer_stream_control_get_stream (m_pControl); - if (G_UNLIKELY (stream == nullptr)) - return; /* Enable the port selector if the stream has one */ portSwitch = findStreamPortSwitch (m_pWidget,stream); if (portSwitch != nullptr) { @@ -2388,15 +3596,16 @@ MateMixerSwitchOption *opt = MATE_MIXER_SWITCH_OPTION(options->data); QString label = mate_mixer_switch_option_get_label(opt); QString name = mate_mixer_switch_option_get_name(opt); - m_pWidget->m_pInputPortList->append(name); +// m_pWidget->m_pInputPortList->append(name); m_pWidget->m_pInputWidget->m_pInputPortCombobox->addItem(label); options = options->next; } MateMixerSwitchOption *option = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH(portSwitch)); QString label = mate_mixer_switch_option_get_label(option); - qDebug() << "设置组合框当前值为:" << label; - m_pWidget->m_pInputWidget->inputWidgetAddPort(); - m_pWidget->m_pInputWidget->m_pInputPortCombobox->setCurrentText(label); + if (m_pWidget->m_pInputPortList->count() > 0) { +// m_pWidget->m_pInputWidget->inputWidgetAddPort(); + m_pWidget->m_pInputWidget->m_pInputPortCombobox->setCurrentText(label); + } connect(m_pWidget->m_pInputWidget->m_pInputPortCombobox,SIGNAL(currentIndexChanged(int)),m_pWidget,SLOT(inputPortComboxChangedSlot(int))); } @@ -2409,7 +3618,6 @@ switches = mate_mixer_stream_list_switches (stream); while (switches != nullptr) { MateMixerStreamSwitch *swtch = MATE_MIXER_STREAM_SWITCH (switches->data); - if (!MATE_MIXER_IS_STREAM_TOGGLE (swtch) && mate_mixer_stream_switch_get_role (swtch) == MATE_MIXER_STREAM_SWITCH_ROLE_PORT) { return MATE_MIXER_SWITCH (swtch); @@ -2425,10 +3633,10 @@ g_debug("on stream control monitor value"); value = value*100; if (value >= 0) { - m_pWidget->m_pInputWidget->m_pInputLevelSlider->setValue(value); + m_pWidget->m_pInputWidget->m_pInputLevelProgressBar->setValue(value); } else { - m_pWidget->m_pInputWidget->m_pInputLevelSlider->setValue(0); + m_pWidget->m_pInputWidget->m_pInputLevelProgressBar->setValue(0); } } @@ -2652,7 +3860,6 @@ g_mkdir_with_parents (path, 0755); g_free (path); - qDebug() << "create_custom_theme" << parent; /* Set the data for index.theme */ keyfile = g_key_file_new (); g_key_file_set_string (keyfile, "Sound Theme", "Name", _("Custom")); @@ -2904,7 +4111,6 @@ g_warning("full path: %s", allpath); qDebug() << filenameStr << FILENAME_KEY <set(FILENAME_KEY, filename); settings->set(NAME_KEY, name); } -// delete settings; } MateMixerSwitch * UkmediaMainWidget::findDeviceProfileSwitch (UkmediaMainWidget *w,MateMixerDevice *device) { const GList *switches; - const gchar *profileLabel = NULL; + const gchar *profileLabel = nullptr; + const gchar *devName = nullptr; + devName = mate_mixer_device_get_name(device); switches = mate_mixer_device_list_switches (device); while (switches != nullptr) { MateMixerDeviceSwitch *swtch = MATE_MIXER_DEVICE_SWITCH (switches->data); MateMixerSwitchOption *active; active = mate_mixer_switch_get_active_option (MATE_MIXER_SWITCH (swtch)); - if (G_LIKELY (active != NULL)) +// w->m_pOutputWidget->m_pProfileCombobox->setCurrentText(profileLabel); + if (G_LIKELY (active != NULL)) { profileLabel = mate_mixer_switch_option_get_label (active); - qDebug() << "profilelabel :" << profileLabel; + } // if (w->m_pOutputWidget->m_pProfileCombobox) - w->m_pOutputWidget->m_pProfileCombobox->setCurrentText(profileLabel); + int devIndex = w->m_pOutputWidget->m_pSelectCombobox->currentIndex(); + QString deviceStr = w->m_pDeviceNameList->at(devIndex); + QByteArray bba = deviceStr.toLatin1(); + const gchar * deviceName = bba.data(); + qDebug() << "profilelabel :" << devName << "device name :" << mate_mixer_device_get_name(device) <m_pOutputWidget->m_pProfileCombobox->setCurrentText(profileLabel); + } if (mate_mixer_device_switch_get_role (swtch) == MATE_MIXER_DEVICE_SWITCH_ROLE_PROFILE) return MATE_MIXER_SWITCH (swtch); - switches = switches->next; + switches = switches->next; } return nullptr; } @@ -3014,6 +4227,43 @@ return outputs_str; } +void UkmediaMainWidget::updateProfileOption() +{ + int index = m_pOutputWidget->m_pSelectCombobox->currentIndex(); + if (index < 0) + return; + QString deviceStr = m_pDeviceNameList->at(index); + QByteArray ba = deviceStr.toLatin1(); + const gchar *deviceName = ba.data(); + const gchar *profileLabel = nullptr; + const gchar *profileName = nullptr; + const gchar *setProfileLabel = nullptr; + MateMixerSwitchOption *activeOption; + MateMixerDevice *pDevice = mate_mixer_context_get_device(m_pContext,deviceName); + const GList *switches; + switches = mate_mixer_device_list_switches (MATE_MIXER_DEVICE(pDevice)); + m_pOutputWidget->m_pProfileCombobox->clear(); + m_pProfileNameList->clear(); + while (switches != nullptr) { + MateMixerDeviceSwitch *swtch = MATE_MIXER_DEVICE_SWITCH (switches->data); + const GList *options; + options = mate_mixer_switch_list_options ( MATE_MIXER_SWITCH(swtch)); + activeOption = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH(swtch)); + setProfileLabel = mate_mixer_switch_option_get_label(activeOption) ; + + while (options != NULL) { + MateMixerSwitchOption *option = MATE_MIXER_SWITCH_OPTION (options->data); + profileLabel = mate_mixer_switch_option_get_label (option); + profileName = mate_mixer_switch_option_get_name(option); + m_pProfileNameList->append(profileName); + m_pOutputWidget->m_pProfileCombobox->addItem(profileLabel); + /* Select the currently active option of the switch */ + options = options->next; + } + switches = switches->next; + } +} + void UkmediaMainWidget::updateDeviceInfo (UkmediaMainWidget *w, MateMixerDevice *device) { const gchar *label; @@ -3022,32 +4272,1191 @@ MateMixerSwitch *profileSwitch; label = mate_mixer_device_get_label (device); - profileSwitch = findDeviceProfileSwitch (w,device); - w->m_pSwitch = profileSwitch; if (profileSwitch != NULL) { MateMixerSwitchOption *active; active = mate_mixer_switch_get_active_option (profileSwitch); if (G_LIKELY (active != NULL)) profileLabel = mate_mixer_switch_option_get_label (active); + + //qDebug() << "update device info ,设置combobox profile:" << profileLabel; + w->m_pOutputWidget->m_pProfileCombobox->setCurrentText(profileLabel); } status = deviceStatus (device); g_free (status); } +void UkmediaMainWidget::onSwitchActiveOptionNotify (MateMixerSwitch *swtch,GParamSpec *pspec,UkmediaMainWidget *w) +{ + MateMixerSwitchOption *action = mate_mixer_switch_get_active_option(swtch); + mate_mixer_switch_option_get_label(action); + const gchar *outputPortLabel = mate_mixer_switch_option_get_label(action); + qDebug() << "update active option notify" << outputPortLabel; + w->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(true); + w->m_pOutputWidget->m_pOutputPortCombobox->setCurrentText(outputPortLabel); + w->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(false); +} + void UkmediaMainWidget::onDeviceProfileActiveOptionNotify (MateMixerDeviceSwitch *swtch,GParamSpec *pspec,UkmediaMainWidget *w) { MateMixerDevice *device; - device = mate_mixer_device_switch_get_device (swtch); - + w->updateInputDevicePort(); + w->updateOutputDevicePort(); updateDeviceInfo (w, device); -// delete settings; } -UkmediaMainWidget::~UkmediaMainWidget() +void UkmediaMainWidget::updateOutputDevicePort() { -// delete player; + MateMixerSwitch *outputPortSwitch; + const GList *options ; + const gchar *outputPortLabel = nullptr; + const gchar *outputPortName = nullptr; + + MateMixerStream *outputStream = mate_mixer_context_get_default_output_stream(m_pContext); + if (outputStream == nullptr) { + return; + } + outputPortSwitch = findStreamPortSwitch(this,outputStream); + options = mate_mixer_switch_list_options(outputPortSwitch); + + MateMixerSwitchOption *outputActivePort; + outputActivePort = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH (outputPortSwitch)); + if (G_LIKELY (outputActivePort != NULL)) { + outputPortLabel = mate_mixer_switch_option_get_label(outputActivePort); + outputPortName = mate_mixer_switch_option_get_name(outputActivePort); + } + if (outputPortSwitch != NULL) { + if (G_LIKELY (outputActivePort != NULL)) + outputPortLabel = mate_mixer_switch_option_get_label(outputActivePort); + if (MATE_MIXER_IS_SWITCH_OPTION (outputActivePort)) { + m_pOutputWidget->m_pOutputPortCombobox->blockSignals(true); + m_pOutputWidget->m_pOutputPortCombobox->setCurrentText(outputPortLabel); + m_pOutputWidget->m_pOutputPortCombobox->blockSignals(false); + } + + g_signal_connect (G_OBJECT (outputPortSwitch), + "notify::active-option", + G_CALLBACK(onOutputSwitchActiveOptionNotify), + this); + } +} + +void UkmediaMainWidget::updateInputDevicePort() +{ + MateMixerSwitch *inputPortSwitch; + const GList *inputOptions ; + const gchar *inputPortLabel = nullptr; + MateMixerStream *inputStream = mate_mixer_context_get_default_input_stream(m_pContext); + if (inputStream == nullptr) { + return; + } + inputPortSwitch = findStreamPortSwitch(this,inputStream); + + inputOptions = mate_mixer_switch_list_options(inputPortSwitch); + MateMixerSwitchOption *inputActiveOption = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH(inputPortSwitch)); + + MateMixerSwitchOption *inputActivePort; + inputActivePort = mate_mixer_switch_get_active_option(MATE_MIXER_SWITCH (inputPortSwitch)); + if (G_LIKELY (inputActiveOption != NULL)) + inputPortLabel = mate_mixer_switch_option_get_label(inputActivePort); + + if (inputPortSwitch != NULL) { + if (G_LIKELY (inputActiveOption != NULL)) + inputPortLabel = mate_mixer_switch_option_get_label(inputActivePort); + if (MATE_MIXER_IS_SWITCH_OPTION (inputActivePort)) { + m_pInputWidget->m_pInputPortCombobox->blockSignals(true); + m_pInputWidget->m_pInputPortCombobox->setCurrentText(inputPortLabel); + m_pInputWidget->m_pInputPortCombobox->blockSignals(false); + } + g_signal_connect (G_OBJECT (inputPortSwitch), + "notify::active-option", + G_CALLBACK(onInputSwitchActiveOptionNotify), + this); + } +} + +void UkmediaMainWidget::onInputSwitchActiveOptionNotify (MateMixerSwitch *swtch,GParamSpec *pspec,UkmediaMainWidget *w) +{ + MateMixerSwitchOption *action = mate_mixer_switch_get_active_option(swtch); + mate_mixer_switch_option_get_label(action); + const gchar *inputPortLabel = mate_mixer_switch_option_get_label(action); + w->m_pInputWidget->m_pInputPortCombobox->blockSignals(true); + w->m_pInputWidget->m_pInputPortCombobox->setCurrentText(inputPortLabel); + w->m_pInputWidget->m_pInputPortCombobox->blockSignals(false); +} + +void UkmediaMainWidget::onOutputSwitchActiveOptionNotify (MateMixerSwitch *swtch,GParamSpec *pspec,UkmediaMainWidget *w) +{ + MateMixerSwitchOption *action = mate_mixer_switch_get_active_option(swtch); + mate_mixer_switch_option_get_label(action); + const gchar *outputPortLabel = mate_mixer_switch_option_get_label(action); + w->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(true); + w->m_pOutputWidget->m_pOutputPortCombobox->setCurrentText(outputPortLabel); + w->m_pOutputWidget->m_pOutputPortCombobox->blockSignals(false); +} + +void UkmediaMainWidget::setConnectingMessage(const char *string) { + QByteArray markup = ""; + if (!string) + markup += tr("Establishing connection to PulseAudio. Please wait...").toUtf8().constData(); + else + markup += string; + markup += ""; +} + +gboolean UkmediaMainWidget::connect_to_pulse(gpointer userdata) +{ + UkmediaMainWidget *w = static_cast(userdata); + + pa_proplist *proplist = pa_proplist_new(); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, QObject::tr("PulseAudio Volume Control").toUtf8().constData()); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "org.PulseAudio.pavucontrol"); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "audio-card"); + pa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "PACKAGE_VERSION"); + + context = pa_context_new_with_proplist(api, nullptr, proplist); + g_assert(context); + + pa_proplist_free(proplist); + + pa_context_set_state_callback(context, context_state_callback, w); + if (pa_context_connect(context, nullptr, PA_CONTEXT_NOFAIL, nullptr) < 0) { + if (pa_context_errno(context) == PA_ERR_INVALID) { + qDebug() << "connect error pulseaudio disconnect "; + w->setConnectingMessage(QObject::tr("Connection to PulseAudio failed. Automatic retry in 5s\n\n" + "In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties\n" + "or default-server in client.conf is misconfigured.\n" + "This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window.\n" + "If this is the case, then PulseAudio should autospawn again, or if this is not configured you should\n" + "run start-pulseaudio-x11 manually.").toUtf8().constData()); + } + } + + return false; +} + +void UkmediaMainWidget::createEventRole() +{ + pa_channel_map cm = { + 1, { PA_CHANNEL_POSITION_MONO } + }; + channelMap = cm; + executeVolumeUpdate(false); +} + +void UkmediaMainWidget::context_state_callback(pa_context *c, void *userdata) { + UkmediaMainWidget *w = static_cast(userdata); + g_assert(c); + + switch (pa_context_get_state(c)) { + case PA_CONTEXT_UNCONNECTED: + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + + case PA_CONTEXT_READY: { + pa_operation *o; + + /* Create event widget immediately so it's first in the list */ + w->createEventRole(); + pa_context_set_subscribe_callback(c, subscribe_cb, w); + if (!(o = pa_context_subscribe(c, (pa_subscription_mask_t) + (PA_SUBSCRIPTION_MASK_SINK| + PA_SUBSCRIPTION_MASK_SOURCE| + PA_SUBSCRIPTION_MASK_SINK_INPUT| + PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT| + PA_SUBSCRIPTION_MASK_CLIENT| + PA_SUBSCRIPTION_MASK_SERVER| + PA_SUBSCRIPTION_MASK_CARD), nullptr, nullptr))) { + w->show_error(QObject::tr("pa_context_subscribe() failed").toUtf8().constData()); + return; + } + pa_operation_unref(o); + if (!(o = pa_context_get_card_info_list(c, card_cb, w))) { + w->show_error(QObject::tr("pa_context_get_card_info_list() failed").toUtf8().constData()); + return; + } + pa_operation_unref(o); + /* These calls are not always supported */ + if ((o = pa_ext_stream_restore_read(c, ext_stream_restore_read_cb, w))) { + pa_operation_unref(o); + + if ((o = pa_ext_stream_restore_subscribe(c, 1, nullptr, nullptr))) + pa_operation_unref(o); + + } else + g_debug(QObject::tr("Failed to initialize stream_restore extension: %s").toUtf8().constData(), pa_strerror(pa_context_errno(w->context))); + break; + } + case PA_CONTEXT_FAILED: + if (w->reconnectTime > 0) { + g_debug("%s", QObject::tr("Connection failed, attempting reconnect").toUtf8().constData()); + qDebug() << "connect failed ,wait to reconnect"; + g_timeout_add_seconds(w->reconnectTime, connectContext, w); + } + return; + case PA_CONTEXT_TERMINATED: + default: + return; + } +} + +void UkmediaMainWidget::ext_stream_restore_subscribe_cb(pa_context *c, void *userdata) +{ + UkmediaMainWidget *w = static_cast(userdata); + pa_operation *o; + if (!(o = pa_ext_stream_restore_read(c, w->ext_stream_restore_read_cb, w))) { + w->show_error(QObject::tr("pa_ext_stream_restore_read() failed").toUtf8().constData()); + return; + } + + pa_operation_unref(o); +} + +void UkmediaMainWidget::ext_stream_restore_read_cb(pa_context *,const pa_ext_stream_restore_info *i,int eol,void *userdata) +{ + UkmediaMainWidget *w = static_cast(userdata); + + if (eol < 0) { + return; + } + + if (eol > 0) { + qDebug() << "Failed to initialize stream_restore extension"; + return; + } + + w->updateRole(*i); +} + +void UkmediaMainWidget::executeVolumeUpdate(bool isMuted) +{ + info.name = role; + info.channel_map.channels = 1; + info.channel_map.map[0] = PA_CHANNEL_POSITION_MONO; + volume.channels = 1; + volume.values[0] = m_pSoundWidget->m_pAlertSlider->value()*65536/100; + info.volume = volume; + info.device = device == "" ? nullptr : device.constData(); + info.mute = isMuted; + + pa_operation* o; + if (!(o = pa_ext_stream_restore_write(get_context(), PA_UPDATE_REPLACE, &info, 1, true, nullptr, nullptr))) { + show_error(tr("pa_ext_stream_restore_write() failed").toUtf8().constData()); + return; + } + pa_operation_unref(o); +} + + + +void UkmediaMainWidget::subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, void *userdata) +{ + UkmediaMainWidget *w = static_cast(userdata); + + switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { + case PA_SUBSCRIPTION_EVENT_CARD: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_operation *o; +// if ((o = pa_context_get_card_info_by_index(c, index, card_cb, w))) { +// w->show_error(QObject::tr("pa_context_get_card_info_by_index() failed").toUtf8().constData()); +// } + w->currentInputPortLabelMap.clear(); + w->m_pCurrentOutputPortLabelList->clear(); + w->m_pCurrentInputPortLabelList->clear(); + w->currentOutputPortLabelMap.clear(); + //将移除的声卡信息在map删除 + QMap::iterator it; + QMap>::iterator temp; + QMap>::iterator profilePriorityMap; + for(it = w->cardMap.begin();it!=w->cardMap.end();) + { + if(it.key() == index) + { + it = w->cardMap.erase(it); + continue; + } + ++it; + } + + for(temp=w->cardProfileMap.begin();temp!=w->cardProfileMap.end();) { + + if (it.key() == index) { + temp= w->cardProfileMap.erase(temp); + continue; + } + ++temp; + } + + for(profilePriorityMap=w->cardProfilePriorityMap.begin();profilePriorityMap!=w->cardProfilePriorityMap.end();) { + + if (profilePriorityMap.key() == index) { + profilePriorityMap= w->cardProfilePriorityMap.erase(profilePriorityMap); + continue; + } + ++profilePriorityMap; + } + + //移除输入端口名 + for(it = w->inputPortNameMap.begin();it!=w->inputPortNameMap.end();) + { + if(it.key() == index) + { + it = w->inputPortNameMap.erase(it); + //qDebug() << "remove input port name map index" << index << w->inputPortNameMap.count(); + continue; + } + ++it; + } + + for(it = w->outputPortNameMap.begin();it!=w->outputPortNameMap.end();) + { + if(it.key() == index) + { + it = w->outputPortNameMap.erase(it); + //qDebug() << "remove output port name map index" << index << w->outputPortNameMap.count(); + continue; + } + ++it; + } + for(it = w->inputPortLabelMap.begin();it!=w->inputPortLabelMap.end();) + { + if(it.key() == index) + { + QString removePortLabel = it.value(); + QMap::iterator removeProfileMap; + for (removeProfileMap = w->inputPortProfileNameMap.begin();removeProfileMap!= w->inputPortProfileNameMap.end();) { + if (removeProfileMap.key() == removePortLabel) { + removeProfileMap = w->inputPortProfileNameMap.erase(removeProfileMap); + continue; + } + ++removeProfileMap; + } + it = w->inputPortLabelMap.erase(it); + //qDebug() << "remove input port label map index" << index << w->inputPortLabelMap.count(); + continue; + } + ++it; + } + + for(it = w->outputPortLabelMap.begin();it!=w->outputPortLabelMap.end();) + { + if(it.key() == index) + { + QString removePortLabel = it.value(); + QMap::iterator removeProfileMap; + for (removeProfileMap = w->profileNameMap.begin();removeProfileMap!= w->profileNameMap.end();) { + if (removeProfileMap.key() == removePortLabel) { + removeProfileMap = w->profileNameMap.erase(removeProfileMap); + continue; + } + ++removeProfileMap; + } + //qDebug() << "remove output port label map index" << it.value() << w->outputPortLabelMap.count(); + it = w->outputPortLabelMap.erase(it); + continue; + } + ++it; + } + + qDebug() << "remove cards" << index << w->inputPortLabelMap.count() << w->outputPortLabelMap.count() ; + for (int i=0;im_pOutputWidget->m_pOutputListWidget->count();i++) { + + QListWidgetItem *item = w->m_pOutputWidget->m_pOutputListWidget->item(i); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)w->m_pOutputWidget->m_pOutputListWidget->itemWidget(item); + int index; + for (it=w->cardMap.begin();it!=w->cardMap.end();) { + if (wid->deviceLabel->text() == it.value()) { + index = it.key(); + break; + } + ++it; + } + w->currentOutputPortLabelMap.insertMulti(index,wid->portLabel->text()); + w->m_pCurrentOutputPortLabelList->append(wid->portLabel->text()); + w->m_pCurrentOutputCardList->append(wid->deviceLabel->text()); + //qDebug() << index << "current output item ************" << item->text() <portLabel->text() << w->m_pOutputPortLabelList->count() ;//<< w->m_pOutputPortLabelList->at(i); + } + + for (int i=0;im_pInputWidget->m_pInputListWidget->count();i++) { + + QListWidgetItem *item = w->m_pInputWidget->m_pInputListWidget->item(i); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)w->m_pInputWidget->m_pInputListWidget->itemWidget(item); + int index; + for (it=w->cardMap.begin();it!=w->cardMap.end();) { + if (wid->deviceLabel->text() == it.value()) { + index = it.key(); + break; + } + ++it; + } + w->currentInputPortLabelMap.insertMulti(index,wid->portLabel->text()); + w->m_pCurrentInputPortLabelList->append(wid->portLabel->text()); + w->m_pCurrentInputCardList->append(wid->deviceLabel->text()); + //qDebug() << i << "current input item ************" << item->text() <portLabel->text() ; + } + w->deleteNotAvailableInputPort(); + w->addAvailableInputPort(); + w->deleteNotAvailableOutputPort(); + w->addAvailableOutputPort(); + + } + else { + pa_operation *o; + if (!(o = pa_context_get_card_info_by_index(c, index, card_cb, w))) { + w->show_error(QObject::tr("pa_context_get_card_info_by_index() failed").toUtf8().constData()); + return; + } + pa_operation_unref(o); + } + break; + } +} + +void UkmediaMainWidget::card_cb(pa_context *, const pa_card_info *i, int eol, void *userdata) { + UkmediaMainWidget *w = static_cast(userdata); + + if (eol < 0) { + if (pa_context_errno(w->context) == PA_ERR_NOENTITY) + return; + + w->show_error(QObject::tr("Card callback failure").toUtf8().constData()); + return; + } + + if (eol > 0) { +// dec_outstanding(w); + return; + } +// bool alreadyInclude = false; +// QMap ::iterator it; +// for(it=w->cardMap.begin();it!=w->cardMap.end();) { +// if (it.key() == i->index) { +// alreadyInclude = true; +// break; +// } +// } +// if (alreadyInclude) + w->cardMap.insert(i->index,i->name); + qDebug() << "update card" << i->name << i->index << i->ports << "card count: "<< w->cardMap.count()<active_profile; + w->updateCard(*i); + } + +void UkmediaMainWidget::updateCard(const pa_card_info &info) { + const char *name; + const char *description, *icon; + std::set profile_priorities; + + description = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_DESCRIPTION); + name = description ? description : info.name; + + icon = pa_proplist_gets(info.proplist, PA_PROP_DEVICE_ICON_NAME); + + this->hasSinks = false; + this->hasSources = false; + profile_priorities.clear(); + + QList profileName; + QMap profilePriorityMap; + for (pa_card_profile_info2 ** p_profile = info.profiles2; *p_profile != nullptr; ++p_profile) { + this->hasSinks = this->hasSinks || ((*p_profile)->n_sinks > 0); + this->hasSources = this->hasSources || ((*p_profile)->n_sources > 0); + profile_priorities.insert(*p_profile); + profileName.append((*p_profile)->name); + profilePriorityMap.insertMulti((*p_profile)->name,(*p_profile)->priority); + } + cardProfilePriorityMap.insertMulti(info.index,profilePriorityMap); + + //拔插耳机的时候删除端口 + QMap::iterator it; + for(it = outputPortNameMap.begin();it!=outputPortNameMap.end();) + { + if(it.key() == info.index) + { + + qDebug() << "remove output port name map index" << info.index << outputPortNameMap.count() << it.value(); + it = outputPortNameMap.erase(it); + continue; + } + ++it; + } + for(it = outputPortLabelMap.begin();it!=outputPortLabelMap.end();) + { + if(it.key() == info.index) + { + QString removePortLabel = it.value(); + QMap::iterator removeProfileMap; + for (removeProfileMap = profileNameMap.begin();removeProfileMap!= profileNameMap.end();) { + if (removeProfileMap.key() == removePortLabel) { + removeProfileMap = profileNameMap.erase(removeProfileMap); + continue; + } + ++removeProfileMap; + } + + it = outputPortLabelMap.erase(it); + + continue; + } + ++it; + } + for(it = inputPortNameMap.begin();it!=inputPortNameMap.end();) + { + if(it.key() == info.index) + { + it = inputPortNameMap.erase(it); + //qDebug() << "remove input port map index" << info.index << inputPortNameMap.count(); + continue; + } + ++it; + } + for(it = inputPortLabelMap.begin();it!=inputPortLabelMap.end();) + { + if(it.key() == info.index) + { + QString removePortLabel = it.value(); + QMap::iterator removeProfileMap; + for (removeProfileMap = inputPortProfileNameMap.begin();removeProfileMap!= inputPortProfileNameMap.end();) { + if (removeProfileMap.key() == removePortLabel) { + removeProfileMap = inputPortProfileNameMap.erase(removeProfileMap); + continue; + } + ++removeProfileMap; + } + it = inputPortLabelMap.erase(it); + //qDebug() << "remove input port Label map index" << info.index << inputPortLabelMap.count(); + continue; + } + ++it; + } + + this->ports.clear(); + for (uint32_t i = 0; i < info.n_ports; ++i) { + PortInfo p; + + p.name = info.ports[i]->name; + p.description = info.ports[i]->description; + p.priority = info.ports[i]->priority; + p.available = info.ports[i]->available; + p.direction = info.ports[i]->direction; + p.latency_offset = info.ports[i]->latency_offset; + if (info.ports[i]->profiles2 != nullptr) + for (pa_card_profile_info2 ** p_profile = info.ports[i]->profiles2; *p_profile != nullptr; ++p_profile) { + p.profiles.push_back((*p_profile)->name); + + } + if (p.direction == 1 && p.available != PA_PORT_AVAILABLE_NO) { + + outputPortNameMap.insertMulti(info.index,p.name); + outputPortLabelMap.insertMulti(info.index,p.description.data()); + + QList portProfileName; + for (auto p_profile : p.profiles) { + portProfileName.append(p_profile.data()); + profileNameMap.insertMulti(p.description.data(),p_profile.data()); + } + cardProfileMap.insertMulti(info.index,portProfileName); + } + else if (p.direction == 2 && p.available != PA_PORT_AVAILABLE_NO){ + inputPortNameMap.insertMulti(info.index,p.name); + inputPortLabelMap.insertMulti(info.index,p.description.data()); + for (auto p_profile : p.profiles) { + inputPortProfileNameMap.insertMulti(p.description.data(),p_profile.data()); + } + } + this->ports[p.name] = p; + } + + this->profiles.clear(); + + for (auto p_profile : profile_priorities) { + bool hasNo = false, hasOther = false; + std::map::iterator portIt; + QByteArray desc = p_profile->description; + + for (portIt = this->ports.begin(); portIt != this->ports.end(); portIt++) { + PortInfo port = portIt->second; + + if (std::find(port.profiles.begin(), port.profiles.end(), p_profile->name) == port.profiles.end()) + continue; + + if (port.available == PA_PORT_AVAILABLE_NO) + hasNo = true; + else { + hasOther = true; + break; + } + } + if (hasNo && !hasOther) + desc += tr(" (unplugged)").toUtf8().constData(); + + if (!p_profile->available) + desc += tr(" (unavailable)").toUtf8().constData(); + + this->profiles.push_back(std::pair(p_profile->name, desc)); + if (p_profile->n_sinks == 0 && p_profile->n_sources == 0) + this->noInOutProfile = p_profile->name; + } + + this->activeProfile = info.active_profile ? info.active_profile->name : ""; + + qDebug() << "this->active profile -----------------" << info.name <name << info.active_profile2->name; + /* Because the port info for sinks and sources is discontinued we need + * to update the port info for them here. */ + if (this->hasSinks) { + updatePorts(this, info, this->ports); + } +} + +void UkmediaMainWidget::show_error(const char *txt) { + char buf[256]; + + snprintf(buf, sizeof(buf), "%s: %s", txt, pa_strerror(pa_context_errno(context))); + qDebug() << "show error:" << QString::fromUtf8(buf); +} + +pa_context* UkmediaMainWidget::get_context() +{ + return context; +} + +void UkmediaMainWidget::updateRole(const pa_ext_stream_restore_info &info) +{ + if (strcmp(info.name, "sink-input-by-media-role:event") != 0) + return; + createEventRole(); +} + +UkmediaMainWidget::~UkmediaMainWidget() +{ +// delete player; +} + + +void UkmediaMainWidget::updatePorts(UkmediaMainWidget *w, const pa_card_info &info, std::map &ports) { + std::map::iterator it; + PortInfo p; + + w->updatePort = false; + w->m_pCurrentOutputPortLabelList->clear(); + w->currentOutputPortLabelMap.clear(); + w->currentInputPortLabelMap.clear(); + w->m_pCurrentInputPortLabelList->clear(); + int ii; + for (ii=0;iim_pOutputPortList->count();ii++) { + if (ii == w->m_pOutputPortList->count()) + break; + } + for (ii = 0;iim_pPrivOutputStreamList->count();ii++) { + if (ii == w->m_pPrivOutputStreamList->count()) + break; + } + + + w->m_pInputWidget->m_pInputPortCombobox->clear(); + w->m_pOutputWidget->m_pOutputPortCombobox->clear(); + w->m_pCurrentInputCardList->clear(); + + int i = 0; + w->m_pOutputPortList->clear(); + w->m_pOutputPortLabelList->clear(); + w->m_pInputPortLabelList->clear(); + w->m_pInputPortList->clear(); + for (auto & port : w->ports) { + QByteArray desc; + it = ports.find(port.first); + + if (it == ports.end()) + continue; + + p = it->second; + desc = p.description; + + if (p.available == PA_PORT_AVAILABLE_YES) { + desc += UkmediaMainWidget::tr(" (plugged in)").toUtf8().constData(); + + } + else if (p.available == PA_PORT_AVAILABLE_NO) { + if (p.name == "analog-output-speaker" || + p.name == "analog-input-microphone-internal") + desc += UkmediaMainWidget::tr(" (unavailable)").toUtf8().constData(); + else + desc += UkmediaMainWidget::tr(" (unplugged)").toUtf8().constData(); + } + + } + + QMap::iterator at; + QMap::iterator cardNameMap; + if (w->firstEntry == true) { + + for(at = w->outputPortLabelMap.begin();at!=w->outputPortLabelMap.end();) + { + + UkuiListWidgetItem *itemW = new UkuiListWidgetItem(w); + + QListWidgetItem * item = new QListWidgetItem(w->m_pOutputWidget->m_pOutputListWidget); + item->setSizeHint(QSize(200,50)); //QSize(120, 40) spacing: 12px; + w->m_pOutputWidget->m_pOutputListWidget->setItemWidget(item, itemW); + QString cardName; + for(cardNameMap = w->cardMap.begin();cardNameMap!=w->cardMap.end();) + { + if (cardNameMap.key() == at.key()) { + cardName = cardNameMap.value(); + break; + } + ++cardNameMap; + } + + itemW->setLabelText(at.value(),cardName); + w->m_pOutputWidget->m_pOutputListWidget->insertItem(i++,item); + + ++at; + } + for(at = w->inputPortLabelMap.begin();at!=w->inputPortLabelMap.end();) + { + UkuiListWidgetItem *itemW = new UkuiListWidgetItem(w); + + QListWidgetItem * item = new QListWidgetItem(w->m_pInputWidget->m_pInputListWidget); + item->setSizeHint(QSize(200,50)); //QSize(120, 40) spacing: 12px; + w->m_pInputWidget->m_pInputListWidget->setItemWidget(item, itemW); + QString cardName; + for(cardNameMap = w->cardMap.begin();cardNameMap!=w->cardMap.end();) + { + if (cardNameMap.key() == at.key()) { + cardName = cardNameMap.value(); + break; + } + ++cardNameMap; + } + //qDebug() << "aaaaaaaaaaaaaaainsert input list widget " << cardName << at.value() << at.key()<< w->cardMap.count(); + itemW->setLabelText(at.value(),cardName); + w->m_pInputWidget->m_pInputListWidget->insertItem(i++,item); + + ++at; + } + + } + else { + //记录上一次output label + for (i=0;im_pOutputWidget->m_pOutputListWidget->count();i++) { + + QListWidgetItem *item = w->m_pOutputWidget->m_pOutputListWidget->item(i); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)w->m_pOutputWidget->m_pOutputListWidget->itemWidget(item); + int index; + for (at=w->cardMap.begin();at!=w->cardMap.end();) { + if (wid->deviceLabel->text() == at.value()) { + index = at.key(); + break; + } + ++at; + } + w->currentOutputPortLabelMap.insertMulti(index,wid->portLabel->text()); + w->m_pCurrentOutputPortLabelList->append(wid->portLabel->text()); + w->m_pCurrentOutputCardList->append(wid->deviceLabel->text()); + //qDebug() << index << "current output item ************" << item->text() <portLabel->text() << w->m_pOutputPortLabelList->count() ;//<< w->m_pOutputPortLabelList->at(i); + } + + for (i=0;im_pInputWidget->m_pInputListWidget->count();i++) { + + QListWidgetItem *item = w->m_pInputWidget->m_pInputListWidget->item(i); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)w->m_pInputWidget->m_pInputListWidget->itemWidget(item); + int index; + for (at=w->cardMap.begin();at!=w->cardMap.end();) { + if (wid->deviceLabel->text() == at.value()) { + index = at.key(); + break; + } + ++at; + } + w->currentInputPortLabelMap.insertMulti(index,wid->portLabel->text()); + w->m_pCurrentInputPortLabelList->append(wid->portLabel->text()); + w->m_pCurrentInputCardList->append(wid->deviceLabel->text()); + //qDebug() << i << "current input item ************" << item->text() <portLabel->text() ; + } + + w->deleteNotAvailableOutputPort(); + w->addAvailableOutputPort(); + w->deleteNotAvailableInputPort(); + w->addAvailableInputPort(); + } + + if (w->m_pOutputWidget->m_pOutputListWidget->count() > 0) { + + w->firstEntry = false; + } + + if (w->firstEntry == false) { + w->m_pPrivOutputStreamList = w->m_pOutputPortList; + } +} + +void UkmediaMainWidget::deleteNotAvailableOutputPort() +{ + //删除不可用的输出端口 + QMap::iterator at; + QMap::iterator it; + int i; + for(i=0,it=currentOutputPortLabelMap.begin();it!=currentOutputPortLabelMap.end();) { + + int count = 0; + for(at = outputPortLabelMap.begin();at!=outputPortLabelMap.end();) + { + if (it.key() == at.key() ){ + if (it.value() == at.value()) { + break; + } + } + ++at; + count ++; + } + //没找到,需要删除 + if (count == outputPortLabelMap.count()) { + int index = indexOfOutputPortInOutputListWidget(it.value()); + if (index == -1) + return; + QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->takeItem(index); + m_pOutputWidget->m_pOutputListWidget->removeItemWidget(item); + m_pCurrentOutputPortLabelList->removeAt(index); + it = currentOutputPortLabelMap.erase(it); + continue; + } + ++it; + ++i; + } +} + +void UkmediaMainWidget::deleteNotAvailableInputPort() +{ + //删除不可用的输入端口 + QMap::iterator at; + QMap::iterator it; + int i; + for(i=0,it=currentInputPortLabelMap.begin();it!=currentInputPortLabelMap.end();) { + + int count = 0; + for(at = inputPortLabelMap.begin();at!=inputPortLabelMap.end();) + { + if (it.key() == at.key() ){ + if (it.value() == at.value()) { + break; + } + } + ++at; + count ++; + } + //没找到,需要删除 + if (count == inputPortLabelMap.count()) { + int index = indexOfInputPortInInputListWidget(it.value()); + if (index == -1) + return; + QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->takeItem(index); + m_pInputWidget->m_pInputListWidget->removeItemWidget(item); + m_pCurrentInputPortLabelList->removeAt(index); + it = currentInputPortLabelMap.erase(it); + continue; + } + ++it; + ++i; + } +} + +void UkmediaMainWidget::addAvailableOutputPort() +{ + QMap::iterator at; + QMap::iterator it; + QMap::iterator cardNameMap; + int i; + //增加端口 + for(at = outputPortLabelMap.begin();at!=outputPortLabelMap.end();) + { + for(i=0,it=currentOutputPortLabelMap.begin();it!=currentOutputPortLabelMap.end();i++) { + if ( at.key() == it.key() && at.value() == it.value()) { + + break; + } + ++it; + } + //需添加到list widget + if (i == currentOutputPortLabelMap.count()) { + UkuiListWidgetItem *itemW = new UkuiListWidgetItem(this); + + QListWidgetItem * item = new QListWidgetItem(m_pOutputWidget->m_pOutputListWidget); + item->setSizeHint(QSize(200,50)); //QSize(120, 40) spacing: 12px; + m_pOutputWidget->m_pOutputListWidget->setItemWidget(item, itemW); + QString cardName; + for(cardNameMap = cardMap.begin();cardNameMap!=cardMap.end();) + { + if (cardNameMap.key() == at.key()) { + cardName = cardNameMap.value(); + break; + } + ++cardNameMap; + } + itemW->setLabelText(at.value(),cardName); + m_pCurrentOutputPortLabelList->append(at.value()); + currentOutputPortLabelMap.insertMulti(at.key(),at.value()); + m_pOutputWidget->m_pOutputListWidget->insertItem(i++,item); + + } + + ++at; + } +} + +void UkmediaMainWidget::addAvailableInputPort() +{ + QMap::iterator it; + QMap::iterator at; + QMap::iterator cardNameMap; + int i; + //增加端口 + for(it = inputPortLabelMap.begin();it!=inputPortLabelMap.end();) + { + + for(i=0,at=currentInputPortLabelMap.begin();at!=currentInputPortLabelMap.end();i++) { + if ( at.key() == it.key() && at.value() == it.value()) { + break; + } + ++at; + } + //需添加到list widget + if (i == currentInputPortLabelMap.count()) { + UkuiListWidgetItem *itemW = new UkuiListWidgetItem(this); + + QListWidgetItem * item = new QListWidgetItem(m_pInputWidget->m_pInputListWidget); + item->setSizeHint(QSize(200,50)); //QSize(120, 40) spacing: 12px; + m_pInputWidget->m_pInputListWidget->setItemWidget(item, itemW); + QString cardName; + for(cardNameMap = cardMap.begin();cardNameMap!=cardMap.end();) + { + if (cardNameMap.key() == it.key()) { + cardName = cardNameMap.value(); + break; + } + ++cardNameMap; + } + + itemW->setLabelText(it.value(),cardName); + m_pCurrentOutputPortLabelList->append(it.value()); + currentInputPortLabelMap.insertMulti(it.key(),it.value()); + m_pOutputWidget->m_pOutputListWidget->insertItem(i++,item); + + } + + ++it; + } +} + +//查找指定声卡名的索引 +int UkmediaMainWidget::findCardIndex(QString cardName) +{ + QMap::iterator it; + + for(it=cardMap.begin();it!=cardMap.end();) { + if (it.value() == cardName) { + return it.key(); + } + ++it; + } + return -1; +} + +QString UkmediaMainWidget::findHighPriorityProfile(int index,QString profile) +{ + QMap>::iterator it; + int priority = 0; + QString profileName = ""; + QMap profileNameMap; + QMap::iterator tempMap; + for (it=cardProfilePriorityMap.begin();it!=cardProfilePriorityMap.end();) { + if (it.key() == index) { + profileNameMap = it.value(); + for (tempMap=profileNameMap.begin();tempMap!=profileNameMap.end();) { + if ( tempMap.key().contains(profile) && tempMap.value() > priority) { + priority = tempMap.value(); + profileName = tempMap.key(); + } + ++tempMap; + } + } + ++it; + } + return profileName; +} + +void UkmediaMainWidget::findOutputListWidgetItem(QString cardName,MateMixerStream *stream) +{ + MateMixerSwitch *portSwitch = findStreamPortSwitch(this,stream); + MateMixerSwitchOption *activePort = mate_mixer_switch_get_active_option(portSwitch); + const gchar *portLabel = mate_mixer_switch_option_get_label(activePort); + if (cardName == "") { + MateMixerDevice *device = mate_mixer_stream_get_device(stream); + cardName = mate_mixer_device_get_name(device); + } + for (int row=0;rowm_pOutputListWidget->count();row++) { + + QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(row); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); +// qDebug() << "findOutputListWidgetItem" << "card name:" << cardName << "portLabel:" << wid->portLabel->text() << "deviceLabel:" << wid->deviceLabel->text(); + if (wid->deviceLabel->text() == cardName && wid->portLabel->text() == portLabel) { + m_pOutputWidget->m_pOutputListWidget->blockSignals(true); +// qDebug() << "set output list widget" << row; + m_pOutputWidget->m_pOutputListWidget->setCurrentRow(row); + m_pOutputWidget->m_pOutputListWidget->blockSignals(false); + break; + } + } +} + +void UkmediaMainWidget::findInputListWidgetItem(QString cardName,MateMixerStream *stream) +{ + MateMixerSwitch *portSwitch = findStreamPortSwitch(this,stream); + MateMixerSwitchOption *activePort = mate_mixer_switch_get_active_option(portSwitch); + + const gchar *portLabel = mate_mixer_switch_option_get_label(activePort); + + for (int row=0;rowm_pInputListWidget->count();row++) { + QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(row); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); + qDebug() << "findInputListWidgetItem" << "card name:" << cardName << "portLabel:" << wid->portLabel->text() << "deviceLabel:" << wid->deviceLabel->text() << "port" << portLabel; + if (wid->deviceLabel->text() == cardName && wid->portLabel->text() == portLabel) { + m_pInputWidget->m_pInputListWidget->blockSignals(true); + m_pInputWidget->m_pInputListWidget->setCurrentRow(row); + qDebug() << "set input list widget" << row; + m_pInputWidget->m_pInputListWidget->blockSignals(false); + break; + } + } +} + +bool UkmediaMainWidget::inputCardListContainBluetooth() +{ + for (int i=0;icount();i++) { + QString cardName = m_pInputCardNameList->at(i); + if (strstr(cardName.toLocal8Bit().data(),"bluez")) + return true; + } + return false; +} + +QString UkmediaMainWidget::blueCardName() +{ + for (int i=0;icount();i++) { + QString cardName = m_pInputCardNameList->at(i); + if (strstr(cardName.toLocal8Bit().data(),"bluez")) + return cardName; + } + return ""; +} + +int UkmediaMainWidget::indexOfOutputPortInOutputListWidget(QString portName) +{ + for (int row=0;rowm_pOutputListWidget->count();row++) { + + QListWidgetItem *item = m_pOutputWidget->m_pOutputListWidget->item(row); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pOutputWidget->m_pOutputListWidget->itemWidget(item); + if (wid->portLabel->text() == portName) { + return row; + } + } + return -1; +} + +int UkmediaMainWidget::indexOfInputPortInInputListWidget(QString portName) +{ + for (int row=0;rowm_pInputListWidget->count();row++) { + + QListWidgetItem *item = m_pInputWidget->m_pInputListWidget->item(row); + UkuiListWidgetItem *wid = (UkuiListWidgetItem *)m_pInputWidget->m_pInputListWidget->itemWidget(item); + if (wid->portLabel->text() == portName) { + return row; + } + } + return -1; +} + +/* + 记录输入stream的card name +*/ +void UkmediaMainWidget::inputStreamMapCardName (QString streamName,QString cardName) +{ + if (inputCardStreamMap.count() == 0) { + inputCardStreamMap.insertMulti(streamName,cardName); + } + QMap::iterator it; + + for (it=inputCardStreamMap.begin();it!=inputCardStreamMap.end();) { + if (it.value() == cardName) { + break; + } + if (it == inputCardStreamMap.end()-1) { + qDebug() << "inputCardSreamMap " << streamName << cardName; + inputCardStreamMap.insertMulti(streamName,cardName); + } + ++it; + } +} + +/* + 记录输出stream的card name +*/ +void UkmediaMainWidget::outputStreamMapCardName(QString streamName, QString cardName) +{ + if (outputCardStreamMap.count() == 0) { + outputCardStreamMap.insertMulti(streamName,cardName); + } + QMap::iterator it; + + for (it=outputCardStreamMap.begin();it!=outputCardStreamMap.end();) { + if (it.value() == cardName) { + break; + } + if (it == outputCardStreamMap.end()-1) { + qDebug() << "outputCardStreamMap " << streamName << cardName; + outputCardStreamMap.insertMulti(streamName,cardName); + } + ++it; + } +} + +/* + 找输入stream对应的card name +*/ +QString UkmediaMainWidget::findInputStreamCardName(QString streamName) +{ + QString cardName; + QMap::iterator it; + for (it=inputCardStreamMap.begin();it!=inputCardStreamMap.end();) { + if (it.key() == streamName) { + cardName = it.value(); + qDebug() << "findInputStreamCardName:" << cardName; + break; + } + ++it; + } + return cardName; +} + +/* + 找输出stream对应的card name +*/ +QString UkmediaMainWidget::findOutputStreamCardName(QString streamName) +{ + QString cardName; + QMap::iterator it; + for (it=outputCardStreamMap.begin();it!=outputCardStreamMap.end();) { + if (it.key() == streamName) { + cardName = it.value(); + break; + } + ++it; + } + return cardName; +} + diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_main_widget.h ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_main_widget.h --- ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_main_widget.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_main_widget.h 2021-05-20 13:08:14.000000000 +0000 @@ -1,3 +1,4 @@ + /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd. @@ -24,6 +25,7 @@ #include "ukmedia_output_widget.h" #include "ukmedia_input_widget.h" #include "ukmedia_sound_effects_widget.h" +#include "ukui_list_widget_item.h" #include #include #include @@ -36,6 +38,12 @@ extern "C" { #include #include +#include +#include +#include +#include +#include +#include } #include #include @@ -43,6 +51,8 @@ #include #include #include +#include +#include #define UKUI_THEME_SETTING "org.ukui.style" #define UKUI_THEME_NAME "style-name" @@ -59,9 +69,12 @@ #define FILENAME_KEY "filename" #define NAME_KEY "name" -#define KEY_SOUNDS_SCHEMA "org.mate.sound" +#define KEY_SOUNDS_SCHEMA "org.ukui.sound" #define UKUI_SWITCH_SETTING "org.ukui.session" -#define UKUI_BOOT_MUSIC_KEY "boot-music" +#define UKUI_STARTUP_MUSIC_KEY "startup-music" +#define UKUI_POWEROFF_MUSIC_KEY "poweroff-music" +#define UKUI_LOGOUT_MUSIC_KEY "logout-music" +#define UKUI_WAKEUP_MUSIC_KEY "weakup-music" #define EVENT_SOUNDS_KEY "event-sounds" #define INPUT_SOUNDS_KEY "input-feedback-sounds" @@ -87,6 +100,20 @@ GVC_LEVEL_SCALE_LINEAR, GVC_LEVEL_SCALE_LOG } LevelScale; + +class PortInfo { +public: + + QByteArray name; + QByteArray description; + uint32_t priority; + int available; + int direction; + int64_t latency_offset; + std::vector profiles; + +}; + class UkmediaMainWidget : public QWidget { Q_OBJECT @@ -94,9 +121,17 @@ public: UkmediaMainWidget(QWidget *parent = nullptr); ~UkmediaMainWidget(); + + static int connectContext(gpointer userdata); static int caProplistMergeAp(ca_proplist *p, va_list ap); static int caPlayForWidget(UkmediaMainWidget *w, uint32_t id, ...); static int caProplistSetForWidget(ca_proplist *p, UkmediaMainWidget *widget); + + QPixmap drawDarkColoredPixmap(const QPixmap &source); + QPixmap drawLightColoredPixmap(const QPixmap &source); + void updateProfileOption(); + void alertIconButtonSetIcon(bool state,int value); + void createAlertSound(UkmediaMainWidget *w); void inputVolumeDarkThemeImage(int value,bool status); void outputVolumeDarkThemeImage(int value,bool status); int getInputVolume(); @@ -193,9 +228,51 @@ static gboolean customThemeDirIsEmpty (void); static MateMixerSwitch *findStreamPortSwitch (UkmediaMainWidget *widget,MateMixerStream *stream); static MateMixerSwitch *findDeviceProfileSwitch (UkmediaMainWidget *widget,MateMixerDevice *device); + static void onSwitchActiveOptionNotify (MateMixerSwitch *swtch,GParamSpec *pspec,UkmediaMainWidget *w); static void onDeviceProfileActiveOptionNotify (MateMixerDeviceSwitch *swtch,GParamSpec *pspec,UkmediaMainWidget *w); static gchar *deviceStatus (MateMixerDevice *device); static void updateDeviceInfo (UkmediaMainWidget *w, MateMixerDevice *device); + void updateOutputDevicePort(); + void updateInputDevicePort(); + static void onInputSwitchActiveOptionNotify (MateMixerSwitch *swtch,GParamSpec *pspec,UkmediaMainWidget *w); + static void onOutputSwitchActiveOptionNotify (MateMixerSwitch *swtch,GParamSpec *pspec,UkmediaMainWidget *w); + + //为一些不能更改提示音音量的机器做一些初始化操作 + void executeVolumeUpdate(bool status); + pa_context* get_context(void); + void show_error(const char *txt); + static void context_state_callback(pa_context *c, void *userdata); + gboolean connect_to_pulse(gpointer userdata); + void setConnectingMessage(const char *string); + void createEventRole(); + void updateRole(const pa_ext_stream_restore_info &info); + static void ext_stream_restore_read_cb(pa_context *,const pa_ext_stream_restore_info *i,int eol,void *userdata); + static void ext_stream_restore_subscribe_cb(pa_context *c, void *userdata); + static void subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t index, void *userdata); + void updateCard(const pa_card_info &info); + static void card_cb(pa_context *, const pa_card_info *i, int eol, void *userdata); + + static void updatePorts(UkmediaMainWidget *w,const pa_card_info &info, std::map &ports); + + void deleteNotAvailableOutputPort(); + void deleteNotAvailableInputPort(); + void addAvailableOutputPort(); + void addAvailableInputPort(); + int findCardIndex(QString cardName); + QString findHighPriorityProfile(int index,QString profile); + void findOutputListWidgetItem(QString cardName,MateMixerStream *stream); + void findInputListWidgetItem(QString cardName,MateMixerStream *stream); + bool inputCardListContainBluetooth(); + int indexOfOutputPortInOutputListWidget(QString portName); + int indexOfInputPortInInputListWidget(QString portName); + void inputStreamMapCardName(QString streamName,QString cardName); + void outputStreamMapCardName(QString streamName,QString cardName); + QString findInputStreamCardName(QString streamName); + QString findOutputStreamCardName(QString streamName); + void setOutputListWidgetRow(); //设置输出设备 + bool exitBluetoochDevice(); + QString blueCardName(); //记录蓝牙声卡名称 + Q_SIGNALS: void appVolumeChangedSignal(bool is_mute,int volume,const QString app_name); @@ -208,7 +285,10 @@ void outputWidgetSliderChangedSlot(int value); void inputWidgetSliderChangedSlot(int value); void ukuiThemeChangedSlot(const QString &); - void bootButtonSwitchChangedSlot(bool status); + void startupButtonSwitchChangedSlot(bool status); + void poweroffButtonSwitchChangedSlot(bool status); + void logoutMusicButtonSwitchChangedSlot(bool status); + void wakeButtonSwitchChangedSlot(bool status); void alertSoundButtonSwitchChangedSlot(bool status); void bootMusicSettingsChanged(); void inputPortComboxChangedSlot(int index); @@ -216,8 +296,15 @@ void windowClosedComboboxChangedSlot(int index); void volumeChangedComboboxChangeSlot(int index); void settingMenuComboboxChangedSlot(int index); -// void profileComboboxChangedSlot(int index); -// void selectComboboxChangedSlot(int index); + void profileComboboxChangedSlot(int index); + void selectComboboxChangedSlot(int index); + void inputMuteButtonSlot(); + void outputMuteButtonSlot(); + void alertVolumeSliderChangedSlot(int value); + void alertSoundVolumeChangedSlot(); + void outputListWidgetCurrentRowChangedSlot(int row); + void inputListWidgetCurrentRowChangedSlot(int row); + private: UkmediaInputWidget *m_pInputWidget; UkmediaOutputWidget *m_pOutputWidget; @@ -230,6 +317,8 @@ MateMixerStreamControl *m_pOutputBarStreamControl; MateMixerStreamControl *m_pInputBarStreamControl; MateMixerStreamControl *m_pControl; + MateMixerStreamControl *m_pMediaRoleControl; + MateMixerStreamControl *m_pPrivInputControl; MateMixerStream *m_pStream; MateMixerDevice *m_pDevice; MateMixerSwitch *m_pSwitch; @@ -237,20 +326,37 @@ QStringList *m_pSoundList; QStringList *m_pThemeDisplayNameList; QStringList *m_pThemeNameList; + QStringList *m_pDeviceLabelList; QStringList *m_pDeviceNameList; + QStringList *m_pInputDeviceLabelList; QStringList *m_pAppNameList; QStringList *m_pOutputStreamList; + QStringList *m_pPrivOutputStreamList; QStringList *m_pInputStreamList; QStringList *m_pAppVolumeList; QStringList *m_pStreamControlList; QStringList *m_pInputPortList; QStringList *m_pOutputPortList; + QStringList *m_pOutputPortLabelList; + QStringList *m_pInputPortLabelList; QStringList *m_pProfileNameList; - + QStringList *m_pSoundThemeList; + QStringList *m_pSoundThemeDirList; + QStringList *m_pSoundThemeXmlNameList; + QStringList *m_pListWidgetLabelList; + + QStringList *m_pCurrentOutputCardList; + QStringList *m_pOutputCardList; + QStringList *m_pCurrentOutputPortLabelList; + QStringList *m_pCurrentInputPortLabelList; + QStringList *m_pCurrentInputCardList; + QStringList *m_pInputCardList; QStringList *m_pSoundNameList; QStringList *eventList; QStringList *eventIdNameList; + QStringList *m_pCardNameList; + QStringList *m_pInputCardNameList; QString m_pDeviceStr; GSettings *m_pSoundSettings; @@ -265,6 +371,42 @@ QString mThemeName; bool m_hasMusic; bool firstEnterSystem = true; + + const gchar* m_privOutputPortLabel = ""; + QByteArray role; + QByteArray device; + pa_channel_map channelMap; + pa_cvolume volume; + pa_context* context ; + pa_mainloop_api* api; + pa_ext_stream_restore_info info; + + int callBackCount = 0; + bool firstEntry = true; + bool hasSinks; + bool hasSources; + QByteArray activeProfile; + QByteArray noInOutProfile; + QByteArray lastActiveProfile; + std::map ports; + std::vector< std::pair > profiles; + QMap cardMap; + QMap outputPortNameMap; + QMap inputPortNameMap; + QMap outputPortLabelMap; + QMap currentOutputPortLabelMap; + QMap currentInputPortLabelMap; + QMap inputPortLabelMap; + QMap profileNameMap; + QMap inputPortProfileNameMap; + QMap> cardProfileMap; + QMap> cardProfilePriorityMap; + QMap inputCardStreamMap; + QMap outputCardStreamMap; + bool updatePort = true; + bool setDefaultstream = true; + int reconnectTime; + QTimer *time; }; #endif // WIDGET_H diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_output_widget.cpp ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_output_widget.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_output_widget.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_output_widget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -18,6 +18,7 @@ * */ #include "ukmedia_output_widget.h" +#include "ukui_list_widget_item.h" #include #include AudioSlider::AudioSlider(QWidget *parent) @@ -33,7 +34,26 @@ UkmediaOutputWidget::UkmediaOutputWidget(QWidget *parent) : QWidget(parent) { // QFILEDEVICE_H + m_pOutputListWidget = new QListWidget(this); + m_pOutputListWidget->setFixedHeight(250); + m_pOutputListWidget->setStyleSheet( + + "QListWidget{" + "background-color:palette(base);" + "padding-left:8;" + "padding-right:20;" + "padding-top:8;" + "padding-bottom:8;}" + "QListWidget::item{" + "border-radius:6px;}" + /**列表项扫过*/ + "QListWidget::item:hover{" + "background-color:rgba(55,144,250,0.5);}" + /**列表项选中*/ + "QListWidget::item::selected{" + "background-color:rgba(55,144,250,1);" + "border-width:0;}"); //加载qss样式文件 QFile QssFile("://combox.qss"); QssFile.open(QFile::ReadOnly); @@ -61,10 +81,10 @@ m_pOutputPortWidget->setFrameShape(QFrame::Shape::Box); //设置大小 - m_pOutputWidget->setMinimumSize(550,203); - m_pOutputWidget->setMaximumSize(960,203); - m_pOutputDeviceWidget->setMinimumSize(550,50); - m_pOutputDeviceWidget->setMaximumSize(960,50); + m_pOutputWidget->setMinimumSize(550,422); + m_pOutputWidget->setMaximumSize(960,422); + m_pOutputDeviceWidget->setMinimumSize(550,319); + m_pOutputDeviceWidget->setMaximumSize(960,319); m_pMasterVolumeWidget->setMinimumSize(550,50); m_pMasterVolumeWidget->setMaximumSize(960,50); m_pChannelBalanceWidget->setMinimumSize(550,50); @@ -76,54 +96,68 @@ m_pOutputLabel = new QLabel(tr("Output"),this); m_pOutputLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - m_pOutputDeviceLabel = new QLabel(tr("Output Device"),m_pOutputWidget); + //~ contents_path /audio/Output Device + m_pOutputDeviceLabel = new QLabel(tr("Output Device:"),m_pOutputWidget); m_pOutputDeviceCombobox = new QComboBox(m_pOutputDeviceWidget); + m_pOutputDeviceCombobox->setFixedWidth(300); + m_pOutputDeviceCombobox->hide(); + //~ contents_path /audio/Master Volume m_pOpVolumeLabel = new QLabel(tr("Master Volume"),m_pMasterVolumeWidget); m_pOutputIconBtn = new UkuiButtonDrawSvg(m_pMasterVolumeWidget); m_pOpVolumeSlider = new AudioSlider(m_pMasterVolumeWidget); m_pOpVolumePercentLabel = new QLabel(m_pMasterVolumeWidget); + //~ contents_path /audio/Balance m_pOpBalanceLabel = new QLabel(tr("Balance"),m_pChannelBalanceWidget); m_pLeftBalanceLabel = new QLabel(tr("Left"),m_pChannelBalanceWidget); - m_pOpBalanceSlider = new UkmediaVolumeSlider(m_pChannelBalanceWidget); + m_pOpBalanceSlider = new UkmediaVolumeSlider(m_pChannelBalanceWidget,true); m_pRightBalanceLabel = new QLabel(tr("Right"),m_pChannelBalanceWidget); m_pOutputPortLabel = new QLabel(tr("Connector"),m_pOutputPortWidget); m_pOutputPortCombobox = new QComboBox(m_pOutputPortWidget); + //~ contents_path /audio/Profile m_pProfileLabel = new QLabel(tr("Profile"),m_pProfileWidget); m_pProfileCombobox = new QComboBox(m_pProfileWidget); m_pProfileCombobox->setMinimumSize(50,32); m_pProfileCombobox->setMaximumSize(900,32); m_pselectWidget->setMinimumSize(550,50); m_pselectWidget->setMaximumSize(960,50); + //~ contents_path /audio/Card m_pSelectDeviceLabel = new QLabel(tr("Card"),m_pselectWidget); m_pSelectCombobox = new QComboBox(m_pselectWidget); m_pProfileLabel->setFixedSize(115,24); + m_pProfileLabel->setFixedSize(150,32); - m_pOpBalanceSlider->setStyle(new CustomStyle()); m_pOpVolumeSlider->setOrientation(Qt::Horizontal); m_pOpBalanceSlider->setOrientation(Qt::Horizontal); m_pOpVolumeSlider->setRange(0,100); m_pOutputIconBtn->setFocusPolicy(Qt::NoFocus); //输出设备添加布局 - QHBoxLayout *outputDeviceLayout = new QHBoxLayout(m_pOutputDeviceWidget); - m_pOutputLabel->setFixedSize(115,18); +// QHBoxLayout *noOutputDeviceLayout = new QHBoxLayout(); +// noOutputDeviceLayout->addWidget(m_pNoAvailableOutputLabel); +// m_pOutputDeviceWidget->setLayout(noOutputDeviceLayout); + + QVBoxLayout *outputDeviceLayout = new QVBoxLayout(); +// m_pOutputDeviceLabel->setFixedSize(115,24); + m_pOutputDeviceLabel->setFixedSize(150,32); m_pOutputDeviceCombobox->setMinimumSize(50,32); m_pOutputDeviceCombobox->setMaximumSize(900,32); - - m_pOutputDeviceLabel->setFixedSize(115,24); - outputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); outputDeviceLayout->addWidget(m_pOutputDeviceLabel); - outputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - outputDeviceLayout->addWidget(m_pOutputDeviceCombobox); - outputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - outputDeviceLayout->setSpacing(0); + outputDeviceLayout->addWidget(m_pOutputListWidget); + +// outputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); +// outputDeviceLayout->addWidget(m_pOutputDeviceLabel); +// outputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); +// outputDeviceLayout->addWidget(m_pOutputDeviceCombobox); +// outputDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); +// outputDeviceLayout->setSpacing(0); m_pOutputDeviceWidget->setLayout(outputDeviceLayout); - outputDeviceLayout->layout()->setContentsMargins(0,0,0,0); + outputDeviceLayout->layout()->setContentsMargins(16,14,16,14); + //主音量添加布局 QHBoxLayout *masterLayout = new QHBoxLayout(m_pMasterVolumeWidget); - m_pOpVolumeLabel->setFixedSize(115,24); + m_pOpVolumeLabel->setFixedSize(150,32); m_pOutputIconBtn->setFixedSize(24,24); m_pOpVolumeSlider->setFixedHeight(20); - m_pOpVolumePercentLabel->setFixedSize(40,24); + m_pOpVolumePercentLabel->setFixedSize(55,24); masterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); masterLayout->addWidget(m_pOpVolumeLabel); masterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); @@ -132,25 +166,25 @@ masterLayout->addWidget(m_pOpVolumeSlider); masterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); masterLayout->addWidget(m_pOpVolumePercentLabel); - masterLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + masterLayout->addItem(new QSpacerItem(10,20,QSizePolicy::Fixed)); masterLayout->setSpacing(0); m_pMasterVolumeWidget->setLayout(masterLayout); m_pMasterVolumeWidget->layout()->setContentsMargins(0,0,0,0); //声道平衡添加布局 QHBoxLayout *soundLayout = new QHBoxLayout(m_pChannelBalanceWidget); - m_pOpBalanceLabel->setFixedSize(115,24); - m_pLeftBalanceLabel->setFixedSize(24,24); + m_pOpBalanceLabel->setFixedSize(150,32); + m_pLeftBalanceLabel->setFixedSize(36,24); m_pOpBalanceSlider->setFixedHeight(20); - m_pRightBalanceLabel->setFixedSize(36,24); + m_pRightBalanceLabel->setFixedSize(55,28); soundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); soundLayout->addWidget(m_pOpBalanceLabel); soundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); soundLayout->addWidget(m_pLeftBalanceLabel); - soundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + soundLayout->addItem(new QSpacerItem(4,20,QSizePolicy::Fixed)); soundLayout->addWidget(m_pOpBalanceSlider); soundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); soundLayout->addWidget(m_pRightBalanceLabel); - soundLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + soundLayout->addItem(new QSpacerItem(10,20,QSizePolicy::Fixed)); soundLayout->setSpacing(0); m_pChannelBalanceWidget->setLayout(soundLayout); m_pChannelBalanceWidget->layout()->setContentsMargins(0,0,0,0); @@ -158,8 +192,7 @@ QHBoxLayout *outputPortLayout = new QHBoxLayout(m_pOutputPortWidget); m_pOutputPortCombobox->setMinimumSize(50,32); m_pOutputPortCombobox->setMaximumSize(900,32); - - m_pOutputPortLabel->setFixedSize(115,24); + m_pOutputPortLabel->setFixedSize(150,32); outputPortLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); outputPortLayout->addWidget(m_pOutputPortLabel); outputPortLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); @@ -171,7 +204,7 @@ //选择的设备布局 QHBoxLayout *pSelectDeviceLayout = new QHBoxLayout(); - m_pSelectDeviceLabel->setFixedSize(115,24); + m_pSelectDeviceLabel->setFixedSize(150,32); m_pSelectCombobox->setMinimumSize(50,32); m_pSelectCombobox->setMaximumSize(900,32); pSelectDeviceLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); @@ -194,19 +227,20 @@ profileLayout->setSpacing(0); m_pProfileWidget->setLayout(profileLayout); profileLayout->layout()->setContentsMargins(0,0,0,0); - m_pProfileWidget->setVisible(false); //进行整体布局 - m_pVlayout = new QVBoxLayout(m_pOutputWidget); + m_pVlayout = new QVBoxLayout; + m_pVlayout->addWidget(m_pOutputDeviceWidget); m_pVlayout->addWidget(m_pMasterVolumeWidget); - m_pVlayout->addWidget(m_pselectWidget); +// m_pVlayout->addWidget(m_pselectWidget); // m_pVlayout->addWidget(m_pProfileWidget); m_pVlayout->addWidget(m_pChannelBalanceWidget); m_pVlayout->setSpacing(1); m_pOutputWidget->setLayout(m_pVlayout); m_pOutputWidget->layout()->setContentsMargins(0,0,0,0); - + m_pselectWidget->hide(); + m_pProfileWidget->hide(); m_pOutputPortWidget->hide(); QVBoxLayout *vLayout1 = new QVBoxLayout(this); vLayout1->addWidget(m_pOutputLabel); @@ -220,53 +254,20 @@ //设置样式 m_pOutputLabel->setObjectName("m_pOutputLabel"); - m_pOpVolumeSlider->setStyleSheet("QSlider::groove:horizontal {" - "border: 0px solid #bbb; }" - "QSlider::sub-page:horizontal {" - "background: #3D6BE5;border-radius: 2px;" - "margin-top:8px;margin-bottom:9px;}" - "QSlider::add-page:horizontal {" - "background: rgba(52,70,80,90%);" - "border: 0px solid #777;" - "border-radius: 2px;" - "margin-top:8px;" - "margin-bottom:9px;}" - "QSlider::handle:horizontal {" - "width: 20px;" - "height: 20px;" - "background: #3D6BE5;" - "border-radius:10px;}"); - m_pOpBalanceSlider->setStyleSheet("QSlider::groove:horizontal {" - "border: 0px solid #bbb; }" - "QSlider::sub-page:horizontal {" - "background: #3D6BE5;border-radius: 2px;" - "margin-top:8px;margin-bottom:9px;}" - "QSlider::add-page:horizontal {" - "background: rgba(52,70,80,90%);" - "border: 0px solid #777;" - "border-radius: 2px;" - "margin-top:8px;" - "margin-bottom:9px;}" - "QSlider::handle:horizontal {" - "width: 20px;" - "height: 20px;" - "background: rgb(61,107,229);" - "border-radius:10px;}"); } void UkmediaOutputWidget::outputWidgetAddPort() { - m_pOutputWidget->setMinimumSize(550,254); - m_pOutputWidget->setMaximumSize(960,254); + m_pOutputWidget->setMinimumSize(550,505); + m_pOutputWidget->setMaximumSize(960,505); m_pVlayout->insertWidget(3,m_pOutputPortWidget); m_pOutputPortWidget->show(); } void UkmediaOutputWidget::outputWidgetRemovePort() { -// m_pVlayout->addSpacing(1); - m_pOutputWidget->setMinimumSize(550,203); - m_pOutputWidget->setMaximumSize(960,203); + m_pOutputWidget->setMinimumSize(550,454); + m_pOutputWidget->setMaximumSize(960,454); m_pVlayout->removeWidget(m_pOutputPortWidget); m_pOutputPortWidget->hide(); } diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_output_widget.h ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_output_widget.h --- ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_output_widget.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_output_widget.h 2021-04-14 01:27:20.000000000 +0000 @@ -30,7 +30,10 @@ #include #include #include "ukui_custom_style.h" +#include "ukui_list_widget_item.h" #include "customstyle.h" +#include + class AudioSlider : public QSlider { @@ -75,6 +78,7 @@ QFrame * m_pOutputPortWidget; QFrame *m_pProfileWidget; QFrame *m_pselectWidget; + QListWidget *m_pOutputListWidget; QLabel *m_pSelectDeviceLabel; QLabel *m_pProfileLabel; diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_sound_effects_widget.cpp ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_sound_effects_widget.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_sound_effects_widget.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_sound_effects_widget.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -30,77 +30,108 @@ UkmediaSoundEffectsWidget::UkmediaSoundEffectsWidget(QWidget *parent) : QWidget(parent) { m_pThemeWidget = new QFrame(this); - m_pShutDownWidget = new QFrame(this); - m_pLagoutWidget = new QFrame(this); + m_pAlertSoundWidget = new QFrame(this); m_pAlertSoundSwitchWidget = new QFrame(this); - m_pWindowClosedWidget = new QFrame(this); + m_pAlertSoundVolumeWidget = new QFrame(this); + m_pStartupMusicWidget = new QFrame(this); + m_pPoweroffMusicWidget = new QFrame(this); + m_pLagoutWidget = new QFrame(this); + m_pWakeupMusicWidget = new QFrame(this); m_pVolumeChangeWidget = new QFrame(this); - m_pSettingSoundWidget = new QFrame(this); m_pThemeWidget->setFrameShape(QFrame::Shape::Box); - m_pShutDownWidget->setFrameShape(QFrame::Shape::Box); + m_pAlertSoundWidget->setFrameShape(QFrame::Shape::Box); + m_pStartupMusicWidget->setFrameShape(QFrame::Shape::Box); m_pLagoutWidget->setFrameShape(QFrame::Shape::Box); m_pAlertSoundSwitchWidget->setFrameShape(QFrame::Shape::Box); - m_pWindowClosedWidget->setFrameShape(QFrame::Shape::Box); + m_pAlertSoundVolumeWidget->setFrameShape(QFrame::Shape::Box); + m_pWakeupMusicWidget->setFrameShape(QFrame::Shape::Box); m_pVolumeChangeWidget->setFrameShape(QFrame::Shape::Box); - m_pSettingSoundWidget->setFrameShape(QFrame::Shape::Box); + m_pPoweroffMusicWidget->setFrameShape(QFrame::Shape::Box); + //~ contents_path /audio/System Sound m_pSoundEffectLabel = new QLabel(tr("System Sound"),this); m_pSoundEffectLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); + //~ contents_path /audio/Sound Theme m_pSoundThemeLabel = new QLabel(tr("Sound Theme"),m_pThemeWidget); m_pSoundThemeCombobox = new QComboBox(m_pThemeWidget); - m_pShutdownlabel = new QLabel(tr("Alert Sound"),m_pShutDownWidget); - m_pShutdownCombobox = new QComboBox(m_pShutDownWidget); - m_pLagoutLabel = new QLabel(tr("Boot Music"),m_pLagoutWidget); + //~ contents_path /audio/Alert Sound + m_pShutdownlabel = new QLabel(tr("Alert Sound"),m_pAlertSoundWidget); + m_pAlertSoundCombobox = new QComboBox(m_pAlertSoundWidget); + //~ contents_path /audio/Alert Volume + m_pAlertSoundLabel = new QLabel(tr("Alert Volume"),m_pAlertSoundVolumeWidget); + m_pAlertVolumeLabel = new QLabel(m_pAlertSoundVolumeWidget); + m_pAlertSlider = new UkmediaVolumeSlider(m_pAlertSoundVolumeWidget); + m_pAlertIconBtn = new UkuiButtonDrawSvg(m_pAlertSoundVolumeWidget); + m_pAlertSlider->setRange(0,100); + QSize iconSize(24,24); + m_pAlertIconBtn->setFocusPolicy(Qt::NoFocus); +// m_pAlertIconBtn->setFlat(true); + m_pAlertIconBtn->setFixedSize(24,24); + m_pAlertIconBtn->setIconSize(iconSize); + m_pAlertSlider->setOrientation(Qt::Horizontal); + QPalette paleteAppIcon = m_pAlertIconBtn->palette(); + paleteAppIcon.setColor(QPalette::Highlight,Qt::transparent); + paleteAppIcon.setBrush(QPalette::Button,QBrush(QColor(1,1,1,0))); + m_pAlertIconBtn->setPalette(paleteAppIcon); +// m_pAlertIconBtn->setProperty("useIconHighlightEffect",true); +// m_pAlertIconBtn->setProperty("iconHighlightEffectMode",true); + + m_pAlertSoundSwitchLabel = new QLabel(tr("Beep Switch"),m_pAlertSoundSwitchWidget); + m_pPoweroffMusicLabel = new QLabel(tr("Poweroff Music"),m_pPoweroffMusicWidget); + m_pStartupMusicLabel = new QLabel(tr("Startup Music"),m_pStartupMusicWidget); + m_pWakeupMusicLabel = new QLabel(tr("Wakeup Music"),m_pWakeupMusicWidget); + m_pVolumeChangeLabel = new QLabel(tr("Volume Change"),m_pVolumeChangeWidget); + m_pLagoutLabel = new QLabel(tr("Logout Music"),m_pLagoutWidget); + m_pLagoutCombobox = new QComboBox(m_pLagoutWidget); - m_pBootButton = new SwitchButton(m_pLagoutWidget); - m_pWindowClosedCombobox = new QComboBox(m_pWindowClosedWidget); + m_pStartupButton = new SwitchButton(m_pStartupMusicWidget); + m_pLogoutButton = new SwitchButton(m_pLagoutWidget); + m_pWakeupMusicButton = new SwitchButton(m_pWakeupMusicWidget); + m_pPoweroffButton = new SwitchButton(m_pPoweroffMusicWidget); m_pVolumeChangeCombobox = new QComboBox(m_pVolumeChangeWidget); - m_pSettingSoundCombobox = new QComboBox(m_pSettingSoundWidget); - m_pAlertSoundSwitchLabel = new QLabel(tr("Beep Switch"),m_pAlertSoundSwitchWidget); m_pAlertSoundSwitchButton = new SwitchButton(m_pAlertSoundSwitchWidget); - m_pWindowClosedLabel = new QLabel(tr("Window Closed"),m_pWindowClosedWidget); - m_pVolumeChangeLabel = new QLabel(tr("Volume Change"),m_pVolumeChangeWidget); - m_pSettingSoundLabel = new QLabel(tr("Setting Menu"),m_pSettingSoundWidget); //设置大小 m_pThemeWidget->setMinimumSize(550,50); m_pThemeWidget->setMaximumSize(960,50); - m_pShutDownWidget->setMinimumSize(550,50); - m_pShutDownWidget->setMaximumSize(960,50); + m_pAlertSoundWidget->setMinimumSize(550,50); + m_pAlertSoundWidget->setMaximumSize(960,50); + m_pStartupMusicWidget->setMinimumSize(550,50); + m_pStartupMusicWidget->setMaximumSize(960,50); m_pLagoutWidget->setMinimumSize(550,50); m_pLagoutWidget->setMaximumSize(960,50); m_pAlertSoundSwitchWidget->setMinimumSize(550,50); m_pAlertSoundSwitchWidget->setMaximumSize(960,50); - m_pWindowClosedWidget->setMinimumSize(550,50); - m_pWindowClosedWidget->setMaximumSize(960,50); + m_pWakeupMusicWidget->setMinimumSize(550,50); + m_pWakeupMusicWidget->setMaximumSize(960,50); m_pVolumeChangeWidget->setMinimumSize(550,50); m_pVolumeChangeWidget->setMaximumSize(960,50); - m_pSettingSoundWidget->setMinimumSize(550,50); - m_pSettingSoundWidget->setMaximumSize(960,50); - - m_pSoundEffectLabel->setFixedSize(120,24); - m_pSoundThemeLabel->setFixedSize(115,24); - m_pShutdownlabel->setFixedSize(115,24); - m_pLagoutLabel->setFixedSize(115,24); - m_pWindowClosedLabel->setFixedSize(115,24); - m_pVolumeChangeLabel->setFixedSize(115,24); - m_pSettingSoundLabel->setFixedSize(115,24); + m_pPoweroffMusicWidget->setMinimumSize(550,50); + m_pPoweroffMusicWidget->setMaximumSize(960,50); + m_pAlertSoundVolumeWidget->setMinimumSize(550,50); + m_pAlertSoundVolumeWidget->setMaximumSize(960,50); + + m_pSoundEffectLabel->setFixedSize(150,32); + m_pSoundThemeLabel->setFixedSize(150,32); + m_pShutdownlabel->setFixedSize(150,32); + m_pLagoutLabel->setFixedSize(150,32); + m_pWakeupMusicLabel->setFixedSize(150,32); + m_pVolumeChangeLabel->setFixedSize(150,32); + m_pPoweroffMusicLabel->setFixedSize(150,32); m_pSoundThemeCombobox->setMinimumSize(50,32); m_pSoundThemeCombobox->setMaximumSize(900,32); - m_pShutdownCombobox->setMinimumSize(50,32); - m_pShutdownCombobox->setMaximumSize(900,32); + m_pAlertSoundCombobox->setMinimumSize(50,32); + m_pAlertSoundCombobox->setMaximumSize(900,32); m_pLagoutCombobox->setMinimumSize(50,32); m_pLagoutCombobox->setMaximumSize(900,32); - m_pWindowClosedCombobox->setMinimumSize(50,32); - m_pWindowClosedCombobox->setMaximumSize(900,32); + m_pVolumeChangeCombobox->setMinimumSize(50,32); m_pVolumeChangeCombobox->setMaximumSize(900,32); - m_pSettingSoundCombobox->setMinimumSize(50,32); - m_pSettingSoundCombobox->setMaximumSize(900,32); + //添加布局 QHBoxLayout *themeLayout = new QHBoxLayout(m_pThemeWidget); themeLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); @@ -112,23 +143,33 @@ m_pThemeWidget->setLayout(themeLayout); m_pThemeWidget->layout()->setContentsMargins(0,0,0,0); - QHBoxLayout *shutdownLayout = new QHBoxLayout(m_pShutDownWidget); - shutdownLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - shutdownLayout->addWidget(m_pShutdownlabel); - shutdownLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - shutdownLayout->addWidget(m_pShutdownCombobox); - shutdownLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - shutdownLayout->setSpacing(0); - m_pShutDownWidget->setLayout(shutdownLayout); - m_pShutDownWidget->layout()->setContentsMargins(0,0,0,0); + QHBoxLayout *AlertLayout = new QHBoxLayout(m_pAlertSoundWidget); + AlertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + AlertLayout->addWidget(m_pShutdownlabel); + AlertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + AlertLayout->addWidget(m_pAlertSoundCombobox); + AlertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + AlertLayout->setSpacing(0); + m_pAlertSoundWidget->setLayout(AlertLayout); + m_pAlertSoundWidget->layout()->setContentsMargins(0,0,0,0); + + //开机音乐设置开关 + QHBoxLayout *startupLayout = new QHBoxLayout(m_pStartupMusicWidget); + startupLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + startupLayout->addWidget(m_pStartupMusicLabel); + startupLayout->addWidget(m_pStartupButton); + startupLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + startupLayout->setSpacing(0); + m_pStartupMusicWidget->setLayout(startupLayout); + m_pStartupMusicWidget->layout()->setContentsMargins(0,0,0,0); - //开关机音乐设置开关 + //注销提示音布局 QHBoxLayout *lagoutLayout = new QHBoxLayout(m_pLagoutWidget); lagoutLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); lagoutLayout->addWidget(m_pLagoutLabel); lagoutLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Expanding)); // lagoutLayout->addWidget(m_pLagoutCombobox); - lagoutLayout->addWidget(m_pBootButton); + lagoutLayout->addWidget(m_pLogoutButton); lagoutLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); lagoutLayout->setSpacing(0); m_pLagoutWidget->setLayout(lagoutLayout); @@ -147,17 +188,34 @@ alertSoundLayout->setSpacing(0); m_pAlertSoundSwitchWidget->setLayout(alertSoundLayout); m_pAlertSoundSwitchWidget->layout()->setContentsMargins(0,0,0,0); + //提示音大小 + QHBoxLayout *alertLayout = new QHBoxLayout(m_pAlertSoundVolumeWidget); + m_pAlertSoundLabel->setFixedSize(150,32); + m_pAlertSlider->setFixedHeight(20); + m_pAlertVolumeLabel->setFixedSize(40,24); + alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + alertLayout->addWidget(m_pAlertSoundLabel); + alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + alertLayout->addWidget(m_pAlertIconBtn); + alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + alertLayout->addWidget(m_pAlertSlider); + alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + alertLayout->addWidget(m_pAlertVolumeLabel); + alertLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + alertLayout->setSpacing(0); + m_pAlertSoundVolumeWidget->setLayout(alertLayout); + m_pAlertSoundVolumeWidget->layout()->setContentsMargins(0,0,0,0); //窗口关闭提示音 - QHBoxLayout *windowClosedLayout = new QHBoxLayout(m_pWindowClosedWidget); - windowClosedLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - windowClosedLayout->addWidget(m_pWindowClosedLabel); - windowClosedLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - windowClosedLayout->addWidget(m_pWindowClosedCombobox); - windowClosedLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - windowClosedLayout->setSpacing(0); - m_pWindowClosedWidget->setLayout(windowClosedLayout); - m_pWindowClosedWidget->layout()->setContentsMargins(0,0,0,0); + QHBoxLayout *wakeupMusicLayout = new QHBoxLayout(m_pWakeupMusicWidget); + wakeupMusicLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + wakeupMusicLayout->addWidget(m_pWakeupMusicLabel); + wakeupMusicLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Expanding)); + wakeupMusicLayout->addWidget(m_pWakeupMusicButton); + wakeupMusicLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + wakeupMusicLayout->setSpacing(0); + m_pWakeupMusicWidget->setLayout(wakeupMusicLayout); + m_pWakeupMusicWidget->layout()->setContentsMargins(0,0,0,0); //音量改变提示音 QHBoxLayout *volumeChangedLayout = new QHBoxLayout(m_pVolumeChangeWidget); @@ -169,36 +227,42 @@ volumeChangedLayout->setSpacing(0); m_pVolumeChangeWidget->setLayout(volumeChangedLayout); m_pVolumeChangeWidget->layout()->setContentsMargins(0,0,0,0); - //设置菜单提示音 - QHBoxLayout *settingMenuLayout = new QHBoxLayout(m_pSettingSoundWidget); - settingMenuLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - settingMenuLayout->addWidget(m_pSettingSoundLabel); - settingMenuLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - settingMenuLayout->addWidget(m_pSettingSoundCombobox); - settingMenuLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); - settingMenuLayout->setSpacing(0); - m_pSettingSoundWidget->setLayout(settingMenuLayout); - m_pSettingSoundWidget->layout()->setContentsMargins(0,0,0,0); + //关机提示音 + QHBoxLayout *poweroffLayout = new QHBoxLayout(m_pPoweroffMusicWidget); + poweroffLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + poweroffLayout->addWidget(m_pPoweroffMusicLabel); + poweroffLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Expanding)); + poweroffLayout->addWidget(m_pPoweroffButton); + poweroffLayout->addItem(new QSpacerItem(16,20,QSizePolicy::Fixed)); + poweroffLayout->setSpacing(0); + m_pPoweroffMusicWidget->setLayout(poweroffLayout); + m_pPoweroffMusicWidget->layout()->setContentsMargins(0,0,0,0); //进行整体布局 - QVBoxLayout *vLayout = new QVBoxLayout(this); - vLayout->addWidget(m_pSoundEffectLabel); - vLayout->addItem(new QSpacerItem(16,14,QSizePolicy::Fixed)); - vLayout->addWidget(m_pLagoutWidget); - vLayout->addItem(new QSpacerItem(16,6,QSizePolicy::Fixed)); - vLayout->addWidget(m_pAlertSoundSwitchWidget); - - vLayout->addItem(new QSpacerItem(16,7,QSizePolicy::Fixed)); - vLayout->addWidget(m_pThemeWidget); - vLayout->addWidget(m_pShutDownWidget); + m_pSoundLayout = new QVBoxLayout(this); + m_pSoundLayout->addWidget(m_pSoundEffectLabel); + m_pSoundLayout->addItem(new QSpacerItem(16,14,QSizePolicy::Fixed)); + m_pSoundLayout->addWidget(m_pStartupMusicWidget); + m_pSoundLayout->addItem(new QSpacerItem(16,1,QSizePolicy::Fixed)); + m_pSoundLayout->addWidget(m_pPoweroffMusicWidget); + m_pSoundLayout->addItem(new QSpacerItem(16,1,QSizePolicy::Fixed)); + m_pSoundLayout->addWidget(m_pLagoutWidget); + m_pSoundLayout->addItem(new QSpacerItem(16,1,QSizePolicy::Fixed)); + m_pSoundLayout->addWidget(m_pWakeupMusicWidget); + + m_pSoundLayout->addItem(new QSpacerItem(16,6,QSizePolicy::Fixed)); + m_pSoundLayout->addWidget(m_pAlertSoundSwitchWidget); +// m_pSoundLayout->addWidget(m_pAlertSoundVolumeWidget); + m_pSoundLayout->addItem(new QSpacerItem(16,7,QSizePolicy::Fixed)); + m_pSoundLayout->addWidget(m_pThemeWidget); + m_pSoundLayout->addWidget(m_pAlertSoundWidget); // vLayout->addWidget(m_pWindowClosedWidget); - vLayout->addWidget(m_pVolumeChangeWidget); + m_pSoundLayout->addWidget(m_pVolumeChangeWidget); // vLayout->addWidget(m_pSettingSoundWidget); - this->setLayout(vLayout); - vLayout->setSpacing(1); + this->setLayout(m_pSoundLayout); + m_pSoundLayout->setSpacing(1); this->layout()->setContentsMargins(0,0,0,0); - m_pSettingSoundWidget->hide(); - m_pWindowClosedWidget->hide(); + m_pAlertSoundVolumeWidget->hide(); } UkmediaSoundEffectsWidget::~UkmediaSoundEffectsWidget() diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_sound_effects_widget.h ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_sound_effects_widget.h --- ukui-control-center-2.0.3/plugins/devices/audio/ukmedia_sound_effects_widget.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukmedia_sound_effects_widget.h 2021-05-20 13:08:14.000000000 +0000 @@ -24,8 +24,10 @@ #include #include #include +#include #include -#include "switchbutton.h" +#include "ukui_custom_style.h" +#include "SwitchButton/switchbutton.h" class UkuiMessageBox : public QMessageBox { @@ -46,12 +48,14 @@ private: QFrame *m_pThemeWidget; - QFrame *m_pShutDownWidget; + QFrame *m_pAlertSoundWidget; QFrame *m_pLagoutWidget; QFrame *m_pAlertSoundSwitchWidget; - QFrame *m_pWindowClosedWidget; + QFrame *m_pAlertSoundVolumeWidget; + QFrame *m_pWakeupMusicWidget; QFrame *m_pVolumeChangeWidget; - QFrame *m_pSettingSoundWidget; + QFrame *m_pStartupMusicWidget; + QFrame *m_pPoweroffMusicWidget; QString qss; QStyledItemDelegate *itemDelegate; @@ -60,18 +64,25 @@ QLabel *m_pShutdownlabel; QLabel *m_pLagoutLabel; QLabel *m_pAlertSoundSwitchLabel; - QLabel *m_pWindowClosedLabel; + QLabel *m_pAlertSoundLabel; + QLabel *m_pAlertVolumeLabel; + QLabel *m_pWakeupMusicLabel; QLabel *m_pVolumeChangeLabel; - QLabel *m_pSettingSoundLabel; + QLabel *m_pPoweroffMusicLabel; + QLabel *m_pStartupMusicLabel; QComboBox *m_pSoundThemeCombobox; - QComboBox *m_pShutdownCombobox; + QComboBox *m_pAlertSoundCombobox; QComboBox *m_pLagoutCombobox; - QComboBox *m_pWindowClosedCombobox; QComboBox *m_pVolumeChangeCombobox; - QComboBox *m_pSettingSoundCombobox; - SwitchButton *m_pBootButton; + QVBoxLayout *m_pSoundLayout; + SwitchButton *m_pStartupButton; + SwitchButton *m_pPoweroffButton; + SwitchButton *m_pLogoutButton; SwitchButton *m_pAlertSoundSwitchButton; + SwitchButton *m_pWakeupMusicButton; + UkmediaVolumeSlider *m_pAlertSlider; + UkuiButtonDrawSvg *m_pAlertIconBtn; }; #endif // UKMEDIASOUNDEFFECTSWIDGET_H diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukui_custom_style.cpp ukui-control-center-3.0.3/plugins/devices/audio/ukui_custom_style.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/ukui_custom_style.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukui_custom_style.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -23,16 +23,53 @@ #include #include #include +#include #include #include -UkmediaVolumeSlider::UkmediaVolumeSlider(QWidget *parent) +UkuiMediaSliderTipLabel::UkuiMediaSliderTipLabel(){ + setAttribute(Qt::WA_TranslucentBackground); +} + +UkuiMediaSliderTipLabel::~UkuiMediaSliderTipLabel(){ +} + +void UkuiMediaSliderTipLabel::paintEvent(QPaintEvent *e) +{ + QStyleOptionFrame opt; + initStyleOption(&opt); + QStylePainter p(this); +// p.setBrush(QBrush(QColor(0x1A,0x1A,0x1A,0x4C))); + p.setBrush(QBrush(QColor(0xFF,0xFF,0xFF,0x33))); + p.setPen(Qt::NoPen); + p.drawRoundedRect(this->rect(), 1, 1); + QPainterPath path; + path.addRoundedRect(opt.rect,6,6); + p.setRenderHint(QPainter::Antialiasing); + setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); + p.drawPrimitive(QStyle::PE_PanelTipLabel, opt); + this->setProperty("blurRegion", QRegion(QRect(0, 0, 1, 1))); + QLabel::paintEvent(e); +} + +UkmediaVolumeSlider::UkmediaVolumeSlider(QWidget *parent,bool needTip) { Q_UNUSED(parent); + if (needTip) { + state = needTip; + m_pTiplabel = new UkuiMediaSliderTipLabel(); + m_pTiplabel->setWindowFlags(Qt::ToolTip); + // qApp->installEventFilter(new AppEventFilter(this)); + m_pTiplabel->setFixedSize(52,30); + m_pTiplabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + } } void UkmediaVolumeSlider::mousePressEvent(QMouseEvent *ev) { + if (state) { + m_pTiplabel->show(); + } //注意应先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况 QSlider::mousePressEvent(ev); //获取鼠标的位置,这里并不能直接从ev中取值(因为如果是拖动的话,鼠标开始点击的位置没有意义了) @@ -48,11 +85,43 @@ QSlider::initStyleOption(option); } -UkmediaVolumeSlider::~UkmediaVolumeSlider() +void UkmediaVolumeSlider::leaveEvent(QEvent *e) +{ + if (state) { + m_pTiplabel->hide(); + } +} + +void UkmediaVolumeSlider::enterEvent(QEvent *e) +{ + if (state) { + m_pTiplabel->show(); + } +} + +void UkmediaVolumeSlider::paintEvent(QPaintEvent *e) { + QRect rect; + QStyleOptionSlider m_option; + QSlider::paintEvent(e); + if (state) { + + this->initStyleOption(&m_option); + rect = this->style()->subControlRect(QStyle::CC_Slider, &m_option,QStyle::SC_SliderHandle,this); + QPoint gPos = this->mapToGlobal(rect.topLeft()); + QString percent; + percent = QString::number(this->value()); + percent.append("%"); + m_pTiplabel->setText(percent); + m_pTiplabel->move(gPos.x()-(m_pTiplabel->width()/2)+9,gPos.y()-m_pTiplabel->height()-1); + } + } +UkmediaVolumeSlider::~UkmediaVolumeSlider() +{ +} void UkuiButtonDrawSvg::init(QImage img, QColor color) { diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukui_custom_style.h ukui-control-center-3.0.3/plugins/devices/audio/ukui_custom_style.h --- ukui-control-center-2.0.3/plugins/devices/audio/ukui_custom_style.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukui_custom_style.h 2021-04-14 01:27:20.000000000 +0000 @@ -24,17 +24,30 @@ #include #include #include +#include static QColor symbolic_color = Qt::gray; +class UkuiMediaSliderTipLabel:public QLabel +{ + public: + UkuiMediaSliderTipLabel(); + ~UkuiMediaSliderTipLabel(); +protected: + void paintEvent(QPaintEvent*); +}; + class UkmediaVolumeSlider : public QSlider { Q_OBJECT public: - UkmediaVolumeSlider(QWidget *parent = nullptr); +// UkmediaVolumeSlider(QWidget *parent = nullptr); + UkmediaVolumeSlider(QWidget *parent = nullptr,bool needTip = false); void initStyleOption(QStyleOptionSlider *option); ~UkmediaVolumeSlider(); - +private: + UkuiMediaSliderTipLabel *m_pTiplabel; + bool state = false; Q_SIGNALS: void silderPressedSignal(int); @@ -46,8 +59,13 @@ // m_displayLabel->move((this->width()-m_displayLabel->width())*this->value()/(this->maximum()-this->minimum()),3); QSlider::mouseMoveEvent(e); } + void leaveEvent(QEvent *e); + + void enterEvent(QEvent *e); + void paintEvent(QPaintEvent *e); }; + class UkuiButtonDrawSvg:public QPushButton { Q_OBJECT diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukui_list_widget_item.cpp ukui-control-center-3.0.3/plugins/devices/audio/ukui_list_widget_item.cpp --- ukui-control-center-2.0.3/plugins/devices/audio/ukui_list_widget_item.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukui_list_widget_item.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -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 "ukui_list_widget_item.h" + +#include +#include +#include +#include +//#include +#include + +UkuiListWidget::UkuiListWidget(QWidget *parent) : + QListWidget(parent) +{ + +} + +UkuiListWidget::~UkuiListWidget() +{ + +} + +UkuiListWidgetItem::UkuiListWidgetItem(QWidget *parent) : + QWidget(parent) +{ + this->setFixedSize(500,50); + + QVBoxLayout *vLayout = new QVBoxLayout; + + portLabel = new QLabel(this); + deviceLabel = new QLabel(this); + + portLabel->setFixedSize(600,20); + deviceLabel->setFixedSize(600,20); + vLayout->addWidget(portLabel); + vLayout->addWidget(deviceLabel); + this->setLayout(vLayout); + + this->show(); +} + +UkuiListWidgetItem::~UkuiListWidgetItem() +{ +} + +void UkuiListWidgetItem::setSelected(bool selected){ + if (selected) { + widget->setStyleSheet("QWidget{background: #3D6BE5; border-radius: 4px;}"); + } else { + widget->setStyleSheet("QListWidget::Item:hover{background:#FF3D6BE5;border-radius: 4px;}"); + } +} + + +void UkuiListWidgetItem::setLabelText(QString portLabel, QString deviceLabel){ + + this->portLabel->setText(portLabel); + this->deviceLabel->setText(deviceLabel); +} + +//void UkuiListWidgetItem::paintEvent(QPaintEvent *event) +//{ +// QStyleOption opt; +// opt.init(this); +// QPainter p(this); +//// double transparence = transparency * 255; +// QColor color = palette().color(QPalette::Base); +//// color.setAlpha(transparence); +// QBrush brush = QBrush(color); +// p.setBrush(brush); +// p.setPen(Qt::NoPen); +// QPainterPath path; +// opt.rect.adjust(0,0,0,0); +// path.addRoundedRect(opt.rect,6,6); +// p.setRenderHint(QPainter::Antialiasing); // 反锯齿; +// p.drawRoundedRect(opt.rect,6,6); +// setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); +// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +//// QWidget::paintEvent(event); +//} + diff -Nru ukui-control-center-2.0.3/plugins/devices/audio/ukui_list_widget_item.h ukui-control-center-3.0.3/plugins/devices/audio/ukui_list_widget_item.h --- ukui-control-center-2.0.3/plugins/devices/audio/ukui_list_widget_item.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/audio/ukui_list_widget_item.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,78 @@ +#ifndef UKUILISTWIDGETITEM_H +#define UKUILISTWIDGETITEM_H + + +/* -*- 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 +#include + +class UkuiListWidget : public QListWidget +{ + Q_OBJECT +public: + UkuiListWidget(QWidget *parent = nullptr); + ~UkuiListWidget(); +protected: + void paintEvent(QPaintEvent*event) { + int i; + for (i = 0 ;i < this->count();i++) { + QListWidgetItem *item = this->item(i); +// item->setTextColor(QColor(0,0,0,0)); + delete item; + } + QListWidget::paintEvent(event); + } + +}; + +class UkuiListWidgetItem : public QWidget +{ + Q_OBJECT + +public: + UkuiListWidgetItem(QWidget *parent = 0); + ~UkuiListWidgetItem(); + +public: + void setLabelText(QString portText,QString deviceLabel); +// void setLabelTextIsWhite(bool selected); + + void setSelected(bool selected); + +// QString text(); + + + QLabel * portLabel; + QLabel * deviceLabel; +protected: +// void paintEvent(QPaintEvent *event); +private: + QWidget * widget; + +}; + +#endif // UKUILISTWIDGETITEM_H diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetooth.cpp ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetooth.cpp --- ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetooth.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetooth.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,41 @@ +#include "bluetooth.h" + +#include + +Bluetooth::Bluetooth() : mFirstLoad(true) { + pluginName = tr("Bluetooth"); + pluginType = DEVICES; +} + +Bluetooth::~Bluetooth() { + if (!mFirstLoad) { +// delete pluginWidget; + } +} + +QString Bluetooth::get_plugin_name() { + return pluginName; +} + +int Bluetooth::get_plugin_type() { + return pluginType; +} + +QWidget *Bluetooth::get_plugin_ui() { + + if (mFirstLoad) { + mFirstLoad = false; + pluginWidget = new BlueToothMain; + } + return pluginWidget; +} + +void Bluetooth::plugin_delay_control() { + +} + +const QString Bluetooth::name() const { + return QStringLiteral("bluetooth"); +} + + diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetooth.h ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetooth.h --- ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetooth.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetooth.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,33 @@ +#ifndef BLUETOOTH_H +#define BLUETOOTH_H + +#include +#include + +#include "shell/interface.h" +#include "bluetoothmain.h" + +class Bluetooth : public QObject, CommonInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") + Q_INTERFACES(CommonInterface) +public: + Bluetooth(); + ~Bluetooth(); + + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + +private: + QString pluginName; + int pluginType; + BlueToothMain * pluginWidget; + bool mFirstLoad; + +}; + +#endif // BLUETOOTH_H diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetoothmain.cpp ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetoothmain.cpp --- ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetoothmain.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetoothmain.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,805 @@ +#include "bluetoothmain.h" + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +BlueToothMain::BlueToothMain(QWidget *parent) + : QMainWindow(parent) +{ + if(QGSettings::isSchemaInstalled("org.ukui.bluetooth")){ + settings = new QGSettings("org.ukui.bluetooth"); + + paired_device_address.clear(); + paired_device_address = settings->get("paired-device-address").toStringList(); + finally_connect_the_device = settings->get("finally-connect-the-device").toString(); + Default_Adapter = settings->get("adapter-address").toString(); + + qDebug() << "GSetting Value: " << Default_Adapter << finally_connect_the_device << paired_device_address; + } +// this->setMinimumSize(582,500); + + m_manager = new BluezQt::Manager(this); + job = m_manager->init(); + job->exec(); + qDebug() << m_manager->isOperational() << m_manager->isBluetoothBlocked(); + + if(m_manager->adapters().size()){ + for(int i = 0; i < m_manager->adapters().size(); i++){ + if(m_manager->adapters().at(i)->address() == "00:1A:7D:DA:71:13"){ + adapter_address_list.insert(0,m_manager->adapters().at(i)->address()); + adapter_name_list.insert(0,m_manager->adapters().at(i)->name()); + }else{ + adapter_address_list << m_manager->adapters().at(i)->address(); + adapter_name_list << m_manager->adapters().at(i)->name(); + } + } + } + + adapterChanged(); + + if(m_manager->adapters().size() == 0){ + qDebug() << "no bluetooth adapter !!!"; + qDebug() << "Program exit !!!"; + return; + }else if(m_manager->adapters().size() == 1){ + m_localDevice = m_manager->adapters().at(0); + if(settings) + settings->set("adapter-address",QVariant::fromValue(m_localDevice->address())); + }else{ + if(adapter_address_list.indexOf(Default_Adapter) != -1){ + m_localDevice = m_manager->adapterForAddress(Default_Adapter); + }else{ + m_localDevice = m_manager->adapterForAddress(adapter_address_list.at(0)); + } + } + + qDebug() << m_localDevice->name() << m_localDevice->isPowered() << m_localDevice->isDiscoverable() << m_localDevice->isDiscovering() << m_localDevice->address(); + + main_widget = new QWidget(this); + this->setCentralWidget(main_widget); + + main_layout = new QVBoxLayout(main_widget); + main_layout->setSpacing(40); + main_layout->setContentsMargins(0,0,30,10); + frame_top = new QWidget(main_widget); + frame_top->setObjectName("frame_top"); + if(m_manager->adapters().size() > 1){ + frame_top->setMinimumSize(582,239); + frame_top->setMaximumSize(1000,239); + }else{ + frame_top->setMinimumSize(582,187); + frame_top->setMaximumSize(1000,187); + } +// frame_top->setStyleSheet("background:blue;"); + frame_middle = new QWidget(main_widget); + frame_middle->setObjectName("frame_middle"); +// frame_middle->setMinimumSize(582,135); +// frame_middle->setStyleSheet("background:blue;"); + frame_bottom = new QWidget(main_widget); + frame_bottom->setObjectName("frame_bottom"); + frame_bottom->setMinimumWidth(582); + frame_bottom->setMaximumWidth(1000); +// frame_bottom->setMinimumHeight(340); +// frame_bottom->setStyleSheet("background:green;"); + + main_layout->addWidget(frame_top,1,Qt::AlignTop); + main_layout->addWidget(frame_middle,1,Qt::AlignTop); + main_layout->addWidget(frame_bottom,1,Qt::AlignTop); + main_layout->addStretch(10); + + Discovery_device_address.clear(); + + InitMainTopUI(); + InitMainMiddleUI(); + InitMainbottomUI(); + this->setLayout(main_layout); + + updateUIWhenAdapterChanged(); +} + +/* + * Initialize the fixed UI in the upper half of the interface + * + */ +void BlueToothMain::InitMainTopUI() +{ + //~ contents_path /bluetooth/Bluetooth + QLabel *label_1 = new QLabel(tr("Bluetooth"),frame_top); + label_1->setFixedSize(100,25); + label_1->setStyleSheet("QLabel{\ + font-size: 18px;\ + font-weight: 500;\ + line-height: 25px;}"); + + QVBoxLayout *top_layout = new QVBoxLayout(); + top_layout->setSpacing(8); + top_layout->setContentsMargins(0,0,0,0); + top_layout->addWidget(label_1); + + QVBoxLayout *layout = new QVBoxLayout(); + layout->setSpacing(2); + layout->setContentsMargins(0,0,0,0); + top_layout->addLayout(layout); + + QFrame *frame_1 = new QFrame(frame_top); + frame_1->setMinimumWidth(582); + frame_1->setFrameShape(QFrame::Shape::Box); + frame_1->setFixedHeight(50); + frame_1->setAutoFillBackground(true); + layout->addWidget(frame_1); + + QHBoxLayout *frame_1_layout = new QHBoxLayout(frame_1); + frame_1_layout->setSpacing(10); + frame_1_layout->setContentsMargins(16,0,16,0); + + //~ contents_path /bluetooth/Turn on Bluetooth + label_2 = new QLabel(frame_1); + label_2->setStyleSheet("QLabel{\ + width: 56px;\ + height: 20px;\ + font-weight: 400;\ + line-height: 20px;}"); + frame_1_layout->addWidget(label_2); + frame_1_layout->addStretch(); + + bluetooth_name = new BluetoothNameLabel(frame_1,300,38); + connect(bluetooth_name,&BluetoothNameLabel::send_adapter_name,this,&BlueToothMain::change_adapter_name); + connect(this,&BlueToothMain::adapter_name_changed,bluetooth_name,&BluetoothNameLabel::set_label_text); + frame_1_layout->addWidget(bluetooth_name); + + open_bluetooth = new SwitchButton(frame_1); + + frame_1_layout->addWidget(open_bluetooth); + + frame_2 = new QFrame(frame_top); + frame_2->setMinimumWidth(582); + frame_2->setFrameShape(QFrame::Shape::Box); + frame_2->setFixedHeight(50); + if(adapter_address_list.size() == 1) + frame_2->setVisible(false); + layout->addWidget(frame_2); + + QHBoxLayout *frame_2_layout = new QHBoxLayout(frame_2); + frame_2_layout->setSpacing(10); + frame_2_layout->setContentsMargins(16,0,16,0); + + QLabel *label_3 = new QLabel(tr("Bluetooth adapter"),frame_2); + label_3->setStyleSheet("QLabel{\ + width: 56px;\ + height: 20px;\ + font-weight: 400;\ + line-height: 20px;}"); + frame_2_layout->addWidget(label_3); + frame_2_layout->addStretch(); + + adapter_list = new QComboBox(frame_2); + adapter_list->clear(); + adapter_list->addItems(adapter_name_list); + adapter_list->setMinimumWidth(300); + adapter_list->setCurrentIndex(adapter_address_list.indexOf(m_localDevice->address())); + connect(adapter_list,SIGNAL(currentIndexChanged(int)),this,SLOT(adapterComboxChanged(int))); + frame_2_layout->addWidget(adapter_list); + + QFrame *frame_3 = new QFrame(frame_top); + frame_3->setMinimumWidth(582); + frame_3->setFrameShape(QFrame::Shape::Box); + frame_3->setFixedHeight(50); + layout->addWidget(frame_3); + + QHBoxLayout *frame_3_layout = new QHBoxLayout(frame_3); + frame_3_layout->setSpacing(10); + frame_3_layout->setContentsMargins(16,0,16,0); + + //~ contents_path /bluetooth/Show icon on taskbar + QLabel *label_4 = new QLabel(tr("Show icon on taskbar"),frame_3); + label_4->setStyleSheet("QLabel{\ + width: 56px;\ + height: 20px;\ + font-weight: 400;\ + line-height: 20px;}"); + frame_3_layout->addWidget(label_4); + frame_3_layout->addStretch(); + + show_panel = new SwitchButton(frame_3); + frame_3_layout->addWidget(show_panel); + if(settings){ + show_panel->setChecked(settings->get("tray-show").toBool()); + }else{ + show_panel->setChecked(false); + show_panel->setDisabledFlag(false); + } + connect(show_panel,&SwitchButton::checkedChanged,this,&BlueToothMain::set_tray_visible); + + QFrame *frame_4 = new QFrame(frame_top); + frame_4->setMinimumWidth(582); + frame_4->setFrameShape(QFrame::Shape::Box); + frame_4->setFixedHeight(50); + layout->addWidget(frame_4); + + QHBoxLayout *frame_4_layout = new QHBoxLayout(frame_4); + frame_4_layout->setSpacing(10); + frame_4_layout->setContentsMargins(16,0,16,0); + + //~ contents_path /bluetooth/Discoverable + QLabel *label_5 = new QLabel(tr("Allow Bluetooth devices to be discoverable"),frame_4); + label_5->setStyleSheet("QLabel{\ + width: 56px;\ + height: 20px;\ + font-weight: 400;\ + line-height: 20px;}"); + frame_4_layout->addWidget(label_5); + frame_4_layout->addStretch(); + + switch_discover = new SwitchButton(frame_4); + frame_4_layout->addWidget(switch_discover); + switch_discover->setChecked(m_localDevice->isDiscoverable()); + connect(switch_discover,&SwitchButton::checkedChanged,this,&BlueToothMain::set_discoverable); + connect(m_localDevice.data(), &BluezQt::Adapter::discoverableChanged, this, [=](bool discoverable){ + switch_discover->setChecked(discoverable); + }); + + connect(open_bluetooth,SIGNAL(checkedChanged(bool)),this,SLOT(onClick_Open_Bluetooth(bool))); + frame_top->setLayout(top_layout); +} + +void BlueToothMain::InitMainMiddleUI() +{ + QVBoxLayout *middle_layout = new QVBoxLayout(frame_middle); + middle_layout->setSpacing(8); + middle_layout->setContentsMargins(0,0,0,0); + + paired_dev_layout = new QVBoxLayout(); + paired_dev_layout->setSpacing(2); + paired_dev_layout->setContentsMargins(0,0,0,0); + + QLabel *middle_label = new QLabel(tr("My Devices"),frame_middle); + middle_label->setStyleSheet("QLabel{width: 72px;\ + height: 25px;\ + font-size: 18px;\ + font-weight: 500;\ + line-height: 25px;}"); + + middle_layout->addWidget(middle_label,Qt::AlignTop); + middle_layout->addLayout(paired_dev_layout,Qt::AlignTop); + + frame_middle->setLayout(middle_layout); +} + +void BlueToothMain::InitMainbottomUI() +{ + QHBoxLayout *title_layout = new QHBoxLayout(); + title_layout->setSpacing(10); + title_layout->setContentsMargins(0,0,10,0); + + //~ contents_path /bluetooth/Other Devices + QLabel *label_1 = new QLabel(tr("Other Devices"),frame_bottom); + label_1->setStyleSheet("QLabel{\ + width: 72px;\ + height: 25px;\ + font-size: 18px;\ + font-weight: 500;\ + line-height: 25px;}"); + + loadLabel = new QLabel(frame_bottom); + loadLabel->setFixedSize(24,24); + + discover_refresh = new QPushButton(tr("Refresh"),frame_bottom); + discover_refresh->setFixedSize(80,32); + + m_timer = new QTimer(this); + m_timer->setInterval(100); + discovering_timer = new QTimer(this); + discovering_timer->setInterval(30000); + connect(discovering_timer,&QTimer::timeout,this,[=]{ + discovering_timer->stop(); + if(m_localDevice->isDiscovering()){ + m_localDevice->stopDiscovery(); + } + }); + + connect(m_timer,&QTimer::timeout,this,&BlueToothMain::Refresh_load_Label_icon); + + //点击刷新按钮,开启适配器查找周围的蓝牙设备 + connect(discover_refresh,&QPushButton::clicked,this,[=]{ + discovering_timer->start(); + startDiscovery(); + }); + + title_layout->addWidget(label_1); + title_layout->addWidget(loadLabel); + title_layout->addStretch(); + title_layout->addWidget(discover_refresh,Qt::AlignVCenter); + + QVBoxLayout *bottom_layout = new QVBoxLayout(frame_bottom); + bottom_layout->setSpacing(8); + bottom_layout->setContentsMargins(0,0,0,0); + bottom_layout->addLayout(title_layout); + + device_list = new QWidget(); + + bottom_layout->addWidget(device_list); + + device_list_layout = new QVBoxLayout(device_list); + device_list_layout->setSpacing(2); + device_list_layout->setContentsMargins(0,0,0,0); + device_list_layout->setAlignment(Qt::AlignTop); + device_list->setLayout(device_list_layout); + + frame_bottom->setLayout(bottom_layout); +} + +void BlueToothMain::startDiscovery() +{ + if(m_localDevice->isDiscovering()){ + m_localDevice->stopDiscovery(); + } + m_localDevice->startDiscovery(); +} + +void BlueToothMain::adapterChanged() +{ + connect(m_manager,&BluezQt::Manager::adapterRemoved,this,[=](BluezQt::AdapterPtr adapter){ +// qDebug() << Q_FUNC_INFO << adapter_address_list.indexOf(adapter.data()->address()); +// qDebug() << Q_FUNC_INFO << adapter_list->currentIndex() << adapter_address_list.at(adapter_list->currentIndex()) << adapter.data()->address() <<__LINE__; + + int i = adapter_address_list.indexOf(adapter.data()->address()); + + adapter_name_list.removeAt(i); + adapter_address_list.removeAll(adapter.data()->address()); + adapter_list->removeItem(i); + + if(adapter_address_list.size() == adapter_name_list.size() == 1){ + frame_2->setVisible(false); + frame_top->setMinimumSize(582,135); + frame_top->setMaximumSize(1000,135); + } + }); + + connect(m_manager,&BluezQt::Manager::adapterAdded,this,[=](BluezQt::AdapterPtr adapter){ + + adapter_address_list << adapter.data()->address(); + adapter_name_list << adapter.data()->name(); + qDebug() << Q_FUNC_INFO << adapter_address_list << "===" << adapter_name_list; + adapter_list->addItem(adapter.data()->name()); + + if((adapter_address_list.size() == adapter_name_list.size()) && (adapter_address_list.size() == 1)){ + frame_top->setMinimumSize(582,187); + frame_top->setMaximumSize(1000,187); + }else if((adapter_address_list.size() == adapter_name_list.size()) && (adapter_address_list.size() > 1)){ + if(!frame_2->isVisible()) + frame_2->setVisible(true); + frame_top->setMinimumSize(582,239); + frame_top->setMaximumSize(1000,239); + } + }); +} + +void BlueToothMain::updateUIWhenAdapterChanged() +{ + connect(m_localDevice.data(),&BluezQt::Adapter::poweredChanged,this,&BlueToothMain::adapterPoweredChanged); + connect(m_localDevice.data(),&BluezQt::Adapter::deviceAdded,this,&BlueToothMain::serviceDiscovered); + connect(m_localDevice.data(),&BluezQt::Adapter::deviceChanged,this,&BlueToothMain::serviceDiscoveredChange); + connect(m_localDevice.data(),&BluezQt::Adapter::nameChanged,this,&BlueToothMain::adapterNameChanged); + connect(m_localDevice.data(),&BluezQt::Adapter::deviceRemoved,this,&BlueToothMain::adapterDeviceRemove); + connect(m_localDevice.data(),&BluezQt::Adapter::discoveringChanged,this,[=](bool discover){ + if(discover){ + loadLabel->setVisible(true); + m_timer->start(); + discover_refresh->setEnabled(false); + discovering_timer->start(); + }else{ + loadLabel->setVisible(false); + m_timer->stop(); + discover_refresh->setEnabled(true); + discovering_timer->stop(); + } + }); + //==============初始化蓝牙信息和基础信息==================================== + bluetooth_name->set_dev_name(m_localDevice->name()); + + if(m_localDevice->isPowered()){ + open_bluetooth->setChecked(true); + bluetooth_name->setVisible(true); + // label_2->setText(tr("Turn off Bluetooth")); + label_2->setText(tr("Turn on Bluetooth")); + if(!frame_bottom->isVisible()) + frame_bottom->setVisible(true); + }else{ + qDebug() << Q_FUNC_INFO << m_manager->isBluetoothBlocked() << __LINE__; + open_bluetooth->setChecked(false); + bluetooth_name->setVisible(false); + label_2->setText(tr("Turn on Bluetooth")); + frame_bottom->setVisible(false); + frame_middle->setVisible(false); + } + //===========================END========================================== + + // =============清空我的设备和蓝牙发现设备栏布局下的所有设备item================= + QLayoutItem *child; + while ((child = paired_dev_layout->takeAt(0)) != 0) + { + qDebug() << Q_FUNC_INFO << __LINE__; + if(child->widget()) + { + child->widget()->setParent(NULL); + } + delete child; + child = nullptr; + } + while ((child = device_list_layout->takeAt(0)) != 0) + { + qDebug() << Q_FUNC_INFO << __LINE__; + if(child->widget()) + { + child->widget()->setParent(NULL); + } + delete child; + child = nullptr; + } + // ========================END=========================================== + qDebug() << Q_FUNC_INFO <devices().size(); + show_flag = false; + Discovery_device_address.clear(); + + for(int i = 0;i < m_localDevice->devices().size(); i++){ + qDebug() << m_localDevice->devices().at(i)->name() << m_localDevice->devices().at(i)->type(); + + addMyDeviceItemUI(m_localDevice->devices().at(i)); + } + device_list_layout->addStretch(); + + qDebug() << Q_FUNC_INFO << m_localDevice->devices().size() << show_flag; + if(m_localDevice->isPowered()){ + if(show_flag) + frame_middle->setVisible(true); + else + frame_middle->setVisible(false); + } + + //当适配器查找设备状态改变时,改变加载动画和刷新按钮的状态 +// connect(m_localDevice.data(),&BluezQt::Adapter::discoveringChanged,this,[=](bool discover){ +// if(discover){ +// loadLabel->setVisible(true); +// m_timer->start(); +// discover_refresh->setEnabled(false); +// discovering_timer->start(); +// }else{ +// loadLabel->setVisible(false); +// m_timer->stop(); +// discover_refresh->setEnabled(true); +// discovering_timer->stop(); +// } +// }); + + if(m_localDevice->isPowered()) + m_localDevice->startDiscovery(); +} + +void BlueToothMain::removeDeviceItemUI(QString address) +{ + qDebug() << Q_FUNC_INFO << address <<__LINE__; + if(Discovery_device_address.indexOf(address) != -1){ + DeviceInfoItem *item = device_list->findChild(address); + if(item){ + device_list_layout->removeWidget(item); + item->setParent(NULL); + delete item; + item = nullptr; + Discovery_device_address.removeAll(address); + }else{ + return; + } + }else{ + DeviceInfoItem *item = frame_middle->findChild(address); + if(item){ + paired_dev_layout->removeWidget(item); + item->setParent(NULL); + delete item; + item = nullptr; + + if(frame_middle->children().size() == 2){ + frame_middle->setVisible(false); + } + }else{ + return; + } + } +} + +void BlueToothMain::addMyDeviceItemUI(BluezQt::DevicePtr dev) +{ + if (dev && dev->isPaired()) { + DeviceInfoItem *item = new DeviceInfoItem(); + connect(item,SIGNAL(sendConnectDevice(QString)),this,SLOT(receiveConnectsignal(QString))); + connect(item,SIGNAL(sendDisconnectDeviceAddress(QString)),this,SLOT(receiveDisConnectSignal(QString))); + connect(item,SIGNAL(sendDeleteDeviceAddress(QString)),this,SLOT(receiveRemoveSignal(QString))); + connect(item,SIGNAL(sendPairedAddress(QString)),this,SLOT(change_device_parent(QString))); + if(dev->isConnected()) + item->initInfoPage(dev->name(), DEVICE_STATUS::LINK, dev); + else + item->initInfoPage(dev->name(), DEVICE_STATUS::UNLINK, dev); + + show_flag = true; + paired_dev_layout->addWidget(item,Qt::AlignTop); + } + return; +} + +void BlueToothMain::leaveEvent(QEvent *event) +{ + qDebug() << Q_FUNC_INFO; +} + +BlueToothMain::~BlueToothMain() +{ + delete settings; + settings = nullptr; + delete device_list; + device_list = nullptr; +} + +void BlueToothMain::onClick_Open_Bluetooth(bool ischeck) +{ + qDebug() << Q_FUNC_INFO << ischeck << m_localDevice->isPowered() << show_flag <<__LINE__; + if(ischeck){ + if(m_manager->isBluetoothBlocked()) + m_manager->setBluetoothBlocked(false); + BluezQt::PendingCall *call = m_localDevice->setPowered(true); + connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *v){ + if(v->error() == 0){ + bluetooth_name->set_dev_name(m_localDevice->name()); + bluetooth_name->setVisible(true); + frame_bottom->setVisible(true); + + if(show_flag) + frame_middle->setVisible(true); +// label_2->setText(tr("Turn off Bluetooth")); + + qDebug() << Q_FUNC_INFO << m_localDevice->isPowered() <<__LINE__; + this->startDiscovery(); + } + }); + }else{ + qDebug() << Q_FUNC_INFO << __LINE__; + if(m_localDevice->isDiscovering()){ + m_localDevice->stopDiscovery(); + } + BluezQt::PendingCall *call = m_localDevice->setPowered(false); + m_manager->setBluetoothBlocked(true); + connect(call,&BluezQt::PendingCall::finished,this,[=](BluezQt::PendingCall *v){ + if(v->error() == 0){ + bluetooth_name->setVisible(false); + qDebug() << Q_FUNC_INFO << !m_localDevice->isPowered() << __LINE__; + frame_bottom->setVisible(false); + + if(frame_middle->isVisible()) + frame_middle->setVisible(false); + + label_2->setText(tr("Turn on Bluetooth")); + } + }); + } +} + +void BlueToothMain::serviceDiscovered(BluezQt::DevicePtr device) +{ + qDebug() << Q_FUNC_INFO << device->type() << device->name() << device->address() << device->uuids().size(); + if(device->isPaired()){ + addMyDeviceItemUI(device); + return; + } + + if(device->uuids().size() == 0 && device->name().split("-").length() == 6 && device->type() == BluezQt::Device::Uncategorized){ + return; + } + if(Discovery_device_address.contains(device->address())){ + return; + } + qDebug() << Q_FUNC_INFO << device->type() << device->name() << device->address() << device->uuids().size(); + + DeviceInfoItem *item = new DeviceInfoItem(device_list); + connect(item,SIGNAL(sendConnectDevice(QString)),this,SLOT(receiveConnectsignal(QString))); + connect(item,SIGNAL(sendDisconnectDeviceAddress(QString)),this,SLOT(receiveDisConnectSignal(QString))); + connect(item,SIGNAL(sendDeleteDeviceAddress(QString)),this,SLOT(receiveRemoveSignal(QString))); + connect(item,SIGNAL(sendPairedAddress(QString)),this,SLOT(change_device_parent(QString))); + + item->initInfoPage(device->name(), DEVICE_STATUS::UNLINK, device); + + device_list_layout->addWidget(item,Qt::AlignTop); + + Discovery_device_address << device->address(); +} + +void BlueToothMain::serviceDiscoveredChange(BluezQt::DevicePtr device) +{ + qDebug() << Q_FUNC_INFO << device->type() << device->name() << device->address() << device->uuids().size(); + if(device->uuids().size() == 0 && device->name().split("-").length() == 6 && device->type() == BluezQt::Device::Uncategorized){ + return; + } + if(device->isPaired() || device->isConnected()) { + return; + } + if(Discovery_device_address.contains(device->address())){ + return; + } + qDebug() << Q_FUNC_INFO << device->type() << device->name() << device->address() << device->uuids().size(); + + DeviceInfoItem *item = new DeviceInfoItem(device_list); + connect(item,SIGNAL(sendConnectDevice(QString)),this,SLOT(receiveConnectsignal(QString))); + connect(item,SIGNAL(sendDisconnectDeviceAddress(QString)),this,SLOT(receiveDisConnectSignal(QString))); + connect(item,SIGNAL(sendDeleteDeviceAddress(QString)),this,SLOT(receiveRemoveSignal(QString))); + connect(item,SIGNAL(sendPairedAddress(QString)),this,SLOT(change_device_parent(QString))); + + item->initInfoPage(device->name(), DEVICE_STATUS::UNLINK, device); + + device_list_layout->addWidget(item,Qt::AlignTop); + + Discovery_device_address << device->address(); +} + +void BlueToothMain::receiveConnectsignal(QString device) +{ + QDBusMessage m = QDBusMessage::createMethodCall("org.ukui.bluetooth","/org/ukui/bluetooth","org.ukui.bluetooth","connectToDevice"); + m << device; + qDebug() << Q_FUNC_INFO << m.arguments().at(0).value() <<__LINE__; + // 发送Message + QDBusMessage response = QDBusConnection::sessionBus().call(m); + // 判断Method是否被正确返回 +// if (response.type()== QDBusMessage::ReplyMessage) +// { +// // QDBusMessage的arguments不仅可以用来存储发送的参数,也用来存储返回值; +// bRet = response.arguments().at(0).toBool(); +// } +// else { +// qDebug()<<"Message In fail!\n"; +// } +// qDebug() << Q_FUNC_INFO << __LINE__; + // qDebug()<<"bRet:"<() <<__LINE__; + // 发送Message + QDBusMessage response = QDBusConnection::sessionBus().call(m); +} + +void BlueToothMain::receiveRemoveSignal(QString address) +{ +// QDBusMessage m = QDBusMessage::createMethodCall("org.ukui.bluetooth","/org/ukui/bluetooth","org.ukui.bluetooth","removeDevice"); +// m << address; +// qDebug() << Q_FUNC_INFO << m.arguments().at(0).value() <<__LINE__; +// // 发送Message +// QDBusMessage response = QDBusConnection::sessionBus().call(m); + qDebug() << Q_FUNC_INFO << address; + + m_localDevice->removeDevice(m_localDevice->deviceForAddress(address)); +} + +void BlueToothMain::Refresh_load_Label_icon() +{ + if(i == 0) + i = 7; + loadLabel->setPixmap(QIcon::fromTheme("ukui-loading-"+QString::number(i,10)).pixmap(24,24)); + loadLabel->update(); + i--; +} + +void BlueToothMain::set_tray_visible(bool value) +{ + settings->set("tray-show",QVariant::fromValue(value)); +} + +void BlueToothMain::set_discoverable(bool value) +{ + if(value){ + if(m_localDevice->discoverableTimeout() != 0) + m_localDevice->setDiscoverableTimeout(0); + } + m_localDevice->setDiscoverable(value); +} + +void BlueToothMain::change_adapter_name(const QString &name) +{ + m_localDevice->setName(name); +} + +void BlueToothMain::change_device_parent(const QString &address) +{ + qDebug() << Q_FUNC_INFO ; + if(!frame_middle->isVisible()){ + frame_middle->setVisible(true); + } + + DeviceInfoItem *item = device_list->findChild(address); + if(item){ + device_list_layout->removeWidget(item); + item->setParent(frame_middle); + paired_dev_layout->addWidget(item); + Discovery_device_address.removeAll(address); + }else{ + return; + } +} + +void BlueToothMain::adapterPoweredChanged(bool value) +{ + qDebug() << Q_FUNC_INFO <set("switch",QVariant::fromValue(value)); + + if(value){ + bluetooth_name->set_dev_name(m_localDevice->name()); + bluetooth_name->setVisible(true); + frame_bottom->setVisible(true); + + if(show_flag) + frame_middle->setVisible(true); + + open_bluetooth->setChecked(true); + this->startDiscovery(); + qDebug() << discovering_timer->isActive(); + }else{ + bluetooth_name->setVisible(false); + open_bluetooth->setChecked(false); + frame_bottom->setVisible(false); + + if(frame_middle->isVisible()) + frame_middle->setVisible(false); + + label_2->setText(tr("Turn on Bluetooth")); + if(m_localDevice->isDiscovering()){ + m_localDevice->stopDiscovery(); + } + qDebug() << discovering_timer->isActive(); + } +} + +void BlueToothMain::adapterComboxChanged(int i) +{ +// qDebug() << Q_FUNC_INFO << i << adapter_address_list.at(i) << adapter_name_list.at(i) << adapter_address_list << adapter_name_list; + if(i != -1){ + m_localDevice = m_manager->adapterForAddress(adapter_address_list.at(i)); + m_localDevice->stopDiscovery(); + updateUIWhenAdapterChanged(); + if(settings) + settings->set("adapter-address",QVariant::fromValue(adapter_address_list.at(i))); + }else{ + if(open_bluetooth->isChecked()){ + open_bluetooth->setChecked(false); + open_bluetooth->setDisabledFlag(false); + } + if(frame_middle->isVisible()){ + frame_middle->setVisible(false); + } + } +} + +void BlueToothMain::adapterNameChanged(const QString &name) +{ + emit this->adapter_name_changed(name); + + //设备名字改变,同时改变combox的当前设备名字 + int index; + index = adapter_address_list.indexOf(m_localDevice->address()); + adapter_name_list.removeAt(index); + adapter_name_list.insert(index,name); +// qDebug() << Q_FUNC_INFO << adapter_name_list << adapter_address_list; + adapter_list->setItemText(index,name); +} + +void BlueToothMain::adapterDeviceRemove(BluezQt::DevicePtr ptr) +{ +// qDebug() << Q_FUNC_INFO << ptr.data()->address() << ptr.data()->name(); + removeDeviceItemUI(ptr.data()->address()); +} + diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetoothmain.h ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetoothmain.h --- ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetoothmain.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetoothmain.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,122 @@ +#ifndef BLUETOOTHMAIN_H +#define BLUETOOTHMAIN_H + +#include "SwitchButton/switchbutton.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 "deviceinfoitem.h" +#include "bluetoothnamelabel.h" + +class BlueToothMain : public QMainWindow +{ + Q_OBJECT +public: + BlueToothMain(QWidget *parent = nullptr); + ~BlueToothMain(); + void InitMainTopUI(); + void InitMainMiddleUI(); + void InitMainbottomUI(); + void startDiscovery(); + void adapterChanged(); + void updateUIWhenAdapterChanged(); + void removeDeviceItemUI(QString address); + void addMyDeviceItemUI(BluezQt::DevicePtr); +protected: + void leaveEvent(QEvent *event); + +signals: + void adapter_name_changed(const QString &name); + +private slots: + void onClick_Open_Bluetooth(bool); + void serviceDiscovered(BluezQt::DevicePtr); + void serviceDiscoveredChange(BluezQt::DevicePtr); + void receiveConnectsignal(QString); + void receiveDisConnectSignal(QString); + void receiveRemoveSignal(QString); + void Refresh_load_Label_icon(); + void set_tray_visible(bool); + void set_discoverable(bool); + void change_adapter_name(const QString &name); + void change_device_parent(const QString &address); + void adapterPoweredChanged(bool value); + void adapterComboxChanged(int i); + void adapterNameChanged(const QString &name); + void adapterDeviceRemove(BluezQt::DevicePtr ptr); +private: + QGSettings *settings = nullptr; + QString Default_Adapter; + QStringList paired_device_address; + QString finally_connect_the_device; + QStringList Discovery_device_address; + QStringList adapter_address_list; + QStringList adapter_name_list; + + QVBoxLayout *main_layout = nullptr; + QFrame *frame_2 = nullptr; + QComboBox *adapter_list = nullptr; + + QWidget *main_widget = nullptr; + QWidget *frame_top = nullptr; + QWidget *frame_middle = nullptr; + QVBoxLayout *paired_dev_layout = nullptr; + QWidget *frame_bottom = nullptr; + BluetoothNameLabel *bluetooth_name = nullptr; + + QVBoxLayout *bottom_layout = nullptr; + QScrollArea *device_area = nullptr; + QWidget *device_list = nullptr; + QVBoxLayout *device_list_layout = nullptr; + + BluezQt::Manager *m_manager = nullptr; + BluezQt::InitManagerJob *job = nullptr; + BluezQt::AdapterPtr m_localDevice = nullptr; + + SwitchButton *open_bluetooth = nullptr; + SwitchButton *show_panel = nullptr; + SwitchButton *switch_discover = nullptr; + + QLabel *label_2 = nullptr; + QLabel *loadLabel = nullptr; + QPushButton *discover_refresh; + QTimer *m_timer = nullptr; + QTimer *discovering_timer =nullptr; + int i = 7; + bool show_flag = false; +}; + +#endif // BLUETOOTHMAIN_H diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetoothnamelabel.cpp ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetoothnamelabel.cpp --- ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetoothnamelabel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetoothnamelabel.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,162 @@ +#include "bluetoothnamelabel.h" + +BluetoothNameLabel::BluetoothNameLabel(QWidget *parent, int x, int y): + QWidget(parent) +{ +// qDebug() << Q_FUNC_INFO << x << y; + + this->setAutoFillBackground(true); + this->setStyleSheet("QWidget{border: none;border-radius:2px;}"); + this->setFixedSize(x,y); + + m_label = new QLabel(this); + m_label->setAlignment(Qt::AlignCenter); + m_label->setGeometry(2,2,this->width()-3,this->height()-3); + m_label->setStyleSheet("QLabel{\ + width: 214px;\ + height: 20px;\ + font-family: PingFangSC-Regular, PingFang SC;\ + font-weight: 400;\ + line-height: 20px;}"); + + m_lineedit = new QLineEdit(this); + m_lineedit->setEchoMode(QLineEdit::Normal); + m_lineedit->setAlignment(Qt::AlignCenter); + connect(m_lineedit,&QLineEdit::editingFinished,this,&BluetoothNameLabel::LineEdit_Input_Complete); + m_lineedit->setGeometry(2,2,this->width()-3,this->height()-3); + m_lineedit->setVisible(false); + + if(QGSettings::isSchemaInstalled("org.ukui.style")){ + settings = new QGSettings("org.ukui.style"); + if(settings->get("style-name").toString() == "ukui-black" || settings->get("style-name").toString() == "ukui-dark") + style_flag = true; + else + style_flag = false; + + switch (settings->get("systemFontSize").toInt()) { + case 11: + case 12: + case 13: + font_width = 100; + break; + case 14: + font_width = 70; + break; + case 15: + case 16: + font_width = 50; + break; + default: + break; + } + qDebug() << Q_FUNC_INFO << connect(settings,&QGSettings::changed,this,&BluetoothNameLabel::settings_changed); + } +} + +BluetoothNameLabel::~BluetoothNameLabel() +{ + +} + +void BluetoothNameLabel::set_dev_name(const QString &dev_name) +{ + QFont ft; + QFontMetrics fm(ft); + QString text = fm.elidedText(dev_name, Qt::ElideMiddle, font_width); + m_label->setText(tr("Can now be found as \"%1\"").arg(text)); + m_label->setToolTip(tr("Can now be found as \"%1\"").arg(dev_name)); + m_label->update(); + + device_name = dev_name; +} + +void BluetoothNameLabel::mouseDoubleClickEvent(QMouseEvent *event) +{ + Q_UNUSED(event); + + m_label->setVisible(false); + + m_lineedit->setText(device_name); + m_lineedit->setVisible(true); + m_lineedit->setFocus(); +} + +void BluetoothNameLabel::leaveEvent(QEvent *event) +{ + Q_UNUSED(event); + + if(!m_lineedit->isVisible()) + this->setStyleSheet("QWidget{border:none;border-radius:2px;}"); +} + +void BluetoothNameLabel::enterEvent(QEvent *event) +{ + Q_UNUSED(event); +// QPalette palette; +// palette.setColor(QPalette::Background, QColor(Qt::white)); +// this->setPalette(palette); +// this->update(); + + if(style_flag) + this->setStyleSheet("QWidget{background-color:black;border:none;border-radius:2px;}"); + else + this->setStyleSheet("QWidget{background-color:white;border:none;border-radius:2px;}"); +} + +void BluetoothNameLabel::LineEdit_Input_Complete() +{ + qDebug() << Q_FUNC_INFO; + if(device_name == m_lineedit->text()){ + set_label_text(device_name); + }else{ + device_name = m_lineedit->text(); + emit this->send_adapter_name(m_lineedit->text()); + } + this->setStyleSheet("QWidget{border:none;border-radius:2px;}"); +} + +void BluetoothNameLabel::set_label_text(const QString &value) +{ + m_lineedit->setVisible(false); + + QFont ft; + QFontMetrics fm(ft); + QString text = fm.elidedText(m_lineedit->text(), Qt::ElideMiddle, font_width); + m_label->setText(tr("Can now be found as \"%1\"").arg(text)); + m_label->setToolTip(tr("Can now be found as \"%1\"").arg(device_name)); + m_label->setVisible(true); +} + +void BluetoothNameLabel::settings_changed(const QString &key) +{ + qDebug() << Q_FUNC_INFO <get("style-name").toString() == "ukui-black" || settings->get("style-name").toString() == "ukui-dark") + style_flag = true; + else + style_flag = false; + }else if(key == "systemFontSize"){ + QFont ft; + ft.setPixelSize(settings->get("systemFontSize").toInt()); + switch (settings->get("systemFontSize").toInt()) { + case 11: + case 12: + case 13: + font_width = 100; + break; + case 14: + font_width = 70; + break; + case 15: + case 16: + font_width = 50; + break; + default: + break; + } + QFontMetrics fm(ft); + QString text = fm.elidedText(device_name, Qt::ElideMiddle, font_width); + m_label->setText(tr("Can now be found as \"%1\"").arg(text)); + m_label->setVisible(true); + } +} diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetoothnamelabel.h ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetoothnamelabel.h --- ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetoothnamelabel.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetoothnamelabel.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,45 @@ +#ifndef BLUETOOTHNAMELABEL_H +#define BLUETOOTHNAMELABEL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class BluetoothNameLabel : public QWidget +{ + Q_OBJECT +public: + BluetoothNameLabel(QWidget *parent = nullptr, int x = 200,int y = 40); + ~BluetoothNameLabel(); + void set_dev_name(const QString &dev_name); +protected: + void mouseDoubleClickEvent(QMouseEvent *event); + void leaveEvent(QEvent *event); + void enterEvent(QEvent *event); + +signals: + void send_adapter_name(const QString &value); + +public slots: + void LineEdit_Input_Complete(); + void set_label_text(const QString &value); + void settings_changed(const QString &key); + +private: + QGSettings *settings; + bool style_flag = false; + + QLabel *m_label = nullptr; + QLineEdit *m_lineedit = nullptr; + QString device_name; + int font_width; +}; + +#endif // BLUETOOTHNAMELABEL_H diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetooth.pro ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetooth.pro --- ukui-control-center-2.0.3/plugins/devices/bluetooth/bluetooth.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/bluetooth.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,57 @@ +include(../../../env.pri) +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets dbus BluezQt + +TEMPLATE = lib +CONFIG += c++11 +CONFIG += plugin + +LIBS += -L /usr/lib/x86_64-linux-gnu -l KF5BluezQt + +TARGET = $$qtLibraryTarget(bluetooth) +DESTDIR = ../.. +target.path = $${PLUGIN_INSTALL_DIRS} + +include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) + +INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE \ + $$PROJECT_ROOTDIR \ + + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked 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_NO_WARNING_OUTPUT \ +# QT_NO_DEBUG_OUTPUT + +# You can also make your code fail to compile if it uses 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 += \ + bluetooth.cpp \ + bluetoothmain.cpp \ + bluetoothnamelabel.cpp \ + deviceinfoitem.cpp \ + loadinglabel.cpp +# mylayout.cpp + +HEADERS += \ + bluetooth.h \ + bluetoothmain.h \ + bluetoothnamelabel.h \ + config.h \ + deviceinfoitem.h \ + loadinglabel.h +# mylayout.h + +# Default rules for deployment. +INSTALLS += target + +FORMS += + diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/config.h ukui-control-center-3.0.3/plugins/devices/bluetooth/config.h --- ukui-control-center-2.0.3/plugins/devices/bluetooth/config.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/config.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,19 @@ +#ifndef CONFIG_H +#define CONFIG_H + +enum DEVICE_TYPE{ + PC = 0, + PHONE, + HEADSET, + OTHER, + Mouse, +}; + +enum DEVICE_STATUS{ + LINK = 0, + UNLINK, + ERROR, + NOT, +}; + +#endif // CONFIG_H diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/deviceinfoitem.cpp ukui-control-center-3.0.3/plugins/devices/bluetooth/deviceinfoitem.cpp --- ukui-control-center-2.0.3/plugins/devices/bluetooth/deviceinfoitem.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/deviceinfoitem.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,328 @@ +#include "deviceinfoitem.h" + +DeviceInfoItem::DeviceInfoItem(QWidget *parent) : QWidget(parent) +{ + if(QGSettings::isSchemaInstalled("org.ukui.style")){ + item_gsettings = new QGSettings("org.ukui.style"); + connect(item_gsettings,&QGSettings::changed,this,&DeviceInfoItem::GSettingsChanges); + } + + this->setMinimumSize(580,50); + this->setMaximumSize(1000,50); +// this->setStyleSheet("background:white;"); + + info_page = new QFrame(this); + info_page->setFrameShape(QFrame::Shape::Box); +// info_page->setStyleSheet("background:blue;"); + info_page->setGeometry(0,0,this->width(),this->height()); + + QHBoxLayout *info_page_layout = new QHBoxLayout(info_page); + info_page_layout->setSpacing(8); + info_page_layout->setContentsMargins(16,0,16,0); + + device_icon = new QLabel(info_page); + info_page_layout->addWidget(device_icon); + + device_name = new QLabel(info_page); + info_page_layout->addWidget(device_name); + info_page_layout->addStretch(); + + device_status = new QLabel(info_page); + info_page_layout->addWidget(device_status); + + connect_btn = new QPushButton(tr("Connect"),this); + connect_btn->setVisible(false); + connect(connect_btn,SIGNAL(clicked(bool)),this,SLOT(onClick_Connect_Btn(bool))); + + disconnect_btn = new QPushButton(tr("Disconnect"),this); + disconnect_btn->setVisible(false); + connect(disconnect_btn,SIGNAL(clicked(bool)),this,SLOT(onClick_Disconnect_Btn(bool))); + + del_btn = new QPushButton(tr("Remove"),this); + del_btn->setVisible(false); + connect(del_btn,SIGNAL(clicked(bool)),this,SLOT(onClick_Delete_Btn(bool))); +} + +DeviceInfoItem::~DeviceInfoItem() +{ + +} + +void DeviceInfoItem::initInfoPage(QString d_name, DEVICE_STATUS status, BluezQt::DevicePtr device) +{ + this->setObjectName(device->address()); + + connect(device.data(),&BluezQt::Device::pairedChanged,this,[=](bool paird){ + qDebug() << Q_FUNC_INFO << "pairedChanged" << paird; + changeDevStatus(paird); + }); + connect(device.data(),&BluezQt::Device::connectedChanged,this,[=](bool connected){ + qDebug() << Q_FUNC_INFO << "connectedChanged" << connected; + setDevConnectedIcon(connected); + }); + connect(device.data(),&BluezQt::Device::nameChanged,this,[=](QString name){ + qDebug() << Q_FUNC_INFO << "nameChanged" << name; + device_name->setText(name); + }); + + QIcon icon_device,icon_status; + if(device->type() == BluezQt::Device::Computer){ + icon_device = QIcon::fromTheme("computer-symbolic"); + }else if(device->type() == BluezQt::Device::Phone){ + icon_device = QIcon::fromTheme("phone-apple-iphone-symbolic"); + }else if((device->type() == BluezQt::Device::Headset)||(device->type() == BluezQt::Device::Headphones)){ + icon_device = QIcon::fromTheme("audio-headphones-symbolic"); + }else if(device->type() == BluezQt::Device::Mouse){ + icon_device = QIcon::fromTheme("input-mouse-symbolic"); + }else if(device->type() == BluezQt::Device::Keyboard){ + icon_device = QIcon::fromTheme("input-keyboard-symbolic"); + }else{ + icon_device = QIcon::fromTheme("bluetooth-symbolic"); + } + device_icon->setPixmap(icon_device.pixmap(QSize(24,24))); + + if(d_name.isEmpty()){ + return; + } + device_name->setText(d_name); + + d_status = status; + device_item = device; + + if(d_status == DEVICE_STATUS::LINK){ + icon_status = QIcon::fromTheme("ukui-dialog-success"); + device_status->setPixmap(icon_status.pixmap(QSize(24,24))); + } +// else if(status == DEVICE_STATUS::UNLINK){ +// icon_status = QIcon::fromTheme("software-update-available-symbolic"); +// device_status->setPixmap(icon_status.pixmap(QSize(24,24))); +// } + + if(item_gsettings->get("style-name").toString() == "ukui-black" || item_gsettings->get("style-name").toString() == "ukui-dark") + { + device_icon->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); + device_icon->setProperty("useIconHighlightEffect", 0x10); + device_status->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); + device_status->setProperty("useIconHighlightEffect", 0x10); + } + + AnimationInit(); +} + +QString DeviceInfoItem::get_dev_name() +{ + return device_item->name(); +} + +void DeviceInfoItem::resizeEvent(QResizeEvent *event) +{ +// this->resize(event->size()); + info_page->resize(event->size()); +} + +void DeviceInfoItem::enterEvent(QEvent *event) +{ + AnimationFlag = true; + mouse_timer->start(); +} + +void DeviceInfoItem::leaveEvent(QEvent *event) +{ +// QDateTime current_date_time = QDateTime::currentDateTime(); +// QString current_time = current_date_time.toString("hh:mm:ss.zzz "); +// qDebug() << Q_FUNC_INFO << current_time; + AnimationFlag = false; + + disconnect_btn->setVisible(false); + connect_btn->setVisible(false); + del_btn->setVisible(false); + + leave_action->setStartValue(QRect(0, 0, info_page->width(), info_page->height())); + leave_action->setEndValue(QRect(0, 0, this->width(), info_page->height())); + leave_action->start(); +} + +void DeviceInfoItem::onClick_Connect_Btn(bool isclicked) +{ + if(!icon_timer&&!connect_timer){ + icon_timer = new QTimer(this); + icon_timer->setInterval(100); + + connect_timer = new QTimer(this); + connect_timer->setInterval(10000); + + connect(connect_timer,&QTimer::timeout,this,[=]{ + if(icon_timer->isActive()){ + icon_timer->stop(); + device_status->setPixmap(QIcon::fromTheme("emblem-danger").pixmap(QSize(24,24))); + device_status->update(); + } + connect_timer->stop(); + }); + + emit sendConnectDevice(device_item->address()); + + i = 7; + + if(!device_status->isVisible()) + device_status->setVisible(true); + + connect(icon_timer,&QTimer::timeout,this,[=]{ + if(i == -1) + i = 7; + device_status->setPixmap(QIcon::fromTheme("ukui-loading-"+QString::number(i,10)).pixmap(24,24)); + device_status->update(); + i--; + }); + connect_timer->start(10000); + icon_timer->start(100); + + }else{ + emit sendConnectDevice(device_item->address()); + connect_timer->start(10000); + icon_timer->start(100); + } +} + +void DeviceInfoItem::onClick_Disconnect_Btn(bool isclicked) +{ +// qDebug() << Q_FUNC_INFO; + emit sendDisconnectDeviceAddress(device_item->address()); +} + +void DeviceInfoItem::onClick_Delete_Btn(bool isclicked) +{ +// qDebug() << Q_FUNC_INFO; +// this->setVisible(false); + emit sendDeleteDeviceAddress(device_item->address()); +} + +void DeviceInfoItem::changeDevStatus(bool pair) +{ + if(icon_timer && icon_timer->isActive()) + icon_timer->stop(); + + if(pair){ + if (!device_item->isConnected()){ + device_status->setVisible(false); + d_status = DEVICE_STATUS::UNLINK; + }else{ + device_status->setVisible(true); + d_status = DEVICE_STATUS::LINK; + QIcon icon_status = QIcon::fromTheme("ukui-dialog-success"); + device_status->setPixmap(icon_status.pixmap(QSize(24,24))); + } + emit sendPairedAddress(device_item->address()); + }else{ +// QIcon icon_status = QIcon::fromTheme("software-installed-symbolic"); +// device_status->setPixmap(icon_status.pixmap(QSize(24,24))); + } +} + +void DeviceInfoItem::setDevConnectedIcon(bool connected) +{ + if(icon_timer && icon_timer->isActive()) + icon_timer->stop(); + + if(connected && device_item->isPaired()){ + d_status = DEVICE_STATUS::LINK; + device_status->setVisible(true); + QIcon icon_status = QIcon::fromTheme("ukui-dialog-success"); + device_status->setPixmap(icon_status.pixmap(QSize(24,24))); + + if(connect_btn->isVisible()){ + connect_btn->setVisible(false); + disconnect_btn->setGeometry(this->width()-BTN_1_X,2,BTN_1_WIDTH,45); + disconnect_btn->setVisible(true); + } + + }else{ + if(disconnect_btn->isVisible()){ + disconnect_btn->setVisible(false); + connect_btn->setGeometry(this->width()-BTN_1_X,2,BTN_1_WIDTH,45); + connect_btn->setVisible(true); + } + + d_status = DEVICE_STATUS::UNLINK; + device_status->setVisible(false); + } +} + +void DeviceInfoItem::AnimationInit() +{ + mouse_timer = new QTimer(this); + mouse_timer->setInterval(300); + + connect(mouse_timer,&QTimer::timeout,this,[=]{ + if(AnimationFlag){ + if(leave_action->state() != QAbstractAnimation::Running){ + enter_action->setStartValue(QRect(0, 0, info_page->width(), info_page->height())); + enter_action->setEndValue(QRect(0, 0, info_page->width()-((device_item->isPaired() && device_item->type() != BluezQt::Device::Mouse && device_item->type() != BluezQt::Device::Keyboard)?ITEM_WIDTH:ITEM_WIDTH1), info_page->height())); + enter_action->start(); + } + } + mouse_timer->stop(); + }); + + enter_action = new QPropertyAnimation(info_page,"geometry"); + enter_action->setDuration(0); + enter_action->setEasingCurve(QEasingCurve::OutQuad); + + connect(enter_action,&QPropertyAnimation::finished,this,[=]{ + if (device_item->isPaired()) { + if (device_item->type() != BluezQt::Device::Mouse && device_item->type() != BluezQt::Device::Keyboard) { + if (d_status == DEVICE_STATUS::LINK){ + disconnect_btn->setGeometry(this->width()-BTN_1_X,2,BTN_1_WIDTH,45); + disconnect_btn->setVisible(true); + }else if (d_status == DEVICE_STATUS::UNLINK){ + connect_btn->setGeometry(this->width()-BTN_1_X,2,BTN_1_WIDTH,45); + connect_btn->setVisible(true); + } + del_btn->setGeometry(this->width()-BTN_2_X,2,BTN_2_WIDTH,45); + del_btn->setVisible(true); + }else{ + del_btn->setGeometry(this->width()-125,2,BTN_1_WIDTH,45); + del_btn->setVisible(true); + } + } else { + connect_btn->setGeometry(this->width()-125,2,BTN_1_WIDTH,45); + connect_btn->setVisible(true); + } + }); + + + leave_action = new QPropertyAnimation(info_page,"geometry"); + leave_action->setDuration(0); + leave_action->setEasingCurve(QEasingCurve::InQuad); +} + +void DeviceInfoItem::updateDeviceStatus(DEVICE_STATUS status) +{ + QIcon icon_status; + if(status == DEVICE_STATUS::LINK){ + icon_status = QIcon::fromTheme("emblem-default"); + device_status->setPixmap(icon_status.pixmap(QSize(24,24))); + }else if(status == DEVICE_STATUS::UNLINK){ + icon_status = QIcon::fromTheme("emblem-important"); + device_status->setPixmap(icon_status.pixmap(QSize(24,24))); + } +} + +void DeviceInfoItem::GSettingsChanges(const QString &key) +{ + qDebug() << Q_FUNC_INFO << key; + if(key == "styleName"){ + if(item_gsettings->get("style-name").toString() == "ukui-black" || item_gsettings->get("style-name").toString() == "ukui-dark") + { + device_icon->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); + device_icon->setProperty("useIconHighlightEffect", 0x10); + device_status->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); + device_status->setProperty("useIconHighlightEffect", 0x10); + }else{ + device_icon->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::black)); + device_icon->setProperty("useIconHighlightEffect", 0x10); + device_status->setProperty("setIconHighlightEffectDefaultColor", QColor(Qt::white)); + device_status->setProperty("useIconHighlightEffect", 0x10); + } + } +} diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/deviceinfoitem.h ukui-control-center-3.0.3/plugins/devices/bluetooth/deviceinfoitem.h --- ukui-control-center-2.0.3/plugins/devices/bluetooth/deviceinfoitem.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/deviceinfoitem.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,89 @@ +#ifndef DEVICEINFOITEM_H +#define DEVICEINFOITEM_H + +#include "config.h" + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define ITEM_WIDTH 220 +#define ITEM_WIDTH1 130 +#define BTN_1_X 215 +#define BTN_2_X 90 +#define BTN_1_WIDTH 120 +#define BTN_2_WIDTH 85 + +class DeviceInfoItem : public QWidget +{ + Q_OBJECT +public: + explicit DeviceInfoItem(QWidget *parent = nullptr); + ~DeviceInfoItem(); + void initInfoPage(QString d_name = "",DEVICE_STATUS status = DEVICE_STATUS::NOT,BluezQt::DevicePtr device = nullptr); + QString get_dev_name(); + void changeDevStatus(bool); + void setDevConnectedIcon(bool); + void AnimationInit(); +protected: + void resizeEvent(QResizeEvent *event); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); +signals: + void sendConnectDevice(QString); + void sendDisconnectDeviceAddress(QString); + void sendDeleteDeviceAddress(QString); + void send_this_item_is_pair(); + void sendPairedAddress(QString); +private slots: + void onClick_Connect_Btn(bool); + void onClick_Disconnect_Btn(bool); + void onClick_Delete_Btn(bool); + void updateDeviceStatus(DEVICE_STATUS status = DEVICE_STATUS::NOT); + void GSettingsChanges(const QString &key); +private: + QGSettings *item_gsettings = nullptr; + + QWidget *parent_widget = nullptr; + QLabel *device_icon = nullptr; + QLabel *device_name = nullptr; + QLabel *device_status = nullptr; + + BluezQt::DevicePtr device_item = nullptr; + + QPushButton *connect_btn = nullptr; + QPushButton *disconnect_btn = nullptr; + QPushButton *del_btn = nullptr; + + DEVICE_STATUS d_status; + + QFrame *info_page = nullptr; + QTimer *icon_timer = nullptr; + QTimer *connect_timer = nullptr; + int i = 7; + + QPropertyAnimation *enter_action = nullptr; + QPropertyAnimation *leave_action = nullptr; + + bool AnimationFlag = false; + QTimer *mouse_timer = nullptr; +}; + +#endif // DEVICEINFOITEM_H diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/loadinglabel.cpp ukui-control-center-3.0.3/plugins/devices/bluetooth/loadinglabel.cpp --- ukui-control-center-2.0.3/plugins/devices/bluetooth/loadinglabel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/loadinglabel.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,39 @@ +#include "loadinglabel.h" + +LoadingLabel::LoadingLabel(QObject *parent) +{ + m_timer = new QTimer(this); + m_timer->setInterval(100); + connect(m_timer,SIGNAL(timeout()),this,SLOT(Refresh_icon())); + this->setPixmap(QIcon::fromTheme("ukui-loading-"+QString("%1").arg(i)).pixmap(this->width(),this->height())); +} + +LoadingLabel::~LoadingLabel() +{ +// delete m_timer; +} + +void LoadingLabel::setTimerStop() +{ + m_timer->start(); +} + +void LoadingLabel::setTimerStart() +{ + m_timer->stop(); +} + +void LoadingLabel::setTimeReresh(int m) +{ + m_timer->setInterval(m); +} + +void LoadingLabel::Refresh_icon() +{ + qDebug() << Q_FUNC_INFO; + if(i == 8) + i = 0; + this->setPixmap(QIcon::fromTheme("ukui-loading-"+QString::number(i,10)).pixmap(this->width(),this->height())); + this->update(); + i++; +} diff -Nru ukui-control-center-2.0.3/plugins/devices/bluetooth/loadinglabel.h ukui-control-center-3.0.3/plugins/devices/bluetooth/loadinglabel.h --- ukui-control-center-2.0.3/plugins/devices/bluetooth/loadinglabel.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/bluetooth/loadinglabel.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,27 @@ +#ifndef LOADINGLABEL_H +#define LOADINGLABEL_H + +#include +#include +#include +#include +#include +#include + +class LoadingLabel : public QLabel +{ +public: + explicit LoadingLabel(QObject *parent = nullptr); + ~LoadingLabel(); + void setTimerStop(); + void setTimerStart(); + void setTimeReresh(int); + +private slots: + void Refresh_icon(); +private: + QTimer *m_timer; + int i; +}; + +#endif // LOADINGLABEL_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/kbdlayoutmanager.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/kbdlayoutmanager.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/kbdlayoutmanager.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/kbdlayoutmanager.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -19,7 +19,8 @@ */ #include "kbdlayoutmanager.h" #include "ui_layoutmanager.h" -#include "tastenbrett.h" +#include "preview/keyboardpainter.h" +#include "CloseButton/closebutton.h" #include #include @@ -63,16 +64,8 @@ setAttribute(Qt::WA_DeleteOnClose); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); - ui->PreBtn->setVisible(false); ui->variantFrame->setFrameShape(QFrame::Shape::Box); @@ -84,14 +77,15 @@ setupComponent(); setupConnect(); } - } KbdLayoutManager::~KbdLayoutManager() { delete ui; + ui = nullptr; if (QGSettings::isSchemaInstalled(KBD_LAYOUTS_SCHEMA)){ delete kbdsettings; + kbdsettings = nullptr; } } @@ -119,10 +113,11 @@ rebuildVariantCombo(); rebuild_listwidget(); + } void KbdLayoutManager::setupConnect(){ - connect(ui->closeBtn, &QPushButton::clicked, [=]{ + connect(ui->closeBtn, &CloseButton::clicked, [=]{ close(); }); connect(ui->cancelBtn, &QPushButton::clicked, [=]{ @@ -143,6 +138,16 @@ rebuildVariantCombo(); }); +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) + connect(ui->variantComboBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ +#else + connect(ui->variantComboBox, QOverload::of(&QComboBox::currentIndexChanged), [=](int index) { +#endif + Q_UNUSED(index) + if (index != -1) + installedNoSame(); + }); + connect(ui->installBtn, &QPushButton::clicked, this, [=]{ QString layout = ui->variantComboBox->currentData().toString(); @@ -153,8 +158,17 @@ rebuild_listwidget(); }); -// connect(ui->PreBtn, &QPushButton::clicked, this, &KbdLayoutManager::preview); + connect(ui->PreBtn, &QPushButton::clicked, this, &KbdLayoutManager::preview); +} + +void KbdLayoutManager::installedNoSame(){ + //最多4个布局,来自GTK控制面板,原因未知 + QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); + if (layouts.length() < MAXNUM && !layouts.contains(ui->variantComboBox->currentData(Qt::UserRole).toString())) + ui->installBtn->setEnabled(true); + else + ui->installBtn->setEnabled(false); } void KbdLayoutManager::rebuildSelectListWidget(){ @@ -197,35 +211,30 @@ ui->variantComboBox->clear(); for (QString name : availablelayoutsList){ QString desc = kbd_get_description_by_id(const_cast(name.toLatin1().data())); + ui->variantComboBox->blockSignals(true); ui->variantComboBox->addItem(desc, name); + ui->variantComboBox->blockSignals(false); } + + installedNoSame(); } void KbdLayoutManager::rebuild_listwidget(){ - //最多4个布局,来自GTK控制面板,原因未知 - QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); - if (layouts.length() >= MAXNUM) - ui->installBtn->setEnabled(false); - else - ui->installBtn->setEnabled(true); + installedNoSame(); ui->listWidget->clear(); + QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); for (QString layout : layouts){ QString desc = kbd_get_description_by_id(const_cast(layout.toLatin1().data())); //自定义widget QWidget * layoutWidget = new QWidget(); layoutWidget->setAttribute(Qt::WA_DeleteOnClose); -// layoutWidget->setStyleSheet("QWidget{border-bottom: 1px solid #f5f6f7}"); QHBoxLayout * mainHLayout = new QHBoxLayout(layoutWidget); QLabel * layoutLabel = new QLabel(layoutWidget); QPushButton * layoutdelBtn = new QPushButton(layoutWidget); -// layoutdelBtn->setIcon(QIcon("://keyboardcontrol/delete.png")); layoutdelBtn->setText(tr("Del")); -// layoutdelBtn->setStyleSheet("" -// "QPushButton{background: #FA6056; border-radius: 2px;}" -// "QPushButton:hover:pressed{background: #E54A50; border-radius: 2px;}"); connect(layoutdelBtn, &QPushButton::clicked, this, [=]{ QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); @@ -244,28 +253,45 @@ item->setSizeHint(QSize(ui->listWidget->width(), 50)); layoutLabel->setText(desc); + QFontMetrics fontWidth(layoutLabel->font()); + QString elideNote = fontWidth.elidedText(desc, Qt::ElideRight, 100); + layoutLabel->setText(elideNote); + layoutLabel->setToolTip(desc); ui->listWidget->addItem(item); ui->listWidget->setItemWidget(item, layoutWidget); } + if (!ui->listWidget->count()) { + ui->installedFrame->setVisible(false); + } else { + ui->installedFrame->setVisible(true); + } } -//void KbdLayoutManager::preview() -//{ -// QString variantID; -// QString layoutID = ui->variantComboBox->currentData(Qt::UserRole).toString(); -// QStringList layList = layoutID.split('\t'); - -// for (int i = 0; i < layList.length(); i++) { -// if (0 == i) { -// layoutID = layList.at(0); -// } -// if (1 == i) { -// variantID = layList.at(1); -// } -// } -// Tastenbrett::launch("pc104", layoutID, variantID, ""); -//} +void KbdLayoutManager::preview() +{ + QString variantID; + QString layoutID = ui->variantComboBox->currentData(Qt::UserRole).toString(); + QStringList layList = layoutID.split('\t'); + + for (int i = 0; i < layList.length(); i++) { + if (0 == i) { + layoutID = layList.at(0); + } + if (1 == i) { + variantID = layList.at(1); + } + } + + KeyboardPainter* layoutPreview = new KeyboardPainter(); + + + qDebug() << " layoutID:" << layoutID << "variantID:" << variantID <generateKeyboardLayout(layoutID, variantID, "pc104", ""); + layoutPreview->setWindowTitle(tr("Keyboard Preview")); + layoutPreview->setModal(true); + layoutPreview->exec(); +} void KbdLayoutManager::kbd_trigger_available_countries(char *countryid){ xkl_config_registry_foreach_country_variant (config_registry, countryid, (TwoConfigItemsProcessFunc)kbd_set_available_countries, NULL); @@ -288,9 +314,6 @@ item.desc = config_item->description; item.name = config_item->name; -// qDebug()<<"countries" << "desc = "<append(item); countries.append(item); } @@ -299,8 +322,6 @@ Layout item; item.desc = config_item->description; item.name = config_item->name; -// qDebug()<<"languages" << "desc = "<append(item); languages.append(item); } @@ -330,6 +351,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/kbdlayoutmanager.h ukui-control-center-3.0.3/plugins/devices/keyboard/kbdlayoutmanager.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/kbdlayoutmanager.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/kbdlayoutmanager.h 2021-04-14 01:27:20.000000000 +0000 @@ -57,7 +57,6 @@ void kbd_trigger_available_countries(char * countryid); void kbd_trigger_available_languages(char * languageid); - void configRegistry(); void setupComponent(); void setupConnect(); @@ -65,7 +64,9 @@ void rebuildVariantCombo(); void rebuild_listwidget(); -// void preview(); + void preview(); + + void installedNoSame(); protected: void paintEvent(QPaintEvent * event); @@ -76,7 +77,6 @@ QStringList layoutsList; QGSettings * kbdsettings; - }; #endif // KBDLAYOUTMANAGER_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/keyboardcontrol.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/keyboardcontrol.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/keyboardcontrol.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/keyboardcontrol.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -21,6 +21,7 @@ #include "ui_keyboardcontrol.h" #include +#include #include #include @@ -36,114 +37,148 @@ #define CC_KEYBOARD_OSD_SCHEMA "org.ukui.control-center.osd" #define CC_KEYBOARD_OSD_KEY "show-lock-tip" -KeyboardControl::KeyboardControl() +KeyboardControl::KeyboardControl() : mFirstLoad(true) { - ui = new Ui::KeyboardControl; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Keyboard"); pluginType = DEVICES; +} - settingsCreate = false; +KeyboardControl::~KeyboardControl() +{ + if (!mFirstLoad) { + delete ui; + ui = nullptr; + if (settingsCreate) { +// delete kbdsettings; + delete settings; + settings = nullptr; + } + } +} - setupStylesheet(); - setupComponent(); +QString KeyboardControl::get_plugin_name() { + return pluginName; +} - // 初始化键盘通用设置GSettings - const QByteArray id(KEYBOARD_SCHEMA); - // 初始化键盘布局GSettings - const QByteArray idd(KBD_LAYOUTS_SCHEMA); - // 初始化按键提示GSettings - const QByteArray iid(CC_KEYBOARD_OSD_SCHEMA); - // 控制面板自带GSettings,不再判断是否安装 - osdSettings = new QGSettings(iid); +int KeyboardControl::get_plugin_type() { + return pluginType; +} - if (QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(idd)){ - settingsCreate = true; +QWidget *KeyboardControl::get_plugin_ui() { + if (mFirstLoad) { + ui = new Ui::KeyboardControl; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + mFirstLoad = false; + settingsCreate = false; + + initTitleLabel(); + setupStylesheet(); + setupComponent(); + + // 初始化键盘通用设置GSettings + const QByteArray id(KEYBOARD_SCHEMA); + // 初始化键盘布局GSettings + // const QByteArray idd(KBD_LAYOUTS_SCHEMA); + // 初始化按键提示GSettings + const QByteArray iid(CC_KEYBOARD_OSD_SCHEMA); + // 控制面板自带GSettings,不再判断是否安装 + osdSettings = new QGSettings(iid); + + if (QGSettings::isSchemaInstalled(id)){ + settingsCreate = true; - kbdsettings = new QGSettings(idd); - settings = new QGSettings(id); +// kbdsettings = new QGSettings(idd); + settings = new QGSettings(id); - //构建布局管理器对象 - layoutmanagerObj = new KbdLayoutManager(); + //构建布局管理器对象 + layoutmanagerObj = new KbdLayoutManager(); - setupConnect(); - initGeneralStatus(); + setupConnect(); + initGeneralStatus(); - rebuildLayoutsComBox(); - } + rebuildLayoutsComBox(); + } + } + return pluginWidget; } -KeyboardControl::~KeyboardControl() -{ - delete ui; - if (settingsCreate){ - delete kbdsettings; - delete settings; - } +void KeyboardControl::plugin_delay_control() { } -QString KeyboardControl::get_plugin_name(){ - return pluginName; -} +const QString KeyboardControl::name() const { -int KeyboardControl::get_plugin_type(){ - return pluginType; + return QStringLiteral("keyboard"); } -QWidget *KeyboardControl::get_plugin_ui(){ - return pluginWidget; +void KeyboardControl::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); } -void KeyboardControl::plugin_delay_control(){ +void KeyboardControl::setupStylesheet(){ -} + //~ contents_path /keyboard/Enable repeat key + ui->enableLabel->setText(tr("Enable repeat key")); + //~ contents_path /keyboard/Delay + ui->delayLabel->setText(tr("Delay")); + //~ contents_path /keyboard/Speed + ui->speedLabel->setText(tr("Speed")); + //~ contents_path /keyboard/Input characters to test the repetition effect: + ui->repeatLabel->setText(tr("Input characters to test the repetition effect:")); + //~ contents_path /keyboard/Tip of keyboard + ui->tipLabel->setText(tr("Tip of keyboard")); + //~ contents_path /keyboard/Keyboard layout + ui->layoutLabel->setText(tr("Keyboard layout")); -void KeyboardControl::setupStylesheet(){ - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); } void KeyboardControl::setupComponent(){ - addWgt = new HoverWidget(""); - addWgt->setObjectName("addwgt"); - addWgt->setMinimumSize(QSize(580, 50)); - addWgt->setMaximumSize(QSize(960, 50)); - addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); - - QHBoxLayout *addLyt = new QHBoxLayout; - - QLabel * iconLabel = new QLabel(); - QLabel * textLabel = new QLabel(tr("Install layouts")); - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); - iconLabel->setPixmap(pixgray); - addLyt->addWidget(iconLabel); - addLyt->addWidget(textLabel); - addLyt->addStretch(); - addWgt->setLayout(addLyt); +// addWgt = new HoverWidget(""); +// addWgt->setObjectName("addwgt"); +// addWgt->setMinimumSize(QSize(580, 50)); +// addWgt->setMaximumSize(QSize(960, 50)); +// addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); + + + ui->layoutFrame_0->hide(); + ui->addLytWidget->hide(); + +// QHBoxLayout *addLyt = new QHBoxLayout; + +// QLabel * iconLabel = new QLabel(); +// QLabel * textLabel = new QLabel(tr("Install layouts")); +// QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); +// iconLabel->setPixmap(pixgray); +// addLyt->addWidget(iconLabel); +// addLyt->addWidget(textLabel); +// addLyt->addStretch(); +// addWgt->setLayout(addLyt); // 悬浮改变Widget状态 - connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname) { - Q_UNUSED(mname); - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(base);"); - }); +// connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname) { +// Q_UNUSED(mname); +// QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); +// iconLabel->setPixmap(pixgray); +// textLabel->setStyleSheet("color: palette(base);"); +// }); // 还原状态 - connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname) { - Q_UNUSED(mname); - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(windowText);"); - }); +// connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname) { +// Q_UNUSED(mname); +// QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); +// iconLabel->setPixmap(pixgray); +// textLabel->setStyleSheet("color: palette(windowText);"); +// }); - ui->addLyt->addWidget(addWgt); +// ui->addLyt->addWidget(addWgt); // 隐藏未开发功能 ui->repeatFrame_5->hide(); @@ -175,39 +210,68 @@ settings->set(RATE_KEY, value); }); - connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname) { - Q_UNUSED(mname); - KbdLayoutManager * templayoutManager = new KbdLayoutManager; - templayoutManager->exec(); + connect(settings,&QGSettings::changed,this,[=](const QString &key) { + if(key == "rate") { + ui->speedHorSlider->setValue(settings->get(RATE_KEY).toInt()); + } else if(key == "repeat") { + keySwitchBtn->setChecked(settings->get(REPEAT_KEY).toBool()); + setKeyboardVisible(keySwitchBtn->isChecked()); + } else if(key == "delay") { + ui->delayHorSlider->setValue(settings->get(DELAY_KEY).toInt()); + } }); - connect(ui->resetBtn, &QPushButton::clicked, this, [=] { - kbdsettings->reset(KBD_LAYOUTS_KEY); + connect(osdSettings,&QGSettings::changed,this,[=](const QString &key) { + if(key == "showLockTip") { + tipKeyboardSwitchBtn->blockSignals(true); + tipKeyboardSwitchBtn->setChecked(osdSettings->get(CC_KEYBOARD_OSD_KEY).toBool()); + tipKeyboardSwitchBtn->blockSignals(false); + } }); - connect(kbdsettings, &QGSettings::changed, [=](QString key) { - if (key == KBD_LAYOUTS_KEY) - rebuildLayoutsComBox(); +// connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname) { +// Q_UNUSED(mname); +// KbdLayoutManager * templayoutManager = new KbdLayoutManager; +// templayoutManager->exec(); +// }); + +// connect(ui->resetBtn, &QPushButton::clicked, this, [=] { +// kbdsettings->reset(KBD_LAYOUTS_KEY); +// if ("zh_CN" == QLocale::system().name()) { +// kbdsettings->set(KBD_LAYOUTS_KEY, "cn"); +// } else { +// kbdsettings->set(KBD_LAYOUTS_KEY, "us"); +// } +// }); + + connect(ui->inputSettingsBtn, &QPushButton::clicked, this, [=]{ + QProcess process; + process.startDetached("fcitx-config-gtk3"); }); +// connect(kbdsettings, &QGSettings::changed, [=](QString key) { +// if (key == KBD_LAYOUTS_KEY) +// rebuildLayoutsComBox(); +// }); + connect(tipKeyboardSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked) { osdSettings->set(CC_KEYBOARD_OSD_KEY, checked); }); -#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - connect(ui->layoutsComBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ -#else - connect(ui->layoutsComBox, QOverload::of(&QComboBox::currentIndexChanged), [=](int index) { -#endif - QStringList layoutsList; - layoutsList.append(ui->layoutsComBox->currentData(Qt::UserRole).toString()); - for (int i = 0; i < ui->layoutsComBox->count(); i++){ - QString id = ui->layoutsComBox->itemData(i, Qt::UserRole).toString(); - if (i != index) //跳过当前item - layoutsList.append(id); - } - kbdsettings->set(KBD_LAYOUTS_KEY, layoutsList); - }); +//#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) +// connect(ui->layoutsComBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ +//#else +// connect(ui->layoutsComBox, QOverload::of(&QComboBox::currentIndexChanged), [=](int index) { +//#endif +// QStringList layoutsList; +// layoutsList.append(ui->layoutsComBox->currentData(Qt::UserRole).toString()); +// for (int i = 0; i < ui->layoutsComBox->count(); i++){ +// QString id = ui->layoutsComBox->itemData(i, Qt::UserRole).toString(); +// if (i != index) //跳过当前item +// layoutsList.append(id); +// } +// kbdsettings->set(KBD_LAYOUTS_KEY, layoutsList); +// }); } void KeyboardControl::initGeneralStatus() { @@ -228,21 +292,21 @@ } void KeyboardControl::rebuildLayoutsComBox() { - QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); - ui->layoutsComBox->blockSignals(true); +// QStringList layouts = kbdsettings->get(KBD_LAYOUTS_KEY).toStringList(); +// ui->layoutsComBox->blockSignals(true); //清空键盘布局下拉列表 - ui->layoutsComBox->clear(); +// ui->layoutsComBox->clear(); //重建键盘布局下拉列表 - for (QString layout : layouts) { - ui->layoutsComBox->addItem(layoutmanagerObj->kbd_get_description_by_id(const_cast(layout.toLatin1().data())), layout); - } - ui->layoutsComBox->blockSignals(false); - if (0 == ui->layoutsComBox->count()) { - ui->layoutsComBox->setVisible(false); - } else { - ui->layoutsComBox->setVisible(true); - } +// for (QString layout : layouts) { +// ui->layoutsComBox->addItem(layoutmanagerObj->kbd_get_description_by_id(const_cast(layout.toLatin1().data())), layout); +// } +// ui->layoutsComBox->blockSignals(false); +// if (0 == ui->layoutsComBox->count()) { +// ui->layoutsComBox->setVisible(false); +// } else { +// ui->layoutsComBox->setVisible(true); +// } } void KeyboardControl::setKeyboardVisible(bool checked) { diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/keyboardcontrol.h ukui-control-center-3.0.3/plugins/devices/keyboard/keyboardcontrol.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/keyboardcontrol.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/keyboardcontrol.h 2021-04-14 01:27:20.000000000 +0000 @@ -51,7 +51,9 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + void initTitleLabel(); void setupStylesheet(); void setupComponent(); void setupConnect(); @@ -67,7 +69,7 @@ QWidget * pluginWidget; QGSettings * settings; - QGSettings * kbdsettings; +// QGSettings * kbdsettings; QGSettings * osdSettings; SwitchButton * keySwitchBtn; @@ -79,6 +81,7 @@ HoverWidget * addWgt; bool settingsCreate; + bool mFirstLoad; }; #endif // KEYBOARDCONTROL_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/keyboardcontrol.ui ukui-control-center-3.0.3/plugins/devices/keyboard/keyboardcontrol.ui --- ukui-control-center-2.0.3/plugins/devices/keyboard/keyboardcontrol.ui 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/keyboardcontrol.ui 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 642 - 682 + 690 @@ -148,7 +148,7 @@ 16 - + 0 @@ -226,7 +226,7 @@ 16 - + 0 @@ -266,33 +266,7 @@ - QSlider{ - width: 178px; - height: 20px; -} -QSlider::groove:horizontal { - border: 0px solid #bbb; - -} -QSlider::sub-page:horizontal { - background: #3D6BE5; - border-radius: 2px; - margin-top:8px; - margin-bottom:9px; -} -QSlider::add-page:horizontal { - background: rgba(52,70,80,90%); - border: 0px solid #777; - border-radius: 2px; - margin-top:8px; - margin-bottom:9px; -} -QSlider::handle:horizontal { - width: 20px; - height: 20px; - background: #3D6BE5; - border-radius:10px; -} + 100 @@ -371,7 +345,7 @@ 16 - + 0 @@ -411,33 +385,7 @@ - QSlider{ - width: 178px; - height: 20px; -} -QSlider::groove:horizontal { - border: 0px solid #bbb; - -} -QSlider::sub-page:horizontal { - background: #3D6BE5; - border-radius: 2px; - margin-top:8px; - margin-bottom:9px; -} -QSlider::add-page:horizontal { - background: rgba(52,70,80,90%); - border: 0px solid #777; - border-radius: 2px; - margin-top:8px; - margin-bottom:9px; -} -QSlider::handle:horizontal { - width: 20px; - height: 20px; - background: #3D6BE5; - border-radius:10px; -} + 10 @@ -516,7 +464,7 @@ 16 - + 0 @@ -524,7 +472,7 @@ - Test repetition rate of the input character: + Input characters to test the repetition effect: true @@ -549,13 +497,13 @@ 200 - 30 + 35 200 - 30 + 35 @@ -613,7 +561,7 @@ 16 - + 0 @@ -688,7 +636,7 @@ 16 - + 0 @@ -748,7 +696,7 @@ - Keyboard Layout + Input Settings true @@ -808,7 +756,7 @@ 16 - + 0 @@ -861,7 +809,7 @@ - + 0 @@ -907,82 +855,22 @@ - + - 0 - 50 + 120 + 0 - 16777215 - 50 + 120 + 16777215 - - QFrame::Box - - - QFrame::Plain + + Input Set - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 48 - - - 16 - - - 16 - - - - - reset default layout - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Reset layout - - - - - - diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/keyboard.pro ukui-control-center-3.0.3/plugins/devices/keyboard/keyboard.pro --- ukui-control-center-2.0.3/plugins/devices/keyboard/keyboard.pro 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/keyboard.pro 2021-04-14 01:27:20.000000000 +0000 @@ -7,9 +7,10 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) -QT += widgets x11extras +QT += widgets x11extras KWindowSystem xml KGuiAddons KCoreAddons concurrent KConfigCore KConfigGui KI18n #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = lib CONFIG += plugin @@ -21,8 +22,10 @@ INCLUDEPATH += \ $$PROJECT_COMPONENTSOURCE \ $$PROJECT_ROOTDIR \ + /usr/include/KF5 \ + /usr/include/xcb \ -LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt +LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -lX11 -lxkbfile CONFIG += link_pkgconfig \ C++11 @@ -35,12 +38,40 @@ SOURCES += \ keyboardcontrol.cpp \ kbdlayoutmanager.cpp \ -# tastenbrett.cpp + \# tastenbrett.cpp + preview/debug.cpp \ + preview/geometry_components.cpp \ + preview/geometry_parser.cpp \ + preview/kbpreviewframe.cpp \ + preview/keyaliases.cpp \ + preview/keyboard_config.cpp \ + preview/keyboardlayout.cpp \ + preview/keyboardpainter.cpp \ + preview/keysym2ucs.cpp \ + preview/keysymhelper.cpp \ + preview/symbol_parser.cpp \ + preview/x11_helper.cpp \ + preview/xkb_rules.cpp HEADERS += \ keyboardcontrol.h \ kbdlayoutmanager.h \ -# tastenbrett.h + \# tastenbrett.h + preview/config-keyboard.h \ + preview/config-workspace.h \ + preview/debug.h \ + preview/geometry_components.h \ + preview/geometry_parser.h \ + preview/kbpreviewframe.h \ + preview/keyaliases.h \ + preview/keyboard_config.h \ + preview/keyboardlayout.h \ + preview/keyboardpainter.h \ + preview/keysym2ucs.h \ + preview/keysymhelper.h \ + preview/symbol_parser.h \ + preview/x11_helper.h \ + preview/xkb_rules.h FORMS += \ keyboardcontrol.ui \ diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/layoutmanager.ui ukui-control-center-3.0.3/plugins/devices/keyboard/layoutmanager.ui --- ukui-control-center-2.0.3/plugins/devices/keyboard/layoutmanager.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/layoutmanager.ui 2021-04-14 01:27:20.000000000 +0000 @@ -33,10 +33,10 @@ 0 - 9 + 15 - 9 + 15 0 @@ -106,6 +106,22 @@ 0 + + 16 + + + + + + 0 + 0 + + + + Manager Keyboard Layout + + + @@ -120,7 +136,7 @@ - + 32 @@ -161,19 +177,6 @@ 48 - - - - 0 - 0 - - - - Manager Keyboard Layout - - - - 24 @@ -457,6 +460,13 @@ + + + CloseButton + QPushButton +
CloseButton/closebutton.h
+
+
diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/config-keyboard.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/config-keyboard.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/config-keyboard.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/config-keyboard.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,9 @@ +#ifndef CONFIG_KEYBOARD_H +#define CONFIG_KEYBOARD_H + +#define HAVE_XINPUT +/* #undef HAVE_UDEV */ + +#define NEW_GEOMETRY + +#endif // CONFIG_KEYBOARD_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/config-workspace.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/config-workspace.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/config-workspace.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/config-workspace.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,166 @@ +/* config-workspace.h. Generated by cmake from config-workspace.h.cmake */ + +/* #undef HAVE_QIMAGEBLITZ */ + +/* Define if you have DPMS support */ +#define HAVE_DPMS 1 + +/* Define if you have the DPMSCapable prototype in */ +/* #undef HAVE_DPMSCAPABLE_PROTO */ + +/* Define if you have the DPMSInfo prototype in */ +/* #undef HAVE_DPMSINFO_PROTO */ + +/* Defines if your system has the libfontconfig library */ +#define HAVE_FONTCONFIG 1 + +/* Defines if your system has the freetype library */ +#define HAVE_FREETYPE 1 + +/* Define if you have gethostname */ +/* #undef HAVE_GETHOSTNAME */ + +/* Define if you have the gethostname prototype */ +/* #undef HAVE_GETHOSTNAME_PROTO */ + +/* Define to 1 if you have the `getpeereid' function. */ +/* #undef HAVE_GETPEEREID */ + +/* Defines if you have Solaris' libkstat */ +/* #undef HAVE_KSTAT */ + +/* Define if you have long long as datatype */ +/* #undef HAVE_LONG_LONG */ + +/* Define to 1 if you have the `nice' function. */ +/* #undef HAVE_NICE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SASL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SASL_SASL_H */ + +/* Define to 1 if you have the `setpriority' function. */ +#define HAVE_SETPRIORITY 1 + +/* Define to 1 if you have the `sigaction' function. */ +/* #undef HAVE_SIGACTION */ + +/* Define to 1 if you have the `sigset' function. */ +/* #undef HAVE_SIGSET */ + +/* Define to 1 if you have statvfs */ +#define HAVE_STATVFS 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STRING_H */ + +/* Define if you have the struct ucred */ +/* #undef HAVE_STRUCT_UCRED */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_LOADAVG_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_MOUNT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STATFS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STATVFS_H 1 + +/* Define to 1 if you have statfs(). */ +#define HAVE_STATFS 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SELECT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKET_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_TYPES_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_VFS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have unsetenv */ +/* #undef HAVE_UNSETENV */ + +/* Define if you have the unsetenv prototype */ +/* #undef HAVE_UNSETENV_PROTO */ + +/* Define if you have usleep */ +/* #undef HAVE_USLEEP */ + +/* Define if you have the usleep prototype */ +/* #undef HAVE_USLEEP_PROTO */ + +/* Define to 1 if you have the `vsnprintf' function. */ +/* #undef HAVE_VSNPRINTF */ + +/* Define to 1 if you have the Wayland libraries. */ +/* #undef WAYLAND_FOUND */ + +/* KDE's default home directory */ +/* #undef KDE_DEFAULT_HOME */ + +/* KDE's binaries directory */ +#define KDE_BINDIR "bin" + +/* KDE's configuration directory */ +#define KDE_CONFDIR "/etc/xdg" + +/* KDE's static data directory */ +#define KDE_DATADIR "share" + +/* Define where your java executable is */ +#undef PATH_JAVA + +/* Define to 1 if you can safely include both and . */ +/* #undef TIME_WITH_SYS_TIME */ + +/* xkb resources directory */ +#define XKBDIR "/usr/share/X11/xkb" + +/* KWin binary name */ +#define KWIN_BIN "kwin_x11" + +/* Number of bits in a file offset, on hosts where this is settable. */ +#define _FILE_OFFSET_BITS 64 + +/* Define 1 if the Breeze window decoration was found */ +#define HAVE_BREEZE_DECO 1 + +#ifdef HAVE_BREEZE_DECO +#define BREEZE_KDECORATION_PLUGIN_ID "org.kde.breeze" +#endif + +/* + * On HP-UX, the declaration of vsnprintf() is needed every time ! + */ + +/* type to use in place of socklen_t if not defined */ +#define kde_socklen_t socklen_t + +#define WORKSPACE_VERSION_STRING "5.16.5" diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/debug.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/debug.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/debug.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/debug.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,11 @@ +// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT! + +#include "debug.h" + + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) +Q_LOGGING_CATEGORY(KCM_KEYBOARD, "org.kde.kcm_keyboard", QtWarningMsg) +#else +Q_LOGGING_CATEGORY(KCM_KEYBOARD, "org.kde.kcm_keyboard") +#endif + diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/debug.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/debug.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/debug.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/debug.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,11 @@ +// This file was generated by ecm_qt_declare_logging_category(): DO NOT EDIT! + +#ifndef ECM_QLOGGINGCATEGORY_KCM_KEYBOARD_DEBUG_H +#define ECM_QLOGGINGCATEGORY_KCM_KEYBOARD_DEBUG_H + +#include + +Q_DECLARE_LOGGING_CATEGORY(KCM_KEYBOARD) + + +#endif diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/geometry_components.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/geometry_components.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/geometry_components.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/geometry_components.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "geometry_components.h" + +#include +#include +#include + + +Q_LOGGING_CATEGORY(KEYBOARD_PREVIEW, "keyboard_preview") + + +GShape::GShape() +{ + cordi_count = 0; +} + +void GShape::setCordinate(double a, double b) +{ + cordii << QPoint(a, b); + cordi_count++; +} + +void GShape::setApprox(double a, double b) +{ + a -= approx.x(); + b -= approx.y(); + approx = QPoint(a, b); +} + +QPoint GShape :: getCordii(int i) const +{ + if (i < cordi_count) { + return cordii[i]; + } + + return QPoint(); +} + +void GShape::display() +{ + qCDebug(KEYBOARD_PREVIEW) << "shape: " << sname << "\n"; + qCDebug(KEYBOARD_PREVIEW) << "(" << approx.x() << "," << approx.y() << ");"; + + for (int i = 0; i < cordi_count; i++) { + qCDebug(KEYBOARD_PREVIEW) << cordii[i]; + } +} + +double GShape::size(int vertical) const +{ + if (!cordii.isEmpty()) { + if (vertical == 0) { + if (approx.x() == 0 && approx.y() == 0) { + int max = 0; + for (int i = 0; i < cordi_count; i++) { + if (max < cordii[i].x()) { + max = cordii[i].x(); + } + } + return max; + } else { + return approx.x(); + } + } else { + if (approx.x() == 0 && approx.y() == 0) { + int max = 0; + for (int i = 0; i < cordi_count; i++) { + if (max < cordii[i].y()) { + max = cordii[i].y(); + } + } + return max; + } + + return approx.y(); + } + } + + return 0; +} + + +Key::Key() +{ + offset = 0; +} + +void Key::setKeyPosition(double x, double y) +{ + position = QPoint(x, y); +} + +void Key::showKey() +{ + qCDebug(KEYBOARD_PREVIEW) << "\n\tKey: " << name << "\tshape: " << shapeName << "\toffset: " << offset; + qCDebug(KEYBOARD_PREVIEW) << "\tposition" << position; +} + + +Row::Row() +{ + top = 0; + left = 0; + keyCount = 0; + vertical = 0; + keyList << Key(); +} + +void Row::addKey() +{ + //qCDebug(KEYBOARD_PREVIEW) << "keyCount: " << keyCount; + keyCount++; + keyList << Key(); +} + +void Row::displayRow() +{ + qCDebug(KEYBOARD_PREVIEW) << "\nRow: (" << left << "," << top << ")\n"; + qCDebug(KEYBOARD_PREVIEW) << "vertical: " << vertical; + for (int i = 0; i < keyCount; i++) { + keyList[i].showKey(); + } +} + + +Section::Section() +{ + top = 0; + left = 0; + angle = 0; + rowCount = 0; + vertical = 0; + rowList << Row(); +} + +void Section::addRow() +{ + //qCDebug(KEYBOARD_PREVIEW) << "\nrowCount: " << rowCount; + rowCount++; + rowList << Row(); +} + +void Section::displaySection() +{ + //qCDebug(KEYBOARD_PREVIEW) << "\nSection: " << name << "\n\tposition: (" << left << "," << top << ");" << angle << "\n"; + //qCDebug(KEYBOARD_PREVIEW) << "vertical: " << vertical; + for (int i = 0; i < rowCount; i++) { + qCDebug(KEYBOARD_PREVIEW) << "\n\t"; + rowList[i].displayRow(); + } +} + + +Geometry::Geometry() +{ + sectionTop = 0; + sectionLeft = 0; + rowTop = 0; + rowLeft = 0; + keyGap = 0; + shape_count = 0; + width = 0; + height = 0; + sectionCount = 0; + vertical = 0; + sectionList << Section(); + shapes << GShape(); + keyShape = QStringLiteral("NORM"); + parsedGeometry = true; +} + +void Geometry::setShapeName(const QString &n) +{ + shapes[shape_count].setShapeName(n); +} + +void Geometry::setShapeCord(double a, double b) +{ + shapes[shape_count].setCordinate(a, b); +} + +void Geometry::setShapeApprox(double a, double b) +{ + shapes[shape_count].setApprox(a, b); +} + +void Geometry::addShape() +{ + shape_count++; + shapes << GShape(); +} + +void Geometry::display() +{ + qCDebug(KEYBOARD_PREVIEW) << name << "\n" << description << "\nwidth:" << width + << "\nheight:" << height << "\n" << "sectionTop:" << sectionTop; + qCDebug(KEYBOARD_PREVIEW) << "\nsectionLeft:" << sectionLeft << "\nrowTop:" << rowTop << "\nrowLeft:" + << rowLeft << "\nkeyGap: " << keyGap << "\nkeyShape:" << keyShape << "\n"; + qCDebug(KEYBOARD_PREVIEW) << "vertical:" << vertical; + + for (int i = 0; i < shape_count; i++) { + shapes[i].display(); + } + + for (int j = 0; j < sectionCount; j++) { + sectionList[j].displaySection(); + } +} + +void Geometry::addSection() +{ + //qCDebug(KEYBOARD_PREVIEW) << "\nsectionCount: " << sectionCount; + sectionCount++; + sectionList << Section(); +} + +GShape Geometry::findShape(const QString &name) +{ + GShape l; + + for (int i = 0; i < shape_count; i++) { + if (shapes[i].getShapeName() == name) { + return shapes[i]; + } + } + return l; +} diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/geometry_components.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/geometry_components.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/geometry_components.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/geometry_components.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef GEOMETRY_COMPONENTS_H +#define GEOMETRY_COMPONENTS_H + +#include +#include +#include +#include + + +Q_DECLARE_LOGGING_CATEGORY(KEYBOARD_PREVIEW) + + +class GShape +{ +private: + QString sname; + QPoint approx; + QList cordii; + int cordi_count; + +public: + GShape(); + void setCordinate(double a, double b); + void setApprox(double a, double b); + QPoint getCordii(int i) const; + void display(); + double size(int vertical) const; + + void setShapeName(const QString &n) + { + sname = n; + } + + QPoint getApprox() const + { + return approx; + } + + QString getShapeName() + { + return sname; + } + + int getCordi_count() const + { + return cordi_count; + } +}; + +class Key +{ +private: + QString name, shapeName; + double offset; + QPoint position; + +public: + Key(); + void setKeyPosition(double x, double y); + + void setOffset(double o) + { + offset = o; + } + + void setKeyName(const QString &n) + { + name = n; + } + + void setShapeName(const QString &n) + { + shapeName = n; + } + + QString getName() + { + return name; + } + + QString getShapeName() + { + return shapeName; + } + + double getOffset() + { + return offset; + } + + QPoint getPosition() + { + return position; + } + + void showKey(); +}; + +class Row +{ +private: + double top, left; + int keyCount, vertical; + QString shapeName; + +public : + QList keyList; + + Row(); + void addKey(); + + void setTop(double t) + { + top = t; + } + + void setLeft(double l) + { + left = l; + } + + void setVertical(int v) + { + vertical = v; + } + + void setShapeName(const QString &n) + { + shapeName = n; + } + + double getTop() + { + return top; + } + + double getLeft() + { + return left; + } + + int getKeyCount() + { + return keyCount; + } + + int getVertical() + { + return vertical; + } + + QString getShapeName() + { + return shapeName; + } + + void displayRow(); +}; + +class Section +{ +private: + QString name, shapeName; + double top, left, angle; + int rowCount, vertical; + +public: + QList rowList; + + Section(); + void addRow(); + + void setName(const QString &n) + { + name = n; + } + + void setShapeName(const QString &n) + { + shapeName = n; + } + + void setTop(double t) + { + top = t; + } + + void setLeft(double l) + { + left = l; + } + + void setAngle(double a) + { + angle = a; + } + + void setVertical(int v) + { + vertical = v; + } + + QString getName() + { + return name; + } + + QString getShapeName() + { + return shapeName; + } + + double getTop() + { + return top; + } + + double getLeft() + { + return left; + } + + double getAngle() + { + return angle; + } + + int getVertical() + { + return vertical; + } + + int getRowCount() + { + return rowCount; + } + + void displaySection(); +}; + +class Geometry +{ +private: + QString name, description, keyShape; + int shape_count, vertical; + int sectionCount; + +public: + QList shapes; + QList
sectionList; + double width, height, sectionTop, sectionLeft, rowTop, rowLeft, keyGap; + bool parsedGeometry; + Geometry(); + + void setWidth(double a) + { + width = a; + } + + void setParsing(bool state) + { + parsedGeometry = state; + } + + void setHeight(double a) + { + height = a; + } + + void setName(const QString &n) + { + name = n; + } + + void setDescription(const QString &d) + { + description = d; + } + + void setKeyShape(const QString &s) + { + keyShape = s; + } + + void setVertical(int v) + { + vertical = v; + } + + double getWidth() + { + return width; + } + + double getHeight() + { + return height; + } + + QString getName() + { + return name; + } + + QString getDescription() + { + return description; + } + + QString getKeyShape() + { + return keyShape; + } + + int getVertical() + { + return vertical; + } + + int getShapeCount() + { + return shape_count; + } + + int getSectionCount() + { + return sectionCount; + } + + bool getParsing() + { + return parsedGeometry; + } + + void setShapeName(const QString &n); + void setShapeCord(double a, double b); + void setShapeApprox(double a, double b); + void addShape(); + void display(); + void addSection(); + GShape findShape(const QString &name); +}; + +#endif //geometry_componets.h diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/geometry_parser.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/geometry_parser.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/geometry_parser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/geometry_parser.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,593 @@ +/* +* Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com) +* +* 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "geometry_parser.h" +#include "geometry_components.h" +#include "xkb_rules.h" + +#include +#include +#include +#include +#include + + +#include +#include "config-workspace.h" + +namespace grammar +{ +keywords::keywords() +{ + add + ("shape", 1) + ("height", 2) + ("width", 3) + ("description", 4) + ("keys", 5) + ("row", 6) + ("section", 7) + ("key", 8) + ("//", 9) + ("/*", 10) + ; +} + + +template +GeometryParser::GeometryParser(): GeometryParser::base_type(start) +{ + + using qi::lexeme; + using qi::char_; + using qi::lit; + using qi::_1; + using qi::_val; + using qi::int_; + using qi::double_; + using qi::eol; + + + name = '"' >> +(char_ - '"') >> '"'; + + ignore = (lit("outline") || lit("overlay") || lit("text")) >> *(char_ - lit("};")) >> lit("};") + || lit("solid") >> *(char_ - lit("};")) >> lit("};") + || lit("indicator") >> *(char_ - ';' - '{') >> ';' || '{' >> *(char_ - lit("};")) >> lit("};") + || lit("indicator") >> '.' >> lit("shape") >> '=' >> name >> ';'; + + comments = lexeme[ lit("//") >> *(char_ - eol || keyword - eol) >> eol || lit("/*") >> *(char_ - lit("*/") || keyword - lit("*/")) >> lit("*/") ]; + + cordinates = ('[' + >> double_[phx::ref(shapeLenX) = _1] + >> ',' + >> double_[phx::ref(shapeLenY) = _1] + >> ']') + || '[' >> double_ >> "," >> double_ >> ']' + ; + + cordinatea = '[' >> double_[phx::ref(approxLenX) = _1] >> "," >> double_[phx::ref(approxLenY) = _1] >> ']'; + + set = '{' >> cordinates >> *(',' >> cordinates) >> '}'; + + setap = '{' >> cordinatea >> *(',' >> cordinatea) >> '}'; + + seta = '{' + >> cordinates[phx::bind(&GeometryParser::setCord, this)] + >> *(',' >> cordinates[phx::bind(&GeometryParser::setCord, this)]) + >> '}' + ; + + description = lit("description") >> '=' >> name[phx::bind(&GeometryParser::getDescription, this, _1)] >> ';'; + + cornerRadius = (lit("cornerRadius") || lit("corner")) >> '=' >> double_; + + shapeDef = lit("shape") + >> name[phx::bind(&GeometryParser::getShapeName, this, _1)] + >> '{' + >> *(lit("approx") >> '=' >> setap[phx::bind(&GeometryParser::setApprox, this)] >> ',' || cornerRadius >> ',' || comments) + >> seta + >> *((',' >> (set || lit("approx") >> '=' >> setap[phx::bind(&GeometryParser::setApprox, this)] || cornerRadius) || comments)) + >> lit("};") + ; + + keyName = '<' >> +(char_ - '>') >> '>'; + + keyShape = *(lit("key.")) >> lit("shape") >> '=' >> name[phx::bind(&GeometryParser::setKeyShape, this, _1)] + || name[phx::bind(&GeometryParser::setKeyShape, this, _1)]; + + keyColor = lit("color") >> '=' >> name; + + keygap = lit("gap") >> '=' >> double_[phx::ref(KeyOffset) = _1] || double_[phx::ref(KeyOffset) = _1]; + + keyDesc = keyName[phx::bind(&GeometryParser::setKeyNameandShape, this, _1)] + || '{' >> (keyName[phx::bind(&GeometryParser::setKeyNameandShape, this, _1)] || keyShape + || keygap[phx::bind(&GeometryParser::setKeyOffset, this)] + || keyColor) + >> *((',' + >> (keyName + || keyShape + || keygap[phx::bind(&GeometryParser::setKeyOffset, this)] + || keyColor)) + || comments) + >> '}'; + + keys = lit("keys") + >> '{' + >> keyDesc[phx::bind(&GeometryParser::setKeyCordi, this)] + >> *((*lit(',') >> keyDesc[phx::bind(&GeometryParser::setKeyCordi, this)] >> *lit(',')) || comments) + >> lit("};"); + + geomShape = ((lit("key.shape") >> '=' >> name[phx::bind(&GeometryParser::setGeomShape, this, _1)]) || (lit("key.color") >> '=' >> name)) >> ';'; + geomLeft = lit("section.left") >> '=' >> double_[phx::ref(geom.sectionLeft) = _1] >> ';'; + geomTop = lit("section.top") >> '=' >> double_[phx::ref(geom.sectionTop) = _1] >> ';'; + geomRowTop = lit("row.top") >> '=' >> double_[phx::ref(geom.rowTop) = _1] >> ';'; + geomRowLeft = lit("row.left") >> '=' >> double_[phx::ref(geom.rowLeft) = _1] >> ';'; + geomGap = lit("key.gap") >> '=' >> double_[phx::ref(geom.keyGap) = _1] >> ';'; + geomVertical = *lit("row.") >> lit("vertical") >> '=' >> (lit("True") || lit("true")) >> ';'; + geomAtt = geomLeft || geomTop || geomRowTop || geomRowLeft || geomGap; + + top = lit("top") >> '=' >> double_ >> ';'; + left = lit("left") >> '=' >> double_ >> ';'; + + row = lit("row")[phx::bind(&GeometryParser::rowinit, this)] + >> '{' + >> *(top[phx::bind(&GeometryParser::setRowTop, this, _1)] + || left[phx::bind(&GeometryParser::setRowLeft, this, _1)] + || localShape[phx::bind(&GeometryParser::setRowShape, this, _1)] + || localColor + || comments + || geomVertical[phx::bind(&GeometryParser::setVerticalRow, this)] + || keys + ) + >> lit("};") || ignore || geomVertical[phx::bind(&GeometryParser::setVerticalSection, this)]; + + angle = lit("angle") >> '=' >> double_ >> ';'; + + localShape = lit("key.shape") >> '=' >> name[_val = _1] >> ';'; + localColor = lit("key.color") >> '=' >> name >> ';'; + localDimension = (lit("height") || lit("width")) >> '=' >> double_ >> ';'; + priority = lit("priority") >> '=' >> double_ >> ';'; + + section = lit("section")[phx::bind(&GeometryParser::sectioninit, this)] + >> name[phx::bind(&GeometryParser::sectionName, this, _1)] + >> '{' + >> *(top[phx::bind(&GeometryParser::setSectionTop, this, _1)] + || left[phx::bind(&GeometryParser::setSectionLeft, this, _1)] + || angle[phx::bind(&GeometryParser::setSectionAngle, this, _1)] + || row[phx::bind(&GeometryParser::addRow, this)] + || localShape[phx::bind(&GeometryParser::setSectionShape, this, _1)] + || geomAtt + || localColor + || localDimension + || priority + || comments) + >> lit("};") || geomVertical[phx::bind(&GeometryParser::setVerticalGeometry, this)]; + + shapeC = lit("shape") >> '.' >> cornerRadius >> ';'; + + shape = shapeDef || shapeC; + + + input = '{' + >> +(width + || height + || comments + || ignore + || description + || (char_ - keyword - '}' + || shape[phx::bind(&Geometry::addShape, &geom)] + || section[phx::bind(&Geometry::addSection, &geom)] + || geomAtt + || geomShape + )) + >> '}'; + + width = lit("width") >> '=' >> double_[phx::bind(&Geometry::setWidth, &geom, _1)] >> ";"; + height = lit("height") >> '=' >> double_[phx::bind(&Geometry::setHeight, &geom, _1)] >> ";"; + + start %= *(lit("default")) + >> lit("xkb_geometry") + >> name[phx::bind(&GeometryParser::getName, this, _1)] + >> input + >> ';' >> *(comments || char_ - lit("xkb_geometry")); +} + +template +void GeometryParser::setCord() +{ + geom.setShapeCord(shapeLenX, shapeLenY); +} + + +template +void GeometryParser::setSectionShape(std::string n) +{ + geom.sectionList[geom.getSectionCount()].setShapeName(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::getName(std::string n) +{ + geom.setName(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::getDescription(std::string n) +{ + geom.setDescription(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::getShapeName(std::string n) +{ + geom.setShapeName(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::setGeomShape(std::string n) +{ + geom.setKeyShape(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::setRowShape(std::string n) +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + geom.sectionList[secn].rowList[rown].setShapeName(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::setApprox() +{ + geom.setShapeApprox(approxLenX, approxLenY); +} + + +template +void GeometryParser::addRow() +{ + geom.sectionList[geom.getSectionCount()].addRow(); +} + + +template +void GeometryParser::sectionName(std::string n) +{ + geom.sectionList[geom.getSectionCount()].setName(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::rowinit() +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + double tempTop = geom.sectionList[secn].getTop(); + QString tempShape = geom.sectionList[secn].getShapeName(); + geom.sectionList[secn].rowList[rown].setTop(tempTop); + geom.sectionList[secn].rowList[rown].setLeft(geom.sectionList[secn].getLeft()); + geom.sectionList[secn].rowList[rown].setShapeName(tempShape); + keyCordiX = geom.sectionList[secn].rowList[rown].getLeft(); + keyCordiY = geom.sectionList[secn].rowList[rown].getTop(); + tempTop = geom.sectionList[secn].getVertical(); + geom.sectionList[secn].rowList[rown].setVertical(tempTop); +} + + +template +void GeometryParser::sectioninit() +{ + int secn = geom.getSectionCount(); + geom.sectionList[secn].setTop(geom.sectionTop); + geom.sectionList[secn].setLeft(geom.sectionLeft); + keyCordiX = geom.sectionList[secn].getLeft(); + keyCordiY = geom.sectionList[secn].getTop(); + geom.sectionList[secn].setShapeName(geom.getKeyShape()); + geom.sectionList[secn].setVertical(geom.getVertical()); +} + + +template +void GeometryParser::setRowTop(double a) +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + double tempTop = geom.sectionList[secn].getTop(); + geom.sectionList[secn].rowList[rown].setTop(a + tempTop); + keyCordiY = geom.sectionList[secn].rowList[rown].getTop(); +} + + +template +void GeometryParser::setRowLeft(double a) +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + double tempLeft = geom.sectionList[secn].getLeft(); + geom.sectionList[secn].rowList[rown].setLeft(a + tempLeft); + keyCordiX = geom.sectionList[secn].rowList[rown].getLeft(); +} + + +template +void GeometryParser::setSectionTop(double a) +{ + //qCDebug(KEYBOARD_PREVIEW) << "\nsectionCount" << geom.sectionCount; + int secn = geom.getSectionCount(); + geom.sectionList[secn].setTop(a + geom.sectionTop); + keyCordiY = geom.sectionList[secn].getTop(); +} + + +template +void GeometryParser::setSectionLeft(double a) +{ + //qCDebug(KEYBOARD_PREVIEW) << "\nsectionCount" << geom.sectionCount; + int secn = geom.getSectionCount(); + geom.sectionList[secn].setLeft(a + geom.sectionLeft); + keyCordiX = geom.sectionList[secn].getLeft(); + +} + + +template +void GeometryParser::setSectionAngle(double a) +{ + //qCDebug(KEYBOARD_PREVIEW) << "\nsectionCount" << geom.sectionCount; + int secn = geom.getSectionCount(); + geom.sectionList[secn].setAngle(a); +} + + +template +void GeometryParser::setVerticalRow() +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + geom.sectionList[secn].rowList[rown].setVertical(1); +} + + +template +void GeometryParser::setVerticalSection() +{ + int secn = geom.getSectionCount(); + geom.sectionList[secn].setVertical(1); +} + + +template +void GeometryParser::setVerticalGeometry() +{ + geom.setVertical(1); +} + + +template +void GeometryParser::setKeyName(std::string n) +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + int keyn = geom.sectionList[secn].rowList[rown].getKeyCount(); + //qCDebug(KEYBOARD_PREVIEW) << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn; + geom.sectionList[secn].rowList[rown].keyList[keyn].setKeyName(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::setKeyShape(std::string n) +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + int keyn = geom.sectionList[secn].rowList[rown].getKeyCount(); + //qCDebug(KEYBOARD_PREVIEW) << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn; + geom.sectionList[secn].rowList[rown].keyList[keyn].setShapeName(QString::fromUtf8(n.data(), n.size())); +} + + +template +void GeometryParser::setKeyNameandShape(std::string n) +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + setKeyName(n); + setKeyShape(geom.sectionList[secn].rowList[rown].getShapeName().toUtf8().constData()); +} + + +template +void GeometryParser::setKeyOffset() +{ + //qCDebug(KEYBOARD_PREVIEW) << "\nhere\n"; + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + int keyn = geom.sectionList[secn].rowList[rown].getKeyCount(); + //qCDebug(KEYBOARD_PREVIEW) << "\nsC: " << secn << "\trC: " << rown << "\tkn: " << keyn; + geom.sectionList[secn].rowList[rown].keyList[keyn].setOffset(KeyOffset); +} + + +template +void GeometryParser::setKeyCordi() +{ + int secn = geom.getSectionCount(); + int rown = geom.sectionList[secn].getRowCount(); + int keyn = geom.sectionList[secn].rowList[rown].getKeyCount(); + int vertical = geom.sectionList[secn].rowList[rown].getVertical(); + + Key key = geom.sectionList[secn].rowList[rown].keyList[keyn]; + + if (vertical == 0) { + keyCordiX += key.getOffset(); + } else { + keyCordiY += key.getOffset(); + } + + geom.sectionList[secn].rowList[rown].keyList[keyn].setKeyPosition(keyCordiX, keyCordiY); + + QString shapeStr = key.getShapeName(); + if (shapeStr.isEmpty()) { + shapeStr = geom.getKeyShape(); + } + + GShape shapeObj = geom.findShape(shapeStr); + int a = shapeObj.size(vertical); + + if (vertical == 0) { + keyCordiX += a + geom.keyGap; + } else { + keyCordiY += a + geom.keyGap; + } + + geom.sectionList[secn].rowList[rown].addKey(); +} + + +Geometry parseGeometry(const QString &model) +{ + using boost::spirit::iso8859_1::space; + typedef std::string::const_iterator iterator_type; + typedef grammar::GeometryParser GeometryParser; + GeometryParser geometryParser; + + Rules::GeometryId geoId = Rules::getGeometryId(model); + QString geometryFile = geoId.fileName; + QString geometryName = geoId.geoName; + + qCDebug(KEYBOARD_PREVIEW) << "looking for model" << model << "geometryName" << geometryName << "in" << geometryFile; + + QString input = getGeometry(geometryFile, geometryName); + if (! input.isEmpty()) { + geometryParser.geom = Geometry(); + input = includeGeometry(input); + std::string parserInput = input.toUtf8().constData(); + + std::string::const_iterator iter = parserInput.begin(); + std::string::const_iterator end = parserInput.end(); + + bool success = phrase_parse(iter, end, geometryParser, space); + + if (success && iter == end) { +// qCDebug(KEYBOARD_PREVIEW) << "Geometry parsing succeeded for" << input.left(20); + geometryParser.geom.setParsing(true); + return geometryParser.geom; + } else { + qCritical() << "Geometry parsing failed for\n\t" << input.left(30); + geometryParser.geom.setParsing(false); + } + } + + if (geometryParser.geom.getParsing()) { + return geometryParser.geom; + } + + qCritical() << "Failed to get geometry" << geometryParser.geom.getName() << "falling back to pc104"; + return parseGeometry(QStringLiteral("pc104")); +} + +QString includeGeometry(QString geometry) +{ + QStringList lines = geometry.split(QStringLiteral("\n")); + int includeLine = -1; + QString includeLineStr; + QString startLine = lines[0]; + for (int i = 0; i < lines.size(); i++) { + includeLineStr = lines[i]; + lines[i] = lines[i].remove(QStringLiteral(" ")); + lines[i] = lines[i].remove(QStringLiteral("\r")); + if (lines[i].startsWith(QLatin1String("include"))) { + includeLine = i; + break; + } + } + if (includeLine == -1) { + return geometry; + } + geometry = geometry.remove(includeLineStr); + lines[includeLine] = lines[includeLine].remove(QStringLiteral("include")); + lines[includeLine] = lines[includeLine].remove(QStringLiteral("\"")); + lines[includeLine] = lines[includeLine].remove(QStringLiteral(")")); + if (lines[includeLine].contains(QStringLiteral("("))) { + QString includeFile = lines[includeLine].split(QStringLiteral("("))[0]; + QString includeGeom = lines[includeLine].split(QStringLiteral("("))[1]; + qCDebug(KEYBOARD_PREVIEW) << "looking to include " << "geometryName" << includeGeom << "in" << includeFile; + QString includeStr = getGeometry(includeFile, includeGeom); + includeStr = getGeometryStrContent(includeStr); + geometry = geometry.remove(startLine); + geometry = geometry.prepend(includeStr); + geometry = geometry.prepend(startLine); + includeGeometry(geometry); + + } + return geometry; +} + +QString getGeometryStrContent(QString geometryStr) +{ + int k = geometryStr.indexOf(QStringLiteral("{")); + int k2 = geometryStr.lastIndexOf(QLatin1String("};")); + geometryStr = geometryStr.mid(k + 1, k2 - k - 2); + return geometryStr; +} + +QString getGeometry(QString geometryFile, QString geometryName) +{ + + QString xkbParentDir = findGeometryBaseDir(); + geometryFile.prepend(xkbParentDir); + QFile gfile(geometryFile); + + if (!gfile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCritical() << "Unable to open the file" << geometryFile; + return QString(); + } + + QString gcontent = gfile.readAll(); + gfile.close(); + + QStringList gcontentList = gcontent.split(QStringLiteral("xkb_geometry ")); + + int current = 0; + for (int i = 1; i < gcontentList.size(); i++) { + if (gcontentList[i].startsWith("\"" + geometryName + "\"")) { + current = i; + break; + } + } + if (current != 0) { + return gcontentList[current].prepend("xkb_geometry "); + } else { + return QString(); + } +} + + +QString findGeometryBaseDir() +{ + QString xkbDir = Rules::findXkbDir(); + return QStringLiteral("%1/geometry/").arg(xkbDir); +} + +} diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/geometry_parser.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/geometry_parser.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/geometry_parser.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/geometry_parser.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef GEOMETRY_PARSER_H +#define GEOMETRY_PARSER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include "geometry_components.h" + +namespace qi = boost::spirit::qi; +namespace ascii = boost::spirit::ascii; +namespace phx = boost::phoenix; +namespace iso = boost::spirit::iso8859_1; + + +namespace grammar +{ + +struct keywords : qi::symbols { + keywords(); +}; + +template +struct GeometryParser : qi::grammar { + + //comments + qi::rulecomments, ignore; + qi::rulelocalDimension, priority; + + //general non-terminals + qi::rulename; + qi::ruledescription; + qi::ruleinput; + + //non-terminals for shape + qi::ruleshape; + qi::ruleshapeDef; + qi::ruleshapeC; + qi::ruleset; + qi::rulesetap; + qi::ruleseta; + qi::rulecornerRadius; + qi::rulecordinatea; + qi::rulecordinates; + + //non-terminals for key + qi::rulekeygap; + qi::rulekeyName; + qi::rulekeyShape; + qi::rulekeyColor; + qi::rulekeyDesc; + qi::rulekeys; + + qi::rulerow; + + qi::rulesection; + + //non-terminals related to local data + qi::rulelocalShape; + qi::rulelocalColor; + + //Geometry non-terminals + qi::rulegeomShape; + qi::rulegeomTop, geomVertical; + qi::rulegeomLeft; + qi::rulegeomRowTop; + qi::rulegeomRowLeft; + qi::rulegeomGap; + qi::rulegeomAtt; + qi::ruleangle; + qi::ruletop; + qi::ruleleft; + qi::rulewidth; + qi::ruleheight; + + qi::rulestart; + Geometry geom; + keywords keyword; + double shapeLenX, shapeLenY, approxLenX, approxLenY, keyCordiX, keyCordiY, KeyOffset; + GeometryParser(); + + //functions for shape + void getShapeName(std::string n); + void setCord(); + void setApprox(); + + //functions for section + void sectionName(std::string n); + void setSectionShape(std::string n); + void setSectionTop(double a); + void setSectionLeft(double a); + void setSectionAngle(double a); + void sectioninit(); + + //functions for row + void setRowShape(std::string n); + void setRowTop(double a); + void setRowLeft(double a); + void rowinit(); + void addRow(); + + //functions for key + void setKeyName(std::string n); + void setKeyShape(std::string n); + void setKeyNameandShape(std::string n); + void setKeyOffset(); + void setKeyCordi(); + + //functions for geometry + void setGeomShape(std::string n); + void getName(std::string n); + void getDescription(std::string n); + + //functions for alignment + void setVerticalRow(); + void setVerticalSection(); + void setVerticalGeometry(); +}; + + + +Geometry parseGeometry(const QString &model); +QString getGeometry(QString geometryFile, QString geometryName); +QString includeGeometry(QString geometry); +QString getGeometryStrContent(QString geometryStr); +QString findGeometryBaseDir(); +} + +#endif //geometry_parser diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/kbpreviewframe.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/kbpreviewframe.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/kbpreviewframe.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/kbpreviewframe.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "kbpreviewframe.h" + +#include "geometry_parser.h" +#include "geometry_components.h" +#include "keyboardlayout.h" +#include "symbol_parser.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +static const QColor keyBorderColor("#d4d4d4"); +static const QColor lev12color(Qt::black); +static const QColor lev34color("#0033FF"); +static const QColor unknownSymbolColor("#FF3300"); +static const int xOffset[] = {10, 10, -15, -15 }; +static const int yOffset[] = {5, -20, 5, -20 }; +static const QColor color[] = { lev12color, lev12color, lev34color, lev34color }; +static const int keyLevel[3][4] = { { 1, 0, 3, 2}, { 1, 0, 5, 4}, { 1, 0, 7, 6} }; +static const QRegExp fkKey(QStringLiteral("^FK\\d+$")); + + +KbPreviewFrame::KbPreviewFrame(QWidget *parent) : + QFrame(parent), + geometry(*new Geometry()) +{ + setFrameStyle(QFrame::Box); + setFrameShadow(QFrame::Sunken); + setMouseTracking(true); + scaleFactor = 1; + l_id = 0; +} + +KbPreviewFrame::~KbPreviewFrame() +{ + delete &geometry; +} + + +int KbPreviewFrame::getWidth() const +{ + return geometry.width; +} +int KbPreviewFrame::getHeight() const +{ + return geometry.height; +} + + +//writes text on the keys call only by paintevent +void KbPreviewFrame::drawKeySymbols(QPainter &painter, QPoint temp[], const GShape &s, const QString &name) +{ + int keyindex = keyboardLayout.findKey(name); + int szx = scaleFactor * s.size(0) / 2 < 20 ? scaleFactor * s.size(0) / 3 : 20; + int szy = scaleFactor * s.size(1) / 2 < 20 ? scaleFactor * s.size(1) / 3 : 20; + QFont kbfont; + if (szx > szy) { + kbfont.setPointSize(szy / 2 < 9 ? szy : 9); + } else { + kbfont.setPointSize(szx / 2 < 9 ? szx / 2 : 9); + } + + painter.setFont(kbfont); + + int cordinate[] = {0, 3, 1, 2}; + float tooltipX = 0, toolTipY = 0; + QString tip; + if (keyindex != -1) { + KbKey key = keyboardLayout.keyList.at(keyindex); + + for (int level = 0; level < (key.getSymbolCount() < 4 ? key.getSymbolCount() : 4); level++) { + + if (keyLevel[l_id][level] < key.getSymbolCount()) { + + QString txt = symbol.getKeySymbol(key.getSymbol(keyLevel[l_id][level])); + + QColor txtColor = txt[0] == -1 ? unknownSymbolColor : color[level]; + + painter.setPen(txtColor); + + painter.drawText(temp[cordinate[level]].x() + xOffset[level]*scaleFactor / 2.5, temp[cordinate[level]].y() + yOffset[level]*scaleFactor / 2.5, szx, szy, Qt::AlignTop, txt); + + QString currentSymbol = key.getSymbol(keyLevel[l_id][level]); + currentSymbol = currentSymbol.size() < 3 ? currentSymbol.append("\t") : currentSymbol; + + if (level == 0) { + tip.append(currentSymbol); + } else { + tip.append("\n" + currentSymbol); + } + } + } + + for (int i = 0 ; i < 4; i++) { + tooltipX += temp[i].x(); + toolTipY += temp[i].y(); + } + + tooltipX = tooltipX / 4; + toolTipY = toolTipY / 4; + QPoint tooltipPoint = QPoint(tooltipX, toolTipY); + + tooltip.append(tip); + tipPoint.append(tooltipPoint); + } else { + painter.setPen(Qt::black); + + if (name.contains(fkKey)) { + QString tempName = name; + tempName.remove(QStringLiteral("K")); + painter.drawText(temp[0].x() + s.size(0) - 10, temp[0].y() + 3 * scaleFactor * s.size(1) / 5, tempName); + } else { + painter.setFont(kbfont); + painter.drawText(temp[0].x() + s.size(0) - 10, temp[0].y() + 3 * scaleFactor * s.size(1) / 5, name); + } + tip = name; + + for (int i = 0 ; i < 4; i++) { + tooltipX += temp[i].x(); + toolTipY += temp[i].y(); + } + + tooltipX = tooltipX / 4; + toolTipY = toolTipY / 4; + QPoint tooltipPoint = QPoint(tooltipX, toolTipY); + + tooltip.append(tip); + tipPoint.append(tooltipPoint); + } +} + + +//draws key shape on QFrame called only by paint event +void KbPreviewFrame::drawShape(QPainter &painter, const GShape &s, int x, int y, int i, const QString &name) +{ + painter.setPen(Qt::black); + int cordi_count = s.getCordi_count(); + + if (geometry.sectionList[i].getAngle() == 0) { + if (cordi_count == 1) { + int width = s.getCordii(0).x(); + int height = s.getCordii(0).y(); + + painter.drawRoundedRect(scaleFactor * x + 2, scaleFactor * y, scaleFactor * width, scaleFactor * height, 4, 4); + + QPoint temp[4]; + + temp[0] = QPoint(scaleFactor * x, scaleFactor * y); + temp[1] = QPoint(scaleFactor * (s.getCordii(0).x() + x), scaleFactor * y); + temp[2] = QPoint(scaleFactor * (s.getCordii(0).x() + x), scaleFactor * (s.getCordii(0).y() + y)); + temp[3] = QPoint(scaleFactor * (x), scaleFactor * (s.getCordii(0).y() + y)); + + drawKeySymbols(painter, temp, s, name); + } else { + QVarLengthArray temp(cordi_count); + for (int i = 0; i < cordi_count; i++) { + temp[i].setX(scaleFactor * (s.getCordii(i).x() + x + 1)); + temp[i].setY(scaleFactor * (s.getCordii(i).y() + y + 1)); + } + + painter.drawPolygon(temp.data(), cordi_count); + drawKeySymbols(painter, temp.data(), s, name); // no length passed here, is this safe? + } + } else { + QVarLengthArray temp(cordi_count == 1 ? 4 : cordi_count); + int size; + + if (cordi_count == 1) { + temp[0] = QPoint(x, y); + temp[1] = QPoint(s.getCordii(0).x() + x, y); + temp[2] = QPoint(s.getCordii(0).x() + x, s.getCordii(0).y() + y); + temp[3] = QPoint(x, s.getCordii(0).y() + y); + size = 4; + } else { + size = cordi_count; + + for (int i = 0; i < cordi_count; i++) { + temp[i].setX((s.getCordii(i).x() + x + 1)); + temp[i].setY((s.getCordii(i).y() + y + 1)); + } + } + + double refX, refY; + + refX = geometry.sectionList[i].getLeft(); + refY = geometry.sectionList[i].getTop(); + + //qCDebug(KEYBOARD_PREVIEW) <<"\ntransform"; + for (int j = 0; j < size; j++) { + double x = temp[j].x() - refX; + double y = temp[j].y() - refY; + + //qCDebug(KEYBOARD_PREVIEW) <<"(" <"; + + float theta = (3.1459 * geometry.sectionList[i].getAngle()) / 180; + double x_ = x * cos(theta) - y * sin(theta); + + //qCDebug(KEYBOARD_PREVIEW) <<"x_= " <type() == QEvent::ToolTip) { + QHelpEvent *helpEvent = static_cast(event); + int index = itemAt(helpEvent->pos()); + + if (index != -1) { + QToolTip::showText(helpEvent->globalPos(), tooltip.at(index)); + } else { + QToolTip::hideText(); + event->ignore(); + } + + return true; + } + return QWidget::event(event); +} + + +void KbPreviewFrame::paintEvent(QPaintEvent *) +{ + if (geometry.getParsing() && keyboardLayout.getParsedSymbol()) { + QPainter painter(this); + + QFont kbfont; + kbfont.setPointSize(9); + + painter.setFont(kbfont); + painter.setBrush(QBrush("#C3C8CB")); + painter.setRenderHint(QPainter::Antialiasing); + + const int strtx = 0, strty = 0, endx = geometry.getWidth(), endy = geometry.getHeight(); + + + painter.setPen("#EDEEF2"); + + painter.drawRect(strtx, strty, scaleFactor * endx + 60, scaleFactor * endy + 60); + + painter.setPen(Qt::black); + painter.setBrush(QBrush("#EDEEF2")); + + for (int i = 0; i < geometry.getSectionCount(); i++) { + + painter.setPen(Qt::black); + + for (int j = 0; j < geometry.sectionList[i].getRowCount(); j++) { + + int keyn = geometry.sectionList[i].rowList[j].getKeyCount(); + + for (int k = 0; k < keyn; k++) { + + Key temp = geometry.sectionList[i].rowList[j].keyList[k]; + + int x = temp.getPosition().x(); + int y = temp.getPosition().y(); + + GShape s; + + s = geometry.findShape(temp.getShapeName()); + QString name = temp.getName(); + + drawShape(painter, s, x, y, i, name); + + } + } + } + + if (symbol.isFailed()) { + painter.setPen(keyBorderColor); + painter.drawRect(strtx, strty, endx, endy); + + const int midx = 470, midy = 240; + painter.setPen(lev12color); + painter.drawText(midx, midy, tr("No preview found")); + } + } else { + QMessageBox errorBox; + errorBox.setText(tr("Unable to open Preview !")); + errorBox.exec(); + } + +} + +// this function draws the keyboard preview on a QFrame +void KbPreviewFrame::generateKeyboardLayout(const QString &layout, const QString &layoutVariant, const QString &model) +{ + qDebug() << " generateKeyboardLayout " << endl; + geometry = grammar::parseGeometry(model); + int endx = geometry.getWidth(), endy = geometry.getHeight(); + + QDesktopWidget *desktopWidget = qApp->desktop(); + QRect screenGeometry = desktopWidget->screenGeometry(); + int screenWidth = screenGeometry.width(); + + scaleFactor = 2.5; + while (scaleFactor * endx + screenWidth / 20 > screenWidth) { + scaleFactor -= 0.2; + } + qCDebug(KEYBOARD_PREVIEW) << "scale factor: 2.5 ->" << scaleFactor; + + setFixedSize(scaleFactor * endx + 60, scaleFactor * endy + 60); + qCDebug(KEYBOARD_PREVIEW) << screenWidth << ":" << scaleFactor << scaleFactor *endx + 60 << scaleFactor *endy + 60; + keyboardLayout = grammar::parseSymbols(layout, layoutVariant); +} + + +//this functions give the index of the tooltip over which mouse hovers +int KbPreviewFrame::itemAt(const QPoint &pos) +{ + int distance = 10000; + int closest = 0; + for (int i = 0; i < tipPoint.size(); i++) { + + int temp = sqrt((pos.x() - tipPoint.at(i).x()) * (pos.x() - tipPoint.at(i).x()) + (pos.y() - tipPoint.at(i).y()) * (pos.y() - tipPoint.at(i).y())); + + if (distance > temp) { + distance = temp; + closest = i; + } + } + + if (distance < 25) { + return closest; + } + + return -1; +} diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/kbpreviewframe.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/kbpreviewframe.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/kbpreviewframe.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/kbpreviewframe.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KBPREVIEWFRAME_H +#define KBPREVIEWFRAME_H + +#include "keyboardlayout.h" + +#include "keysymhelper.h" +#include "keyaliases.h" + +#include +#include +#include +#include +#include + + +Q_DECLARE_LOGGING_CATEGORY(KEYBOARD_PREVIEW) + + +class Geometry; +class GShape; + + +class KbPreviewFrame : public QFrame +{ + Q_OBJECT + +private: + static const int width = 1100, height = 490; + + KeySymHelper symbol; + Aliases alias; + QStringList tooltip; + QList tipPoint; + int l_id; + Geometry &geometry; + float scaleFactor; + KbLayout keyboardLayout; + + void drawKeySymbols(QPainter &painter, QPoint temp[], const GShape &s, const QString &name); + void drawShape(QPainter &painter, const GShape &s, int x, int y, int i, const QString &name); + + int itemAt(const QPoint &pos); + + +protected: + bool event(QEvent *event) override; + +public: + explicit KbPreviewFrame(QWidget *parent = nullptr); + ~KbPreviewFrame() override; + void paintEvent(QPaintEvent *event) override; + void generateKeyboardLayout(const QString &layout, const QString &layoutVariant, const QString &model); + int getWidth() const; + int getHeight() const; + + int getLevel() + { + return keyboardLayout.getLevel(); + } + + void setL_id(int lId) + { + l_id = lId; + repaint(); + } + + QString getLayoutName() const + { + return keyboardLayout.getLayoutName(); + } + + float getScaleFactor() + { + return scaleFactor; + } +}; + +#endif // KBPREVIEWFRAME_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyaliases.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyaliases.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyaliases.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyaliases.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keyaliases.h" +#include "xkb_rules.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "config-workspace.h" + + +Aliases::Aliases() +{ + QString filename = findaliasdir(); + QFile file(filename); + file.open(QIODevice::ReadOnly | QIODevice::Text); + QString content = file.readAll(); + file.close(); + + QListals; + als = content.split(QStringLiteral("xkb_keycodes")); + + for (int i = 1; i < als.size(); i++) { + + QString temp = als.at(i); + + temp = temp.remove(QStringLiteral(" ")); + temp = temp.remove(QStringLiteral("\n")); + temp = temp.remove(QStringLiteral("\"")); + temp = temp.remove(QStringLiteral(">")); + temp = temp.remove(QStringLiteral("<")); + temp = temp.remove(QStringLiteral(";")); + temp = temp.remove(QStringLiteral("}")); + temp = temp.remove(QStringLiteral("{")); + + QListalskeys; + + alskeys = temp.split(QStringLiteral("alias")); + + if (temp.startsWith(QLatin1String("qwerty"))) { + + for (int k = 1; k < alskeys.size(); k++) { + + QString tmp = alskeys.at(k); + int inofeq = tmp.indexOf(QStringLiteral("=")); + + QString lat = tmp.left(inofeq); + QString key = tmp.mid(inofeq + 1); + + qwerty[lat] = key; + } + } + + if (temp.startsWith(QLatin1String("azerty"))) { + + for (int k = 1; k < alskeys.size(); k++) { + QString tmp = alskeys.at(k); + + int inofeq = tmp.indexOf(QStringLiteral("=")); + + QString lat = tmp.left(inofeq); + QString key = tmp.mid(inofeq + 1); + + azerty[lat] = key; + } + } + + if (temp.startsWith(QLatin1String("qwertz"))) { + for (int k = 1; k < alskeys.size(); k++) { + + QString tmp = alskeys.at(k); + + int inofeq = tmp.indexOf(QStringLiteral("=")); + + QString lat = tmp.left(inofeq); + QString key = tmp.mid(inofeq + 1); + + qwertz[lat] = key; + } + } + } + +} + + +QString Aliases::getAlias(const QString &cname, const QString &name) +{ + QMessageBox q; + QString a = name; + + if (cname == QLatin1String("ma") || cname == QLatin1String("be") || cname == QLatin1String("fr")) { + a = azerty.value(name); + } else { + a = qwerty.value(name); + } + + return a; +} + +QString Aliases::findaliasdir() +{ + QString xkbDir = Rules::findXkbDir(); + return QStringLiteral("%1/keycodes/aliases").arg(xkbDir); +} diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyaliases.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyaliases.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyaliases.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyaliases.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef ALIASES_H +#define ALIASES_H + +#include + +class Aliases +{ +private: + QMapqwerty; + QMapazerty; + QMapqwertz; + QString findaliasdir(); + +public: + Aliases(); + QString getAlias(const QString &type, const QString &name); +}; + +#endif // ALIASES_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboard_config.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboard_config.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboard_config.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboard_config.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keyboard_config.h" +#include "debug.h" + +#include +#include + + +static const char* const SWITCHING_POLICIES[] = {"Global", "Desktop", "WinClass", "Window", nullptr }; +static const char LIST_SEPARATOR[] = ","; +//static const char* DEFAULT_LAYOUT = "us"; +static const char DEFAULT_MODEL[] = "pc104"; + +static const QString CONFIG_FILENAME(QStringLiteral("kxkbrc")); +static const QString CONFIG_GROUPNAME(QStringLiteral("Layout")); + +const int KeyboardConfig::NO_LOOPING = -1; + +KeyboardConfig::KeyboardConfig() +{ + setDefaults(); +} + +QString KeyboardConfig::getSwitchingPolicyString(SwitchingPolicy switchingPolicy) { + return SWITCHING_POLICIES[switchingPolicy]; +} + +static int findStringIndex(const char* const strings[], const QString& toFind, int defaultIndex) +{ + for(int i=0; strings[i] != nullptr; i++) { + if( toFind == strings[i] ) { + return i; + } + } + return defaultIndex; +} + +void KeyboardConfig::setDefaults() +{ + keyboardModel = DEFAULT_MODEL; + resetOldXkbOptions = false; + xkbOptions.clear(); + + // init layouts options + configureLayouts = false; + layouts.clear(); +// layouts.append(LayoutUnit(DEFAULT_LAYOUT)); + layoutLoopCount = NO_LOOPING; + + // switch control options + switchingPolicy = SWITCH_POLICY_GLOBAL; +// stickySwitching = false; +// stickySwitchingDepth = 2; + + // display options + showIndicator = true; + indicatorType = SHOW_LABEL; + showSingle = false; +} + +static +KeyboardConfig::IndicatorType getIndicatorType(bool showFlag, bool showLabel) +{ + if( showFlag ) { + if( showLabel ) + return KeyboardConfig::SHOW_LABEL_ON_FLAG; + else + return KeyboardConfig::SHOW_FLAG; + } + else { + return KeyboardConfig::SHOW_LABEL; + } +} + + +void KeyboardConfig::load() +{ + KConfigGroup config(KSharedConfig::openConfig( CONFIG_FILENAME, KConfig::NoGlobals ), CONFIG_GROUPNAME); + + keyboardModel = config.readEntry("Model", ""); + + resetOldXkbOptions = config.readEntry("ResetOldOptions", false); + QString options = config.readEntry("Options", ""); + xkbOptions = options.split(LIST_SEPARATOR, QString::SkipEmptyParts); + + configureLayouts = config.readEntry("Use", false); + QString layoutsString = config.readEntry("LayoutList", ""); + QStringList layoutStrings = layoutsString.split(LIST_SEPARATOR, QString::SkipEmptyParts); +// if( layoutStrings.isEmpty() ) { +// layoutStrings.append(DEFAULT_LAYOUT); +// } + layouts.clear(); + foreach(const QString& layoutString, layoutStrings) { + layouts.append(LayoutUnit(layoutString)); + } + if( layouts.isEmpty() ) { + configureLayouts = false; + } + + layoutLoopCount = config.readEntry("LayoutLoopCount", NO_LOOPING); + + QString layoutMode = config.readEntry("SwitchMode", "Global"); + switchingPolicy = static_cast(findStringIndex(SWITCHING_POLICIES, layoutMode, SWITCH_POLICY_GLOBAL)); + + showIndicator = config.readEntry("ShowLayoutIndicator", true); + + bool showFlag = config.readEntry("ShowFlag", false); + bool showLabel = config.readEntry("ShowLabel", true); + indicatorType = getIndicatorType(showFlag, showLabel); + + showSingle = config.readEntry("ShowSingle", false); + + QString labelsStr = config.readEntry("DisplayNames", ""); + QStringList labels = labelsStr.split(LIST_SEPARATOR, QString::KeepEmptyParts); + for(int i=0; i KeyboardConfig::getDefaultLayouts() const +{ + QList defaultLayoutList; + int i = 0; + foreach(const LayoutUnit& layoutUnit, layouts) { + defaultLayoutList.append(layoutUnit); + if( layoutLoopCount != KeyboardConfig::NO_LOOPING && i >= layoutLoopCount-1 ) + break; + i++; + } + return defaultLayoutList; +} + +QList KeyboardConfig::getExtraLayouts() const +{ + if( layoutLoopCount == KeyboardConfig::NO_LOOPING ) + return QList(); + + return layouts.mid(layoutLoopCount, layouts.size()); +} diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboard_config.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboard_config.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboard_config.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboard_config.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KEYBOARD_CONFIG_H_ +#define KEYBOARD_CONFIG_H_ + +#include "x11_helper.h" + +#include +#include +#include +#include +#include + +/** + * This class provides configuration options for keyboard module + */ +class KeyboardConfig +{ +public: + static const int MAX_LABEL_LEN = 3; + static const int NO_LOOPING; // = -1; + + enum SwitchingPolicy { + SWITCH_POLICY_GLOBAL = 0, + SWITCH_POLICY_DESKTOP = 1, + SWITCH_POLICY_APPLICATION = 2, + SWITCH_POLICY_WINDOW = 3 + }; + + enum IndicatorType { + SHOW_LABEL = 0, + SHOW_FLAG = 1, + SHOW_LABEL_ON_FLAG = 2 + }; + + QString keyboardModel; + // resetOldXkbOptions is now also "set xkb options" + bool resetOldXkbOptions; + QStringList xkbOptions; + + // init layouts options + bool configureLayouts; + QList layouts; + int layoutLoopCount; + + // switch control options + SwitchingPolicy switchingPolicy; +// bool stickySwitching; +// int stickySwitchingDepth; + + // display options + bool showIndicator; + IndicatorType indicatorType; + bool showSingle; + + KeyboardConfig(); + + QList getDefaultLayouts() const; + QList getExtraLayouts() const; + bool isFlagShown() const { + return indicatorType == SHOW_FLAG || indicatorType == SHOW_LABEL_ON_FLAG; + } + bool isLabelShown() const { + return indicatorType == SHOW_LABEL || indicatorType == SHOW_LABEL_ON_FLAG; + } + + void setDefaults(); + void load(); + void save(); + + static QString getSwitchingPolicyString(SwitchingPolicy switchingPolicy); +}; + +#endif /* KEYBOARD_CONFIG_H_ */ diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboardlayout.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboardlayout.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboardlayout.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboardlayout.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#include "keyboardlayout.h" + +#include +#include +#include + + +KbKey::KbKey() +{ + symbolCount = 0; + symbols << QString(); +} + + +void KbKey::setKeyName(QString n) +{ + keyName = n; +} + + +void KbKey::addSymbol(QString n, int i) +{ + if (!symbols.contains(n)) { + symbols[i] = n; + symbolCount++; + symbols << QString(); + } +} + + +QString KbKey::getSymbol(int i) +{ + if (i < symbolCount) { + return symbols[i]; + } else { + return QString(); + } +} + + +void KbKey::display() +{ + qCDebug(KEYBOARD_PREVIEW) << keyName << " : "; + for (int i = 0; i < symbolCount; i++) { + qCDebug(KEYBOARD_PREVIEW) << "\t" << symbols[i]; + } +} + + +KbLayout::KbLayout() +{ + keyCount = 0; + includeCount = 0; + level = 4; + keyList << KbKey(); + include << QString(); + parsedSymbol = true; +} + + +void KbLayout::setName(QString n) +{ + name = n; +} + + +void KbLayout::addInclude(QString n) +{ + if (!include.contains(n)) { + include[includeCount] = n; + includeCount++; + include << QString(); + } +} + + +void KbLayout :: addKey() +{ + keyCount++; + keyList << KbKey(); +} + + +QString KbLayout :: getInclude(int i) +{ + if (i < includeCount) { + return include[i]; + } else { + return QString(); + } +} + + +int KbLayout :: findKey(QString n) +{ + for (int i = 0 ; i < keyCount ; i++) { + if (keyList[i].keyName == n) { + return i; + } + } + return -1; +} + + +void KbLayout::display() +{ +// qCDebug(KEYBOARD_PREVIEW) << name << "\n"; +// for(int i = 0; i +#include +#include +#include + + +Q_DECLARE_LOGGING_CATEGORY(KEYBOARD_PREVIEW) + + +class KbKey +{ +private: + QList symbols; + int symbolCount; + +public: + QString keyName; + + KbKey(); + + void setKeyName(QString n); + void addSymbol(QString n, int i); + QString getSymbol(int i); + + int getSymbolCount() + { + return symbolCount; + } + + void display(); +}; + + +class KbLayout +{ +private: + QList include; + QString name; + int keyCount, includeCount, level; + bool parsedSymbol; + +public: + QList keyList; + QString country; + + KbLayout(); + + void setName(QString n); + void addInclude(QString n); + void addKey(); + QString getInclude(int i); + int findKey(QString n); + + void setLevel(int lvl) + { + level = lvl; + } + + int getLevel() + { + return level; + } + + int getKeyCount() + { + return keyCount; + } + + int getIncludeCount() + { + return includeCount; + } + + QString getLayoutName() const + { + return name; + } + + void setParsedSymbol(bool state) + { + parsedSymbol = state; + } + + bool getParsedSymbol() + { + return parsedSymbol; + } + + void display(); +}; + +#endif //KEYBOARDLAYOUT_NEW_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboardpainter.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboardpainter.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboardpainter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboardpainter.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keyboardpainter.h" +#include "geometry_components.h" + +#include +#include +#include +#include + + +KeyboardPainter::KeyboardPainter(): + kbDialog(new QDialog(this)), + kbframe(new KbPreviewFrame(this)), + exitButton(new QPushButton(tr("Close"), this)), + levelBox(new QComboBox(this)) +{ + this->setFixedSize(1250, 600); + kbframe->setFixedSize(1100, 490); + exitButton->setFixedSize(120, 30); + levelBox->setFixedSize(360, 30); + + QVBoxLayout *vLayout = new QVBoxLayout(this); + QHBoxLayout *hLayout = new QHBoxLayout(); + + hLayout->addWidget(exitButton, 0, Qt::AlignLeft); + hLayout->addWidget(levelBox, 0, Qt::AlignRight); + hLayout->addSpacing(30); + + vLayout->addWidget(kbframe); + vLayout->addLayout(hLayout); + + connect(exitButton, &QPushButton::clicked, this, &KeyboardPainter::close); + connect(levelBox, SIGNAL(activated(int)), this, SLOT(levelChanged(int))); + + setWindowTitle(kbframe->getLayoutName()); + levelBox->setVisible(false); +} + + +void KeyboardPainter::generateKeyboardLayout(const QString &layout, const QString &variant, const QString &model, const QString &title) +{ + kbframe->generateKeyboardLayout(layout, variant, model); + kbframe->setFixedSize(getWidth(), getHeight()); + kbDialog->setFixedSize(getWidth(), getWidth()); + setWindowTitle(title); + + int level = kbframe->getLevel(); + + if (level > 4) { + levelBox->addItem(tr("Keyboard layout levels"), (tr("Level %1, %2").arg(3, 4))); + for (int i = 5; i <= level; i += 2) { + levelBox->addItem(tr("Keyboard layout levels"), (tr("Level %1, %2").arg(i, i + 1))); + } + } else { + levelBox->setVisible(false); + } +} + +void KeyboardPainter::levelChanged(int l_id) +{ + kbframe->setL_id(l_id); +} + +int KeyboardPainter::getHeight() +{ + int height = kbframe->getHeight(); + height = kbframe->getScaleFactor() * height + 50; + return height; +} + +int KeyboardPainter::getWidth() +{ + int width = kbframe->getWidth(); + width = kbframe->getScaleFactor() * width + 20; + return width; +} + +KeyboardPainter::~KeyboardPainter() +{ + delete kbframe; + kbframe = nullptr; + delete exitButton; + exitButton = nullptr; + delete levelBox; + levelBox = nullptr; +} diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboardpainter.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboardpainter.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keyboardpainter.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keyboardpainter.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef KEYBOARDPAINTER_H +#define KEYBOARDPAINTER_H + +#include "kbpreviewframe.h" + +#include + +class QPushButton; +class QComboBox; + +class KeyboardPainter : public QDialog +{ + Q_OBJECT + +public: + explicit KeyboardPainter(); + ~KeyboardPainter() override; + void generateKeyboardLayout(const QString &layout, const QString &variant, const QString &model, const QString &title); + int getHeight(); + int getWidth(); + +public Q_SLOTS: + void levelChanged(int l_id); + +private: + QDialog *kbDialog; + KbPreviewFrame *kbframe; + QPushButton *exitButton; + QComboBox *levelBox; +}; + +#endif // KEYBOARDPAINTER_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keysym2ucs.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keysym2ucs.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keysym2ucs.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keysym2ucs.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,901 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* $XFree86$ + * This module converts keysym values into the corresponding ISO 10646-1 + * (UCS, Unicode) values. + * + * The array keysymtab[] contains pairs of X11 keysym values for graphical + * characters and the corresponding Unicode value. The function + * keysym2ucs() maps a keysym onto a Unicode value using a binary search, + * therefore keysymtab[] must remain SORTED by keysym value. + * + * The keysym -> UTF-8 conversion will hopefully one day be provided + * by Xlib via XmbLookupString() and should ideally not have to be + * done in X applications. But we are not there yet. + * + * We allow to represent any UCS character in the range U+00000000 to + * U+00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. + * This admittedly does not cover the entire 31-bit space of UCS, but + * it does cover all of the characters up to U+10FFFF, which can be + * represented by UTF-16, and more, and it is very unlikely that higher + * UCS codes will ever be assigned by ISO. So to get Unicode character + * U+ABCD you can directly use keysym 0x1000abcd. + * + * NOTE: The comments in the table below contain the actual character + * encoded in UTF-8, so for viewing and editing best use an editor in + * UTF-8 mode. + * + * Author: Markus G. Kuhn , University of Cambridge, June 1999 + * + * Special thanks to Richard Verhoeven for preparing + * an initial draft of the mapping table. + */ + +#include "keysym2ucs.h" + +struct codepair { + unsigned short keysym; + unsigned short ucs; +} keysymtab[] = { + { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ + { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ + { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ + { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ + { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ + { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ + { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ + { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ + { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ + { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ + { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ + { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ + { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ + { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ + { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ + { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ + { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ + { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ + { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ + { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ + { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ + { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ + { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ + { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ + { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ + { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ + { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ + { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ + { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ + { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ + { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ + { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ + { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ + { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ + { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ + { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ + { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ + { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ + { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ + { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ + { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ + { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ + { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ + { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ + { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ + { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ + { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ + { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ + { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ + { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ + { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ + { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ + { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ + { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ + { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ + { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ + { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ + { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ + { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ + { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ + { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ + { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ + { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ + { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ + { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ + { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ + { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ + { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ + { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ + { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ + { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ + { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ + { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ + { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ + { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ + { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ + { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ + { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ + { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ + { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ + { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ + { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ + { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ + { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ + { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ + { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ + { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ + { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ + { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ + { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ + { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ + { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ + { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ + { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ + { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ + { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ + { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ + { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ + { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ + { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ + { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ + { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ + { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ + { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ + { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ + { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ + { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ + { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ + { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ + { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ + { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ + { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ + { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ + { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ + { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ + { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ + { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ + { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ + { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ + { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ + { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ + { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ + { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ + { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ + { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ + { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ + { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ + { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ + { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ + { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ + { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ + { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ + { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ + { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ + { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ + { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ + { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ + { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ + { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ + { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ + { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ + { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ + { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ + { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ + { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ + { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ + { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ + { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ + { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ + { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ + { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ + { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ + { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ + { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ + { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ + { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ + { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ + { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ + { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ + { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ + { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ + { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ + { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ + { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ + { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ + { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ + { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ + { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ + { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ + { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ + { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ + { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ + { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ + { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */ + { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ + { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ + { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ + { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ + { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ + { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ + { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ + { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ + { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ + { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ + { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ + { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ + { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ + { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ + { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ + { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ + { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ + { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ + { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ + { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ + { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ + { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ + { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ + { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ + { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ + { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ + { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ + { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ + { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ + { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ + { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ + { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ + { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ + { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ + { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ + { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ + { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ + { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ + { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ + { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ + { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ + { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ + { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ + { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ + { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ + { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ + { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ + { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ + { 0x08a1, 0x23b7 }, /* leftradical ⎷ RADICAL SYMBOL BOTTOM */ + { 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */ + { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ + { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ LEFT SQUARE BRACKET UPPER CORNER */ + { 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ LEFT SQUARE BRACKET LOWER CORNER */ + { 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ RIGHT SQUARE BRACKET UPPER CORNER */ + { 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ RIGHT SQUARE BRACKET LOWER CORNER */ + { 0x08ab, 0x239b }, /* topleftparens ⎛ LEFT PARENTHESIS UPPER HOOK */ + { 0x08ac, 0x239d }, /* botleftparens ⎝ LEFT PARENTHESIS LOWER HOOK */ + { 0x08ad, 0x239e }, /* toprightparens ⎞ RIGHT PARENTHESIS UPPER HOOK */ + { 0x08ae, 0x23a0 }, /* botrightparens ⎠ RIGHT PARENTHESIS LOWER HOOK */ + { 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ LEFT CURLY BRACKET MIDDLE PIECE */ + { 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ RIGHT CURLY BRACKET MIDDLE PIECE */ + /* 0x08b1 topleftsummation ? ??? */ + /* 0x08b2 botleftsummation ? ??? */ + /* 0x08b3 topvertsummationconnector ? ??? */ + /* 0x08b4 botvertsummationconnector ? ??? */ + /* 0x08b5 toprightsummation ? ??? */ + /* 0x08b6 botrightsummation ? ??? */ + /* 0x08b7 rightmiddlesummation ? ??? */ + { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ + { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ + { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ + { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ + { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ + { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ + { 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */ + { 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */ + { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ + { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ + { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ + { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ + { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ + { 0x08dd, 0x222a }, /* union ∪ UNION */ + { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ + { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ + { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ + { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ + { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ + { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ + { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ + { 0x09df, 0x2422 }, /* blank ␢ BLANK SYMBOL */ + { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ + { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ + { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ + { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ + { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ + { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ + { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ + { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ + { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ + { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ + { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ + { 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 */ + { 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 */ + { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ + { 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 */ + { 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 */ + { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ + { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ + { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ + { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ + { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ + { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ + { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ + { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ + { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ + { 0x0aaa, 0x2013 }, /* endash – EN DASH */ + { 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */ + { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ + { 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */ + { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ + { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ + { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ + { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ + { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ + { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ + { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ + { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ + { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ + { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ + { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ + { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ + { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ + /* 0x0abf marker ? ??? */ + { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ + { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ + { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ + { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ + { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ + { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ + /* 0x0acb trademarkincircle ? ??? */ + { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ + { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ + { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ + { 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */ + { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ + { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ + /* 0x0ad5 permille ? ??? */ + { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ + { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ + { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ + /* 0x0ada hexagram ? ??? */ + { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ + { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ + { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ + { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ + { 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */ + { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ + { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ + { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ + { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ + { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ + { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ + { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ + { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ + { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ + { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ + { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ + { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ + { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ + { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ + { 0x0af1, 0x2020 }, /* dagger † DAGGER */ + { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ + { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ + { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ + { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ + { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ + { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ + { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ + { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ + { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ + { 0x0afc, 0x2038 }, /* caret ‸ CARET */ + { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ + /* 0x0aff cursor ? ??? */ + { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ + { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ + { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ + { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ + { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ + { 0x0bc2, 0x22a5 }, /* downtack ⊥ UP TACK */ + { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ + { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ + { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ + { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ + { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */ + { 0x0bce, 0x22a4 }, /* uptack ⊤ DOWN TACK */ + { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ + { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ + { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ + { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ + { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ + { 0x0bdc, 0x22a2 }, /* lefttack ⊢ RIGHT TACK */ + { 0x0bfc, 0x22a3 }, /* righttack ⊣ LEFT TACK */ + { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ + { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ + { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ + { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ + { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ + { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ + { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ + { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ + { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ + { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ + { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ + { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ + { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ + { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ + { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ + { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ + { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ + { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ + { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ + { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ + { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ + { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ + { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ + { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ + { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ + { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ + { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ + { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ + { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ + { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ + { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ + { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ + { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ + { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ + { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ + { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ + { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ + { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ + { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ + { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ + { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ + { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ + { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ + { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ + { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ + { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ + { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ + { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ + { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ + { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ + { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ + { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ + { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ + { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ + { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ + { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ + { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ + { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ + { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ + { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ + { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ + { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ + { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ + { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ + { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ + { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ + { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ + { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ + { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ + { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ + { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ + { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ + { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ + { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ + { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ + { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ + { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ + { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ + { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ + { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ + { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ + { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ + { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ + { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ + { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ + { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ + { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ + { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ + { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ + { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ + { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ + { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ + { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ + { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ + { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ + { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ + { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ + { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ + { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ + { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ + { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ + { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ + { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ + { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ + { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ + { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ + { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ + { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ + { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ + { 0x0ef3, 0x3181 }, /* Hangul_KkogjiDalrinIeung ㆁ HANGUL LETTER YESIEUNG */ + { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ + { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ + { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ + { 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */ + { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ + { 0x13a4, 0x20ac }, /* Euro € EURO SIGN */ + { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ + { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ + { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ + + /* Combining symbols */ + { 0xfe50, 0x0300 }, /* dead_grave */ + { 0xfe51, 0x0301 }, /* dead_acute" */ + { 0xfe52, 0x0302 }, /* dead_circumflex" */ + { 0xfe53, 0x0303 }, /* dead_tilde" */ + { 0xfe54, 0x0304 }, /* dead_macron" */ + { 0xfe55, 0x0306 }, /* dead_breve" */ + { 0xfe56, 0x0307 }, /* dead_abovedot" */ + { 0xfe57, 0x0308 }, /* dead_diaeresis" */ + { 0xfe58, 0x030A }, /* dead_abovering" */ + { 0xfe59, 0x030B }, /* dead_doubleacute" */ + { 0xfe5a, 0x030C }, /* dead_caron" */ + { 0xfe5b, 0x0327 }, /* dead_cedilla" */ + { 0xfe5c, 0x0328 }, /* dead_ogonek" */ + { 0xfe60, 0x0323 }, /* dead_belowdot */ + + /* Special function keys. */ + + { 0xff08, 0x0008 }, /* XK_BackSpace */ + { 0xff09, 0x0009 }, /* XK_Tab */ + { 0xff0a, 0x000a }, /* XK_Linefeed */ + { 0xff0d, 0x000d }, /* XK_Return */ + { 0xff13, 0x0013 }, /* XK_Pause */ + { 0xff1b, 0x001b }, /* XK_Escape */ + { 0xff50, 0x0001 }, /* XK_Home */ + { 0xff51, 0x001c }, /* XK_Left */ + { 0xff52, 0x001e }, /* XK_Up */ + { 0xff53, 0x001d }, /* XK_Right */ + { 0xff54, 0x001f }, /* XK_Down */ + { 0xff55, 0x000b }, /* XK_Prior */ + { 0xff56, 0x000c }, /* XK_Next */ + { 0xff57, 0x0004 }, /* XK_End */ + { 0xff6a, 0x0005 }, /* XK_Help */ + { 0xffff, 0x007f }, /* XK_Delete */ +}; + +long keysym2ucs(KeySym keysym) +{ + int min = 0; + int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; + int mid; + + /* first check for Latin-1 characters (1:1 mapping) */ + if ((keysym >= 0x0020 && keysym <= 0x007e) || + (keysym >= 0x00a0 && keysym <= 0x00ff)) { + return keysym; + } + + /* also check for directly encoded 24-bit UCS characters */ + if ((keysym & 0xff000000) == 0x01000000) { + return keysym & 0x00ffffff; + } + + /* binary search in table */ + while (max >= min) { + mid = (min + max) / 2; + if (keysymtab[mid].keysym < keysym) { + min = mid + 1; + } else if (keysymtab[mid].keysym > keysym) { + max = mid - 1; + } else { + /* found it */ + return keysymtab[mid].ucs; + } + } + + /* no matching Unicode value found */ + return -1; +} diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keysym2ucs.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keysym2ucs.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keysym2ucs.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keysym2ucs.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2012 Andriy Rysin (arysin@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KEYSYM2UCS_H +#define KEYSYM2UCS_H + +#include +#include + +extern long keysym2ucs(KeySym keysym); + +#endif diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keysymhelper.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keysymhelper.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keysymhelper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keysymhelper.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "keysymhelper.h" +#include "keysym2ucs.h" + +#include +#include +#include + +#include + + +KeySymHelper::KeySymHelper() +{ + nill = 0; +} + +QString KeySymHelper::getKeySymbol(const QString &opton) +{ + if (keySymbolMap.contains(opton)) { + return keySymbolMap[opton]; + } + + const char *str = opton.toLatin1().data(); + +#if 0 + //TODO: figure out how to use this so we don't need our own symkey2ucs mapping + int res = Xutf8LookupString(XIC ic, XKeyPressedEvent * event, char *buffer_return, int bytes_buffer, KeySym * keysym_return, Status * status_return); + +#else + + KeySym keysym = XStringToKeysym(str); + + //TODO: make it more generic +// if( keysym == 0xfe03 ) +// return "L3"; + + long ucs = keysym2ucs(keysym); + +// if( ucs == -1 && (keysym >= 0xFE50 && keysym <= 0xFE5F) ) { +// ucs = 0x0300 + (keysym & 0x000F); +// qWarning() << "Got dead symbol" << QString("0x%1").arg(keysym, 0, 16) << "named" << opton << "will use" << QString("0x%1").arg(ucs, 0, 16) << "as UCS"; +// } + + if (ucs == -1) { + nill++; + qWarning() << "No mapping from keysym:" << QStringLiteral("0x%1").arg(keysym, 0, 16) << "named:" << opton << "to UCS"; + return ""; + } + + QString ucsStr = QString(QChar((int)ucs)); + + // Combining Diacritical Marks + if (ucs >= 0x0300 && ucs <= 0x036F) { + ucsStr = " " + ucsStr + " "; + } + +// qWarning() << "--" << opton << "keysym: " << keysym << QString("0x%1").arg(keysym, 0, 16) << "keysym2string" << XKeysymToString(keysym) +// << "---" << QString("0x%1").arg(ucs, 0, 16) << ucsStr; + + keySymbolMap[opton] = ucsStr; + + return ucsStr; + +#endif + +} + diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keysymhelper.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keysymhelper.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/keysymhelper.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/keysymhelper.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KEYSYMHELPER_H +#define KEYSYMHELPER_H + +#include +#include + +class KeySymHelper +{ +public: + KeySymHelper(); + + QString getKeySymbol(const QString &opton); + bool isFailed() const + { + return nill >= 120; + } + +private: + QMap keySymbolMap; + int nill; +}; + +#endif // KEYSYMHELPER_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/symbol_parser.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/symbol_parser.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/symbol_parser.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/symbol_parser.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "symbol_parser.h" +#include "xkb_rules.h" + +#include +#include +#include +#include +#include + + +namespace grammar +{ + +symbol_keywords::symbol_keywords() +{ + add("key", 2)("include", 1)("//", 3)("*/", 4); +} + +levels::levels() +{ + add("ONE", 1)("TWO", 2)("THREE", 3)("FOUR", 4)("SIX", 6)("EIGHT", 8); +} + +template +SymbolParser::SymbolParser() : + SymbolParser::base_type(start) +{ + using qi::lexeme; + using qi::char_; + using qi::lit; + using qi::_1; + using qi::_val; + using qi::int_; + using qi::double_; + using qi::eol; + + newKey = 0; + + name %= '"' >> +(char_ - '"') >> '"'; + + group = lit("Group") >> int_; + + comments = lexeme[lit("//") >> *(char_ - eol || symbolKeyword - eol) >> eol + || lit("/*") >> *(char_ - lit("*/") || symbolKeyword - lit("*/")) + >> lit("*/")]; + + include = lit("include") + >> name[phx::bind(&SymbolParser::getInclude, this, _1)]; + + type = lit("type") >> '[' >> group >> lit(']') >> lit('=') >> lit("\"") + >> *(char_ - lvl) + >> *lvl[phx::bind(&SymbolParser::setLevel, this, _1)] + >> *(char_ - lvl - '"') >> lit("\""); + + symbol = +(char_ - ',' - ']'); + + symbols = *(lit("symbols") >> '[' >> group >> lit(']') >> lit('=')) >> '[' + >> symbol[phx::bind(&SymbolParser::getSymbol, this, _1)] + >> *(',' >> symbol[phx::bind(&SymbolParser::getSymbol, this, _1)]) + >> ']'; + + keyName = '<' >> *(char_ - '>') >> '>'; + + key = (lit("key") + >> keyName[phx::bind(&SymbolParser::addKeyName, this, _1)] >> '{' + >> *(type >> ',') >> symbols >> *(',' >> type) >> lit("};")) + || lit("key") >> lit(".") >> type >> lit(";"); + + ee = *(char_ - symbolKeyword - '{') >> '{' >> *(char_ - '}' - ';') + >> lit("};"); + + start = *(char_ - lit("xkb_symbols") || comments) >> lit("xkb_symbols") + >> name[phx::bind(&SymbolParser::setName, this, _1)] >> '{' + >> *(key[phx::bind(&SymbolParser::addKey, this)] || include || ee + || char_ - '}' - symbolKeyword || comments) >> lit("};") + >> *(comments || char_); +} + +template +void SymbolParser::getSymbol(std::string n) +{ + int index = layout.keyList[keyIndex].getSymbolCount(); + layout.keyList[keyIndex].addSymbol(QString::fromUtf8(n.data(), n.size()), + index); + //qCDebug(KEYBOARD_PREVIEW) << "adding symbol: " << QString::fromUtf8(n.data(), n.size()); + //qCDebug(KEYBOARD_PREVIEW) << "added symbol: " << layout.keyList[keyIndex].getSymbol(index) << " in " << keyIndex << " at " << index; +} + +template +void SymbolParser::addKeyName(std::string n) +{ + QString kname = QString::fromUtf8(n.data(), n.size()); + if (kname.startsWith(QLatin1String("Lat"))) { + kname = alias.getAlias(layout.country, kname); + } + keyIndex = layout.findKey(kname); + //qCDebug(KEYBOARD_PREVIEW) << layout.getKeyCount(); + if (keyIndex == -1) { + layout.keyList[layout.getKeyCount()].keyName = kname; + keyIndex = layout.getKeyCount(); + newKey = 1; + } + // qCDebug(KEYBOARD_PREVIEW) << "key at" << keyIndex; +} + +template +void SymbolParser::addKey() +{ + if (newKey == 1) { + layout.addKey(); + newKey = 0; + //qCDebug(KEYBOARD_PREVIEW) << "new key"; + } +} + +template +void SymbolParser::getInclude(std::string n) +{ + layout.addInclude(QString::fromUtf8(n.data(), n.size())); +} + +template +void SymbolParser::setName(std::string n) +{ + layout.setName(QString::fromUtf8(n.data(), n.size())); + //qCDebug(KEYBOARD_PREVIEW) << layout.getLayoutName(); +} + +template +void SymbolParser::setLevel(int lvl) +{ + if (lvl > layout.getLevel()) { + layout.setLevel(lvl); + qCDebug(KEYBOARD_PREVIEW) << lvl; + } +} + +QString findSymbolBaseDir() +{ + QString xkbDir = Rules::findXkbDir(); + return QStringLiteral("%1/symbols/").arg(xkbDir); +} + +QString findLayout(const QString &layout, const QString &layoutVariant) +{ + + QString symbolBaseDir = findSymbolBaseDir(); + QString symbolFile = symbolBaseDir.append(layout); + + QFile sfile(symbolFile); + if (!sfile.open(QIODevice::ReadOnly | QIODevice::Text)) { + //qCDebug(KEYBOARD_PREVIEW) << "unable to open the file"; + return QStringLiteral("I/O ERROR"); + } + + QString scontent = sfile.readAll(); + sfile.close(); + QStringList scontentList = scontent.split(QStringLiteral("xkb_symbols")); + + QString variant; + QString input; + + if (layoutVariant.isEmpty()) { + input = scontentList.at(1); + input.prepend("xkb_symbols"); + } + + else { + int current = 1; + + while (layoutVariant != variant && current < scontentList.size()) { + input = scontentList.at(current); + + QString symbolCont = scontentList.at(current); + + int index = symbolCont.indexOf(QStringLiteral("\"")); + symbolCont = symbolCont.mid(index); + index = symbolCont.indexOf(QStringLiteral("{")); + symbolCont = symbolCont.left(index); + symbolCont = symbolCont.remove(QStringLiteral(" ")); + variant = symbolCont.remove(QStringLiteral("\"")); + + input.prepend("xkb_symbols"); + current++; + } + } + + return input; +} + +KbLayout parseSymbols(const QString &layout, const QString &layoutVariant) +{ + + using boost::spirit::iso8859_1::space; + typedef std::string::const_iterator iterator_type; + typedef grammar::SymbolParser SymbolParser; + + SymbolParser symbolParser; + + symbolParser.layout.country = layout; + QString input = findLayout(layout, layoutVariant); + + if (input == QLatin1String("I/O ERROR")) { + symbolParser.layout.setParsedSymbol(false); + return symbolParser.layout; + } + + std::string parserInput = input.toUtf8().constData(); + + std::string::const_iterator iter = parserInput.begin(); + std::string::const_iterator end = parserInput.end(); + + bool success = phrase_parse(iter, end, symbolParser, space); + + if (success && iter == end) { + qCDebug(KEYBOARD_PREVIEW) << "Symbols Parsing succeeded"; + symbolParser.layout.setParsedSymbol(true); + + } else { + qWarning() << "Symbols Parsing failed\n" << input; + symbolParser.layout.setParsedSymbol(false); + } + + for (int currentInclude = 0; + currentInclude < symbolParser.layout.getIncludeCount(); + currentInclude++) { + QString include = symbolParser.layout.getInclude(currentInclude); + QStringList includeFile = include.split(QStringLiteral("(")); + if (includeFile.size() == 2) { + QString file = includeFile.at(0); + QString layout = includeFile.at(1); + layout.remove(QStringLiteral(")")); + input = findLayout(file, layout); + + } + + else { + QString a; + a.clear(); + input = findLayout(includeFile.at(0), a); + } + + parserInput = input.toUtf8().constData(); + + std::string::const_iterator iter = parserInput.begin(); + std::string::const_iterator end = parserInput.end(); + + success = phrase_parse(iter, end, symbolParser, space); + + if (success && iter == end) { + qCDebug(KEYBOARD_PREVIEW) << "Symbols Parsing succeeded"; + symbolParser.layout.setParsedSymbol(true); + + } else { + qCDebug(KEYBOARD_PREVIEW) << "Symbols Parsing failed\n"; + qCDebug(KEYBOARD_PREVIEW) << input; + symbolParser.layout.setParsedSymbol(false); + } + + } + + //s.layout.display(); + if (symbolParser.layout.getParsedSymbol()) { + return symbolParser.layout; + } else { + return parseSymbols(QStringLiteral("us"), QStringLiteral("basic")); + } +} + +} diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/symbol_parser.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/symbol_parser.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/symbol_parser.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/symbol_parser.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2013 Shivam Makkar (amourphious1992@gmail.com) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SYMBOL_PARSER_H +#define SYMBOL_PARSER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "keyboardlayout.h" +#include "keyaliases.h" + + +namespace qi = boost::spirit::qi; +namespace ascii = boost::spirit::ascii; +namespace phx = boost::phoenix; +namespace iso = boost::spirit::iso8859_1; + + +namespace grammar +{ + +struct symbol_keywords : qi::symbols { + symbol_keywords(); +}; + +struct levels : qi::symbols { + levels(); +}; + +template +struct SymbolParser : qi::grammar { + + SymbolParser(); + + qi::rulestart; + qi::rulename; + qi::rulekeyName; + qi::rulesymbols; + qi::rulekey; + qi::ruletype; + qi::rulegroup; + qi::rulesymbol; + qi::rulecomments; + qi::ruleee; + qi::ruleinclude; + + KbLayout layout; + int keyIndex, newKey; + symbol_keywords symbolKeyword; + levels lvl; + Aliases alias; + + void getSymbol(std::string n); + void addKeyName(std::string n); + void getInclude(std::string n); + void addKey(); + void setName(std::string n); + void setLevel(int lvl); +}; + +KbLayout parseSymbols(const QString &layout, const QString &layoutVariant); +QString findSymbolBaseDir(); +} + +#endif //SYMBOL_PARSER_H diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/x11_helper.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/x11_helper.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/x11_helper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/x11_helper.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,453 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "x11_helper.h" +#include "debug.h" + +#define explicit explicit_is_keyword_in_cpp +#include +#undef explicit + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +// more information about the limit https://bugs.freedesktop.org/show_bug.cgi?id=19501 +const int X11Helper::MAX_GROUP_COUNT = 4; +const int X11Helper::ARTIFICIAL_GROUP_LIMIT_COUNT = 8; + +const char X11Helper::LEFT_VARIANT_STR[] = "("; +const char X11Helper::RIGHT_VARIANT_STR[] = ")"; + +bool X11Helper::xkbSupported(int* xkbOpcode) +{ + if (!QX11Info::isPlatformX11()) { + return false; + } + // Verify the Xlib has matching XKB extension. + + int major = XkbMajorVersion; + int minor = XkbMinorVersion; + + if (!XkbLibraryVersion(&major, &minor)) + { + qCWarning(KCM_KEYBOARD) << "Xlib XKB extension " << major << '.' << minor << + " != " << XkbMajorVersion << '.' << XkbMinorVersion; + return false; + } + + // Verify the X server has matching XKB extension. + + int opcode_rtrn; + int error_rtrn; + int xkb_opcode; + if( ! XkbQueryExtension(QX11Info::display(), &opcode_rtrn, &xkb_opcode, &error_rtrn, &major, &minor)) { + qCWarning(KCM_KEYBOARD) << "X server XKB extension " << major << '.' << minor << + " != " << XkbMajorVersion << '.' << XkbMinorVersion; + return false; + } + + if( xkbOpcode != nullptr ) { + *xkbOpcode = xkb_opcode; + } + + return true; +} + +void X11Helper::switchToNextLayout() +{ + int size = getLayoutsList().size(); //TODO: could optimize a bit as we don't need the layouts - just count + int group = (X11Helper::getGroup() + 1) % size; + X11Helper::setGroup(group); +} + +void X11Helper::scrollLayouts(int delta) +{ + int size = getLayoutsList().size(); //TODO: could optimize a bit as we don't need the layouts - just count + int group = X11Helper::getGroup() + delta; + group = group < 0 ? size - ((-group) % size) : group % size; + + X11Helper::setGroup(group); +} + +QStringList X11Helper::getLayoutsListAsString(const QList& layoutsList) +{ + QStringList stringList; + foreach(const LayoutUnit& layoutUnit, layoutsList) { + stringList << layoutUnit.toString(); + } + return stringList; +} + +bool X11Helper::setLayout(const LayoutUnit& layout) +{ + QList currentLayouts = getLayoutsList(); + int idx = currentLayouts.indexOf(layout); + if( idx == -1 || idx >= X11Helper::MAX_GROUP_COUNT ) { + qCWarning(KCM_KEYBOARD) << "Layout" << layout.toString() << "is not found in current layout list" + << getLayoutsListAsString(currentLayouts); + return false; + } + + return X11Helper::setGroup((unsigned int)idx); +} + +bool X11Helper::setDefaultLayout() { + return X11Helper::setGroup(0); +} + +bool X11Helper::isDefaultLayout() { + return X11Helper::getGroup() == 0; +} + +LayoutUnit X11Helper::getCurrentLayout() +{ + if (!QX11Info::isPlatformX11()) { + return LayoutUnit(); + } + QList currentLayouts = getLayoutsList(); + unsigned int group = X11Helper::getGroup(); + if( group < (unsigned int)currentLayouts.size() ) + return currentLayouts[group]; + + qCWarning(KCM_KEYBOARD) << "Current group number" << group << "is outside of current layout list" << + getLayoutsListAsString(currentLayouts); + return LayoutUnit(); +} + +LayoutSet X11Helper::getCurrentLayouts() +{ + LayoutSet layoutSet; + + QList currentLayouts = getLayoutsList(); + layoutSet.layouts = currentLayouts; + + unsigned int group = X11Helper::getGroup(); + if( group < (unsigned int)currentLayouts.size() ) { + layoutSet.currentLayout = currentLayouts[group]; + } + else { + qCWarning(KCM_KEYBOARD) << "Current group number" << group << "is outside of current layout list" << getLayoutsListAsString(currentLayouts); + layoutSet.currentLayout = LayoutUnit(); + } + + return layoutSet; +} + + +//static QString addNum(const QString& str, int n) +//{ +// QString format("%1%2"); +// if( str.length() >= 3 ) return format.arg(str.left(2)).arg(n); +// return format.arg(str).arg(n); +//} + +QList X11Helper::getLayoutsList() +{ + if (!QX11Info::isPlatformX11()) { + return QList(); + } + XkbConfig xkbConfig; + QList layouts; + if( X11Helper::getGroupNames(QX11Info::display(), &xkbConfig, X11Helper::LAYOUTS_ONLY) ) { + for(int i=0; i" << endl; +// qCDebug(KCM_KEYBOARD) << group; +// xcb_void_cookie_t cookie; +// cookie = xcb_xkb_latch_lock_state(QX11Info::connection(), +// XCB_XKB_ID_USE_CORE_KBD, +// 0, 0, +// 1, +// group, +// 0, 0, 0 +// ); +// xcb_generic_error_t *error = nullptr; +// error = xcb_request_check(QX11Info::connection(), cookie); +// if (error) { +// qCDebug(KCM_KEYBOARD) << "Couldn't change the group" << error->error_code; +// return false; +// } + + return true; +} + +unsigned int X11Helper::getGroup() +{ + XkbStateRec xkbState; + XkbGetState( QX11Info::display(), XkbUseCoreKbd, &xkbState ); + return xkbState.group; +} + +bool X11Helper::getGroupNames(Display* display, XkbConfig* xkbConfig, FetchType fetchType) +{ + static const char OPTIONS_SEPARATOR[] = ","; + + Atom real_prop_type; + int fmt; + unsigned long nitems, extra_bytes; + char *prop_data = nullptr; + Status ret; + + Atom rules_atom = XInternAtom(display, _XKB_RF_NAMES_PROP_ATOM, False); + + /* no such atom! */ + if (rules_atom == None) { /* property cannot exist */ + qCWarning(KCM_KEYBOARD) << "Failed to fetch layouts from server:" << "could not find the atom" << _XKB_RF_NAMES_PROP_ATOM; + return false; + } + + ret = XGetWindowProperty(display, + DefaultRootWindow(display), + rules_atom, 0L, _XKB_RF_NAMES_PROP_MAXLEN, + False, XA_STRING, &real_prop_type, &fmt, + &nitems, &extra_bytes, + (unsigned char **) (void *) &prop_data); + + /* property not found! */ + if (ret != Success) { + qCWarning(KCM_KEYBOARD) << "Failed to fetch layouts from server:" << "Could not get the property"; + return false; + } + + /* has to be array of strings */ + if ((extra_bytes > 0) || (real_prop_type != XA_STRING) || (fmt != 8)) { + if (prop_data) + XFree(prop_data); + qCWarning(KCM_KEYBOARD) << "Failed to fetch layouts from server:" << "Wrong property format"; + return false; + } + +// qCDebug(KCM_KEYBOARD) << "prop_data:" << nitems << prop_data; + QStringList names; + for(char* p=prop_data; p-prop_data < (long)nitems && p != nullptr; p += strlen(p)+1) { + names.append( p ); +// qDebug() << " " << p; + } + + if( names.count() < 4 ) { //{ rules, model, layouts, variants, options } + XFree(prop_data); + return false; + } + + if( fetchType == ALL || fetchType == LAYOUTS_ONLY ) { + QStringList layouts = names[2].split(OPTIONS_SEPARATOR); + QStringList variants = names[3].split(OPTIONS_SEPARATOR); + + for(int ii=0; iilayouts << (layouts[ii] != nullptr ? layouts[ii] : QLatin1String("")); + xkbConfig->variants << (ii < variants.count() && variants[ii] != nullptr ? variants[ii] : QLatin1String("")); + } + qCDebug(KCM_KEYBOARD) << "Fetched layout groups from X server:" + << "\tlayouts:" << xkbConfig->layouts + << "\tvariants:" << xkbConfig->variants; + } + + if( fetchType == ALL || fetchType == MODEL_ONLY ) { + xkbConfig->keyboardModel = (names[1] != nullptr ? names[1] : QLatin1String("")); + qCDebug(KCM_KEYBOARD) << "Fetched keyboard model from X server:" << xkbConfig->keyboardModel; + } + + if( fetchType == ALL ) { + if( names.count() >= 5 ) { + QString options = (names[4] != nullptr ? names[4] : QLatin1String("")); + xkbConfig->options = options.split(OPTIONS_SEPARATOR); + qCDebug(KCM_KEYBOARD) << "Fetched xkbOptions from X server:" << options; + } + } + + XFree(prop_data); + return true; +} + +XEventNotifier::XEventNotifier(): + xkbOpcode(-1) +{ + if( QCoreApplication::instance() == nullptr ) { + qCWarning(KCM_KEYBOARD) << "Layout Widget won't work properly without QCoreApplication instance"; + } +} + +void XEventNotifier::start() +{ + qCDebug(KCM_KEYBOARD) << "qCoreApp" << QCoreApplication::instance(); + if( QCoreApplication::instance() != nullptr && X11Helper::xkbSupported(&xkbOpcode) ) { + registerForXkbEvents(QX11Info::display()); + + // start the event loop + QCoreApplication::instance()->installNativeEventFilter(this); + } +} + +void XEventNotifier::stop() +{ + if( QCoreApplication::instance() != nullptr ) { + //TODO: unregister + // XEventNotifier::unregisterForXkbEvents(QX11Info::display()); + + // stop the event loop + QCoreApplication::instance()->removeNativeEventFilter(this); + } +} + + +bool XEventNotifier::isXkbEvent(xcb_generic_event_t* event) +{ +// qDebug() << "event response type:" << (event->response_type & ~0x80) << xkbOpcode << ((event->response_type & ~0x80) == xkbOpcode + XkbEventCode); + return (event->response_type & ~0x80) == xkbOpcode + XkbEventCode; +} + +bool XEventNotifier::processOtherEvents(xcb_generic_event_t* /*event*/) +{ + return true; +} + +bool XEventNotifier::processXkbEvents(xcb_generic_event_t* event) +{ + _xkb_event *xkbevt = reinterpret_cast<_xkb_event *>(event); + if( XEventNotifier::isGroupSwitchEvent(xkbevt) ) { +// qDebug() << "group switch event"; + emit(layoutChanged()); + } + else if( XEventNotifier::isLayoutSwitchEvent(xkbevt) ) { +// qDebug() << "layout switch event"; + emit(layoutMapChanged()); + } + return true; +} + +bool XEventNotifier::nativeEventFilter(const QByteArray &eventType, void *message, long *) +{ +// qDebug() << "event type:" << eventType; + if (eventType == "xcb_generic_event_t") { + xcb_generic_event_t* ev = static_cast(message); + if( isXkbEvent(ev) ) { + processXkbEvents(ev); + } + else { + processOtherEvents(ev); + } + } + return false; +} + +//bool XEventNotifier::x11Event(XEvent * event) +//{ +// // qApp->x11ProcessEvent ( event ); +// if( isXkbEvent(event) ) { +// processXkbEvents(event); +// } +// else { +// processOtherEvents(event); +// } +// return QWidget::x11Event(event); +//} + +bool XEventNotifier::isGroupSwitchEvent(_xkb_event* xkbEvent) +{ +// XkbEvent *xkbEvent = (XkbEvent*) event; +#define GROUP_CHANGE_MASK \ + ( XkbGroupStateMask | XkbGroupBaseMask | XkbGroupLatchMask | XkbGroupLockMask ) + + return xkbEvent->any.xkbType == XkbStateNotify && (xkbEvent->state_notify.changed & GROUP_CHANGE_MASK); +} + +bool XEventNotifier::isLayoutSwitchEvent(_xkb_event* xkbEvent) +{ +// XkbEvent *xkbEvent = (XkbEvent*) event; + + return //( (xkbEvent->any.xkb_type == XkbMapNotify) && (xkbEvent->map.changed & XkbKeySymsMask) ) || +/* || ( (xkbEvent->any.xkb_type == XkbNamesNotify) && (xkbEvent->names.changed & XkbGroupNamesMask) || )*/ + (xkbEvent->any.xkbType == XkbNewKeyboardNotify); +} + +int XEventNotifier::registerForXkbEvents(Display* display) +{ + int eventMask = XkbNewKeyboardNotifyMask | XkbStateNotifyMask; + if( ! XkbSelectEvents(display, XkbUseCoreKbd, eventMask, eventMask) ) { + qCWarning(KCM_KEYBOARD) << "Couldn't select desired XKB events"; + return false; + } + return true; +} + + +static const char LAYOUT_VARIANT_SEPARATOR_PREFIX[] = "("; +static const char LAYOUT_VARIANT_SEPARATOR_SUFFIX[] = ")"; + +static QString& stripVariantName(QString& variant) +{ + if( variant.endsWith(LAYOUT_VARIANT_SEPARATOR_SUFFIX) ) { + int suffixLen = strlen(LAYOUT_VARIANT_SEPARATOR_SUFFIX); + return variant.remove(variant.length()-suffixLen, suffixLen); + } + return variant; +} + +LayoutUnit::LayoutUnit(const QString& fullLayoutName) +{ + QStringList lv = fullLayoutName.split(LAYOUT_VARIANT_SEPARATOR_PREFIX); + layout = lv[0]; + variant = lv.size() > 1 ? stripVariantName(lv[1]) : QLatin1String(""); +} + +QString LayoutUnit::toString() const +{ + if( variant.isEmpty() ) + return layout; + + return layout + LAYOUT_VARIANT_SEPARATOR_PREFIX+variant+LAYOUT_VARIANT_SEPARATOR_SUFFIX; +} + +const int LayoutUnit::MAX_LABEL_LENGTH = 3; diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/x11_helper.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/x11_helper.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/x11_helper.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/x11_helper.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef X11_HELPER_H_ +#define X11_HELPER_H_ + +#include +#include +#include +#include +#include +#include + +#include +//#include + +//union _xkb_event; +//class xcb_generic_event_t; + +// TODO: remove this when we can include xcb/xkb.h +namespace +{ +typedef struct _xcb_xkb_map_notify_event_t { + uint8_t response_type; + uint8_t xkbType; + uint16_t sequence; + xcb_timestamp_t time; + uint8_t deviceID; + uint8_t ptrBtnActions; + uint16_t changed; + xcb_keycode_t minKeyCode; + xcb_keycode_t maxKeyCode; + uint8_t firstType; + uint8_t nTypes; + xcb_keycode_t firstKeySym; + uint8_t nKeySyms; + xcb_keycode_t firstKeyAct; + uint8_t nKeyActs; + xcb_keycode_t firstKeyBehavior; + uint8_t nKeyBehavior; + xcb_keycode_t firstKeyExplicit; + uint8_t nKeyExplicit; + xcb_keycode_t firstModMapKey; + uint8_t nModMapKeys; + xcb_keycode_t firstVModMapKey; + uint8_t nVModMapKeys; + uint16_t virtualMods; + uint8_t pad0[2]; +} _xcb_xkb_map_notify_event_t; +typedef struct _xcb_xkb_state_notify_event_t { + uint8_t response_type; + uint8_t xkbType; + uint16_t sequence; + xcb_timestamp_t time; + uint8_t deviceID; + uint8_t mods; + uint8_t baseMods; + uint8_t latchedMods; + uint8_t lockedMods; + uint8_t group; + int16_t baseGroup; + int16_t latchedGroup; + uint8_t lockedGroup; + uint8_t compatState; + uint8_t grabMods; + uint8_t compatGrabMods; + uint8_t lookupMods; + uint8_t compatLoockupMods; + uint16_t ptrBtnState; + uint16_t changed; + xcb_keycode_t keycode; + uint8_t eventType; + uint8_t requestMajor; + uint8_t requestMinor; +} _xcb_xkb_state_notify_event_t; +typedef union { + /* All XKB events share these fields. */ + struct { + uint8_t response_type; + uint8_t xkbType; + uint16_t sequence; + xcb_timestamp_t time; + uint8_t deviceID; + } any; + _xcb_xkb_map_notify_event_t map_notify; + _xcb_xkb_state_notify_event_t state_notify; +} _xkb_event; +} + +class XEventNotifier : public QObject, public QAbstractNativeEventFilter { + Q_OBJECT + +Q_SIGNALS: + void layoutChanged(); + void layoutMapChanged(); + +public: + XEventNotifier(); + ~XEventNotifier() override {} + + virtual void start(); + virtual void stop(); + +protected: +// bool x11Event(XEvent * e); + virtual bool processOtherEvents(xcb_generic_event_t* e); + virtual bool processXkbEvents(xcb_generic_event_t* e); + bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override; + +private: + int registerForXkbEvents(Display* display); + bool isXkbEvent(xcb_generic_event_t* event); + bool isGroupSwitchEvent(_xkb_event* event); + bool isLayoutSwitchEvent(_xkb_event* event); + + int xkbOpcode; +}; + +struct XkbConfig { + QString keyboardModel; + QStringList layouts; + QStringList variants; + QStringList options; + + bool isValid() { return ! layouts.empty(); } +}; + + +struct LayoutUnit { + static const int MAX_LABEL_LENGTH; + + //TODO: move these to private? + QString layout; + QString variant; + + LayoutUnit() {} + explicit LayoutUnit(const QString& fullLayoutName); + LayoutUnit(const QString& layout_, const QString& variant_) { + layout = layout_; + variant = variant_; + } + /*explicit*/ LayoutUnit(const LayoutUnit& layoutUnit) { + layout = layoutUnit.layout; + variant = layoutUnit.variant; + displayName = layoutUnit.displayName; + shortcut = layoutUnit.shortcut; + } + + QString getRawDisplayName() const { return displayName; } + QString getDisplayName() const { return !displayName.isEmpty() ? displayName : layout; } + void setDisplayName(const QString& name) { displayName = name; } + + void setShortcut(const QKeySequence& shortcut) { this->shortcut = shortcut; } + QKeySequence getShortcut() const { return shortcut; } + + bool isEmpty() const { return layout.isEmpty(); } + bool isValid() const { return ! isEmpty(); } + bool operator==(const LayoutUnit& layoutItem) const { + return layout==layoutItem.layout && variant==layoutItem.variant; + } + bool operator!=(const LayoutUnit& layoutItem) const { + return ! (*this == layoutItem); + } + QString toString() const; + +private: + QString displayName; + QKeySequence shortcut; +}; + +struct LayoutSet { + QList layouts; + LayoutUnit currentLayout; + + LayoutSet() {} + + LayoutSet(const LayoutSet& currentLayouts) { + this->layouts = currentLayouts.layouts; + this->currentLayout = currentLayouts.currentLayout; + } + + bool isValid() const { + return currentLayout.isValid() && layouts.contains(currentLayout); + } + + bool operator == (const LayoutSet& currentLayouts) const { + return this->layouts == currentLayouts.layouts + && this->currentLayout == currentLayouts.currentLayout; + } + + LayoutSet& operator = (const LayoutSet& currentLayouts) { + this->layouts = currentLayouts.layouts; + this->currentLayout = currentLayouts.currentLayout; + return *this; + } + + QString toString() const { + QString str(currentLayout.toString()); + str += QLatin1String(": "); + foreach(const LayoutUnit& layoutUnit, layouts) { + str += layoutUnit.toString() + " "; + } + return str; + } + + static QString toString(const QList& layoutUnits) { + QString str; + foreach(const LayoutUnit& layoutUnit, layoutUnits) { + str += layoutUnit.toString() + ","; + } + return str; + } +}; + +class X11Helper +{ +public: + static const int MAX_GROUP_COUNT; + static const int ARTIFICIAL_GROUP_LIMIT_COUNT; + + static const char LEFT_VARIANT_STR[]; + static const char RIGHT_VARIANT_STR[]; + + static bool xkbSupported(int* xkbOpcode); + + static void switchToNextLayout(); + static void scrollLayouts(int delta); + static bool isDefaultLayout(); + static bool setDefaultLayout(); + static bool setLayout(const LayoutUnit& layout); + static LayoutUnit getCurrentLayout(); + static LayoutSet getCurrentLayouts(); + static QList getLayoutsList(); + static QStringList getLayoutsListAsString(const QList& layoutsList); + + enum FetchType { ALL, LAYOUTS_ONLY, MODEL_ONLY }; + static bool getGroupNames(Display* dpy, XkbConfig* xkbConfig, FetchType fetchType); + +private: + static unsigned int getGroup(); + static bool setGroup(unsigned int group); +}; + +#endif /* X11_HELPER_H_ */ diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/xkb_rules.cpp ukui-control-center-3.0.3/plugins/devices/keyboard/preview/xkb_rules.cpp --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/xkb_rules.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/xkb_rules.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,497 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "xkb_rules.h" +#include "config-workspace.h" +#include "debug.h" + +#include + +#include +#include +#include // for Qt::escape +#include + +#include +//#include +//#include + +#include "x11_helper.h" + +// for findXkbRuleFile +#include +#include +#include +#include +#include +#include +#include "config-workspace.h" + + + +class RulesHandler : public QXmlDefaultHandler +{ +public: + RulesHandler(Rules* rules_, bool fromExtras_): + rules(rules_), + fromExtras(fromExtras_){} + + bool startElement(const QString &namespaceURI, const QString &localName, + const QString &qName, const QXmlAttributes &attributes) override; + bool endElement(const QString &namespaceURI, const QString &localName, + const QString &qName) override; + bool characters(const QString &str) override; +// bool fatalError(const QXmlParseException &exception); +// QString errorString() const; + +private: +// QString getString(const QString& text); + + QStringList path; + Rules* rules; + const bool fromExtras; +}; + +static QString translate_xml_item(const QString& itemText) +{ + if (itemText.isEmpty()) { // i18n warns on empty input strings + return itemText; + } + //messages are already extracted from the source XML files by xkb + //the characters '<' and '>' (but not '"') are HTML-escaped in the xkeyboard-config translation files, so we need to convert them before/after looking up the translation + //note that we cannot use QString::toHtmlEscaped() here because that would convert '"' as well + QString msgid(itemText); + return i18nd("xkeyboard-config", msgid.replace(QLatin1Literal("<"), QLatin1Literal("<")).replace(QLatin1Literal(">"), QLatin1Literal(">")).toUtf8()).replace(QLatin1Literal("<"), QLatin1Literal("<")).replace(QLatin1Literal(">"), QLatin1Literal(">")); +} + +static QString translate_description(ConfigItem* item) +{ + return item->description.isEmpty() + ? item->name : translate_xml_item(item->description); +} + +static bool notEmpty(const ConfigItem* item) +{ + return ! item->name.isEmpty(); +} + +template +void removeEmptyItems(QList& list) +{ +#ifdef __GNUC__ +#if __GNUC__ == 4 && (__GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ < 3) || (__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ < 4) +#warning Compiling with a workaround for GCC < 4.8.3 || GCC < 4.7.4 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58800 + Q_FOREACH(T* x, list) { + ConfigItem *y = static_cast(x); + if (y->name.isEmpty()) { + list.removeAll(x); + } + } +#else + QtConcurrent::blockingFilter(list, notEmpty); +#endif +#endif +} + +static +void postProcess(Rules* rules) +{ + //TODO remove elements with empty names to safeguard us + removeEmptyItems(rules->layoutInfos); + removeEmptyItems(rules->modelInfos); + removeEmptyItems(rules->optionGroupInfos); + +// setlocale(LC_ALL, ""); +// bindtextdomain("xkeyboard-config", LOCALE_DIR); + foreach(ModelInfo* modelInfo, rules->modelInfos) { + modelInfo->vendor = translate_xml_item(modelInfo->vendor); + modelInfo->description = translate_description(modelInfo); + } + + foreach(LayoutInfo* layoutInfo, rules->layoutInfos) { + layoutInfo->description = translate_description(layoutInfo); + + removeEmptyItems(layoutInfo->variantInfos); + foreach(VariantInfo* variantInfo, layoutInfo->variantInfos) { + variantInfo->description = translate_description(variantInfo); + } + } + foreach(OptionGroupInfo* optionGroupInfo, rules->optionGroupInfos) { + optionGroupInfo->description = translate_description(optionGroupInfo); + + removeEmptyItems(optionGroupInfo->optionInfos); + foreach(OptionInfo* optionInfo, optionGroupInfo->optionInfos) { + optionInfo->description = translate_description(optionInfo); + } + } +} + + +Rules::Rules(): + version(QStringLiteral("1.0")) +{ +} + +QString Rules::getRulesName() +{ + if (!QX11Info::isPlatformX11()) { + return QString(); + } + XkbRF_VarDefsRec vd; + char *tmp = nullptr; + + if (XkbRF_GetNamesProp(QX11Info::display(), &tmp, &vd) && tmp != nullptr ) { + // qCDebug(KCM_KEYBOARD) << "namesprop" << tmp ; + const QString name(tmp); + XFree(tmp); + return name; + } + + return {}; +} + +QString Rules::findXkbDir() +{ + return QStringLiteral(XKBDIR); +} + +static QString findXkbRulesFile() +{ + QString rulesFile; + QString rulesName = Rules::getRulesName(); + + const QString xkbDir = Rules::findXkbDir(); + if ( ! rulesName.isNull() ) { + rulesFile = QStringLiteral("%1/rules/%2.xml").arg(xkbDir, rulesName); + } else { + // default to evdev + rulesFile = QStringLiteral("%1/rules/evdev.xml").arg(xkbDir); + } + + return rulesFile; +} + +static +void mergeRules(Rules* rules, Rules* extraRules) +{ + rules->modelInfos.append( extraRules->modelInfos ); + rules->optionGroupInfos.append( extraRules->optionGroupInfos ); // need to iterate and merge? + + QList layoutsToAdd; + foreach(LayoutInfo* extraLayoutInfo, extraRules->layoutInfos) { + LayoutInfo* layoutInfo = findByName(rules->layoutInfos, extraLayoutInfo->name); + if( layoutInfo != nullptr ) { + layoutInfo->variantInfos.append( extraLayoutInfo->variantInfos ); + layoutInfo->languages.append( extraLayoutInfo->languages ); + } + else { + layoutsToAdd.append(extraLayoutInfo); + } + } + rules->layoutInfos.append(layoutsToAdd); + qCDebug(KCM_KEYBOARD) << "Merged from extra rules:" << extraRules->layoutInfos.size() << "layouts," << extraRules->modelInfos.size() << "models," << extraRules->optionGroupInfos.size() << "option groups"; + + // base rules now own the objects - remove them from extra rules so that it does not try to delete them + extraRules->layoutInfos.clear(); + extraRules->modelInfos.clear(); + extraRules->optionGroupInfos.clear(); +} + + +const char Rules::XKB_OPTION_GROUP_SEPARATOR = ':'; + +Rules* Rules::readRules(ExtrasFlag extrasFlag) +{ + Rules* rules = new Rules(); + QString rulesFile = findXkbRulesFile(); + if( ! readRules(rules, rulesFile, false) ) { + delete rules; + rules = nullptr; + return nullptr; + } + if( extrasFlag == Rules::READ_EXTRAS ) { + QRegExp regex(QStringLiteral("\\.xml$")); + Rules* rulesExtra = new Rules(); + QString extraRulesFile = rulesFile.replace(regex, QStringLiteral(".extras.xml")); + if( readRules(rulesExtra, extraRulesFile, true) ) { // not fatal if it fails + mergeRules(rules, rulesExtra); + } + delete rulesExtra; + rulesExtra = nullptr; + } + return rules; +} + + +Rules* Rules::readRules(Rules* rules, const QString& filename, bool fromExtras) +{ + QFile file(filename); + if( !file.open(QFile::ReadOnly | QFile::Text) ) { + qCCritical(KCM_KEYBOARD) << "Cannot open the rules file" << file.fileName(); + return nullptr; + } + + RulesHandler rulesHandler(rules, fromExtras); + + QXmlSimpleReader reader; + reader.setContentHandler(&rulesHandler); + reader.setErrorHandler(&rulesHandler); + + QXmlInputSource xmlInputSource(&file); + + qCDebug(KCM_KEYBOARD) << "Parsing xkb rules from" << file.fileName(); + + if( ! reader.parse(xmlInputSource) ) { + qCCritical(KCM_KEYBOARD) << "Failed to parse the rules file" << file.fileName(); + return nullptr; + } + + postProcess(rules); + + return rules; +} + +bool RulesHandler::startElement(const QString &/*namespaceURI*/, const QString &/*localName*/, + const QString &qName, const QXmlAttributes &attributes) +{ + path << QString(qName); + + QString strPath = path.join(QStringLiteral("/")); + if( strPath.endsWith(QLatin1String("layoutList/layout/configItem")) ) { + rules->layoutInfos << new LayoutInfo(fromExtras); + } + else if( strPath.endsWith(QLatin1String("layoutList/layout/variantList/variant")) ) { + rules->layoutInfos.last()->variantInfos << new VariantInfo(fromExtras); + } + else if( strPath.endsWith(QLatin1String("modelList/model")) ) { + rules->modelInfos << new ModelInfo(); + } + else if( strPath.endsWith(QLatin1String("optionList/group")) ) { + rules->optionGroupInfos << new OptionGroupInfo(); + rules->optionGroupInfos.last()->exclusive = (attributes.value(QStringLiteral("allowMultipleSelection")) != QLatin1String("true")); + } + else if( strPath.endsWith(QLatin1String("optionList/group/option")) ) { + rules->optionGroupInfos.last()->optionInfos << new OptionInfo(); + } + else if( strPath == ("xkbConfigRegistry") && ! attributes.value(QStringLiteral("version")).isEmpty() ) { + rules->version = attributes.value(QStringLiteral("version")); + qCDebug(KCM_KEYBOARD) << "xkbConfigRegistry version" << rules->version; + } + return true; +} + +bool RulesHandler::endElement(const QString &/*namespaceURI*/, const QString &/*localName*/, const QString &/*qName*/) +{ + path.removeLast(); + return true; +} + +bool RulesHandler::characters(const QString &str) +{ + if( !str.trimmed().isEmpty() ) { + QString strPath = path.join(QStringLiteral("/")); + if( strPath.endsWith(QLatin1String("layoutList/layout/configItem/name")) ) { + if( rules->layoutInfos.last() != nullptr ) { + rules->layoutInfos.last()->name = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "name:" << str; + } + // skipping invalid entry + } + else if( strPath.endsWith(QLatin1String("layoutList/layout/configItem/description")) ) { + rules->layoutInfos.last()->description = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "descr:" << str; + } + else if( strPath.endsWith(QLatin1String("layoutList/layout/configItem/languageList/iso639Id")) ) { + rules->layoutInfos.last()->languages << str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "\tlang:" << str; + } + else if( strPath.endsWith(QLatin1String("layoutList/layout/variantList/variant/configItem/name")) ) { + rules->layoutInfos.last()->variantInfos.last()->name = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "\tvariant name:" << str; + } + else if( strPath.endsWith(QLatin1String("layoutList/layout/variantList/variant/configItem/description")) ) { + rules->layoutInfos.last()->variantInfos.last()->description = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "\tvariant descr:" << str; + } + else if( strPath.endsWith(QLatin1String("layoutList/layout/variantList/variant/configItem/languageList/iso639Id")) ) { + rules->layoutInfos.last()->variantInfos.last()->languages << str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "\tvlang:" << str; + } + else if( strPath.endsWith(QLatin1String("modelList/model/configItem/name")) ) { + rules->modelInfos.last()->name = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "name:" << str; + } + else if( strPath.endsWith(QLatin1String("modelList/model/configItem/description")) ) { + rules->modelInfos.last()->description = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "\tdescr:" << str; + } + else if( strPath.endsWith(QLatin1String("modelList/model/configItem/vendor")) ) { + rules->modelInfos.last()->vendor = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "\tvendor:" << str; + } + else if( strPath.endsWith(QLatin1String("optionList/group/configItem/name")) ) { + rules->optionGroupInfos.last()->name = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "name:" << str; + } + else if( strPath.endsWith(QLatin1String("optionList/group/configItem/description")) ) { + rules->optionGroupInfos.last()->description = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "\tdescr:" << str; + } + else if( strPath.endsWith(QLatin1String("optionList/group/option/configItem/name")) ) { + rules->optionGroupInfos.last()->optionInfos.last()->name = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "name:" << str; + } + else if( strPath.endsWith(QLatin1String("optionList/group/option/configItem/description")) ) { + rules->optionGroupInfos.last()->optionInfos.last()->description = str.trimmed(); +// qCDebug(KCM_KEYBOARD) << "\tdescr:" << str; + } + } + return true; +} + +bool LayoutInfo::isLanguageSupportedByLayout(const QString& lang) const +{ + if( languages.contains(lang) || isLanguageSupportedByVariants(lang) ) + return true; + +// // return yes if no languages found in layout or its variants +// if( languages.empty() ) { +// foreach(const VariantInfo* info, variantInfos) { +// if( ! info->languages.empty() ) +// return false; +// } +// return true; +// } + + return false; +} + +bool LayoutInfo::isLanguageSupportedByVariants(const QString& lang) const +{ + foreach(const VariantInfo* info, variantInfos) { + if( info->languages.contains(lang) ) + return true; + } + return false; +} + +bool LayoutInfo::isLanguageSupportedByDefaultVariant(const QString& lang) const +{ + if( languages.contains(lang) ) + return true; + + if( languages.empty() && isLanguageSupportedByVariants(lang) ) + return true; + + return false; +} + +bool LayoutInfo::isLanguageSupportedByVariant(const VariantInfo* variantInfo, const QString& lang) const +{ + if( variantInfo->languages.contains(lang) ) + return true; + + // if variant has no languages try to "inherit" them from layout + if( variantInfo->languages.empty() && languages.contains(lang) ) + return true; + + return false; +} + +#ifdef NEW_GEOMETRY + +Rules::GeometryId Rules::getGeometryId(const QString& model) { + QString xkbDir = Rules::findXkbDir(); + QString rulesName = Rules::getRulesName(); + QString ruleFileName = QStringLiteral("%1/rules/%2").arg(xkbDir, rulesName); + QFile ruleFile(ruleFileName); + + GeometryId defaultGeoId(QStringLiteral("pc"), QStringLiteral("pc104")); + + if ( ! ruleFile.open(QIODevice::ReadOnly | QIODevice::Text) ){ + qCCritical(KCM_KEYBOARD) << "Unable to open file" << ruleFileName; + return defaultGeoId; + } + + QString modelGeoId = model; + bool inTable = false; + QTextStream in(&ruleFile); + + while (!in.atEnd()) { + QString line = in.readLine().trimmed(); + + if( line.isEmpty() || QRegExp(QStringLiteral("^\\s*//")).indexIn(line) != -1 ) + continue; + + QRegExp modelGroupRegex(QStringLiteral("!\\s*(\\$[a-zA-Z0-9_]+)\\s*=(.*)")); + + if( modelGroupRegex.indexIn(line) != -1 ) { + QStringList parts = modelGroupRegex.capturedTexts(); + QString groupName = parts[1]; + QStringList models = parts[2].split(QRegExp(QStringLiteral("\\s+")), QString::SkipEmptyParts); + +// qCDebug(KCM_KEYBOARD) << "modelGroup definition" << groupName << ":" << models; + if( models.contains(model) ) { + modelGeoId = groupName; + } + continue; + } + + + if( inTable ) { + QRegExp modelTableEntry (QStringLiteral("\\s*(\\$?[a-zA-Z0-9_]+|\\*)\\s*=\\s*([a-zA-Z0-9_]+)\\(([a-zA-Z0-9_%]+)\\)")); + if( modelTableEntry.indexIn(line) == -1 ) { + if( QRegExp(QStringLiteral("^!\\s*")).indexIn(line) != -1 ) + break; + + qCWarning(KCM_KEYBOARD) << "could not parse geometry line" << line; + continue; + } + + QStringList parts = modelTableEntry.capturedTexts(); + QString modelName = parts[1]; + QString fileName = parts[2]; + QString geoName = parts[3]; + if( geoName == QLatin1String("%m") ) { + geoName = model; + } + if( modelName == QLatin1String("*") ) { + defaultGeoId = GeometryId(fileName, geoName); + } + +// qCDebug(KCM_KEYBOARD) << "geo entry" << modelName << fileName << geoName; + + if( modelName == model ) { + return GeometryId(fileName, geoName); + } + + continue; + } + + QRegExp modelTableHeader (QStringLiteral("!\\s+model\\s*=\\s*geometry")); + if( modelTableHeader.indexIn(line) != -1 ) { + inTable = true; + continue; + } + + } + + return defaultGeoId; +} + +#endif diff -Nru ukui-control-center-2.0.3/plugins/devices/keyboard/preview/xkb_rules.h ukui-control-center-3.0.3/plugins/devices/keyboard/preview/xkb_rules.h --- ukui-control-center-2.0.3/plugins/devices/keyboard/preview/xkb_rules.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/keyboard/preview/xkb_rules.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2010 Andriy Rysin (rysin@kde.org) + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +#ifndef XKB_RULES_H_ +#define XKB_RULES_H_ + +#include +#include +#include + +#include "config-keyboard.h" + +struct ConfigItem { + QString name; + QString description; +}; + +template +inline T* findByName(QList list, QString name) { + foreach(T* info, list) { + if( info->name == name ) + return info; + } + return nullptr; +} + +struct VariantInfo: public ConfigItem { + QList languages; + const bool fromExtras; + + VariantInfo(bool fromExtras_): + fromExtras(fromExtras_) {} +}; + +struct LayoutInfo: public ConfigItem { + QList variantInfos; + QList languages; + const bool fromExtras; + +// LayoutInfo() {} + LayoutInfo(bool fromExtras_): + fromExtras(fromExtras_) {} + ~LayoutInfo() { foreach(VariantInfo* variantInfo, variantInfos) delete variantInfo; } + + VariantInfo* getVariantInfo(const QString& variantName) const { + return findByName(variantInfos, variantName); + } + + bool isLanguageSupportedByLayout(const QString& lang) const; + bool isLanguageSupportedByDefaultVariant(const QString& lang) const; + bool isLanguageSupportedByVariants(const QString& lang) const; + bool isLanguageSupportedByVariant(const VariantInfo* variantInfo, const QString& lang) const; +}; + +struct ModelInfo: public ConfigItem { + QString vendor; +}; + +struct OptionInfo: public ConfigItem { +}; + +struct OptionGroupInfo: public ConfigItem { + QList optionInfos; + bool exclusive; + + ~OptionGroupInfo() { foreach(OptionInfo* opt, optionInfos) delete opt; } + + const OptionInfo* getOptionInfo(const QString& optionName) const { + return findByName(optionInfos, optionName); + } +}; + +struct Rules { + enum ExtrasFlag { NO_EXTRAS, READ_EXTRAS }; + + static const char XKB_OPTION_GROUP_SEPARATOR; + + QList layoutInfos; + QList modelInfos; + QList optionGroupInfos; + QString version; + + Rules(); + + ~Rules() { + foreach(LayoutInfo* layoutInfo, layoutInfos) delete layoutInfo; + foreach(ModelInfo* modelInfo, modelInfos) delete modelInfo; + foreach(OptionGroupInfo* optionGroupInfo, optionGroupInfos) delete optionGroupInfo; + } + + const LayoutInfo* getLayoutInfo(const QString& layoutName) const { + return findByName(layoutInfos, layoutName); + } + + const OptionGroupInfo* getOptionGroupInfo(const QString& optionGroupName) const { + return findByName(optionGroupInfos, optionGroupName); + } + + static Rules* readRules(ExtrasFlag extrasFlag); + static Rules* readRules(Rules* rules, const QString& filename, bool fromExtras); + static QString getRulesName(); + static QString findXkbDir(); + +#ifdef NEW_GEOMETRY + class GeometryId { + public: + QString fileName; + QString geoName; + + GeometryId(const QString& fileName_, const QString& geoName_): + fileName(fileName_), + geoName(geoName_) {} + + GeometryId& operator=(const GeometryId& geoId) { + fileName = geoId.fileName; + geoName = geoId.geoName; + return *this; + } + }; + + static GeometryId getGeometryId(const QString& model); +#endif + +}; + +#endif /* XKB_RULES_H_ */ diff -Nru ukui-control-center-2.0.3/plugins/devices/mouse/mousecontrol.cpp ukui-control-center-3.0.3/plugins/devices/mouse/mousecontrol.cpp --- ukui-control-center-2.0.3/plugins/devices/mouse/mousecontrol.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/mouse/mousecontrol.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -20,11 +20,16 @@ #include "mousecontrol.h" #include "ui_mousecontrol.h" -#include -#include - +#include #include +#include #include +#include +#include +#include +#include +#include +#include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 @@ -39,25 +44,26 @@ #include } -#define MOUSE_SCHEMA "org.ukui.peripherals-mouse" -#define HAND_KEY "left-handed" -#define DOUBLE_CLICK_KEY "double-click" -#define LOCATE_KEY "locate-pointer" -#define CURSOR_SIZE_KEY "cursor-size" -#define ACCELERATION_KEY "motion-acceleration" -#define THRESHOLD_KEY "motion-threshold" +#define MOUSE_SCHEMA "org.ukui.peripherals-mouse" +#define HAND_KEY "left-handed" +#define DOUBLE_CLICK_KEY "double-click" +#define LOCATE_KEY "locate-pointer" +#define CURSOR_SIZE_KEY "cursor-size" +#define ACCELERATION_KEY "motion-acceleration" +#define THRESHOLD_KEY "motion-threshold" +#define WHEEL_KEY "wheel-speed" +#define ACCEL_KEY "mouse-accel" -#define SESSION_SCHEMA "org.ukui.session" -#define SESSION_MOUSE_KEY "mouse-size-changed" +#define SESSION_SCHEMA "org.ukui.session" +#define SESSION_MOUSE_KEY "mouse-size-changed" -#define DESKTOP_SCHEMA "org.mate.interface" -#define CURSOR_BLINK_KEY "cursor-blink" +#define DESKTOP_SCHEMA "org.mate.interface" +#define CURSOR_BLINK_KEY "cursor-blink" #define CURSOR_BLINK_TIME_KEY "cursor-blink-time" -#define MOUSE_MID_GET_CMD "/usr/bin/mouse-midbtn-speed-get" -#define MOUSE_MID_SET_CMD "/usr/bin/mouse-midbtn-speed-set" +#define THEME_SCHEMA "org.ukui.style" -MyLabel::MyLabel(){ +MyLabel::MyLabel() { setAttribute(Qt::WA_DeleteOnClose); @@ -73,17 +79,17 @@ const QByteArray id(MOUSE_SCHEMA); if (QGSettings::isSchemaInstalled(id)){ - mSettings = new QGSettings(id); + mSettings = new QGSettings(id, QByteArray(), this); } - + this->setToolTip(tr("double-click to test")); } -MyLabel::~MyLabel(){ - if (QGSettings::isSchemaInstalled(MOUSE_SCHEMA)) - delete mSettings; +MyLabel::~MyLabel() { + } -void MyLabel::mouseDoubleClickEvent(QMouseEvent *event){ +void MyLabel::mouseDoubleClickEvent(QMouseEvent *event) { + Q_UNUSED(event); int delay = mSettings->get(DOUBLE_CLICK_KEY).toInt(); setPixmap(QPixmap(":/img/plugins/mouse/double-click-on.png")); QTimer::singleShot(delay, this, [=]{ @@ -92,111 +98,128 @@ } -MouseControl::MouseControl() +MouseControl::MouseControl() : mFirstLoad(true) { - ui = new Ui::MouseControl; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Mouse"); pluginType = DEVICES; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - -// QString qss; -// QFile QssFile("://combox.qss"); -// QssFile.open(QFile::ReadOnly); - -// if (QssFile.isOpen()){ -// qss = QLatin1String(QssFile.readAll()); -// QssFile.close(); -// } - -// pluginWidget->setStyleSheet("background: #ffffff;"); - -// ui->handWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); -// ui->pointerSpeedWidget->setStyleSheet("QWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); -// ui->sensitivityWidget->setStyleSheet("QWidget{background: #F4F4F4;}"); -// ui->visibilityWidget->setStyleSheet("QWidget{background: #F4F4F4;}"); -// ui->pointerSizeWidget->setStyleSheet("QWidget{background: #F4F4F4; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); - - //全局未生效,再次设置 -// ui->pointerSizeComBox->setView(new QListView()); -// ui->pointerSizeComBox->setStyleSheet(qss); -// ui->handHabitComBox->setView(new QListView()); -// ui->handHabitComBox->setStyleSheet(qss); - - -// ui->cursorWeightWidget->setStyleSheet("QWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); -// ui->cursorSpeedWidget->setStyleSheet("QWidget{background: #F4F4F4;}"); -// ui->flashingWidget->setStyleSheet("QWidget{background: #F4F4F4; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); - - //初始化鼠标设置GSettings - const QByteArray id(MOUSE_SCHEMA); - const QByteArray sessionId(SESSION_SCHEMA); - const QByteArray idd(DESKTOP_SCHEMA); - if (QGSettings::isSchemaInstalled(sessionId) && QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(DESKTOP_SCHEMA)) { - sesstionSetttings = new QGSettings(sessionId); - settings = new QGSettings(id); - desktopSettings = new QGSettings(idd); - - setupComponent(); - - initHandHabitStatus(); - initPointerStatus(); - initCursorStatus(); - initWheelStatus(); - } - - - } -MouseControl::~MouseControl() -{ - delete ui; - if (QGSettings::isSchemaInstalled(MOUSE_SCHEMA) && QGSettings::isSchemaInstalled(SESSION_SCHEMA)) { - delete settings; - delete sesstionSetttings; - delete desktopSettings; +MouseControl::~MouseControl() { + if (!mFirstLoad) { + delete ui; + ui = nullptr; } } -QString MouseControl::get_plugin_name(){ +QString MouseControl::get_plugin_name() { return pluginName; } -int MouseControl::get_plugin_type(){ +int MouseControl::get_plugin_type() { return pluginType; } -QWidget *MouseControl::get_plugin_ui(){ +QWidget *MouseControl::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + ui = new Ui::MouseControl; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + initSearchText(); + initTitleLabel(); + + //初始化鼠标设置GSettings + const QByteArray id(MOUSE_SCHEMA); + const QByteArray sessionId(SESSION_SCHEMA); + const QByteArray idd(DESKTOP_SCHEMA); + const QByteArray themeId(THEME_SCHEMA); + if (QGSettings::isSchemaInstalled(sessionId) && + QGSettings::isSchemaInstalled(id) && + QGSettings::isSchemaInstalled(idd)) { + sesstionSetttings = new QGSettings(sessionId, QByteArray(), this); + settings = new QGSettings(id, QByteArray(), this); + desktopSettings = new QGSettings(idd, QByteArray(), this); + mThemeSettings = new QGSettings(themeId, QByteArray(), this); + + mouseKeys = settings->keys(); + + setupComponent(); + + initHandHabitStatus(); + initPointerStatus(); + initCursorStatus(); + initWheelStatus(); + } + } return pluginWidget; } -void MouseControl::plugin_delay_control(){ +void MouseControl::plugin_delay_control() { + +} + +const QString MouseControl::name() const { + return QStringLiteral("mouse"); } -void MouseControl::setupComponent(){ +void MouseControl::initSearchText() { + //~ contents_path /mouse/Hand habit + ui->handLabel->setText(tr("Hand habit")); + //~ contents_path /mouse/Doubleclick delay + ui->delayLabel->setText(tr("Doubleclick delay")); + //~ contents_path /mouse/Speed + ui->speedLabel->setText(tr("Speed")); + ui->label_2->setMinimumWidth(50); + ui->label_3->setMinimumWidth(50); + //~ contents_path /mouse/Acceleration + ui->accelLabel->setText(tr("Acceleration")); + //~ contents_path /mouse/Visibility + ui->visLabel->setText(tr("Visibility")); + //~ contents_path /mouse/Pointer size + ui->sizeLabel->setText(tr("Pointer size")); + //~ contents_path /mouse/Enable flashing on text area + ui->flashLabel->setText(tr("Enable flashing on text area")); + //~ contents_path /mouse/Cursor speed + ui->cursorspdLabel->setText(tr("Cursor speed")); + ui->label_17->setMinimumWidth(50); + ui->label_18->setMinimumWidth(50); + ui->label_6->setMinimumWidth(50); + ui->label_7->setMinimumWidth(50); + ui->label_21->setMinimumWidth(50); + ui->label_22->setMinimumWidth(50); +} + +void MouseControl::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); + ui->title3Label->setFont(font); +} + +void MouseControl::setupComponent() { -// ui->title3Label->hide(); -// ui->cursorSpeedFrame->hide(); ui->cursorWeightFrame->hide(); //设置左手右手鼠标控件 ui->handHabitComBox->addItem(tr("Lefthand"), true); ui->handHabitComBox->addItem(tr("Righthand"), false); - MyLabel * testLabel = new MyLabel(); - ui->doubleClickHorLayout->addWidget(testLabel); + ui->doubleClickHorLayout->addWidget(new MyLabel()); //设置指针可见性控件 visiblityBtn = new SwitchButton(pluginWidget); ui->visibilityHorLayout->addWidget(visiblityBtn); + // 鼠标加速度控件 + mAccelBtn = new SwitchButton(pluginWidget); + mAccelBtn->setChecked(settings->get(ACCEL_KEY).toBool()); + ui->accelLayout->addStretch(); + ui->accelLayout->addWidget(mAccelBtn); + //设置指针大小 ui->pointerSizeComBox->setMaxVisibleItems(5); ui->pointerSizeComBox->addItem(tr("Default(Recommended)"), 24); //100% @@ -204,8 +227,8 @@ ui->pointerSizeComBox->addItem(tr("Large"), 48); //150% //设置鼠标滚轮是否显示 - if (!g_file_test(MOUSE_MID_GET_CMD, G_FILE_TEST_EXISTS) || !g_file_test(MOUSE_MID_SET_CMD, G_FILE_TEST_EXISTS)){ - ui->midSpeedFrame->hide(); + if (!mouseKeys.contains("wheelSpeed")) { + ui->midSpeedFrame->setVisible(false); } //设置启用光标闪烁 @@ -215,54 +238,104 @@ #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) connect(ui->handHabitComBox, static_cast(&QComboBox::currentIndexChanged), this, [=](int index){ #else - connect(ui->handHabitComBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->handHabitComBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { #endif Q_UNUSED(index) settings->set(HAND_KEY, ui->handHabitComBox->currentData().toBool()); }); - connect(ui->doubleclickHorSlider, &QSlider::sliderReleased, [=]{ + connect(ui->doubleclickHorSlider, &QSlider::sliderReleased, [=] { settings->set(DOUBLE_CLICK_KEY, ui->doubleclickHorSlider->value()); qApp->setDoubleClickInterval(ui->doubleclickHorSlider->value()); }); - connect(ui->pointerSpeedSlider, &QSlider::valueChanged, [=](int value){ + connect(ui->pointerSpeedSlider, &QSlider::valueChanged, [=](int value) { settings->set(ACCELERATION_KEY, static_cast(value)/ui->pointerSpeedSlider->maximum()*10); }); - connect(ui->pointerSensitivitySlider, &QSlider::valueChanged, [=](int value){ - settings->set(THRESHOLD_KEY, 10*value/ui->pointerSensitivitySlider->maximum()); + connect(visiblityBtn, &SwitchButton::checkedChanged, [=](bool checked) { + settings->set(LOCATE_KEY, checked); }); - connect(visiblityBtn, &SwitchButton::checkedChanged, [=](bool checked){ - settings->set(LOCATE_KEY, checked); + connect(ui->pointerSizeComBox, static_cast(&QComboBox::currentIndexChanged), this, &MouseControl::mouseSizeChange); + + connect(flashingBtn, &SwitchButton::checkedChanged, [=](bool checked) { + ui->cursorSpeedFrame->setVisible(checked); + desktopSettings->set(CURSOR_BLINK_KEY, checked); + mThemeSettings->set(CURSOR_BLINK_KEY, checked); + if (!checked) { + mThemeSettings->set(CURSOR_BLINK_TIME_KEY, 0); + } else { + int mValue = ui->cursorSpeedSlider->maximum() - ui->cursorSpeedSlider->value() + ui->cursorSpeedSlider->minimum(); + mThemeSettings->set(CURSOR_BLINK_TIME_KEY, mValue); + } }); - connect(ui->pointerSizeComBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ - Q_UNUSED(index) - settings->set(CURSOR_SIZE_KEY, ui->pointerSizeComBox->currentData().toInt()); + connect(ui->midHorSlider, &QSlider::sliderReleased, [=] { + settings->set(WHEEL_KEY, ui->midHorSlider->value()); + }); - QStringList keys = sesstionSetttings->keys(); - if (keys.contains("mouseSizeChanged")) { - sesstionSetttings->set(SESSION_MOUSE_KEY, true); + connect(settings,&QGSettings::changed,[=] (const QString &key){ + if(key == "locatePointer") { + visiblityBtn->blockSignals(true); + visiblityBtn->setChecked(settings->get(LOCATE_KEY).toBool()); + visiblityBtn->blockSignals(false); + } else if(key == "mouseAccel") { + ui->doubleclickHorSlider->blockSignals(true); + mAccelBtn->setChecked(settings->get(ACCEL_KEY).toBool()); + ui->doubleclickHorSlider->blockSignals(false); + } else if(key == "doubleClick") { + int dc = settings->get(DOUBLE_CLICK_KEY).toInt(); + ui->doubleclickHorSlider->blockSignals(true); + ui->doubleclickHorSlider->setValue(dc); + ui->doubleclickHorSlider->blockSignals(false); + } else if(key == "wheelSpeed") { + ui->midHorSlider->setValue(settings->get(WHEEL_KEY).toInt()); + } else if(key == "motionAcceleration") { + ui->pointerSpeedSlider->blockSignals(true); + ui->pointerSpeedSlider->setValue(static_cast(settings->get(ACCELERATION_KEY).toDouble()*100)); + ui->pointerSpeedSlider->blockSignals(false); + } else if(key == "leftHanded") { + int handHabitIndex = ui->handHabitComBox->findData(settings->get(HAND_KEY).toBool()); + ui->handHabitComBox->blockSignals(true); + ui->handHabitComBox->setCurrentIndex(handHabitIndex); + ui->handHabitComBox->blockSignals(false); + } else if(key == "cursorSize") { + int pointerSizeIndex = ui->pointerSizeComBox->findData(settings->get(CURSOR_SIZE_KEY).toInt()); + ui->pointerSizeComBox->blockSignals(true); + ui->pointerSizeComBox->setCurrentIndex(pointerSizeIndex); + ui->pointerSizeComBox->blockSignals(false); } }); - connect(flashingBtn, &SwitchButton::checkedChanged, [=](bool checked){ - desktopSettings->set(CURSOR_BLINK_KEY, checked); + connect(desktopSettings,&QGSettings::changed,[=](const QString &key) { + if(key == "cursorBlinkTime") { + ui->cursorSpeedSlider->blockSignals(true); + int mValue = ui->cursorSpeedSlider->maximum() - desktopSettings->get(CURSOR_BLINK_TIME_KEY).toInt() + ui->cursorSpeedSlider->minimum(); + ui->cursorSpeedSlider->setValue(mValue); + ui->cursorSpeedSlider->blockSignals(false); + } else if(key == "cursorBlink") { + flashingBtn->blockSignals(true); + flashingBtn->setChecked(desktopSettings->get(CURSOR_BLINK_KEY).toBool()); + ui->cursorSpeedFrame->setVisible(desktopSettings->get(CURSOR_BLINK_KEY).toBool()); + flashingBtn->blockSignals(false); + } }); - connect(ui->midHorSlider, &QSlider::sliderReleased, [=]{ - _set_mouse_mid_speed(ui->midHorSlider->value()); + connect(ui->cursorSpeedSlider, &QSlider::sliderReleased, [=] { + + int mValue = ui->cursorSpeedSlider->maximum() - ui->cursorSpeedSlider->value() + ui->cursorSpeedSlider->minimum(); + desktopSettings->set(CURSOR_BLINK_TIME_KEY, mValue); + mThemeSettings->set(CURSOR_BLINK_TIME_KEY, mValue); }); - connect(ui->cursorSpeedSlider, &QSlider::sliderReleased, [=]{ - desktopSettings->set(CURSOR_BLINK_TIME_KEY, ui->cursorSpeedSlider->value()); + connect(mAccelBtn, &SwitchButton::checkedChanged, this, [=] (bool checked) { + settings->set(ACCEL_KEY, checked); }); } -void MouseControl::initHandHabitStatus(){ +void MouseControl::initHandHabitStatus() { int handHabitIndex = ui->handHabitComBox->findData(settings->get(HAND_KEY).toBool()); ui->handHabitComBox->blockSignals(true); @@ -275,7 +348,7 @@ ui->doubleclickHorSlider->blockSignals(false); } -void MouseControl::initPointerStatus(){ +void MouseControl::initPointerStatus() { //当前系统指针加速值,-1为系统默认 double mouse_acceleration = settings->get(ACCELERATION_KEY).toDouble(); @@ -284,7 +357,7 @@ int mouse_threshold = settings->get(THRESHOLD_KEY).toInt(); //当从接口获取的是-1,则代表系统默认值,真实值需要从底层获取 - if (mouse_threshold == -1 || static_cast(mouse_acceleration) == -1){ + if (mouse_threshold == -1 || static_cast(mouse_acceleration) == -1) { // speed sensitivity int accel_numerator, accel_denominator, threshold; //当加速值和灵敏度为系统默认的-1时,从底层获取到默认的具体值 @@ -300,11 +373,6 @@ ui->pointerSpeedSlider->setValue(static_cast(settings->get(ACCELERATION_KEY).toDouble()*100)); ui->pointerSpeedSlider->blockSignals(false); - //初始化指针敏感度控件 - ui->pointerSensitivitySlider->blockSignals(true); - ui->pointerSensitivitySlider->setValue(settings->get(THRESHOLD_KEY).toInt()*100); - ui->pointerSensitivitySlider->blockSignals(false); - //初始化可见性控件 visiblityBtn->blockSignals(true); visiblityBtn->setChecked(settings->get(LOCATE_KEY).toBool()); @@ -317,46 +385,50 @@ ui->pointerSizeComBox->blockSignals(false); } -void MouseControl::initCursorStatus(){ +void MouseControl::initCursorStatus() { flashingBtn->blockSignals(true); flashingBtn->setChecked(desktopSettings->get(CURSOR_BLINK_KEY).toBool()); + ui->cursorSpeedFrame->setVisible(desktopSettings->get(CURSOR_BLINK_KEY).toBool()); flashingBtn->blockSignals(false); ui->cursorSpeedSlider->blockSignals(true); - ui->cursorSpeedSlider->setValue(desktopSettings->get(CURSOR_BLINK_TIME_KEY).toInt()); + int mValue = ui->cursorSpeedSlider->maximum() - desktopSettings->get(CURSOR_BLINK_TIME_KEY).toInt() + ui->cursorSpeedSlider->minimum(); + ui->cursorSpeedSlider->setValue(mValue); ui->cursorSpeedSlider->blockSignals(false); } -void MouseControl::initWheelStatus(){ - int value = _get_mouse_mid_speed(); +void MouseControl::initWheelStatus() { + ui->midHorSlider->blockSignals(true); - ui->midHorSlider->setValue(value); + if (mouseKeys.contains("wheelSpeed")) { + ui->midHorSlider->setValue(settings->get(WHEEL_KEY).toInt()); + } ui->midHorSlider->blockSignals(false); } -int MouseControl::_get_mouse_mid_speed(){ +void MouseControl::mouseSizeChange() { - int value = 0; + settings->set(CURSOR_SIZE_KEY, ui->pointerSizeComBox->currentData().toInt()); - if (g_file_test(MOUSE_MID_GET_CMD, G_FILE_TEST_EXISTS)){ - QProcess * getProcess = new QProcess(); - getProcess->start(MOUSE_MID_GET_CMD); - getProcess->waitForFinished(); - - QByteArray ba = getProcess->readAllStandardOutput(); - QString speedStr = QString(ba.data()).simplified(); - value = speedStr.toInt(); + QStringList keys = sesstionSetttings->keys(); + if (keys.contains("mouseSizeChanged")) { + sesstionSetttings->set(SESSION_MOUSE_KEY, true); } - return value; -} - -void MouseControl::_set_mouse_mid_speed(int value){ - QString cmd; - - cmd = MOUSE_MID_SET_CMD + QString(" ") + QString::number(value); + QString filename = QDir::homePath() + "/.config/kcminputrc"; + QSettings *mouseSettings = new QSettings(filename, QSettings::IniFormat); - QProcess * setProcess = new QProcess(); - setProcess->start(cmd); - setProcess->waitForFinished(); + mouseSettings->beginGroup("Mouse"); + mouseSettings->setValue("cursorSize", ui->pointerSizeComBox->currentData().toInt()); + mouseSettings->endGroup(); + + delete mouseSettings; + mouseSettings = nullptr; + + QDBusMessage message = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange"); + QList args; + args.append(5); + args.append(0); + message.setArguments(args); + QDBusConnection::sessionBus().send(message); } diff -Nru ukui-control-center-2.0.3/plugins/devices/mouse/mousecontrol.h ukui-control-center-3.0.3/plugins/devices/mouse/mousecontrol.h --- ukui-control-center-2.0.3/plugins/devices/mouse/mousecontrol.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/mouse/mousecontrol.h 2021-04-14 01:27:20.000000000 +0000 @@ -23,15 +23,12 @@ #include #include #include - #include #include #include - #include - - #include +#include #include "shell/interface.h" #include "SwitchButton/switchbutton.h" @@ -40,7 +37,7 @@ class MouseControl; } -class MyLabel : public QLabel{ +class MyLabel : public QLabel { Q_OBJECT public: MyLabel(); @@ -67,15 +64,18 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + void initSearchText(); + void initTitleLabel(); void setupComponent(); void initHandHabitStatus(); void initPointerStatus(); void initCursorStatus(); void initWheelStatus(); - int _get_mouse_mid_speed(); - void _set_mouse_mid_speed(int value); +private slots: + void mouseSizeChange(); private: Ui::MouseControl *ui; @@ -83,16 +83,23 @@ SwitchButton * visiblityBtn; SwitchButton * flashingBtn; + SwitchButton * mAccelBtn; - QGSettings * settings; - QGSettings * sesstionSetttings; - QGSettings * desktopSettings; + + QGSettings *settings; + QGSettings *sesstionSetttings; + QGSettings *desktopSettings; + QGSettings *mThemeSettings; int pluginType; QString leftStr; QString rightStr; QString pluginName; + + QStringList mouseKeys; + + bool mFirstLoad; }; #endif // MOUSECONTROL_H diff -Nru ukui-control-center-2.0.3/plugins/devices/mouse/mousecontrol.ui ukui-control-center-3.0.3/plugins/devices/mouse/mousecontrol.ui --- ukui-control-center-2.0.3/plugins/devices/mouse/mousecontrol.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/mouse/mousecontrol.ui 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 800 - 781 + 817 @@ -109,7 +109,7 @@ 0 - + 0 @@ -196,9 +196,9 @@ 0 - + - + 0 0 @@ -211,7 +211,7 @@ - 136 + 16777215 16777215 @@ -221,9 +221,22 @@ + + + Qt::Vertical + + + + 10 + 40 + + + + + - + 0 0 @@ -236,7 +249,7 @@ - 40 + 16777215 16777215 @@ -250,8 +263,11 @@ + + 1 + - 9 + 10 1 @@ -264,7 +280,7 @@ - + 0 0 @@ -277,7 +293,7 @@ - 40 + 16777215 16777215 @@ -339,9 +355,9 @@ 0 - + - + 0 0 @@ -354,7 +370,7 @@ - 136 + 16777215 16777215 @@ -364,9 +380,22 @@ + + + Qt::Vertical + + + + 10 + 40 + + + + + - + 0 0 @@ -379,7 +408,7 @@ - 40 + 16777215 16777215 @@ -394,7 +423,7 @@ - 100 + 170 1000 @@ -413,7 +442,7 @@ - + 0 0 @@ -426,7 +455,7 @@ - 40 + 16777215 16777215 @@ -489,6 +518,22 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 12 + + + + + @@ -530,7 +575,7 @@ 0 - + 0 @@ -555,6 +600,19 @@ + + + Qt::Vertical + + + + 10 + 40 + + + + + @@ -570,7 +628,7 @@ - 40 + 16777215 16777215 @@ -617,7 +675,7 @@ - 40 + 16777215 16777215 @@ -638,7 +696,7 @@ - + 550 @@ -671,12 +729,12 @@ 0 - + 0 - + 0 @@ -696,85 +754,7 @@ - Sensitivity - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - - 40 - 16777215 - - - - Low - - - - - - - - - - 100 - - - 1000 - - - 50 - - - 50 - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - - 40 - 0 - - - - - 40 - 16777215 - - - - Qt::LeftToRight - - - High - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Acceleration @@ -819,7 +799,7 @@ - + 0 @@ -834,7 +814,7 @@ - 128 + 16777215 16777215 @@ -897,7 +877,7 @@ - + 0 @@ -982,7 +962,7 @@ 20 - 14 + 12 @@ -1026,7 +1006,7 @@ 0 - + 0 @@ -1258,7 +1238,7 @@ 0 - + 0 @@ -1303,7 +1283,7 @@ - Fast + Slow @@ -1327,6 +1307,9 @@ Qt::Horizontal + + false + @@ -1350,7 +1333,7 @@ - Slow + Fast Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff -Nru ukui-control-center-2.0.3/plugins/devices/mouse/mouse.pro ukui-control-center-3.0.3/plugins/devices/mouse/mouse.pro --- ukui-control-center-2.0.3/plugins/devices/mouse/mouse.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/mouse/mouse.pro 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) -QT += widgets x11extras +QT += widgets x11extras dbus #greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = lib @@ -30,6 +30,7 @@ PKGCONFIG += gio-2.0 \ gio-unix-2.0 \ gsettings-qt \ + x11 #DEFINES += QT_DEPRECATED_WARNINGS diff -Nru ukui-control-center-2.0.3/plugins/devices/mousecontrol/mousecontrol.cpp ukui-control-center-3.0.3/plugins/devices/mousecontrol/mousecontrol.cpp --- ukui-control-center-2.0.3/plugins/devices/mousecontrol/mousecontrol.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/mousecontrol/mousecontrol.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -67,6 +67,7 @@ MouseControl::~MouseControl() { delete ui; + ui = nullptr; DeInitDBusMouse(); } diff -Nru ukui-control-center-2.0.3/plugins/devices/printer/printer.cpp ukui-control-center-3.0.3/plugins/devices/printer/printer.cpp --- ukui-control-center-2.0.3/plugins/devices/printer/printer.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/printer/printer.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -28,178 +28,173 @@ #define ITEMFIXEDHEIGH 58 -Printer::Printer(){ - ui = new Ui::Printer; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - +Printer::Printer() : mFirstLoad(true) +{ + //~ contents_path /printer/Printer pluginName = tr("Printer"); pluginType = DEVICES; - -// ui->addFrame->installEventFilter(this); - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - -// pluginWidget->setStyleSheet("background: #ffffff;"); -// ui->addWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - - ui->listWidget->setSpacing(0); -// ui->listWidget->setStyleSheet("QListWidget#listWidget{border: none;}"); - - - pTimer = new QTimer(this); - pTimer->setInterval(1000); - connect(pTimer, SIGNAL(timeout()), this, SLOT(refreshPrinterDev())); - - initComponent(); } Printer::~Printer() { - delete ui; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } } -QString Printer::get_plugin_name(){ +QString Printer::get_plugin_name() +{ return pluginName; } -int Printer::get_plugin_type(){ +int Printer::get_plugin_type() +{ return pluginType; } -QWidget *Printer::get_plugin_ui(){ +QWidget *Printer::get_plugin_ui() +{ + if (mFirstLoad) { + mFirstLoad = false; + ui = new Ui::Printer; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + //~ contents_path /printer/Add Printers And Scanners + ui->titleLabel->setText(tr("Add Printers And Scanners")); + + // 禁用选中效果 + ui->listWidget->setFocusPolicy(Qt::NoFocus); + ui->listWidget->setSelectionMode(QAbstractItemView::NoSelection); + + initTitleLabel(); + initComponent(); + + refreshPrinterDevSlot(); + } return pluginWidget; } -void Printer::plugin_delay_control(){ +void Printer::plugin_delay_control() +{ +} +const QString Printer::name() const +{ + return QStringLiteral("printer"); } -void Printer::initComponent(){ +void Printer::initTitleLabel() +{ + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); + ui->listWidget->setSpacing(1); +} -// ui->addBtn->setIcon(QIcon("://img/plugins/printer/add.png")); -// ui->addBtn->setIconSize(QSize(48, 48)); -// ui->addBtn->setStyleSheet("QPushButton{background-color:transparent;}"); +void Printer::initComponent() +{ + mAddWgt = new HoverWidget("", pluginWidget); + mAddWgt->setObjectName("addwgt"); + mAddWgt->setMinimumSize(QSize(580, 50)); + mAddWgt->setMaximumSize(QSize(960, 50)); + mAddWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button);border-radius: 4px;}" + "HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); - addWgt = new HoverWidget(""); - addWgt->setObjectName("addwgt"); - addWgt->setMinimumSize(QSize(580, 50)); - addWgt->setMaximumSize(QSize(960, 50)); - addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); + ui->listWidget->setStyleSheet("QListWidget::Item:hover{background:palette(base);}"); QHBoxLayout *addLyt = new QHBoxLayout; - QLabel * iconLabel = new QLabel(); - QLabel * textLabel = new QLabel(tr("Add printers and scanners")); + QLabel *iconLabel = new QLabel(); + QLabel *textLabel = new QLabel(tr("Add printers and scanners")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); + iconLabel->setProperty("useIconHighlightEffect", true); + iconLabel->setProperty("iconHighlightEffectMode", 1); + addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); - addWgt->setLayout(addLyt); - - // 悬浮改变Widget状态 - connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(base);"); + mAddWgt->setLayout(addLyt); - }); - // 还原状态 - connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(windowText);"); - }); - - connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname){ + connect(mAddWgt, &HoverWidget::widgetClicked, this, [=](QString mname) { + Q_UNUSED(mname) runExternalApp(); }); - ui->addLyt->addWidget(addWgt); - - pTimer->start(); + ui->addLyt->addWidget(mAddWgt); + mTimer = new QTimer(this); + connect(mTimer, &QTimer::timeout, this, [=] { + refreshPrinterDevSlot(); + }); -// connect(ui->addBtn, &QPushButton::clicked, this, [=]{ -// runExternalApp(); -// }); + mTimer->start(1000); } -void Printer::refreshPrinterDev(){ - - ui->listWidget->clear(); - +void Printer::refreshPrinterDevSlot() +{ QStringList printer = QPrinterInfo::availablePrinterNames(); - for (int num = 0; num < printer.count(); num++){ + for (int num = 0; num < printer.count(); num++) { + QStringList env = QProcess::systemEnvironment(); - QWidget * baseWidget = new QWidget; - baseWidget->setAttribute(Qt::WA_DeleteOnClose); + env << "LANG=en_US.UTF-8"; - QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget); - baseVerLayout->setSpacing(0); - baseVerLayout->setContentsMargins(0, 0, 0, 8); - - QWidget * pdWidget = new QWidget(baseWidget); - - QHBoxLayout * pdHorLayout = new QHBoxLayout(pdWidget); - pdHorLayout->setSpacing(8); - pdHorLayout->setContentsMargins(16, 0, 0, 0); - - QLabel * pdIconLabel = new QLabel(pdWidget); - QSizePolicy iconSizePolicy = pdIconLabel->sizePolicy(); - iconSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); - iconSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); - pdIconLabel->setSizePolicy(iconSizePolicy); - pdIconLabel->setFixedSize(QSize(24, 24)); - pdIconLabel->setScaledContents(true); - pdIconLabel->setPixmap(QPixmap("://img/plugins/printer/printer.png")); - - QLabel * pdLabel = new QLabel(pdWidget); - QSizePolicy txtSizePolicy = pdLabel->sizePolicy(); - txtSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); - txtSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); - pdLabel->setSizePolicy(txtSizePolicy); - pdLabel->setScaledContents(true); - pdLabel->setText(printer.at(num)); - - pdHorLayout->addWidget(pdIconLabel); - pdHorLayout->addWidget(pdLabel); - pdHorLayout->addStretch(); - - pdWidget->setLayout(pdHorLayout); + QProcess *process = new QProcess; + process->setEnvironment(env); + process->start("lpstat -p "+printer.at(num)); + process->waitForFinished(); + + QString ba = process->readAllStandardOutput(); + delete process; + QString printer_stat = QString(ba.data()); + + HoverBtn *printerItem = new HoverBtn(printer.at(num), pluginWidget); + printerItem->mPitLabel->setText(printer.at(num)); + printerItem->mAbtBtn->setText(tr("Attrs")); + QIcon printerIcon = QIcon::fromTheme("printer"); + printerItem->mPitIcon->setPixmap(printerIcon.pixmap(printerIcon.actualSize(QSize(24, 24)))); + connect(printerItem->mAbtBtn, &QPushButton::clicked, this, [=] { + runExternalApp(); + }); + + // 标志位flag用来判断该打印机是否可用,flag1用来决定是否新增窗口(为真则加) + bool flag = printer_stat.contains("disable", Qt::CaseSensitive) + || printer_stat.contains("Unplugged or turned off", Qt::CaseSensitive); + + bool flag1 = true; + + // 遍历窗口列表,判断列表中是否已经存在该打印机,若存在,便判断该打印机是否可用,不可用则从列表中删除该打印机窗口 + for (int j = 0; j < ui->listWidget->count(); j++) { + QString itemData = ui->listWidget->item(j)->data(Qt::UserRole).toString(); + if (!itemData.compare(printer.at(num))) { + if (flag) { + ui->listWidget->takeItem(j); + flag1 = false; + break; + } + flag1 = false; + break; + } + } // - baseVerLayout->addWidget(pdWidget); - baseVerLayout->addStretch(); - - baseWidget->setLayout(baseVerLayout); - - - QListWidgetItem * item = new QListWidgetItem(ui->listWidget); - item->setSizeHint(QSize(ui->listWidget->width(), ITEMFIXEDHEIGH)); - ui->listWidget->setItemWidget(item, baseWidget); + if (!flag && flag1) { + QListWidgetItem *item = new QListWidgetItem(ui->listWidget); + item->setData(Qt::UserRole, printer.at(num)); + + item->setSizeHint(QSize(QSizePolicy::Expanding, 50)); + ui->listWidget->setItemWidget(item, printerItem); + } } } -void Printer::runExternalApp(){ +void Printer::runExternalApp() +{ QString cmd = "system-config-printer"; QProcess process(this); process.startDetached(cmd); } - -//bool Printer::eventFilter(QObject *watched, QEvent *event) -//{ -// if (watched == ui->addFrame){ -// if (event->type() == QEvent::MouseButtonPress){ -// QMouseEvent * mouseEvent = static_cast(event); -// if (mouseEvent->button() == Qt::LeftButton){ -// runExternalApp(); -// return true; -// } else -// return false; -// } -// } -// return QObject::eventFilter(watched, event); -//} diff -Nru ukui-control-center-2.0.3/plugins/devices/printer/printer.h ukui-control-center-3.0.3/plugins/devices/printer/printer.h --- ukui-control-center-2.0.3/plugins/devices/printer/printer.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/printer/printer.h 2021-05-20 13:08:14.000000000 +0000 @@ -28,6 +28,7 @@ #include "shell/interface.h" #include "HoverWidget/hoverwidget.h" #include "ImageUtil/imageutil.h" +#include "HoverBtn/hoverbtn.h" namespace Ui { class Printer; @@ -47,27 +48,26 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); void initComponent(); - void runExternalApp(); private: -// bool eventFilter(QObject *watched, QEvent *event); - -private: Ui::Printer *ui; QString pluginName; int pluginType; QWidget * pluginWidget; - HoverWidget * addWgt; + HoverWidget * mAddWgt; -private: - QTimer * pTimer; + bool mFirstLoad; + + QTimer *mTimer; public slots: - void refreshPrinterDev(); + void refreshPrinterDevSlot(); }; diff -Nru ukui-control-center-2.0.3/plugins/devices/printer/printer.pro ukui-control-center-3.0.3/plugins/devices/printer/printer.pro --- ukui-control-center-2.0.3/plugins/devices/printer/printer.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/printer/printer.pro 2021-04-14 01:27:20.000000000 +0000 @@ -7,6 +7,7 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) +include($$PROJECT_COMPONENTSOURCE/hoverbtn.pri) QT += widgets printsupport diff -Nru ukui-control-center-2.0.3/plugins/devices/printer/printer.ui ukui-control-center-3.0.3/plugins/devices/printer/printer.ui --- ukui-control-center-2.0.3/plugins/devices/printer/printer.ui 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/printer/printer.ui 2021-04-14 01:27:20.000000000 +0000 @@ -172,9 +172,15 @@ + + + 550 + 0 + + - 16777215 + 960 16777215 diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/addshortcutdialog.cpp ukui-control-center-3.0.3/plugins/devices/shortcut/addshortcutdialog.cpp --- ukui-control-center-2.0.3/plugins/devices/shortcut/addshortcutdialog.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/addshortcutdialog.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -17,63 +17,84 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ + #include "addshortcutdialog.h" #include "ui_addshortcutdialog.h" - +#include "CloseButton/closebutton.h" #include "realizeshortcutwheel.h" #define DEFAULTPATH "/usr/share/applications/" extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); -addShortcutDialog::addShortcutDialog(QWidget *parent) : +addShortcutDialog::addShortcutDialog(QList generalEntries, + QList customEntries, QWidget *parent) : QDialog(parent), - ui(new Ui::addShortcutDialog) + ui(new Ui::addShortcutDialog), + gsPath(""), + systemEntry(generalEntries), + customEntry(customEntries), + keyIsAvailable(false) { ui->setupUi(this); - setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); - setAttribute(Qt::WA_TranslucentBackground); - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); - -// ui->frame->setStyleSheet("QFrame{background: #ffffff; border: none; border-radius: 6px;}"); - - //关闭按钮在右上角,窗体radius 6px,所以按钮只得6px -// ui->closeBtn->setStyleSheet("QPushButton#closeBtn{background: #ffffff; border: none; border-radius: 6px;}" -// "QPushButton:hover:!pressed#closeBtn{background: #FA6056; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}" -// "QPushButton:hover:pressed#closeBtn{background: #E54A50; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}"); - -// QString lineEditQss = QString("QLineEdit{background: #E9E9E9; border: none; border-radius: 4px;}"); -// ui->nameLineEdit->setStyleSheet(lineEditQss); -// ui->execLineEdit->setStyleSheet(lineEditQss); + initSetup(); + slotsSetup(); + limitInput(); + refreshCertainChecked(); +} -// QString btnQss = QString("QPushButton{background: #E9E9E9; border-radius: 4px;}" -// "QPushButton:checked{background: #3d6be5; border-radius: 4px;}" -// "QPushButton:hover:!pressed{background: #3d6be5; border-radius: 4px;}" -// "QPushButton:hover:pressed{background: #415FC4; border-radius: 4px;}"); +addShortcutDialog::~addShortcutDialog() +{ + delete ui; + ui = nullptr; +} -// ui->cancelBtn->setStyleSheet(btnQss); -// ui->certainBtn->setStyleSheet(btnQss); +void addShortcutDialog::initSetup() +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(tr("Add custom shortcut")); - ui->closeBtn->setIcon(QIcon(QPixmap("://img/titlebar/close.svg"))); + ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); ui->noteLabel->setPixmap(QPixmap("://img/plugins/shortcut/note.png")); + ui->execLineEdit->setReadOnly(true); ui->stackedWidget->setCurrentIndex(1); + ui->kkeysequencewidget->setClearButtonShown(false); + ui->kkeysequencewidget->setMultiKeyShortcutsAllowed(false); + ui->kkeysequencewidget->setModifierlessAllowed(false); + ui->kkeysequencewidget->setCheckForConflictsAgainst(KKeySequenceWidget::None); +} - - refreshCertainChecked(); - - gsPath = ""; - - connect(ui->closeBtn, &QPushButton::clicked, [=](bool checked){ - Q_UNUSED(checked) - close(); +void addShortcutDialog::slotsSetup() +{ + connect(ui->kkeysequencewidget, &KKeySequenceWidget::keySequenceChanged, this, + [=](QKeySequence seq){ + qDebug() << seq.toString() << keyToLib(seq.toString()); + if (ui->kkeysequencewidget->isKeySequenceAvailable(seq)) { + if (conflictWithGlobalShortcuts(seq) || conflictWithStandardShortcuts(seq) + || conflictWithSystemShortcuts(seq) || conflictWithCustomShortcuts(seq)) { + ui->kkeysequencewidget->clearKeySequence(); + ui->kkeysequencewidget->clearFocus(); + ui->label_4->setText(tr("shortcut conflict")); + ui->stackedWidget->setCurrentIndex(0); + keyIsAvailable = false; + refreshCertainChecked(); + } else if (!isKeyAvailable(seq)) { + ui->kkeysequencewidget->clearKeySequence(); + ui->kkeysequencewidget->clearFocus(); + ui->label_4->setText(tr("invaild shortcut")); + ui->stackedWidget->setCurrentIndex(0); + keyIsAvailable = false; + refreshCertainChecked(); + } else { + ui->stackedWidget->setCurrentIndex(1); + keyIsAvailable = true; + refreshCertainChecked(); + } + } }); connect(ui->openBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) @@ -81,12 +102,13 @@ }); connect(ui->execLineEdit, &QLineEdit::textChanged, [=](QString text){ - if (text.endsWith("desktop") || - (!g_file_test(text.toLatin1().data(), G_FILE_TEST_IS_DIR) && g_file_test(text.toLatin1().data(), G_FILE_TEST_IS_EXECUTABLE))){ + if (text.endsWith("desktop") + || (!g_file_test(text.toLatin1().data(), + G_FILE_TEST_IS_DIR) + && g_file_test(text.toLatin1().data(), G_FILE_TEST_IS_EXECUTABLE))) { ui->certainBtn->setChecked(true); ui->stackedWidget->setCurrentIndex(1); - - } else{ + } else { ui->certainBtn->setChecked(false); ui->stackedWidget->setCurrentIndex(0); } @@ -95,19 +117,30 @@ }); connect(ui->nameLineEdit, &QLineEdit::textChanged, [=](QString text){ + QStringList customName; + for (KeyEntry *ckeyEntry : customEntry) { + customName << ckeyEntry->nameStr; + if (customName.contains(text)) { + ui->stackedWidget->setCurrentIndex(0); + ui->label_4->setText(tr("repeated naming")); + } else { + ui->stackedWidget->setCurrentIndex(1); + } + } refreshCertainChecked(); }); - connect(ui->cancelBtn, &QPushButton::clicked, [=]{ + connect(ui->cancelBtn, &QPushButton::clicked, [=] { close(); }); - connect(ui->certainBtn, &QPushButton::clicked, [=]{ - emit shortcutInfoSignal(gsPath, ui->nameLineEdit->text(), ui->execLineEdit->text()); + connect(ui->certainBtn, &QPushButton::clicked, [=] { + emit shortcutInfoSignal(gsPath, ui->nameLineEdit->text(), selectedfile, + ui->kkeysequencewidget->keySequence().toString()); close(); }); - connect(this, &addShortcutDialog::finished, [=]{ + connect(this, &addShortcutDialog::finished, [=] { gsPath = ""; ui->nameLineEdit->clear(); ui->execLineEdit->clear(); @@ -118,22 +151,51 @@ }); } -addShortcutDialog::~addShortcutDialog() +void addShortcutDialog::setTitleText(QString text) { - delete ui; -} - -void addShortcutDialog::setTitleText(QString text){ ui->titleLabel->setText(text); } -void addShortcutDialog::setUpdateEnv(QString path, QString name, QString exec){ +void addShortcutDialog::setUpdateEnv(QString path, QString name, QString exec) +{ gsPath = path; ui->nameLineEdit->setText(name); ui->execLineEdit->setText(exec); } -void addShortcutDialog::paintEvent(QPaintEvent *event) { +void addShortcutDialog::limitInput() +{ + // 大小写字母数字中文 + QRegExp rx("[a-zA-Z0-9\u4e00-\u9fa5]+"); + QRegExpValidator *regValidator = new QRegExpValidator(rx); + // 输入限制 + ui->nameLineEdit->setValidator(regValidator); + // 字符长度限制 + // ui->nameLineEdit->setMaxLength(10); +} + +QString addShortcutDialog::keyToLib(QString key) +{ + if (key.contains("+")) { + QStringList keys = key.split("+"); + if (keys.count() == 2) { + QString lower = keys.at(1); + QString keyToLib = "<" + keys.at(0) + ">" + lower.toLower(); + + return keyToLib; + } else if (keys.count() == 3) { + QString lower = keys.at(2); + QString keyToLib = "<" + keys.at(0) + ">" + "<" + keys.at(1) + ">" + lower.toLower(); + + return keyToLib; + } + } + + return key; +} + +void addShortcutDialog::paintEvent(QPaintEvent *event) +{ Q_UNUSED(event); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); @@ -147,6 +209,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); @@ -155,7 +218,6 @@ QImage img = pixmap.toImage(); qt_blurImage(img, 10, false, false); - // 挖掉中心 pixmap = QPixmap::fromImage(img); QPainter pixmapPainter2(&pixmap); @@ -170,12 +232,13 @@ // 绘制一个背景 p.save(); - p.fillPath(rectPath,palette().color(QPalette::Base)); + p.fillPath(rectPath, palette().color(QPalette::Base)); p.restore(); } -void addShortcutDialog::openProgramFileDialog(){ - QString filters = "Desktop files(*.desktop)"; +void addShortcutDialog::openProgramFileDialog() +{ + QString filters = tr("Desktop files(*.desktop)"); QFileDialog fd; fd.setDirectory(DEFAULTPATH); fd.setAcceptMode(QFileDialog::AcceptOpen); @@ -183,23 +246,121 @@ fd.setNameFilter(filters); fd.setFileMode(QFileDialog::ExistingFile); fd.setWindowTitle(tr("select desktop")); - fd.setLabelText(QFileDialog::Accept, "Select"); + fd.setLabelText(QFileDialog::Reject, tr("Cancel")); if (fd.exec() != QDialog::Accepted) return; - QString selectedfile; selectedfile = fd.selectedFiles().first(); QString exec = selectedfile.section("/", -1, -1); -// exec.replace(".desktop", ""); ui->execLineEdit->setText(exec); } -void addShortcutDialog::refreshCertainChecked(){ - if (ui->nameLineEdit->text().isEmpty() || ui->execLineEdit->text().isEmpty() || ui->stackedWidget->currentIndex() == 0){ - ui->certainBtn->setEnabled(false); +void addShortcutDialog::refreshCertainChecked() +{ + if (ui->nameLineEdit->text().isEmpty() || ui->execLineEdit->text().isEmpty() + || ui->stackedWidget->currentIndex() == 0 + || !keyIsAvailable) { + ui->certainBtn->setDisabled(true); + } else { + ui->certainBtn->setDisabled(false); + } +} + +bool addShortcutDialog::conflictWithGlobalShortcuts(const QKeySequence &keySequence) +{ + QHash > clashing; + for (int i = 0; i < keySequence.count(); ++i) { + QKeySequence keys(keySequence[i]); + + if (!KGlobalAccel::isGlobalShortcutAvailable(keySequence)) { + clashing.insert(keySequence, KGlobalAccel::getGlobalShortcutsByKey(keys)); + } + } + + if (clashing.isEmpty()) { + return false; + } else { + qDebug() << "conflict With Global Shortcuts"; + } + + return true; +} + +bool addShortcutDialog::conflictWithStandardShortcuts(const QKeySequence &seq) +{ + KStandardShortcut::StandardShortcut ssc = KStandardShortcut::find(seq); + if (ssc != KStandardShortcut::AccelNone) { + qDebug() << "conflict With Standard Shortcuts"; + return true; + } + + return false; +} + +bool addShortcutDialog::conflictWithSystemShortcuts(const QKeySequence &seq) +{ + QString systemKeyStr = keyToLib(seq.toString()); + + if (systemKeyStr.contains("Ctrl")) { + systemKeyStr.replace("Ctrl", "Control"); + } + for (KeyEntry *ckeyEntry : systemEntry) { + if (systemKeyStr == ckeyEntry->valueStr) { + qDebug() << "conflictWithSystemShortcuts" << seq; + return true; + } + } + return false; +} + +bool addShortcutDialog::conflictWithCustomShortcuts(const QKeySequence &seq) +{ + QString customKeyStr = keyToLib(seq.toString()); + + for (KeyEntry *ckeyEntry : customEntry) { + if (customKeyStr == ckeyEntry->bindingStr) { + qDebug() << "conflictWithCustomShortcuts" << seq; + return true; + } + } + return false; +} + +bool addShortcutDialog::isKeyAvailable(const QKeySequence &seq) +{ + QString keyStr = seq.toString(); + + if (!keyStr.contains("+")) { + qDebug() << "is not Available"; + return false; + } else if (keyStr.contains("Num") || keyStr.contains("Space") + || keyStr.contains("Meta") || keyStr.contains("Ins") || keyStr.contains("Home") + || keyStr.contains("PgUp") || keyStr.contains("Del") || keyStr.contains("End") + || keyStr.contains("PgDown") || keyStr.contains("Print") + || keyStr.contains("Backspace") || keyStr.contains("ScrollLock") + || keyStr.contains("Return") || keyStr.contains("Enter") + || keyStr.contains("Tab") || keyStr.contains("CapsLock") + || keyStr.contains("Left") || keyStr.contains("Right") + || keyStr.contains("Up") || keyStr.contains("Down") + || keyStr.contains("Clear Grab")) { + qDebug() << "is not Available"; + return false; } else { - ui->certainBtn->setEnabled(true); + QStringList keys = keyStr.split("+"); + if (keys.count() == 4) { + qDebug() << "is not Available"; + return false; + } else { + QString key = keys.at(keys.count() - 1); + if (!key.contains(QRegExp("[A-Z]")) && !key.contains(QRegExp("[a-z]")) + && !key.contains(QRegExp("[0-9]"))) { + qDebug() << "is not Available"; + return false; + } + } } + + return true; } diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/addshortcutdialog.h ukui-control-center-3.0.3/plugins/devices/shortcut/addshortcutdialog.h --- ukui-control-center-2.0.3/plugins/devices/shortcut/addshortcutdialog.h 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/addshortcutdialog.h 2021-05-20 13:08:14.000000000 +0000 @@ -24,6 +24,26 @@ #include #include #include +#include +#include +#include +#include + +typedef struct _KeyEntry KeyEntry; + +struct _KeyEntry { + QString gsSchema; + QString keyStr; + QString valueStr; + QString descStr; + + QString gsPath; + QString nameStr; + QString bindingStr; + QString actionStr; +}; + +Q_DECLARE_METATYPE(KeyEntry *) namespace Ui { class addShortcutDialog; @@ -34,30 +54,42 @@ Q_OBJECT public: - explicit addShortcutDialog(QWidget *parent = nullptr); + explicit addShortcutDialog(QList generalEntries, QList customEntries, + QWidget *parent = nullptr); ~addShortcutDialog(); public: + void initSetup(); + void slotsSetup(); void setTitleText(QString text); void openProgramFileDialog(); void setUpdateEnv(QString path, QString name, QString exec); void refreshCertainChecked(); + void limitInput(); + bool conflictWithStandardShortcuts(const QKeySequence &seq); + bool conflictWithGlobalShortcuts(const QKeySequence &seq); + bool conflictWithSystemShortcuts(const QKeySequence &seq); + bool conflictWithCustomShortcuts(const QKeySequence &seq); + bool isKeyAvailable(const QKeySequence &seq); + QString keyToLib(QString key); protected: void paintEvent(QPaintEvent *); - private: Ui::addShortcutDialog *ui; private: QString gsPath; - + QString selectedfile; + QList systemEntry; + QList customEntry; + bool keyIsAvailable; Q_SIGNALS: - void shortcutInfoSignal(QString path, QString name, QString exec); + void shortcutInfoSignal(QString path, QString name, QString exec, QString key); }; #endif // ADDSHORTCUTDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/addshortcutdialog.ui ukui-control-center-3.0.3/plugins/devices/shortcut/addshortcutdialog.ui --- ukui-control-center-2.0.3/plugins/devices/shortcut/addshortcutdialog.ui 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/addshortcutdialog.ui 2021-05-20 13:08:14.000000000 +0000 @@ -6,496 +6,444 @@ 0 0 - 430 - 360 + 470 + 326 - 430 - 360 + 470 + 326 - 430 - 360 + 470 + 326 Dialog - + 0 - 0 + 40 - 9 + 42 - 9 + 50 - 0 + 32 - - - QFrame::NoFrame + + + 24 - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - 0 - - - - - 0 - - - 8 - - - 8 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - - - - - - 0 - - - 32 - - - 16 - - - 32 - - - 32 - - - - - - 0 - 0 - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 32 - - - - - - - - 0 - - - - - - 0 - 0 - - - - Shortcut name - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 258 - 28 - - - - - 258 - 28 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 8 - - - - - - - - 16 - - - - - - 0 - 0 - - - - Shortcut exec - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 182 - 28 - - - - - 182 - 28 - - - - - - - - - 60 - 28 - - - - - 60 - 28 - - - - Open - - - - - - - - - - 0 - 24 - - - - - 16777215 - 24 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 8 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 16 - 16 - - - - - 16 - 16 - - - - - - - - - - - - 0 - 0 - - - - Invalid executable, please re-enter - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - + + + + + + + 0 + 0 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + + + 9 + + + + + 16 + + + + + + 0 + 0 + + + + Exec + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 227 + 36 + + + + + 227 + 36 + + + + + + + + + 60 + 36 + + + + + 60 + 36 + + + + Qt::NoFocus + + + Open + + + + + + + + + 0 + + + + + + 0 + 0 + + + + Name + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 302 + 36 + + + + + 302 + 36 + + + + + + + + + + + + Key + - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 88 - - - - - - - - 16 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 120 - 36 - - - - - 120 - 36 - - - - Cancel - - - - - - - - 120 - 36 - - - - - 120 - 36 - - - - Certain - - - true - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 302 + 36 + + + + + 302 + 36 + + + + KKeySequenceWidget::None + + + + + + + + + + + + 0 + 24 + + + + + 16777215 + 24 + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 8 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 16 + 16 + + + + + 16 + 16 + + + + + + + + + + + + 0 + 0 + + + + Invalid executable, please re-enter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + 16 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 120 + 36 + + + + + 120 + 36 + + + + Qt::NoFocus + + + Cancel + + + + + + + + 120 + 36 + + + + + 120 + 36 + + + + Save + + + true + + + + + + + KKeySequenceWidget + QWidget +
kkeysequencewidget.h
+
+
diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/customlineedit.cpp ukui-control-center-3.0.3/plugins/devices/shortcut/customlineedit.cpp --- ukui-control-center-2.0.3/plugins/devices/shortcut/customlineedit.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/customlineedit.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -25,7 +25,7 @@ QLineEdit(parent), _oldshortcut(shortcut) { - _wait = "New Shortcut..."; + _wait = tr("New Shortcut..."); flag = true; setFocusPolicy(Qt::ClickFocus); @@ -35,15 +35,8 @@ { } -//void CustomLineEdit::mousePressEvent(QMouseEvent *e){ -// if (e->buttons() & Qt::LeftButton){ -// this->setText("New Shortcut..."); -// } -//} void CustomLineEdit::focusInEvent(QFocusEvent *evt){ -// if (this->text() == _oldshortcut) -// this->setText(_wait); this->setText(_wait); flag = true; } diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/customlineedit.h ukui-control-center-3.0.3/plugins/devices/shortcut/customlineedit.h --- ukui-control-center-2.0.3/plugins/devices/shortcut/customlineedit.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/customlineedit.h 2021-04-14 01:27:20.000000000 +0000 @@ -33,7 +33,6 @@ explicit CustomLineEdit(QString shortcut, QWidget *parent = 0); ~CustomLineEdit(); -// virtual void mousePressEvent(QMouseEvent * e); virtual void focusOutEvent(QFocusEvent * evt); virtual void focusInEvent(QFocusEvent * evt); virtual void keyReleaseEvent(QKeyEvent * evt); diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/defineshortcutitem.cpp ukui-control-center-3.0.3/plugins/devices/shortcut/defineshortcutitem.cpp --- ukui-control-center-2.0.3/plugins/devices/shortcut/defineshortcutitem.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/defineshortcutitem.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -27,7 +27,6 @@ DefineShortcutItem::DefineShortcutItem(QString name, QString binding) { -// setAttribute(Qt::WA_DeleteOnClose); _deleteable = false; _updateable = false; @@ -111,17 +110,23 @@ pLineEdit->updateOldShow(newBinding); } -void DefineShortcutItem::mousePressEvent(QMouseEvent *e){ - if (e->button() == Qt::LeftButton && _deleteable){ +void DefineShortcutItem::enterEvent(QEvent *) +{ + if (_deleteable){ pButton->show(); } +} - QWidget::mousePressEvent(e); +void DefineShortcutItem::leaveEvent(QEvent *) +{ + if (_deleteable){ + pButton->hide(); + } } void DefineShortcutItem::mouseDoubleClickEvent(QMouseEvent *e){ if (e->button() == Qt::LeftButton && _updateable){ - emit updateShortcutSignal(); + //emit updateShortcutSignal(); } QWidget::mouseDoubleClickEvent(e); } diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/defineshortcutitem.h ukui-control-center-3.0.3/plugins/devices/shortcut/defineshortcutitem.h --- ukui-control-center-2.0.3/plugins/devices/shortcut/defineshortcutitem.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/defineshortcutitem.h 2021-04-14 01:27:20.000000000 +0000 @@ -49,7 +49,8 @@ void setShortcutBinding(QString newBinding); protected: - virtual void mousePressEvent(QMouseEvent * e); + virtual void enterEvent(QEvent *); + virtual void leaveEvent(QEvent *); virtual void mouseDoubleClickEvent(QMouseEvent * e); diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/getshortcutworker.cpp ukui-control-center-3.0.3/plugins/devices/shortcut/getshortcutworker.cpp --- ukui-control-center-2.0.3/plugins/devices/shortcut/getshortcutworker.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/getshortcutworker.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -31,75 +31,77 @@ { } -void GetShortcutWorker::run(){ - +void GetShortcutWorker::run() +{ // list system shortcut QByteArray id(KEYBINDINGS_SYSTEM_SCHEMA); - GSettings * systemgsettings; + GSettings *systemgsettings; if (QGSettings::isSchemaInstalled(id)) { systemgsettings = g_settings_new(KEYBINDINGS_SYSTEM_SCHEMA); } else { return; } - - char ** skeys = g_settings_list_keys(systemgsettings); - for (int i=0; skeys[i]!= NULL; i++){ - //切换为mutter后,原先为string的变为字符串数组,这块只取了字符串数组的第一个元素 + char **skeys = g_settings_list_keys(systemgsettings); + for (int i = 0; skeys[i] != NULL; i++) { + // 切换为mutter后,原先为string的变为字符串数组,这块只取了字符串数组的第一个元素 GVariant *variant = g_settings_get_value(systemgsettings, skeys[i]); gsize size = g_variant_get_size(variant); - char ** tmp = const_cast(g_variant_get_strv(variant, &size)); - char * str = tmp[0]; + char **tmp = const_cast(g_variant_get_strv(variant, &size)); + char *str = tmp[0]; - //保存系统快捷键 - QString key = QString(skeys[i]); QString value = QString(str); - if (value != ""){ + // 保存系统快捷键 + QString key = QString(skeys[i]); + QString value = QString(str); + if (value != "") { generalShortcutGenerate(KEYBINDINGS_SYSTEM_SCHEMA, key, value); } } g_strfreev(skeys); g_object_unref(systemgsettings); - // list desktop shortcut - GSettings * desktopsettings; + GSettings *desktopsettings = NULL; if (QGSettings::isSchemaInstalled(KEYBINDINGS_DESKTOP_SCHEMA)) { desktopsettings = g_settings_new(KEYBINDINGS_DESKTOP_SCHEMA); - } - - char ** dkeys = g_settings_list_keys(desktopsettings); - for (int i=0; dkeys[i]!= NULL; i++){ - //跳过非快捷键 - if (!g_strcmp0(dkeys[i], "active") || !g_strcmp0(dkeys[i], "volume-step") || - !g_strcmp0(dkeys[i], "priority") || !g_strcmp0(dkeys[i], "enable-osd")) - continue; - - GVariant *variant = g_settings_get_value(desktopsettings, dkeys[i]); - gsize size = g_variant_get_size(variant); - char * str = const_cast(g_variant_get_string(variant, &size)); - - //保存桌面快捷键 - QString key = QString(dkeys[i]); QString value = QString(str); - if (value != ""){ - generalShortcutGenerate(KEYBINDINGS_DESKTOP_SCHEMA, key, value); + char **dkeys = g_settings_list_keys(desktopsettings); + for (int i = 0; dkeys[i] != NULL; i++) { + // 跳过非快捷键 + if (!g_strcmp0(dkeys[i], "active") || !g_strcmp0(dkeys[i], "volume-step") + || !g_strcmp0(dkeys[i], "priority") || !g_strcmp0(dkeys[i], "enable-osd")) + continue; + + GVariant *variant = g_settings_get_value(desktopsettings, dkeys[i]); + gsize size = g_variant_get_size(variant); + char *str = const_cast(g_variant_get_string(variant, &size)); + + // 保存桌面快捷键 + QString key = QString(dkeys[i]); + QString value = QString(str); + if (value.contains("KP_Delete")) { + value = "Del"; + generalShortcutGenerate(KEYBINDINGS_DESKTOP_SCHEMA, key, value); + } + if (value != "" && !value.contains("XF86") && !value.contains("KP_")) { + generalShortcutGenerate(KEYBINDINGS_DESKTOP_SCHEMA, key, value); + } } + g_strfreev(dkeys); + g_object_unref(desktopsettings); } - g_strfreev(dkeys); - g_object_unref(desktopsettings); // list custdom shortcut QList existsPath = listExistsCustomShortcutPath(); - for (char * path : existsPath){ - - char * prepath = QString(KEYBINDINGS_CUSTOM_DIR).toLatin1().data(); - char * fullpath = strcat(prepath, path); + for (char *path : existsPath) { + QString strFullPath = QString(KEYBINDINGS_CUSTOM_DIR); + strFullPath.append(path); const QByteArray ba(KEYBINDINGS_CUSTOM_SCHEMA); - const QByteArray bba(fullpath); - QGSettings * settings = new QGSettings(ba, bba); + const QByteArray bba(strFullPath.toLatin1().data()); + QGSettings *settings = new QGSettings(ba, bba, this); - QString pathStr = QString(fullpath); + QString pathStr = strFullPath; QString actionStr = settings->get(ACTION_KEY).toString(); QString bindingStr = settings->get(BINDING_KEY).toString(); QString nameStr = settings->get(NAME_KEY).toString(); @@ -107,6 +109,5 @@ customShortcutGenerate(pathStr, nameStr, bindingStr, actionStr); } - emit workerComplete(); } diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/shortcut.cpp ukui-control-center-3.0.3/plugins/devices/shortcut/shortcut.cpp --- ukui-control-center-2.0.3/plugins/devices/shortcut/shortcut.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/shortcut.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -28,7 +28,6 @@ #include "realizeshortcutwheel.h" #include "defineshortcutitem.h" - /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ @@ -41,12 +40,15 @@ #include } - #define ITEMHEIGH 36 +#define TITLEWIDGETHEIGH 40 +#define SYSTEMTITLEWIDGETHEIGH 50 +#define UKUI_STYLE_SCHEMA "org.ukui.style" +#define SYSTEM_FONT_EKY "system-font-size" -//快捷键屏蔽键 +// 快捷键屏蔽键 QStringList forbiddenKeys = { - //Navigation keys + // Navigation keys "Home", "Left", "Up", @@ -67,706 +69,526 @@ QList generalEntries; QList customEntries; -Shortcut::Shortcut() +Shortcut::Shortcut() : mFirstLoad(true) { - ui = new Ui::Shortcut; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Shortcut"); pluginType = DEVICES; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - -// pluginWidget->setStyleSheet("background: #ffffff;"); - -// ui->generalListWidget->setStyleSheet("QListWidget#generalListWidget{background: #ffffff; border: none;}"); - -// ui->showBtn->setStyleSheet("QPushButton{background: #E9E9E9; border-radius: 4px;}" -// "QPushButton:hover:!pressed{background: #3d6be5; border-radius: 4px;}" -// "QPushButton:hover:pressed{background: #415FC4; border-radius: 4px;}"); - -// ui->resetBtn->setStyleSheet("QPushButton{background: #E9E9E9; border-radius: 4px;}" -// "QPushButton:hover:!pressed{background: #3d6be5; border-radius: 4px;}" -// "QPushButton:hover:pressed{background: #415FC4; border-radius: 4px;}"); - -// ui->customListWidget->setStyleSheet("QListWidget#customListWidget{background: #ffffff; border: none;}"); - -// ui->addWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - - pKeyMap = new KeyMap; - addDialog = new addShortcutDialog(); - showDialog = new ShowAllShortcut(); - - showList << "terminal" << "screenshot" << "area-screenshot" << "peony-qt" << "logout" << "screensaver"; - - setupComponent(); - setupConnect(); - initFunctionStatus(); } Shortcut::~Shortcut() { - delete ui; - delete pKeyMap; - delete addDialog; - delete showDialog; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + delete pKeyMap; + pKeyMap = nullptr; + } } -QString Shortcut::get_plugin_name(){ +QString Shortcut::get_plugin_name() +{ return pluginName; } -int Shortcut::get_plugin_type(){ +int Shortcut::get_plugin_type() +{ return pluginType; } -QWidget *Shortcut::get_plugin_ui(){ +QWidget *Shortcut::get_plugin_ui() +{ + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::Shortcut; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + pKeyMap = new KeyMap; + + isCloudService = false; + + initTitleLabel(); + setupComponent(); + setupConnect(); + initFunctionStatus(); + connectToServer(); + } return pluginWidget; } -void Shortcut::plugin_delay_control(){ +void Shortcut::plugin_delay_control() +{ +} +const QString Shortcut::name() const +{ + return QStringLiteral("shortcut"); } -void Shortcut::setupComponent(){ -// ui->addLabel->setPixmap(QPixmap("://img/plugins/printer/add.png")); +void Shortcut::initTitleLabel() +{ + QFont font; + font.setPixelSize(18); + ui->systemLabel->setFont(font); + ui->customLabel->setFont(font); +} - ui->generalListWidget->setFocusPolicy(Qt::NoFocus); - ui->generalListWidget->setSelectionMode(QAbstractItemView::NoSelection); - ui->generalListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->generalListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->generalListWidget->setSpacing(1); +void Shortcut::connectToServer() +{ + cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", + "/org/kylinssoclient/path", + "org.freedesktop.kylinssoclient.interface", + QDBusConnection::sessionBus()); + if (!cloudInterface->isValid()) { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), + QString( + "org.freedesktop.kylinssoclient.interface"), "shortcutChanged", this, + SLOT(shortcutChangedSlot())); + // 将以后所有DBus调用的超时设置为 milliseconds + cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} - ui->customListWidget->setFocusPolicy(Qt::NoFocus); - ui->customListWidget->setSelectionMode(QAbstractItemView::NoSelection); - ui->customListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->customListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->customListWidget->setSpacing(0); -// ui->customListWidget->setFixedHeight((showList.length() * ITEMHEIGH)); +void Shortcut::setupComponent() +{ + //~ contents_path /shortcut/System Shortcut + ui->systemLabel->setText(tr("System Shortcut")); + //~ contents_path /shortcut/Customize Shortcut + ui->customLabel->setText(tr("Customize Shortcut")); + + QWidget *systemTitleWidget = new QWidget; + QVBoxLayout *systemVerLayout = new QVBoxLayout(systemTitleWidget); + + systemTitleWidget->setFixedHeight(SYSTEMTITLEWIDGETHEIGH); + systemTitleWidget->setStyleSheet("QWidget{background: palette(window);" + "border: none; border-radius: 4px}"); + systemVerLayout->setSpacing(0); + systemVerLayout->setContentsMargins(16, 15, 19, 0); + + QLabel *titleLabel = new QLabel(systemTitleWidget); + titleLabel->setText(tr("System Shortcut")); + + systemVerLayout->addWidget(titleLabel); + systemVerLayout->addStretch(); + systemTitleWidget->setLayout(systemVerLayout); addWgt = new HoverWidget(""); addWgt->setObjectName("addwgt"); addWgt->setMinimumSize(QSize(580, 50)); addWgt->setMaximumSize(QSize(960, 50)); - addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); + addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button); border-radius: 4px;}" + "HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); QHBoxLayout *addLyt = new QHBoxLayout; - QLabel * iconLabel = new QLabel(); - QLabel * textLabel = new QLabel(tr("Add custom shortcut")); + QLabel *iconLabel = new QLabel(); + //~ contents_path /shortcut/Add custom shortcut + QLabel *textLabel = new QLabel(tr("Add custom shortcut")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); + iconLabel->setPixmap(pixgray); + iconLabel->setProperty("useIconHighlightEffect", true); + iconLabel->setProperty("iconHighlightEffectMode", 1); addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); addWgt->setLayout(addLyt); - // 悬浮改变Widget状态 - connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(base);"); - - }); - // 还原状态 - connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(windowText);"); - }); - ui->addLyt->addWidget(addWgt); - - -// ui->addFrame->installEventFilter(this); -// ui->generalListWidget->setSelectionMode(QAbstractItemView::SingleSelection); - ui->generalListWidget->setSelectionMode(QAbstractItemView::NoSelection); - - ui->resetBtn->hide(); - } -void Shortcut::setupConnect(){ +void Shortcut::setupConnect() +{ + connect(addWgt, &HoverWidget::widgetClicked, this, [=](){ + addShortcutDialog *addDialog = new addShortcutDialog(generalEntries, customEntries); + addDialog->setTitleText(QObject::tr("Customize Shortcut")); + + connect(addDialog, &addShortcutDialog::shortcutInfoSignal, + [=](QString path, QString name, QString exec, QString key){ + createNewShortcut(path, name, exec, key); + }); - connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname){ addDialog->exec(); }); - - connect(ui->showBtn, &QPushButton::clicked, [=]{ - QMap systemMap; - QMap desktopMap; - - //最新快捷键数据 - for (int i = 0; i < generalEntries.count(); i++){ - if (generalEntries[i]->gsSchema == KEYBINDINGS_DESKTOP_SCHEMA){ - desktopMap.insert(generalEntries[i]->keyStr, generalEntries[i]->valueStr); - } else if (generalEntries[i]->gsSchema == KEYBINDINGS_SYSTEM_SCHEMA){ - systemMap.insert(generalEntries[i]->keyStr, generalEntries[i]->valueStr); - } - - } - QMap> generalMaps; - if (desktopMap.count() != 0) { - generalMaps.insert("Desktop", desktopMap); - } -// if (systemMap.count() != 0) { -// generalMaps.insert("System", systemMap); -// } - showDialog->buildComponent(generalMaps); - showDialog->exec(); - }); - - connect(addDialog, &addShortcutDialog::shortcutInfoSignal, [=](QString path, QString name, QString exec){ - createNewShortcut(path, name, exec); - }); - - connect(ui->generalListWidget, &QListWidget::itemSelectionChanged, [=]{ - QList selectedItems = ui->generalListWidget->selectedItems(); - if (selectedItems.count() == 1){ - ui->resetBtn->show(); - } else{ - ui->resetBtn->hide(); - } - }); - - connect(ui->resetBtn, &QPushButton::clicked, [=]{ - QList selectedItems = ui->generalListWidget->selectedItems(); - if (!selectedItems.isEmpty()){ - QListWidgetItem * sItem = selectedItems.first(); - DefineShortcutItem * wItem = dynamic_cast(ui->generalListWidget->itemWidget(sItem)); -// KeyEntry * currentEntry = dynamic_cast(wItem->userData(Qt::UserRole)); - KeyEntry * currentEntry = wItem->property("userData").value(); - - const QByteArray id(currentEntry->gsSchema.toLatin1().data()); - QGSettings * settings = new QGSettings(id); - - settings->reset(currentEntry->keyStr); - - QString value = settings->get(currentEntry->keyStr).toString(); - wItem->setShortcutBinding(value); - - // 同时更新 显示全部快捷键中 对应键值 - for (int index = 0; index < generalEntries.count(); index++){ - if (currentEntry->keyStr == generalEntries[index]->keyStr){ - generalEntries[index]->valueStr = value; - } - } - delete settings; - } - }); } -void Shortcut::initFunctionStatus(){ +void Shortcut::initFunctionStatus() +{ generalEntries.clear(); customEntries.clear(); - //使用线程获取快捷键 + // 使用线程获取快捷键 pThread = new QThread; pWorker = new GetShortcutWorker; - connect(pWorker, &GetShortcutWorker::generalShortcutGenerate, this, [=](QString schema, QString key, QString value){ - //qDebug() << "general shortcut" << schema << key << value; - KeyEntry * generalKeyEntry = new KeyEntry; - generalKeyEntry->gsSchema = schema; - generalKeyEntry->keyStr = key; - generalKeyEntry->valueStr = value; - generalEntries.append(generalKeyEntry); - - }); - connect(pWorker, &GetShortcutWorker::customShortcutGenerate, this, [=](QString path, QString name, QString binding, QString action){ - //qDebug() << "custom shortcut" << path << name << binding; - KeyEntry * customKeyEntry = new KeyEntry; + if (isCloudService == false) { + connect(pWorker, &GetShortcutWorker::generalShortcutGenerate, this, + [=](QString schema, QString key, QString value){ + // qDebug() << "general shortcut" << schema << key << value; + KeyEntry *generalKeyEntry = new KeyEntry; + generalKeyEntry->gsSchema = schema; + generalKeyEntry->keyStr = key; + generalKeyEntry->valueStr = value; + generalEntries.append(generalKeyEntry); + }); + } + connect(pWorker, &GetShortcutWorker::customShortcutGenerate, this, + [=](QString path, QString name, QString binding, QString action){ + // qDebug() << "custom shortcut" << path << name << binding; + KeyEntry *customKeyEntry = new KeyEntry; customKeyEntry->gsSchema = KEYBINDINGS_CUSTOM_SCHEMA; customKeyEntry->gsPath = path; customKeyEntry->nameStr = name; customKeyEntry->bindingStr = binding; customKeyEntry->actionStr = action; customEntries.append(customKeyEntry); - }); - connect(pWorker, &GetShortcutWorker::workerComplete, this, [=]{ - pThread->quit(); //退出事件循环 - pThread->wait(); //释放资源 + connect(pWorker, &GetShortcutWorker::workerComplete, this, [=] { + pThread->quit(); // 退出事件循环 + pThread->wait(); // 释放资源 }); pWorker->moveToThread(pThread); connect(pThread, &QThread::started, pWorker, &GetShortcutWorker::run); - connect(pThread, &QThread::finished, this, [=]{ - //系统快捷键 - appendGeneralItems(); - ui->generalListWidget->setFixedHeight(ui->generalListWidget->count() * ITEMHEIGH); - initGeneralItemsStyle(); + connect(pThread, &QThread::finished, this, [=] { + QMap systemMap; + QMap desktopMap; + + // 最新快捷键数据 + for (int i = 0; i < generalEntries.count(); i++) { + if (generalEntries[i]->gsSchema == KEYBINDINGS_DESKTOP_SCHEMA) { + desktopMap.insert(generalEntries[i]->keyStr, generalEntries[i]->valueStr); + } else if (generalEntries[i]->gsSchema == KEYBINDINGS_SYSTEM_SCHEMA) { + systemMap.insert(generalEntries[i]->keyStr, generalEntries[i]->valueStr); + } + } + + desktopMap = MergerOfTheSamekind(desktopMap); + + QMap > generalMaps; + if (desktopMap.count() != 0) { + generalMaps.insert("Desktop", desktopMap); + } + // 构建系统快捷键界面 + appendGeneralItems(generalMaps); - //自定义快捷键 + // 构建自定义快捷键界面 appendCustomItems(); - ui->customListWidget->setFixedHeight(ui->customListWidget->count() * ITEMHEIGH); - initCustomItemsStyle(); + isCloudService = false; }); connect(pThread, &QThread::finished, pWorker, &GetShortcutWorker::deleteLater); pThread->start(); +} +QMap Shortcut:: MergerOfTheSamekind(QMap desktopMap) +{ + QMap::iterator it = desktopMap.begin(); + for (; it != desktopMap.end(); it++) { + QString name = it.key().at(it.key().size() - 1); + QString name_modification = it.key().left(it.key().length() - 1); + if (name == '2') { + desktopMap[name_modification] = desktopMap[name_modification]+" or "+it.value(); + desktopMap.erase(it); + it = desktopMap.begin()+1;// 除之后要将指针指向后面一个 + } + } + return desktopMap; } -void Shortcut::appendGeneralItems(){ - for (KeyEntry * gkeyEntry: generalEntries){ - if (showList.contains(gkeyEntry->keyStr)){ +QWidget *Shortcut::buildGeneralWidget(QString schema, QMap subShortcutsMap) +{ + GSettingsSchema *pSettings; + QString domain; - GSettingsSchema * pSettings; + if (schema == "Desktop") { + pSettings + = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory( + "/usr/share/glib-2.0/schemas/", + g_settings_schema_source_get_default(), + FALSE, NULL), + KEYBINDINGS_DESKTOP_SCHEMA, + FALSE); + domain = "ukui-settings-daemon"; + } else if (schema == "System") { + pSettings + = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory( + "/usr/share/glib-2.0/schemas/", + g_settings_schema_source_get_default(), + FALSE, NULL), + KEYBINDINGS_SYSTEM_SCHEMA, + FALSE); + domain = "gsettings-desktop-schemas"; + } else { + return NULL; + } - pSettings = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory("/usr/share/glib-2.0/schemas/", g_settings_schema_source_get_default(), FALSE, NULL), - KEYBINDINGS_DESKTOP_SCHEMA, - FALSE); + QWidget *pWidget = new QWidget; + pWidget->setAttribute(Qt::WA_DeleteOnClose); + QVBoxLayout *pVerLayout = new QVBoxLayout(pWidget); + pVerLayout->setSpacing(2); + pVerLayout->setContentsMargins(0, 0, 0, 16); - QByteArray ba = QString("ukui-settings-daemon").toLatin1(); - QByteArray ba1 = gkeyEntry->keyStr.toLatin1(); + pWidget->setLayout(pVerLayout); - GSettingsSchemaKey * keyObj = g_settings_schema_get_key(pSettings, ba1.data()); + QMap::iterator it = subShortcutsMap.begin(); - char * i18nKey; - i18nKey = const_cast(g_dgettext(ba.data(), g_settings_schema_key_get_summary(keyObj))); + for (; it != subShortcutsMap.end(); it++) { + QWidget *gWidget = new QWidget; + gWidget->setFixedHeight(TITLEWIDGETHEIGH); + gWidget->setStyleSheet( + "QWidget{background: palette(window); border: none; border-radius: 4px}"); - DefineShortcutItem * singleWidget = new DefineShortcutItem(QString(i18nKey), gkeyEntry->valueStr); - singleWidget->setFrameShape(QFrame::Shape::Box); -// singleWidget->setUserData(Qt::UserRole, gkeyEntry); - singleWidget->setProperty("userData", QVariant::fromValue(gkeyEntry)); + QHBoxLayout *gHorLayout = new QHBoxLayout(gWidget); + gHorLayout->setSpacing(24); + gHorLayout->setContentsMargins(16, 0, 19, 0); - CustomLineEdit * line = singleWidget->lineeditComponent(); - line->setFocusPolicy(Qt::NoFocus); - connect(line, &CustomLineEdit::shortcutCodeSignals, this, [=](QList keyCode){ - newBindingRequest(keyCode); - }); + QByteArray ba = domain.toLatin1(); + QByteArray ba1 = it.key().toLatin1(); - QListWidgetItem * item = new QListWidgetItem(ui->generalListWidget); - item->setSizeHint(QSize(ui->generalListWidget->width(), ITEMHEIGH)); - item->setData(Qt::UserRole, ""); - ui->generalListWidget->setItemWidget(item, singleWidget); - } - } -} + GSettingsSchemaKey *keyObj = g_settings_schema_get_key(pSettings, ba1.data()); -void Shortcut::appendCustomItems(){ - for (KeyEntry * ckeyEntry : customEntries){ - buildCustomItem(ckeyEntry); - } -} + char *i18nKey; + QLabel *nameLabel = new QLabel(gWidget); + i18nKey = const_cast(g_dgettext(ba.data(), g_settings_schema_key_get_summary( + keyObj))); -void Shortcut::buildCustomItem(KeyEntry * nkeyEntry){ - DefineShortcutItem * singleWidget = new DefineShortcutItem(nkeyEntry->nameStr, nkeyEntry->bindingStr); - singleWidget->setDeleteable(true); - singleWidget->setUpdateable(true); -// singleWidget->setUserData(Qt::UserRole, nkeyEntry); - singleWidget->setProperty("userData", QVariant::fromValue(nkeyEntry)); - connect(singleWidget, &DefineShortcutItem::updateShortcutSignal, [=]{ - addDialog->setTitleText(QObject::tr("Update Shortcut")); - addDialog->setUpdateEnv(nkeyEntry->gsPath, nkeyEntry->nameStr, nkeyEntry->actionStr); - addDialog->exec(); + nameLabel->setText(QString(i18nKey)); + nameLabel->setToolTip(QString(i18nKey)); - }); + QFontMetrics fontMetrics(nameLabel->font()); + QLabel *bindingLabel = new QLabel(gWidget); - CustomLineEdit * line = singleWidget->lineeditComponent(); - connect(line, &CustomLineEdit::shortcutCodeSignals, this, [=](QList keyCode){ - newBindingRequest(keyCode); - }); + bindingLabel->setText(it.value()); + bindingLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - QPushButton * button = singleWidget->btnComponent(); + nameLabel->setText(fontMetrics.elidedText(QString(i18nKey), Qt::ElideRight, 180)); + const QByteArray styleID(UKUI_STYLE_SCHEMA); - QListWidgetItem * item = new QListWidgetItem(ui->customListWidget); - item->setSizeHint(QSize(ui->customListWidget->width(), ITEMHEIGH)); - item->setData(Qt::UserRole, nkeyEntry->gsPath); - ui->customListWidget->setItemWidget(item, singleWidget); + if (QGSettings::isSchemaInstalled(styleID)) { + QGSettings *styleUKUI = new QGSettings(styleID, QByteArray(), this); + connect(styleUKUI, &QGSettings::changed, this, [=](const QString &key){ + if (key == "systemFontSize") { + QFontMetrics fm(nameLabel->font()); + nameLabel->setText(fm.elidedText(QString(i18nKey), Qt::ElideRight, 180)); + } + }); + } - connect(button, &QPushButton::clicked, [=]{ - int row = ui->customListWidget->row(item); - QListWidgetItem * obItem = ui->customListWidget->takeItem(row); + QHBoxLayout *tHorLayout = new QHBoxLayout(); + QSpacerItem *horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - delete obItem; + tHorLayout->addItem(horizontalSpacer); + tHorLayout->addWidget(bindingLabel); + tHorLayout->setMargin(0); + gHorLayout->addWidget(nameLabel); + gHorLayout->addStretch(); + gHorLayout->addLayout(tHorLayout); - ui->customListWidget->setFixedHeight(ui->customListWidget->count() * ITEMHEIGH); + gWidget->setLayout(gHorLayout); - initCustomItemsStyle(); + pVerLayout->addWidget(gWidget); - deleteCustomShortcut(nkeyEntry->gsPath); - }); + g_settings_schema_key_unref(keyObj); + } + + g_settings_schema_unref(pSettings); + + return pWidget; } -void Shortcut::initItemsStyle(QListWidget *listWidget){ - int total = listWidget->count(); - for (int row = 0; row < total; row++){ - QString style; - QString subStyle; - if (1 == total){ //总数为1 - style = "QWidget{background: #F4F4F4; border: none; border-radius: 6px;}"; - subStyle = "background: #F4F4F4; border: none; border-radius: 4px;"; - } else if (0 == row && (row % 2 == 0)){ //首位 - style = "QWidget{background: #F4F4F4; border: none; border-top-left-radius: 6px; border-top-right-radius: 6px;}"; - subStyle = "background: #F4F4F4; border: none; border-radius: 4px;"; - } else if (total - 1 == row){ //末位 - if (0 == row % 2){ - style = "QWidget{background: #F4F4F4; border: none; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"; - subStyle = "background: #F4F4F4; border: none; border-radius: 4px;"; - } else { - style = "QWidget{background: #EEEEEE; border: none; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"; - subStyle = "background: #EEEEEE; border: none; border-radius: 4px;"; - } - } else if (row % 2 == 0){ - style = "QWidget{background: #F4F4F4; border: none;}"; - subStyle = "background: #F4F4F4; border: none; border-radius: 4px;"; - } else if (row % 2 != 0){ - style = "QWidget{background: #EEEEEE; border: none;}"; - subStyle = "background: #EEEEEE; border: none; border-radius: 4px;"; +void Shortcut::appendGeneralItems(QMap > shortcutsMap) +{ + QMap >::iterator it = shortcutsMap.begin(); + for (; it != shortcutsMap.end(); it++) { + QWidget *gWidget = buildGeneralWidget(it.key(), it.value()); + if (gWidget != NULL) { + gWidget->setMaximumWidth(960); + ui->verticalLayout->addWidget(gWidget); } + } +} - QWidget * widget = listWidget->itemWidget(listWidget->item(row)); - DefineShortcutItem * pShortcutItem = dynamic_cast(widget); -// pShortcutItem->widgetComponent()->setStyleSheet(style); -// pShortcutItem->btnComponent()->setStyleSheet(subStyle); +void Shortcut::appendCustomItems() +{ + for (KeyEntry *ckeyEntry : customEntries) { + buildCustomItem(ckeyEntry); } } -void Shortcut::initGeneralItemsStyle(){ - initItemsStyle(ui->generalListWidget); +void Shortcut::buildCustomItem(KeyEntry *nkeyEntry) +{ + QPushButton *customBtn = new QPushButton(); + QHBoxLayout *customHorLayout = new QHBoxLayout(customBtn); + + customBtn->setContextMenuPolicy(Qt::ActionsContextMenu); + customBtn->setFixedHeight(40); + customBtn->setMaximumWidth(960); + customHorLayout->setSpacing(24); + customHorLayout->setContentsMargins(16, 0, 19, 0); + + QLabel *nameLabel = new QLabel(customBtn); + QLabel *bindingLabel = new QLabel(customBtn); + + QFontMetrics fm(nameLabel->font()); + QString nameStr = fm.elidedText(nkeyEntry->nameStr, Qt::ElideRight, 180); + nameLabel->setText(nameStr); + nameLabel->setToolTip(nkeyEntry->nameStr); + + bindingLabel->setText(nkeyEntry->bindingStr); + bindingLabel->setFixedWidth(240); + bindingLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + + const QByteArray styleID(UKUI_STYLE_SCHEMA); + + if (QGSettings::isSchemaInstalled(styleID)) { + QGSettings *styleUKUI = new QGSettings(styleID, QByteArray(), this); + + connect(styleUKUI, &QGSettings::changed, this, [=](const QString &key){ + if (key == "systemFontSize") { + QFontMetrics fontMetrics(nameLabel->font()); + nameLabel->setText(fontMetrics.elidedText(nkeyEntry->nameStr, Qt::ElideRight, 180)); + } + }); + } + + customHorLayout->addWidget(nameLabel); + customHorLayout->addStretch(); + customHorLayout->addWidget(bindingLabel); + + customBtn->setLayout(customHorLayout); + ui->verticalLayout_3->addWidget(customBtn); + + QAction *edit = new QAction(customBtn); + QAction *del = new QAction(customBtn); + + edit->setText(tr("Edit")); + del->setText(tr("Delete")); + // customBtn->addAction(edit); + customBtn->addAction(del); + connect(del, &QAction::triggered, this, [=](){ + customBtn->deleteLater(); + deleteCustomShortcut(nkeyEntry->gsPath); + customEntries.removeOne(nkeyEntry); + }); } -void Shortcut::initCustomItemsStyle(){ - initItemsStyle(ui->customListWidget); +QString Shortcut::keyToUI(QString key) +{ + if (key.contains("+")) { + QStringList keys = key.split("+"); + QString keyToUI = keys.join(" "); + return keyToUI; + } + return key; +} + +QString Shortcut::keyToLib(QString key) +{ + if (key.contains("+")) { + QStringList keys = key.split("+"); + if (keys.count() == 2) { + QString lower = keys.at(1); + QString keyToLib = "<" + keys.at(0) + ">" + lower.toLower(); + qDebug() << "count = 2,keyToLib = " << keyToLib; + return keyToLib; + } else if (keys.count() == 3) { + QString lower = keys.at(2); + QString keyToLib = "<" + keys.at(0) + ">" + "<" + keys.at(1) + ">" + lower.toLower(); + qDebug() << "count = 3,keyToLib = " << keyToLib; + return keyToLib; + } + } + qDebug() << "count = 1,keyToLib = " << key; + return key; } -void Shortcut::createNewShortcut(QString path, QString name, QString exec){ +void Shortcut::createNewShortcut(QString path, QString name, QString exec, QString key) +{ + qDebug() << "createNewShortcut" << path << name << exec << key; QString availablepath; - if (path.isEmpty()){ - availablepath = findFreePath(); //创建快捷键 + if (path.isEmpty()) { + availablepath = findFreePath(); // 创建快捷键 - //更新数据 - KeyEntry * nKeyentry = new KeyEntry; + // 更新数据 + KeyEntry *nKeyentry = new KeyEntry; nKeyentry->gsPath = availablepath; nKeyentry->nameStr = name; - nKeyentry->bindingStr = DEFAULT_BINDING; + nKeyentry->bindingStr = keyToLib(key); nKeyentry->actionStr = exec; customEntries.append(nKeyentry); - /*********刷新界面(添加)******/ buildCustomItem(nKeyentry); - - ui->customListWidget->setFixedHeight(ui->customListWidget->count() * ITEMHEIGH); - - initCustomItemsStyle(); - /******************/ - - } else { - availablepath = path; //更新快捷键 + availablepath = path; // 更新快捷键 - //更新数据 + // 更新数据 int i = 0; - for (; i < customEntries.count(); i++){ - if (customEntries[i]->gsPath == availablepath){ + for (; i < customEntries.count(); i++) { + if (customEntries[i]->gsPath == availablepath) { customEntries[i]->nameStr = name; customEntries[i]->actionStr = exec; break; } } - - //刷新界面(更新) - for (int row = 0; row < ui->customListWidget->count(); row++){ - QListWidgetItem * item = ui->customListWidget->item(row); - if (!QString::compare(item->data(Qt::UserRole).toString(), availablepath)){ - DefineShortcutItem * widgetItem = dynamic_cast(ui->customListWidget->itemWidget(item)); - widgetItem->setShortcutName(name); - KeyEntry * uKeyentry = customEntries.at(i); -// widgetItem->setUserData(Qt::UserRole, uKeyentry); - widgetItem->setProperty("userData", QVariant::fromValue(uKeyentry)); - } - } } -// if (availablepath.isEmpty()){ -// qDebug() << "add custom shortcut failed"; -// return; -// } - const QByteArray id(KEYBINDINGS_CUSTOM_SCHEMA); const QByteArray idd(availablepath.toLatin1().data()); - QGSettings * settings = new QGSettings(id, idd); + QGSettings *settings = new QGSettings(id, idd, this); - settings->set(BINDING_KEY, DEFAULT_BINDING); + settings->set(BINDING_KEY, keyToLib(key)); settings->set(NAME_KEY, name); settings->set(ACTION_KEY, exec); delete settings; + settings = nullptr; } -void Shortcut::deleteCustomShortcut(QString path){ +void Shortcut::deleteCustomShortcut(QString path) +{ if (path.isEmpty()) return; - gboolean ret; - GError ** error = NULL; + QProcess p(0); + QStringList args; - char * fullpath = path.toLatin1().data(); + char *fullpath = path.toLatin1().data(); + QString cmd = "dconf"; - DConfClient * client = dconf_client_new (); - - ret = dconf_client_write_sync (client, fullpath, NULL, NULL, NULL, error); - - if (!ret) - qDebug() << "Delete Custom ShortCut Failed!"; - - g_object_unref (client); -} - -void Shortcut::newBindingRequest(QList keyCode){ - QObject * object = QObject::sender(); - - CustomLineEdit * current = qobject_cast(object); //孙子 - QWidget * widget = current->parentWidget(); - DefineShortcutItem * widgetItem = dynamic_cast(widget->parentWidget()); -// KeyEntry * nkeyEntry = dynamic_cast(widgetItem->userData(Qt::UserRole)); - KeyEntry * nkeyEntry = widgetItem->property("userData").value(); - - QString shortcutString = getBindingName(keyCode); - int len = shortcutString.length(); - //check for unmodified keys - if (nkeyEntry->gsPath.isEmpty()){ //非自定义快捷键的修改 - if (keyCode.count() == 1 && shortcutString.length() <= 1){ - if (shortcutString.contains(QRegExp("[a-z]")) || - shortcutString.contains(QRegExp("[0-9]")) || - keyIsForbidden(shortcutString)){ - const QByteArray iid(nkeyEntry->gsSchema.toLatin1().data()); - QGSettings * settings = new QGSettings(iid); - current->setText(settings->get(nkeyEntry->keyStr).toString()); - current->updateOldShow(settings->get(nkeyEntry->keyStr).toString()); - current->clearFocus(); - qDebug() << "Please try with a key such as Control, Alt or Shift at the same time."; - delete settings; - return; - } - } - - if(shortcutString.isEmpty()){ //fn - qDebug() << "the key is null"; - const QByteArray iid(nkeyEntry->gsSchema.toLatin1().data()); - QGSettings * settings = new QGSettings(iid); - - current->setText(settings->get(nkeyEntry->keyStr).toString()); - current->updateOldShow(settings->get(nkeyEntry->keyStr).toString()); - current->clearFocus(); - delete settings; - return; - } - if(shortcutString.endsWith(">")){ //special key - qDebug() << "end with >"; - const QByteArray iid(nkeyEntry->gsSchema.toLatin1().data()); - QGSettings * settings = new QGSettings(iid); - - current->setText(settings->get(nkeyEntry->keyStr).toString()); - current->updateOldShow(settings->get(nkeyEntry->keyStr).toString()); - current->clearFocus(); - delete settings; - return; - } - /* flag to see if the new accelerator was in use by something */ - for (KeyEntry * ckeyEntry : generalEntries){ - if (shortcutString == ckeyEntry->valueStr){ - const QByteArray iid(nkeyEntry->gsSchema.toLatin1().data()); - QGSettings * settings = new QGSettings(iid); - - current->setText(settings->get(nkeyEntry->keyStr).toString()); - current->updateOldShow(settings->get(nkeyEntry->keyStr).toString()); - current->clearFocus(); - qDebug() << QString("The shortcut \"%1\" is already used for\n\"%2\",please reset!!!").arg(shortcutString).arg(ckeyEntry->keyStr); - delete settings; - return; - } - } - const QByteArray iid(nkeyEntry->gsSchema.toLatin1().data()); - QGSettings * settings = new QGSettings(iid); - - settings->set(nkeyEntry->keyStr, shortcutString); - delete settings; - - //更新 - for (int index = 0; index < generalEntries.count(); index++){ - if (nkeyEntry->keyStr == generalEntries[index]->keyStr){ - generalEntries[index]->valueStr = shortcutString; - } - } - }else { //自定义快捷键的修改 - qDebug() << "custom key"; - - if(shortcutString.isEmpty()){ //fn - current->setText(nkeyEntry->bindingStr); - current->updateOldShow(nkeyEntry->bindingStr); - current->clearFocus(); - qDebug() << "Please try with a valid key."; - return; - } - if(shortcutString.endsWith(">")){ //special key - current->setText(nkeyEntry->bindingStr); - current->updateOldShow(nkeyEntry->bindingStr); - current->clearFocus(); - qDebug() << "Please try with a valid key value"; - return; - } - /* flag to see if the new accelerator was in use by something */ - for (KeyEntry * ckeyEntry : generalEntries){ - if (shortcutString == ckeyEntry->valueStr){ - current->setText(nkeyEntry->bindingStr); - current->updateOldShow(nkeyEntry->bindingStr); - current->clearFocus(); - qDebug() << QString("The shortcut \"%1\" is already used for\n\"%2\",please reset!!!").arg(shortcutString).arg(ckeyEntry->keyStr); - return; - } - } - if (keyCode.count() == 1){ - if (shortcutString.contains(QRegExp("[a-z]")) || - shortcutString.contains(QRegExp("[0-9]")) || - keyIsForbidden(shortcutString)){ - current->setText(nkeyEntry->bindingStr); - current->updateOldShow(nkeyEntry->bindingStr); - current->clearFocus(); - qDebug() << "Please try with a key such as Control, Alt or Shift at the same time."; - return; - } - } - if (keyCode.count() == 2){ - if (shortcutString == "F1"){ - current->setText(nkeyEntry->bindingStr); - current->updateOldShow(nkeyEntry->bindingStr); - current->clearFocus(); - qDebug() << "Please try with a valid key."; - return; - } else if (shortcutString.startsWith("<")){ - int len = shortcutString.length(); - for(int i = 0; i < len; i++){ - qDebug() << "len : " << len << shortcutString.at(i); - if(shortcutString.at(i) == ">"){ - len = len - i - 1; - qDebug() << len; - break; - } - } - if(len > 3) - { - qDebug() << nkeyEntry->bindingStr; - current->setText(nkeyEntry->bindingStr); - current->updateOldShow(nkeyEntry->bindingStr); - current->clearFocus(); - return; - } - } - } - if(keyCode.count() == 3){ - int len = shortcutString.length(); - int count = 0; - for(int i = 0; i < len; i++){ - qDebug() << "len : " << len << shortcutString.at(i); - if(shortcutString.at(i) == ">"){ - count += 1; - if(count == 2){ - len = len - i - 1; - qDebug() << len; - break; - } - } - } - if(len > 3) - { - qDebug() << nkeyEntry->bindingStr; - current->setText(nkeyEntry->bindingStr); - current->updateOldShow(nkeyEntry->bindingStr); - current->clearFocus(); - return; - } - } - - const QByteArray id(KEYBINDINGS_CUSTOM_SCHEMA); - const QByteArray idd(nkeyEntry->gsPath.toLatin1().data()); - QGSettings * settings = new QGSettings(id, idd); - settings->set(BINDING_KEY, shortcutString); - delete settings; - - //更新 - for (int index = 0; index < customEntries.count(); index++){ - if (nkeyEntry->nameStr == customEntries[index]->nameStr){ - customEntries[index]->bindingStr = shortcutString; - } - } - } - - current->setText(shortcutString); - current->updateOldShow(shortcutString); - //已经设置了值,清除焦点不再监听 - current->clearFocus(); -} - -/** - * @brief Shortcut::getBindingName - * @param keyCode - * @return - */ -QString Shortcut::getBindingName(QList keyCode){ - QStringList tmpList; - for (int keycode : keyCode){ - if (keycode >= 16777216 && keycode <= 16777254){ //1677216=Escape; 16777254=ScrollLock - if(keycode == 16777223 || keycode == 16777225){ // 16777223=Delete 16777225=Print - tmpList.append(pKeyMap->keycodeTokeystring(keycode)); - }else { - tmpList.append(QString("<%1>").arg(pKeyMap->keycodeTokeystring(keycode))); - } - } - else if (keycode >= 48 && keycode <= 57){ // 48 = 0; 57 = 9 - QString str = pKeyMap->keycodeTokeystring(keycode); - tmpList.append(str.split("K_").at(1)); - } - else if (keycode >= 65 && keycode <= 90){ - QString str = pKeyMap->keycodeTokeystring(keycode); - tmpList.append(str.toLower()); - } - else - tmpList.append(pKeyMap->keycodeTokeystring(keycode)); - } - return tmpList.join(""); + args.append("reset"); + args.append("-f"); + args.append(fullpath); + p.execute(cmd, args);// command是要执行的命令,args是参数 + qDebug()<<"wait for finish"; + p.waitForFinished(-1); + qDebug()<addFrame){ -// if (event->type() == QEvent::MouseButtonPress){ -// QMouseEvent * mouseEvent = static_cast(event); -// if (mouseEvent->button() == Qt::LeftButton){ -// addDialog->setTitleText(QObject::tr("Add Shortcut")); -// addDialog->exec(); -// return true; -// } else -// return false; -// } -// } -// return QObject::eventFilter(watched, event); -//} - -//bool Shortcut::event(QEvent *event){ -// qDebug() << "---111--->"; -// if (event->type() == QEvent::MouseButtonPress){ -// qDebug() << "-------------->"; -// QMouseEvent * mouseEvent = dynamic_cast(event); -// if (!ui->customListWidget->geometry().contains(mouseEvent->globalX(), mouseEvent->globalY())){ -// qDebug() << "=============>"; -// emit hideDelBtn(); -// } -// } -// return QObject::event(event); -//} - +void Shortcut::shortcutChangedSlot() +{ + qDebug() << "receive cloud service signal"; + while (ui->verticalLayout_3->count()) { + QWidget *p = ui->verticalLayout_3->takeAt(0)->widget(); + ui->verticalLayout_3->removeWidget(p); + p->deleteLater(); + } + isCloudService = true; + initFunctionStatus(); +} diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/shortcut.h ukui-control-center-3.0.3/plugins/devices/shortcut/shortcut.h --- ukui-control-center-2.0.3/plugins/devices/shortcut/shortcut.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/shortcut.h 2021-05-20 13:08:14.000000000 +0000 @@ -22,40 +22,25 @@ #include #include - +#include #include #include +#include +#include #include "shell/interface.h" - #include "keymap.h" #include "addshortcutdialog.h" #include "getshortcutworker.h" -#include "showallshortcut.h" #include "HoverWidget/hoverwidget.h" #include "ImageUtil/imageutil.h" QT_BEGIN_NAMESPACE -namespace Ui { class Shortcut; } +namespace Ui { +class Shortcut; +} QT_END_NAMESPACE -typedef struct _KeyEntry KeyEntry; - -struct _KeyEntry{ -// int keyval; - QString gsSchema; - QString keyStr; - QString valueStr; - QString descStr; - - QString gsPath; - QString nameStr; - QString bindingStr; - QString actionStr; -}; - -Q_DECLARE_METATYPE(KeyEntry *) - class Shortcut : public QObject, CommonInterface { Q_OBJECT @@ -71,56 +56,53 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); void setupComponent(); void setupConnect(); void initFunctionStatus(); - void appendGeneralItems(); + void appendGeneralItems(QMap > shortcutsMap); void appendCustomItems(); - void buildCustomItem(KeyEntry * nkeyEntry); - - void initItemsStyle(QListWidget * listWidget); - void initGeneralItemsStyle(); - void initCustomItemsStyle(); + void buildCustomItem(KeyEntry *nkeyEntry); + QWidget *buildGeneralWidget(QString schema, QMap subShortcutsMap); - void createNewShortcut(QString path, QString name, QString exec); + void createNewShortcut(QString path, QString name, QString exec, QString key); void deleteCustomShortcut(QString path); - void newBindingRequest(QList keyCode); - - QString getBindingName(QList keyCode); bool keyIsForbidden(QString key); + void connectToServer(); + QMap MergerOfTheSamekind(QMap desktopMap); -public: - QStringList showList; - -protected: -// bool event(QEvent *event); -// bool eventFilter(QObject *watched, QEvent *event); + QString keyToUI(QString key); + QString keyToLib(QString key); private: Ui::Shortcut *ui; QString pluginName; int pluginType; - QWidget * pluginWidget; + QWidget *pluginWidget; HoverWidget *addWgt; private: - QThread * pThread; - GetShortcutWorker * pWorker; + QThread *pThread; + GetShortcutWorker *pWorker; - KeyMap * pKeyMap; + KeyMap *pKeyMap; - addShortcutDialog * addDialog; - ShowAllShortcut * showDialog; + QDBusInterface *cloudInterface; + bool isCloudService; -Q_SIGNALS: - void hideDelBtn(); + bool mFirstLoad; +private slots: + void shortcutChangedSlot(); +Q_SIGNALS: + void hideDelBtn(); }; #endif // SHORTCUT_H diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/shortcut.pro ukui-control-center-3.0.3/plugins/devices/shortcut/shortcut.pro --- ukui-control-center-2.0.3/plugins/devices/shortcut/shortcut.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/shortcut.pro 2021-05-20 13:08:14.000000000 +0000 @@ -1,8 +1,9 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) -QT += widgets +QT += widgets dbus KXmlGui KGlobalAccel greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = lib @@ -36,8 +37,7 @@ getshortcutworker.cpp \ keymap.cpp \ realizeshortcutwheel.cpp \ - shortcut.cpp \ - showallshortcut.cpp + shortcut.cpp HEADERS += \ addshortcutdialog.h \ @@ -46,12 +46,10 @@ getshortcutworker.h \ keymap.h \ realizeshortcutwheel.h \ - shortcut.h \ - showallshortcut.h + shortcut.h FORMS += \ addshortcutdialog.ui \ - shortcut.ui \ - showallshortcut.ui + shortcut.ui INSTALLS += target diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/shortcut.ui ukui-control-center-3.0.3/plugins/devices/shortcut/shortcut.ui --- ukui-control-center-2.0.3/plugins/devices/shortcut/shortcut.ui 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/shortcut.ui 2021-05-20 13:08:14.000000000 +0000 @@ -10,13 +10,22 @@ 664 + + + 550 + 0 + + + + + 960 + 16777215 + + Shortcut - - - 8 - + 0 @@ -26,258 +35,110 @@ 32 - - 48 - - - - - 550 - 0 - + + + + 0 + 0 + - - - 960 - 16777215 - + + System Shortcut + + + + + + + + + + + 0 + 0 + + + + Custom Shortcut + + + + + + + 6 + + + 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - + + + + 2 + + + + + + + + 0 + 60 + + + + + 16777215 + 60 + + + - 16 + 8 + + + 0 + + + 0 + + + 0 - 10 + 0 - - - - 0 - 0 - - - - System Shortcut - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 8 - - - - - - + 0 - - - - - 136 - 36 - - - - - 16777215 - 36 - - - - Show all shortcut - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 136 - 36 - - - - - 136 - 36 - - - - Reset default - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 32 - - - - - - - - - 0 - 0 - - - - Custom Shortcut - - - - - - - 8 + + 0 - + 0 - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - 8 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 8 - - - 0 - - - 0 - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 32 - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - -
+
+
+ +
+ + + + Qt::Vertical + + + + 17 + 231 + + +
diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/showallshortcut.cpp ukui-control-center-3.0.3/plugins/devices/shortcut/showallshortcut.cpp --- ukui-control-center-2.0.3/plugins/devices/shortcut/showallshortcut.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/showallshortcut.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,344 +0,0 @@ -/* -*- 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 "showallshortcut.h" -#include "ui_showallshortcut.h" -#include "commonComponent/ImageUtil/imageutil.h" - - -#include -#include -#include - -#include - -#include "realizeshortcutwheel.h" - -/* qt会将glib里的signals成员识别为宏,所以取消该宏 - * 后面如果用到signals时,使用Q_SIGNALS代替即可 - **/ -#ifdef signals -#undef signals -#endif - -extern "C" { -#include -#include -} - -#define TITLEWIDGETHEIGH 36 - -extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); - -ShowAllShortcut::ShowAllShortcut(QWidget *parent) : - QDialog(parent), - ui(new Ui::ShowAllShortcut) -{ - ui->setupUi(this); - setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); - setAttribute(Qt::WA_TranslucentBackground); - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); - - - -// ui->frame->setStyleSheet("QFrame{background: #ffffff; border: none; border-radius: 6px;}"); - - //关闭按钮在右上角,窗体radius 6px,所以按钮只得6px -// ui->closeBtn->setStyleSheet("QPushButton#closeBtn{background: #ffffff; border: none; border-radius: 6px;}" -// "QPushButton:hover:!pressed#closeBtn{background: #FA6056; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}" -// "QPushButton:hover:pressed#closeBtn{background: #E54A50; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}"); - - ui->closeBtn->setIcon(QIcon(QPixmap("://img/titlebar/close.svg"))); - - connect(ui->closeBtn, &QPushButton::clicked, [=](bool checked){ - Q_UNUSED(checked) - close(); - }); - -} - -ShowAllShortcut::~ShowAllShortcut() -{ - delete ui; -} - -void ShowAllShortcut::buildComponent(QMap > shortcutsMap){ - ui->searchLineEdit->setVisible(false); - if (ui->scrollArea->widget()){ - ui->scrollArea->takeWidget(); - delete ui->scrollArea->widget(); - } - - QWidget * baseWidget = new QWidget; - baseWidget->setAttribute(Qt::WA_DeleteOnClose); - baseWidget->setFixedWidth(ui->scrollArea->width()); - baseWidget->setStyleSheet("QWidget{background: palette(base);/* border-radius: 6px;*/ }"); - - QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget); - baseVerLayout->setSpacing(0); - baseVerLayout->setMargin(0); - - QMap>::iterator it = shortcutsMap.begin(); - for (; it != shortcutsMap.end(); it++){ - - ClickWidget * tWidget; - if (it.key() == "Desktop") - tWidget = new ClickWidget(tr("Desktop")); - else - tWidget = new ClickWidget(it.key()); - - if (it == shortcutsMap.begin()){ -// tWidget->setStyleSheet("ClickWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); - } else{ -// tWidget->setStyleSheet("ClickWidget{background: #F4F4F4;}"); - } - - QWidget * gWidget = buildGeneralWidget(it.key(), it.value()); - - if ((it+1) == shortcutsMap.end()) - connect(tWidget, &ClickWidget::widgetClicked, [=](bool checked){ - gWidget->setVisible(checked); - if (tWidget->checked()){ -// tWidget->setStyleSheet("ClickWidget{background: #F4F4F4;}"); - } else { -// tWidget->setStyleSheet("ClickWidget{background: #F4F4F4; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); - } - }); - else - connect(tWidget, &ClickWidget::widgetClicked, [=](bool checked){ - gWidget->setVisible(checked); - }); - - - baseVerLayout->addWidget(tWidget); - baseVerLayout->addWidget(gWidget); - } - baseVerLayout->addStretch(); - - ui->scrollArea->setWidget(baseWidget); - -} - -QWidget * ShowAllShortcut::buildTitleWidget(QString tName){ - QWidget * titleWidget = new QWidget; - titleWidget->setAttribute(Qt::WA_DeleteOnClose); - titleWidget->setFixedHeight(TITLEWIDGETHEIGH); -// titleWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - - QHBoxLayout * titleHorLayout = new QHBoxLayout(titleWidget); - titleHorLayout->setSpacing(0); - titleHorLayout->setContentsMargins(16, 0, 32, 0); - - QLabel * titleNameLabel = new QLabel(titleWidget); - if (tName == "Desktop") - titleNameLabel->setText(tr("Desktop")); - else - titleNameLabel->setText(tName); - - QPushButton * directionBtn = new QPushButton(titleWidget); - directionBtn->setFixedSize(16, 16); - directionBtn->setCheckable(true); - - titleHorLayout->addWidget(titleNameLabel); - titleHorLayout->addStretch(); - titleHorLayout->addWidget(directionBtn); - - titleWidget->setLayout(titleHorLayout); - - return titleWidget; -} - -QWidget * ShowAllShortcut::buildGeneralWidget(QString schema, QMap subShortcutsMap){ - - GSettingsSchema * pSettings; - QString domain; - - if (schema == "Desktop"){ - pSettings = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory("/usr/share/glib-2.0/schemas/", g_settings_schema_source_get_default(), FALSE, NULL), - KEYBINDINGS_DESKTOP_SCHEMA, - FALSE); - domain = "ukui-settings-daemon"; - - } else if (schema == "System"){ - pSettings = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory("/usr/share/glib-2.0/schemas/", g_settings_schema_source_get_default(), FALSE, NULL), - KEYBINDINGS_SYSTEM_SCHEMA, - FALSE); - domain = "gsettings-desktop-schemas"; - } - - QWidget * pWidget = new QWidget; - pWidget->setAttribute(Qt::WA_DeleteOnClose); -// pWidget->setStyleSheet("QWidget{background: #ffffff; border: none;}"); - QVBoxLayout * pVerLayout = new QVBoxLayout(pWidget); - pVerLayout->setSpacing(2); - pVerLayout->setMargin(0); - - pWidget->setLayout(pVerLayout); - - QMap::iterator it = subShortcutsMap.begin(); - - for (; it != subShortcutsMap.end(); it++){ - - QWidget * gWidget = new QWidget; - gWidget->setFixedHeight(TITLEWIDGETHEIGH); - gWidget->setStyleSheet("QWidget{background: palette(button); border: none;}"); - - QHBoxLayout * gHorLayout = new QHBoxLayout(gWidget); - gHorLayout->setSpacing(0); - gHorLayout->setContentsMargins(16, 0, 32, 0); - - // - QByteArray ba = domain.toLatin1(); - QByteArray ba1 = it.key().toLatin1(); - - GSettingsSchemaKey * keyObj = g_settings_schema_get_key(pSettings, ba1.data()); - - char * i18nKey; - QLabel * nameLabel = new QLabel(gWidget); - i18nKey = const_cast(g_dgettext(ba.data(), g_settings_schema_key_get_summary(keyObj))); - nameLabel->setText(QString(i18nKey)); - - QLabel * bindingLabel = new QLabel(gWidget); - bindingLabel->setText(it.value()); - - gHorLayout->addWidget(nameLabel); - gHorLayout->addStretch(); - gHorLayout->addWidget(bindingLabel); - - gWidget->setLayout(gHorLayout); - - - pVerLayout->addWidget(gWidget); - - g_settings_schema_key_unref(keyObj); - } - - g_settings_schema_unref(pSettings); - - return pWidget; - -} - - -void ShowAllShortcut::paintEvent(QPaintEvent *event) { - Q_UNUSED(event); - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); - QPainterPath rectPath; - rectPath.addRoundedRect(this->rect().adjusted(10, 10, -10, -10), 6, 6); - - // 画一个黑底 - QPixmap pixmap(this->rect().size()); - pixmap.fill(Qt::transparent); - QPainter pixmapPainter(&pixmap); - pixmapPainter.setRenderHint(QPainter::Antialiasing); - pixmapPainter.setPen(Qt::transparent); - pixmapPainter.setBrush(Qt::black); - - pixmapPainter.drawPath(rectPath); - pixmapPainter.end(); - - // 模糊这个黑底 - QImage img = pixmap.toImage(); - - qt_blurImage(img, 10, false, false); - // 挖掉中心 - pixmap = QPixmap::fromImage(img); - QPainter pixmapPainter2(&pixmap); - pixmapPainter2.setRenderHint(QPainter::Antialiasing); - pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); - pixmapPainter2.setPen(Qt::transparent); - pixmapPainter2.setBrush(Qt::transparent); - pixmapPainter2.drawPath(rectPath); - - // 绘制阴影 - p.drawPixmap(this->rect(), pixmap, pixmap.rect()); - // 绘制一个背景 - p.save(); - p.fillPath(rectPath,palette().color(QPalette::Base)); - p.restore(); -} - -ClickWidget::ClickWidget(QString name){ - setAttribute(Qt::WA_DeleteOnClose); - setFixedHeight(TITLEWIDGETHEIGH); - - QHBoxLayout * titleHorLayout = new QHBoxLayout(this); - titleHorLayout->setSpacing(0); - titleHorLayout->setContentsMargins(16, 0, 32, 0); - - QLabel * titleNameLabel = new QLabel(this); - titleNameLabel->setText(name); -// titleNameLabel->setStyleSheet("background: #F4F4F4;"); - - directionBtn = new QPushButton(this); - directionBtn->setFixedSize(16, 16); - directionBtn->setCheckable(true); - directionBtn->setChecked(true); - directionBtn->setStyleSheet("QPushButton{background: palette(button); border: none;}"); - - QPixmap pixUP = ImageUtil::loadSvg(":/img/plugins/shortcut/up.svg", "white", 24); - QPixmap pixdwon = ImageUtil::loadSvg(":/img/plugins/shortcut/down.svg", "white", 24); - - directionBtn->setIcon(pixUP); - connect(directionBtn, &QPushButton::toggled, [=](bool checked){ - if (checked) { - directionBtn->setIcon(pixUP); - } else { - directionBtn->setIcon(pixdwon); - } - }); - - connect(directionBtn, &QPushButton::clicked, this, &ClickWidget::widgetClicked); - - titleHorLayout->addWidget(titleNameLabel); - titleHorLayout->addStretch(); - titleHorLayout->addWidget(directionBtn); - - setLayout(titleHorLayout); -} - -bool ClickWidget::checked(){ - return directionBtn->isChecked(); -} - -void ClickWidget::mousePressEvent(QMouseEvent *e){ - Q_UNUSED(e) - - directionBtn->setChecked(!directionBtn->isChecked()); - - emit widgetClicked(directionBtn->isChecked()); -} - -void ClickWidget::paintEvent(QPaintEvent *e){ - Q_UNUSED(e) - - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); -} - diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/showallshortcut.h ukui-control-center-3.0.3/plugins/devices/shortcut/showallshortcut.h --- ukui-control-center-2.0.3/plugins/devices/shortcut/showallshortcut.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/showallshortcut.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,75 +0,0 @@ -/* -*- 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 SHOWALLSHORTCUT_H -#define SHOWALLSHORTCUT_H - -#include -#include - -namespace Ui { -class ShowAllShortcut; -} - -class ClickWidget : public QWidget -{ - Q_OBJECT - -public: - explicit ClickWidget(QString name); - ~ClickWidget(){} - -public: - bool checked(); - -protected: - void mousePressEvent(QMouseEvent * e); - void paintEvent(QPaintEvent * e); - -private: - QPushButton * directionBtn; - -Q_SIGNALS: - void widgetClicked(bool checked); - -}; - -class ShowAllShortcut : public QDialog -{ - Q_OBJECT - -public: - explicit ShowAllShortcut(QWidget *parent = nullptr); - ~ShowAllShortcut(); - -public: - void buildComponent(QMap> shortcutsMap); - - QWidget * buildTitleWidget(QString tName); - QWidget * buildGeneralWidget(QString schema, QMap subShortcutsMap); - -protected: - void paintEvent(QPaintEvent *); - - -private: - Ui::ShowAllShortcut *ui; -}; - -#endif // SHOWALLSHORTCUT_H diff -Nru ukui-control-center-2.0.3/plugins/devices/shortcut/showallshortcut.ui ukui-control-center-3.0.3/plugins/devices/shortcut/showallshortcut.ui --- ukui-control-center-2.0.3/plugins/devices/shortcut/showallshortcut.ui 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/shortcut/showallshortcut.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,258 +0,0 @@ - - - ShowAllShortcut - - - - 0 - 0 - 505 - 600 - - - - - 0 - 0 - - - - - 16777215 - 600 - - - - Dialog - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 16777215 - 600 - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 9 - - - 9 - - - 0 - - - - - 0 - - - 0 - - - - - 0 - - - 8 - - - 8 - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - - - - - - 8 - - - 32 - - - 16 - - - 32 - - - 32 - - - - - - 0 - 0 - - - - System Shortcuts - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 16 - - - - - - - - - 374 - 36 - - - - - 374 - 36 - - - - - - - - - 0 - 0 - - - - - 430 - 400 - - - - - 430 - 400 - - - - true - - - - - 0 - 0 - 428 - 398 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - - diff -Nru ukui-control-center-2.0.3/plugins/devices/touchpad/touchpad.cpp ukui-control-center-3.0.3/plugins/devices/touchpad/touchpad.cpp --- ukui-control-center-2.0.3/plugins/devices/touchpad/touchpad.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/touchpad/touchpad.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -35,81 +35,33 @@ #include } -#define TOUCHPAD_SCHEMA "org.ukui.peripherals-touchpad" -#define ACTIVE_TOUCHPAD_KEY "touchpad-enabled" +#define TOUCHPAD_SCHEMA "org.ukui.peripherals-touchpad" +#define ACTIVE_TOUCHPAD_KEY "touchpad-enabled" #define DISABLE_WHILE_TYPING_KEY "disable-while-typing" -#define TOUCHPAD_CLICK_KEY "tap-to-click" -#define V_EDGE_KEY "vertical-edge-scrolling" -#define H_EDGE_KEY "horizontal-edge-scrolling" -#define V_FINGER_KEY "vertical-two-finger-scrolling" -#define H_FINGER_KEY "horizontal-two-finger-scrolling" -#define N_SCROLLING "none" +#define TOUCHPAD_CLICK_KEY "tap-to-click" +#define V_EDGE_KEY "vertical-edge-scrolling" +#define H_EDGE_KEY "horizontal-edge-scrolling" +#define V_FINGER_KEY "vertical-two-finger-scrolling" +#define H_FINGER_KEY "horizontal-two-finger-scrolling" +#define N_SCROLLING "none" bool findSynaptics(); bool _supportsXinputDevices(); XDevice* _deviceIsTouchpad (XDeviceInfo * deviceinfo); bool _deviceHasProperty (XDevice * device, const char * property_name); -Touchpad::Touchpad() +Touchpad::Touchpad() : mFirstLoad(true) { - ui = new Ui::Touchpad; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Touchpad"); pluginType = DEVICES; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - -// QString qss; -// QFile QssFile("://combox.qss"); -// QssFile.open(QFile::ReadOnly); - -// if (QssFile.isOpen()){ -// qss = QLatin1String(QssFile.readAll()); -// QssFile.close(); -// } - -// pluginWidget->setStyleSheet("background: #ffffff;"); - - ui->scrollingTypeComBox->setView(new QListView()); -// ui->scrollingTypeComBox->setStyleSheet(qss); - -// ui->enableWidget->setStyleSheet("QWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); -// ui->typingWidget->setStyleSheet("QWidget{background: #F4F4F4;}"); -// ui->clickWidget->setStyleSheet("QWidget{background: #F4F4F4;}"); -// ui->scrollingWidget->setStyleSheet("QWidget{background: #F4F4F4; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); - - const QByteArray id(TOUCHPAD_SCHEMA); - - if (QGSettings::isSchemaInstalled(TOUCHPAD_SCHEMA)){ - tpsettings = new QGSettings(id); - setupComponent(); - if (findSynaptics()){ - qDebug() << "Touch Devices Available"; - ui->tipLabel->hide(); - initTouchpadStatus(); - } else { - ui->clickFrame->hide(); - ui->enableFrame->hide(); - ui->scrollingFrame->hide(); - ui->typingFrame->hide(); - } - } - - - } Touchpad::~Touchpad() { - delete ui; - if (QGSettings::isSchemaInstalled(TOUCHPAD_SCHEMA)){ - delete tpsettings; + if (!mFirstLoad) { + delete ui; + ui = nullptr; } - - } QString Touchpad::get_plugin_name(){ @@ -121,6 +73,39 @@ } QWidget *Touchpad::get_plugin_ui(){ + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::Touchpad; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + //~ contents_path /touchpad/Touchpad Settings + ui->titleLabel->setText(tr("Touchpad Settings")); + + initTitleLabel(); + initWaylandDbus(); + isWaylandPlatform(); + setupComponent(); + ui->scrollingTypeComBox->setView(new QListView()); + const QByteArray id(TOUCHPAD_SCHEMA); + + if (QGSettings::isSchemaInstalled(TOUCHPAD_SCHEMA)){ + tpsettings = new QGSettings(id, QByteArray(), this); + initConnection(); + if (findSynaptics() || mExistTouchpad) { + qDebug() << "Touch Devices Available"; + ui->tipLabel->hide(); + initTouchpadStatus(); + } else { + ui->clickFrame->hide(); + ui->enableFrame->hide(); + ui->scrollingFrame->hide(); + ui->typingFrame->hide(); + } + } + } return pluginWidget; } @@ -128,28 +113,44 @@ } +const QString Touchpad::name() const { + + return QStringLiteral("touchpad"); +} + +void Touchpad::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); +} + void Touchpad::setupComponent(){ - // enableBtn = new SwitchButton(pluginWidget); ui->enableHorLayout->addWidget(enableBtn); - // typingBtn = new SwitchButton(pluginWidget); ui->typingHorLayout->addWidget(typingBtn); - // clickBtn = new SwitchButton(pluginWidget); ui->clickHorLayout->addWidget(clickBtn); - // - ui->scrollingTypeComBox->addItem(tr("Disable rolling"), N_SCROLLING); - ui->scrollingTypeComBox->addItem(tr("Vertical edge scrolling"), V_EDGE_KEY); - ui->scrollingTypeComBox->addItem(tr("Horizontal edge scrolling"), H_EDGE_KEY); - ui->scrollingTypeComBox->addItem(tr("Vertical two-finger scrolling"), V_FINGER_KEY); - ui->scrollingTypeComBox->addItem(tr("Horizontal two-finger scrolling"), H_FINGER_KEY); + if (mIsWayland) { + ui->scrollingTypeComBox->addItem(tr("Disable rolling"), N_SCROLLING); + ui->scrollingTypeComBox->addItem(tr("Edge scrolling"), V_EDGE_KEY); + ui->scrollingTypeComBox->addItem(tr("Two-finger scrolling"), V_FINGER_KEY); + } else { + ui->scrollingTypeComBox->addItem(tr("Disable rolling"), N_SCROLLING); + ui->scrollingTypeComBox->addItem(tr("Vertical edge scrolling"), V_EDGE_KEY); + ui->scrollingTypeComBox->addItem(tr("Horizontal edge scrolling"), H_EDGE_KEY); + ui->scrollingTypeComBox->addItem(tr("Vertical two-finger scrolling"), V_FINGER_KEY); + ui->scrollingTypeComBox->addItem(tr("Horizontal two-finger scrolling"), H_FINGER_KEY); + } +} +void Touchpad::initConnection() { connect(enableBtn, &SwitchButton::checkedChanged, [=](bool checked){ tpsettings->set(ACTIVE_TOUCHPAD_KEY, checked); + setModuleVisible(checked); }); connect(typingBtn, &SwitchButton::checkedChanged, [=](bool checked){ @@ -160,22 +161,25 @@ tpsettings->set(TOUCHPAD_CLICK_KEY, checked); }); -#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 8) connect(ui->scrollingTypeComBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ -#else - connect(ui->scrollingTypeComBox, static_cast(&QComboBox::currentIndexChanged), [=](int index){ -#endif Q_UNUSED(index) //旧滚动类型设置为false,跳过N_SCROLLING QString oldType = _findKeyScrollingType(); - if (QString::compare(oldType, N_SCROLLING) != 0) - tpsettings->set(oldType, false); + if (QString::compare(oldType, N_SCROLLING) != 0) { + tpsettings->set(oldType, false); + } //新滚动类型设置为true,跳过N_SCROLLING QString data = ui->scrollingTypeComBox->currentData().toString(); if (QString::compare(data, N_SCROLLING) != 0) tpsettings->set(data, true); + if (QString::compare(data, N_SCROLLING) == 0) { + tpsettings->set(V_EDGE_KEY,false); + tpsettings->set(H_EDGE_KEY,false); + tpsettings->set(V_FINGER_KEY,false); + tpsettings->set(H_FINGER_KEY,false); + } }); } @@ -183,6 +187,7 @@ //初始化启用按钮 enableBtn->blockSignals(true); enableBtn->setChecked(tpsettings->get(ACTIVE_TOUCHPAD_KEY).toBool()); + setModuleVisible(tpsettings->get(ACTIVE_TOUCHPAD_KEY).toBool()); enableBtn->blockSignals(false); // 初始化打字禁用 @@ -213,6 +218,66 @@ return N_SCROLLING; } +void Touchpad::setModuleVisible(bool visible) { + ui->typingFrame->setVisible(visible); + ui->clickFrame->setVisible(visible); + ui->scrollingFrame->setVisible(visible); +} + +void Touchpad::isWaylandPlatform() { + QString sessionType = getenv("XDG_SESSION_TYPE"); + if (!sessionType.compare(kSession, Qt::CaseSensitive)) { + mIsWayland = true; + } else { + mIsWayland = false; + } +} + +void Touchpad::initWaylandDbus() { + + mWaylandIface = new QDBusInterface("org.ukui.KWin", + "/org/ukui/KWin/InputDevice", + "org.ukui.KWin.InputDeviceManager", + QDBusConnection::sessionBus(), + this); + if (mWaylandIface->isValid()) { + initWaylandTouchpadStatus(); + } +} + +void Touchpad::initWaylandTouchpadStatus() { + + QVariant deviceReply = mWaylandIface->property("devicesSysNames"); + + if (deviceReply.isValid()) { + QStringList deviceList = deviceReply.toStringList(); + for (QString device : deviceList) { + QDBusInterface *deviceIface = new QDBusInterface("org.ukui.KWin", + "/org/ukui/KWin/InputDevice/"+ device, + "org.ukui.KWin.InputDevice", + QDBusConnection::sessionBus(), + this); + if (deviceIface->isValid() && + deviceIface->property("touchpad").toBool()) { + mExistTouchpad = true; + return; + } + } + } + mExistTouchpad = false; +} + +void Touchpad::initWaylandConnection() { + + connect(enableBtn, &SwitchButton::checkedChanged, this, [=](bool checked){ + mDeviceIface->setProperty("enabled", checked); + }); + + connect(clickBtn, &SwitchButton::checkedChanged, this, [=](bool checked){ + mDeviceIface->setProperty("tapToClick", checked); + }); +} + bool findSynaptics(){ XDeviceInfo *device_info; int n_devices; diff -Nru ukui-control-center-2.0.3/plugins/devices/touchpad/touchpad.h ukui-control-center-3.0.3/plugins/devices/touchpad/touchpad.h --- ukui-control-center-2.0.3/plugins/devices/touchpad/touchpad.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/touchpad/touchpad.h 2021-04-14 01:27:20.000000000 +0000 @@ -26,10 +26,16 @@ #include #include +#include +#include +#include +#include #include "shell/interface.h" #include "SwitchButton/switchbutton.h" +const QString kSession = "wayland"; + namespace Ui { class Touchpad; } @@ -48,14 +54,25 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); void setupComponent(); + void initConnection(); void initTouchpadStatus(); QString _findKeyScrollingType(); private: + void setModuleVisible(bool visible); + void isWaylandPlatform(); + + void initWaylandDbus(); + void initWaylandTouchpadStatus(); + void initWaylandConnection(); + +private: Ui::Touchpad *ui; QString pluginName; @@ -68,6 +85,14 @@ SwitchButton * clickBtn; QGSettings * tpsettings; + + bool mFirstLoad; + bool mIsWayland; + bool mExistTouchpad; + + QDBusInterface *mWaylandIface; + QDBusInterface *mDeviceIface; + }; #endif // TOUCHPAD_H diff -Nru ukui-control-center-2.0.3/plugins/devices/touchpad/touchpad.pro ukui-control-center-3.0.3/plugins/devices/touchpad/touchpad.pro --- ukui-control-center-2.0.3/plugins/devices/touchpad/touchpad.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/devices/touchpad/touchpad.pro 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) -QT += widgets x11extras +QT += widgets x11extras dbus greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -29,6 +29,8 @@ C++11 PKGCONFIG += gsettings-qt \ + xi \ + x11 DEFINES += QT_DEPRECATED_WARNINGS diff -Nru ukui-control-center-2.0.3/plugins/messages-task/about/about.cpp ukui-control-center-3.0.3/plugins/messages-task/about/about.cpp --- ukui-control-center-2.0.3/plugins/messages-task/about/about.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/about/about.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -21,249 +21,355 @@ #include "about.h" #include "ui_about.h" -#include "memoryentry.h" + +#include +#include +#include + +#ifdef Q_OS_LINUX +#include +#elif defined(Q_OS_FREEBSD) +#include +#include +#endif #include #include #include #include +#include -const QString TYPEVERSION = "Kylin V10"; -const QString UbuntuVesion = "Ubuntu 20.04 LTS"; -const QString UbuntuVesionEnhance = "Ubuntu 20.04.1 LTS"; - -About::About() -{ - ui = new Ui::About; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); +#define THEME_STYLE_SCHEMA "org.ukui.style" +#define STYLE_NAME_KEY "style-name" +#define CONTAIN_STYLE_NAME_KEY "styleName" +#define UKUI_DEFAULT "ukui-default" +#define UKUI_DARK "ukui-dark" + +const QString vTen = "v10"; +const QString vTenEnhance = "v10.1"; +const QString vFour = "v4"; +About::About() : mFirstLoad(true) +{ + //~ contents_path /about/About pluginName = tr("About"); pluginType = NOTICEANDTASKS; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - _data_init(); - - setupDesktopComponent(); - setupKernelCompenent(); - setupVersionCompenent(); - setupSerialComponent(); } About::~About() { - delete ui; -// delete interface; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } } -QString About::get_plugin_name(){ +QString About::get_plugin_name() +{ return pluginName; } -int About::get_plugin_type(){ +int About::get_plugin_type() +{ return pluginType; } -QWidget *About::get_plugin_ui(){ +QWidget *About::get_plugin_ui() +{ + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::About; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + initTitleLabel(); + initSearchText(); + initActiveDbus(); + setupDesktopComponent(); + setupVersionCompenent(); + setupSerialComponent(); + setupKernelCompenent(); + } + return pluginWidget; } -void About::plugin_delay_control(){ - +void About::plugin_delay_control() +{ } -void About::_data_init(){ - QStringList infoList = computerinfo.split("\n\n"); - QString available; - if (infoList.length() > 1){ - available = infoList.at(1); - } - else { - available = ""; - } - if (available != ""){ - for (QString line : available.split("\n")){ - if (!line.contains(":")) - continue; - QStringList lineList = line.split(":"); - infoMap.insert(lineList.at(0).simplified(), lineList.at(1).simplified()); - } - } +const QString About::name() const +{ + return QStringLiteral("about"); } -void About::setupDesktopComponent() { - //获取当前桌面环境 +void About::setupDesktopComponent() +{ + // 获取当前桌面环境 QString dEnv; - foreach (dEnv, QProcess::systemEnvironment()){ + foreach (dEnv, QProcess::systemEnvironment()) { if (dEnv.startsWith("XDG_CURRENT_DESKTOP")) break; } - //设置当前桌面环境信息 + // 设置当前桌面环境信息 if (!dEnv.isEmpty()) { QString desktop = dEnv.section("=", -1, -1); - ui->desktopContent->setText(desktop); + if (desktop.contains("UKUI", Qt::CaseInsensitive)) { + ui->desktopContent->setText("UKUI"); + } else { + ui->desktopContent->setText(desktop); + } } -// QProcess *userPro = new QProcess(); -// userPro->start("whoami"); -// userPro->waitForFinished(); - -// std::string output = userPro->readAll().toStdString(); - QString name = qgetenv("USER"); if (name.isEmpty()) { name = qgetenv("USERNAME"); } - ui->userContent->setText(name); } -void About::setupKernelCompenent() { - QString kernal = QSysInfo::kernelType() + " " + QSysInfo::kernelVersion(); - QString diskSize; +void About::setupKernelCompenent() +{ QString memorySize; QString cpuType; - //ubuntukylin youker DBus interface - QDBusInterface *youkerInterface; - for (int i = 0; i < 2; i++) { - youkerInterface = new QDBusInterface("com.kylin.assistant.systemdaemon", - "/com/kylin/assistant/systemdaemon", - "com.kylin.assistant.systemdaemon", - QDBusConnection::systemBus()); - } - if (!youkerInterface->isValid()) { - qCritical() << "Create youker Interface Failed When Get Computer info: " << QDBusConnection::systemBus().lastError(); - return; - } + QString kernal = QSysInfo::kernelType() + " " + QSysInfo::kernelVersion(); + memorySize = getTotalMemory(); - QDBusReply> diskinfo; - diskinfo = youkerInterface ->call("get_harddisk_info"); - if (!diskinfo.isValid()) { - qDebug()<<"diskinfo is invalid"< res = diskinfo.value(); - diskSize = res["DiskCapacity"].toString(); - if (diskSize.contains("<1_1>")) { - int index = diskSize.indexOf("<1_1>"); - QString disk1 = diskSize.left(index); - QString disk2 = diskSize.mid(index + 5, diskSize.length() - index - 5); - diskSize = tr("Disk One:") + disk1 + " " + tr("Disk Two:")+disk2; - } + ui->kernalContent->setText(kernal); + ui->memoryContent->setText(memorySize); + + QDBusInterface youkerInterface("com.kylin.assistant.systemdaemon", + "/com/kylin/assistant/systemdaemon", + "com.kylin.assistant.systemdaemon", + QDBusConnection::systemBus()); + if (!youkerInterface.isValid()) { + qCritical() << "Create youker Interface Failed When Get Computer info: " << + QDBusConnection::systemBus().lastError(); + return; } - QDBusReply> cpuinfo; - cpuinfo = youkerInterface ->call("get_cpu_info"); - if (!diskinfo.isValid()) { - qDebug()<<"cpuinfo is invalid"< > cpuinfo; + cpuinfo = youkerInterface.call("get_cpu_info"); + if (!cpuinfo.isValid()) { + qDebug() << "cpuinfo is invalid" << endl; } else { QMap res = cpuinfo.value(); cpuType = res["CpuVersion"].toString(); } - MemoryEntry * memoryInfo = new MemoryEntry; - QStringList memory = memoryInfo->totalMemory(); - memorySize = memorySize + memory.at(0) + "(" + memory.at(1) + tr(" available") + ")"; - ui->cpuContent->setText(cpuType); - ui->diskContent->setText(diskSize); - ui->kernalContent->setText(kernal); - ui->memoryContent->setText(memorySize); - - qDebug()<<"cpuType and "<diskContent->setVisible(false); } -void About::setupVersionCompenent() { +void About::setupVersionCompenent() +{ QString versionPath = "/etc/os-release"; - QStringList osRes = readFile(versionPath); + QStringList osRes = readFile(versionPath); + QString versionID; QString version; + if (QGSettings::isSchemaInstalled(THEME_STYLE_SCHEMA)) { + themeStyleQgsettings = new QGSettings(THEME_STYLE_SCHEMA, QByteArray(), this); + } else { + themeStyleQgsettings = nullptr; + qDebug()< -1) { + versionID = rx.cap(1); + } } + + if (!QLocale::system().name().compare("zh_CN", Qt::CaseInsensitive)) { + if (str.contains("VERSION=")) { + QRegExp rx("VERSION=\"(.*)\"$"); + int pos = rx.indexIn(str); + if (pos > -1) { + version = rx.cap(1); + } + } + } else { + if (str.contains("VERSION_US=")) { + QRegExp rx("VERSION_US=\"(.*)\"$"); + int pos = rx.indexIn(str); + if (pos > -1) { + version = rx.cap(1); + } + } + } + } + + if (!version.isEmpty()) { + ui->versionContent->setText(version); } - if (UbuntuVesion == version) { - version = "UbuntuKylin 20.04 LTS"; - } else if (UbuntuVesionEnhance == version) { - version = "UbuntuKylin 20.04.1 LTS"; - } - ui->versionContent->setText(version); - if (version == "Kylin V10" || version == "Kylin V10.1") { - ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/galaxyUnicorn.png")); + + if (!versionID.compare(vTen, Qt::CaseInsensitive) || + !versionID.compare(vTenEnhance, Qt::CaseInsensitive) || + !versionID.compare(vFour, Qt::CaseInsensitive)) { + ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logo-light.svg")); //默认设置为light + if (themeStyleQgsettings != nullptr && themeStyleQgsettings->keys().contains(CONTAIN_STYLE_NAME_KEY)) { + if (themeStyleQgsettings->get(STYLE_NAME_KEY).toString() == UKUI_DARK) { //深色模式改为dark + ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logo-dark.svg")); + } + connect(themeStyleQgsettings,&QGSettings::changed,this,[=](QString changedKey) { //监听主题变化 + if (changedKey == CONTAIN_STYLE_NAME_KEY) { + if (themeStyleQgsettings->get(STYLE_NAME_KEY).toString() == UKUI_DARK) { + ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logo-dark.svg")); + } else { + ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logo-light.svg")); + } + } + }); + } } else { -// qDebug()<<"version----->"<activeFrame->setVisible(false); ui->trialButton->setVisible(false); - //设置桌面环境LOGO ui->logoLabel->setPixmap(QPixmap("://img/plugins/about/logoukui.svg")); } } -void About::setupSerialComponent() { - ui->trialButton->setFlat(true); - ui->trialButton->setStyleSheet("text-align: left"); - //ubuntukylin youker DBus interface - QDBusInterface *activeInterface = new QDBusInterface("org.freedesktop.activation", - "/org/freedesktop/activation", - "org.freedesktop.activation.interface", - QDBusConnection::systemBus()); - if (!activeInterface->isValid()) { - qDebug() << "Create active Interface Failed When Get Computer info: " << QDBusConnection::systemBus().lastError(); +void About::setupSerialComponent() +{ + if (!activeInterface.get()->isValid()) { + qDebug() << "Create active Interface Failed When Get active info: " << + QDBusConnection::systemBus().lastError(); return; } - int status; - QDBusReply activeStatus; - activeStatus = activeInterface ->call("status"); - if (!activeStatus.isValid()) { - qDebug()<<"activeStatus is invalid"<call("status"); + if (activeReply.type() == QDBusMessage::ReplyMessage) { + status = activeReply.arguments().at(0).toInt(); } - QString serial; QDBusReply serialReply; - serialReply = activeInterface ->call("serial_number"); + serialReply = activeInterface.get()->call("serial_number"); if (!serialReply.isValid()) { qDebug()<<"serialReply is invalid"<"<activeContent->setText(tr("Inactivated")); - } else { + if (1 == status) { ui->activeContent->setText(tr("Activated")); ui->activeButton->hide(); + ui->trialButton->hide(); + } else { + QDBusMessage dateReply = activeInterface.get()->call("date"); + QString dateRes; + if (dateReply.type() == QDBusMessage::ReplyMessage) { + dateRes = dateReply.arguments().at(0).toString(); + if (!dateRes.isEmpty()) { + ui->activeContent->setText(tr("The system has expired. The expiration time is:") + + dateRes); + } else { + ui->activeContent->setText(tr("Inactivated")); + } + } } - ui->serviceContent->setText(serial); connect(ui->activeButton, &QPushButton::clicked, this, &About::runActiveWindow); connect(ui->trialButton, &QPushButton::clicked, this, &About::showPdf); } -QStringList About::readFile(QString filepath) { +qlonglong About::calculateTotalRam() +{ + qlonglong ret = -1; +#ifdef Q_OS_LINUX + struct sysinfo info; + if (sysinfo(&info) == 0) + // manpage "sizes are given as multiples of mem_unit bytes" + ret = qlonglong(info.totalram) * info.mem_unit; +#elif defined(Q_OS_FREEBSD) + /* Stuff for sysctl */ + size_t len; + + unsigned long memory; + len = sizeof(memory); + sysctlbyname("hw.physmem", &memory, &len, NULL, 0); + + ret = memory; +#endif + return ret; +} + +QString About::getTotalMemory() +{ + const QString fileName = "/proc/meminfo"; + QFile meninfoFile(fileName); + if (!meninfoFile.exists()) { + printf("/proc/meminfo file not exist \n"); + } + if (!meninfoFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + printf("open /proc/meminfo fail \n"); + } + + QTextStream in(&meninfoFile); + QString line = in.readLine(); + float memtotal = 0; + + while (!line.isNull()) { + if (line.contains("MemTotal")) { + line.replace(QRegExp("[\\s]+"), " "); + + QStringList lineList = line.split(" "); + QString mem = lineList.at(1); + memtotal = mem.toFloat(); + break; + } else { + line = in.readLine(); + } + } + + memtotal = ceil(memtotal / 1024 / 1024); + // 向2的n次方取整 + int nPow = ceil(log(memtotal)/log(2.0)); + memtotal = pow(2.0, nPow); + + return QString::number(memtotal) + " GB"; +} + +QStringList About::totalMemory() +{ + QStringList res; + const qlonglong totalRam = calculateTotalRam(); + + if (totalRam > 0) { + QString total = KFormat().formatByteSize(totalRam, 0, KFormat::JEDECBinaryDialect); + QString available = KFormat().formatByteSize(totalRam, 1, KFormat::JEDECBinaryDialect); + if (atof(total.toLatin1()) < atof(available.toLatin1())) { + qSwap(total, available); + } + res << total << available; + return res; + } + return res; +} + + +QStringList About::readFile(QString filepath) +{ QStringList fileCont; QFile file(filepath); - if(file.exists()) { - if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (file.exists()) { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "ReadFile() failed to open" << filepath; return QStringList(); } QTextStream textStream(&file); - while(!textStream.atEnd()) { - QString line= textStream.readLine(); + while (!textStream.atEnd()) { + QString line = textStream.readLine(); line.remove('\n'); fileCont<titleLabel->setFont(font); +} -void About::_call_dbus_get_computer_info(){ - interface = new QDBusInterface("com.kylin.assistant.qsessiondbus", - "/com/kylin/assistant/qsessiondbus", - "com.kylin.assistant.qsessiondbus", - QDBusConnection::systemBus()); - - if (!interface->isValid()){ - qCritical() << "Create Client Interface Failed When Get Computer info: " << QDBusConnection::systemBus().lastError(); - return; - } - -// QDBusConnection::systemBus().connect("com.control.center.qt.systemdbus", -// "/", -// "com.control.center.interface", -// "computerinfo", this, -// SLOT(get(QString))); +void About::initSearchText() +{ + //~ contents_path /about/version + ui->versionLabel->setText(tr("version")); + //~ contents_path /about/Kernel + ui->kernalLabel->setText(tr("Kernel")); + //~ contents_path /about/CPU + ui->cpuLabel->setText(tr("CPU")); + //~ contents_path /about/Memory + ui->memoryLabel->setText(tr("Memory")); + ui->diskLabel->setVisible(false); +} - QDBusReply reply = interface->call("GetComputerInfo"); - if (reply.isValid()){ - computerinfo = reply.value(); - } - else { - qCritical() << "Call 'GetComputerInfo' Failed!" << reply.error().message(); +void About::initActiveDbus() +{ + activeInterface = QSharedPointer( + new QDBusInterface("org.freedesktop.activation", + "/org/freedesktop/activation", + "org.freedesktop.activation.interface", + QDBusConnection::systemBus())); + if (activeInterface.get()->isValid()) { + connect(activeInterface.get(), SIGNAL(activation_result(int)), this, SLOT(activeSlot(int))); } - - - //async -// QDBusPendingCall async = interface->asyncCall("GetComputerInfo"); -// QDBusPendingCallWatcher * watcher = new QDBusPendingCallWatcher(async, this); - -// connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(call_finished_slot(QDBusPendingCallWatcher*))); } -//void About::call_finished_slot(QDBusPendingCallWatcher * call){ -// qDebug() << "----------------start------------>"; -// QDBusPendingReply reply = *call; -// if (!reply.isError()){ -// QString info = reply.argumentAt<0>(); -// qDebug() << "-----------0--->" << "\n" << info; -// } -// else{ -// qDebug() << reply.error().message(); -// } -// call->deleteLater(); -//} - - -void About::runActiveWindow() { +void About::runActiveWindow() +{ QString cmd = "kylin-activation"; QProcess process(this); process.startDetached(cmd); } -void About::showPdf() { - QString cmd = "atril /usr/share/man/statement.pdf.gz"; +void About::showPdf() +{ + QStringList res = getUserDefaultLanguage(); + QString lang = res.at(1); + QString cmd; + QFile pdfFile_zh("/usr/share/kylin-verify-gui/免责协议.pdf"); + QFile pdfFile_en("/usr/share/kylin-verify-gui/disclaimers.pdf"); + if (lang.split(':').at(0) == "zh_CN") { + if (pdfFile_zh.exists()) { + cmd = "atril /usr/share/kylin-verify-gui/免责协议.pdf"; + } else { + cmd = "atril /usr/share/man/statement.pdf.gz"; + } + } else { + if (pdfFile_en.exists()) { + cmd = "atril /usr/share/kylin-verify-gui/disclaimers.pdf"; + } + else { + cmd = "atril /usr/share/man/statement_en.pdf.gz"; + } + } + QProcess process(this); process.startDetached(cmd); } +void About::activeSlot(int activeSignal) +{ + if (!activeSignal) { + setupSerialComponent(); + } +} + + +QStringList About::getUserDefaultLanguage() { + QString formats; + QString language; + QStringList result; + + unsigned int uid = getuid(); + QString objpath = "/org/freedesktop/Accounts/User"+QString::number(uid); + + QDBusInterface iproperty("org.freedesktop.Accounts", + objpath, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + QDBusReply > reply = iproperty.call("GetAll", "org.freedesktop.Accounts.User"); + if (reply.isValid()) { + QMap propertyMap; + propertyMap = reply.value(); + if (propertyMap.keys().contains("FormatsLocale")) { + formats = propertyMap.find("FormatsLocale").value().toString(); + } + if(language.isEmpty() && propertyMap.keys().contains("Language")) { + language = propertyMap.find("Language").value().toString(); + } + } else { + //qDebug() << "reply failed"; + } + result.append(formats); + result.append(language); + return result; +} diff -Nru ukui-control-center-2.0.3/plugins/messages-task/about/about.h ukui-control-center-3.0.3/plugins/messages-task/about/about.h --- ukui-control-center-2.0.3/plugins/messages-task/about/about.h 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/about/about.h 2021-05-20 13:08:14.000000000 +0000 @@ -22,20 +22,15 @@ #include #include - #include #include #include #include - #include #include #include - -#define MANUFACTURER "Manufacturer" -#define VERSION "Version" -#define PRODUCTNAME "Product Name" -#define SERIALNUMBER "Serial Number" +#include +#include #include "shell/interface.h" @@ -55,39 +50,51 @@ QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; - QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; -public: +private: void initUI(); QStringList readFile(QString filePath); - void _call_dbus_get_computer_info(); - void _data_init(); -private: + void initTitleLabel(); + void initSearchText(); + void initActiveDbus(); void setupDesktopComponent(); void setupKernelCompenent(); void setupVersionCompenent(); void setupSerialComponent(); + qlonglong calculateTotalRam(); + + QStringList totalMemory(); + + QString getTotalMemory(); + + QStringList getUserDefaultLanguage(); private: Ui::About *ui; QString pluginName; int pluginType; - QWidget * pluginWidget; + QWidget *pluginWidget; - QLabel * envlogoLabel; - QLabel * logoLabel; + QLabel *envlogoLabel; + QLabel *logoLabel; - QDBusInterface * interface; + QDBusInterface *interface; QString computerinfo; QMap infoMap; + QSharedPointer activeInterface; + + bool mFirstLoad; + QGSettings *themeStyleQgsettings; private slots: -// void call_finished_slot(QDBusPendingCallWatcher * call); void runActiveWindow(); void showPdf(); + void activeSlot(int activeSignal); }; #endif // ABOUT_H diff -Nru ukui-control-center-2.0.3/plugins/messages-task/about/about.pro ukui-control-center-3.0.3/plugins/messages-task/about/about.pro --- ukui-control-center-2.0.3/plugins/messages-task/about/about.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/about/about.pro 2021-04-14 01:27:20.000000000 +0000 @@ -15,14 +15,10 @@ #DEFINES += QT_DEPRECATED_WARNINGS HEADERS += \ - about.h \ - entry.h \ - memoryentry.h + about.h SOURCES += \ - about.cpp \ - entry.cpp \ - memoryentry.cpp + about.cpp FORMS += \ about.ui diff -Nru ukui-control-center-2.0.3/plugins/messages-task/about/about.ui ukui-control-center-3.0.3/plugins/messages-task/about/about.ui --- ukui-control-center-2.0.3/plugins/messages-task/about/about.ui 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/about/about.ui 2021-04-14 01:27:20.000000000 +0000 @@ -71,6 +71,9 @@ + + 0 + @@ -114,7 +117,7 @@ - + 0 @@ -134,14 +137,14 @@ - version + Version - TextLabel + Kylin Linux Desktop V10 (SP1) @@ -177,7 +180,10 @@ - Copyright 2009-2020 @ Kylinos All rights reserved + Copyright © 2009-2021 KylinSoft. All rights reserved. + + + true @@ -271,6 +277,9 @@ + + true + @@ -374,7 +383,7 @@ - + 0 @@ -513,13 +522,13 @@ - 100 + 90 0 - 16777215 + 90 16777215 @@ -543,18 +552,18 @@ - 100 + 90 0 - 16777215 + 90 16777215 - Service serial number + Serial @@ -603,13 +612,13 @@ - 150 + 90 0 - 220 + 150 16777215 @@ -620,7 +629,7 @@ - Trial version disclaimer + Protocol diff -Nru ukui-control-center-2.0.3/plugins/messages-task/about/entry.cpp ukui-control-center-3.0.3/plugins/messages-task/about/entry.cpp --- ukui-control-center-2.0.3/plugins/messages-task/about/entry.cpp 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/about/entry.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,48 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2020 Harald Sitter - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -#include "entry.h" - -Entry::Entry(const KLocalizedString &label_, const QString &value_) - : label(label_) - , value(value_) -{ - Q_ASSERT(label.isEmpty() || localizedLabel(Language::English).endsWith(':')); -} - -Entry::~Entry() = default; - -// When false this entry is garbage (e.g. incomplete data) and shouldn't be rendered. -bool Entry::isValid() const -{ - return !label.toString().isEmpty() && !value.isEmpty(); -} - -// Returns textual representation of entry. -QString Entry::diagnosticLine(Language language) const -{ - // FIXME: This isn't really working for right-to-left - // The answer probably is in uncide control characters, but - // didn't work when tried. - // Essentially what needs to happen is that the label should be RTL - // that is to say the colon should be on the left, BUT englishy words - // within that should be LTR, everything besides the label should be LTR - // because we do not localize the values I don't think? - return localizedLabel(language) + ' ' + value + '\n'; -} - -QString Entry::localizedLabel(Language language) const -{ - switch (language) { - case Language::System: - return label.toString(); - case Language::English: - // https://bugs.kde.org/show_bug.cgi?id=416247 - return label.toString(QStringList { QStringLiteral("en_US") }); - } - Q_UNREACHABLE(); - return QStringLiteral("Unknown Label Language %1 (bug in KInfocenter!):").arg( - QString::number(static_cast(language))); -} diff -Nru ukui-control-center-2.0.3/plugins/messages-task/about/entry.h ukui-control-center-3.0.3/plugins/messages-task/about/entry.h --- ukui-control-center-2.0.3/plugins/messages-task/about/entry.h 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/about/entry.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2020 Harald Sitter - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -#ifndef ENTRY_H -#define ENTRY_H - -#include -#include - -// Generic dumpable info entry. -// This encapsulates a table entry so that it may be put into the UI -// and also serialized into textual form for copy to clipboard. -// All entries that are meant to be serializable should derive from this! -// This class may either be subclassed or used as-is if label/value are trivial -// to obtain. -class Entry -{ -public: - enum class Language { - System, - English - }; - - Entry(const KLocalizedString &label_, const QString &value_); - virtual ~Entry(); - - // When false this entry is garbage (e.g. incomplete data) and shouldn't be rendered. - bool isValid() const; - - // Returns textual representation of entry. - QString diagnosticLine(Language language = Language::System) const; - - // Descriptive label - KLocalizedString label; - // Value of the entry (e.g. the version of plasma) - QString value; - -private: - QString localizedLabel(Language language) const; -}; - -#endif // ENTRY_H diff -Nru ukui-control-center-2.0.3/plugins/messages-task/about/memoryentry.cpp ukui-control-center-3.0.3/plugins/messages-task/about/memoryentry.cpp --- ukui-control-center-2.0.3/plugins/messages-task/about/memoryentry.cpp 2020-06-18 07:43:39.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/about/memoryentry.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2020 Harald Sitter - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -#include "memoryentry.h" - -#include -#include -#include - -#ifdef Q_OS_LINUX -#include -#elif defined(Q_OS_FREEBSD) -#include -#include -#endif - -MemoryEntry::MemoryEntry() : Entry(ki18n("Memory:"), totalMemory().at(1)) -{ -} - -qlonglong MemoryEntry::calculateTotalRam() -{ - qlonglong ret = -1; -#ifdef Q_OS_LINUX - struct sysinfo info; - if (sysinfo(&info) == 0) - // manpage "sizes are given as multiples of mem_unit bytes" - ret = qlonglong(info.totalram) * info.mem_unit; -#elif defined(Q_OS_FREEBSD) - /* Stuff for sysctl */ - size_t len; - - unsigned long memory; - len = sizeof(memory); - sysctlbyname("hw.physmem", &memory, &len, NULL, 0); - - ret = memory; -#endif - return ret; -} - -QStringList MemoryEntry::totalMemory() -{ - QStringList res; - const qlonglong totalRam = calculateTotalRam(); - - if (totalRam > 0) { - QString total = KFormat().formatByteSize(totalRam, 0); - QString available = KFormat().formatByteSize(totalRam, 1); - res << total << available; - return res; - } -// return ki18n("Unknown amount of RAM", "Unknown"); - return res; -} diff -Nru ukui-control-center-2.0.3/plugins/messages-task/about/memoryentry.h ukui-control-center-3.0.3/plugins/messages-task/about/memoryentry.h --- ukui-control-center-2.0.3/plugins/messages-task/about/memoryentry.h 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/about/memoryentry.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -/* - SPDX-FileCopyrightText: 2012-2020 Harald Sitter - SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL -*/ - -#ifndef MEMORYENTRY_H -#define MEMORYENTRY_H - -#include "entry.h" - -#include - -class MemoryEntry : public Entry -{ -public: - MemoryEntry(); - static qlonglong calculateTotalRam(); - static QStringList totalMemory(); -}; - -#endif // MEMORYENTRY_H diff -Nru ukui-control-center-2.0.3/plugins/messages-task/experienceplan/experienceplan.cpp ukui-control-center-3.0.3/plugins/messages-task/experienceplan/experienceplan.cpp --- ukui-control-center-2.0.3/plugins/messages-task/experienceplan/experienceplan.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/experienceplan/experienceplan.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -33,14 +33,6 @@ pluginName = tr("Experienceplan"); pluginType = NOTICEANDTASKS; -// pluginWidget->setStyleSheet("background: #ffffff;"); - -// ui->joinWidget->setStyleSheet("QWidget{background: #F4F4F4; border: none; border-radius: 6px;}"); - -// ui->termsBtn->setStyleSheet("QPushButton{background: #ffffff; color: #3D6BE5;}" -// "QPushButton:hover:!pressed{background: #ffffff; color: #ffffff;}" -// "QPushButton:hover:pressed{background: #ffffff; color: #ffffff;}"); - QByteArray id(E_PLAN_SCHEMA); eSettings = new QGSettings(id); @@ -52,8 +44,9 @@ ExperiencePlan::~ExperiencePlan() { delete ui; - + ui = nullptr; delete eSettings; + eSettings = nullptr; } QString ExperiencePlan::get_plugin_name(){ @@ -72,6 +65,11 @@ } +const QString ExperiencePlan::name() const{ + + return QStringLiteral("experienceplan"); +} + void ExperiencePlan::setupComponent(){ joinSwitchBtn = new SwitchButton(pluginWidget); diff -Nru ukui-control-center-2.0.3/plugins/messages-task/experienceplan/experienceplan.h ukui-control-center-3.0.3/plugins/messages-task/experienceplan/experienceplan.h --- ukui-control-center-2.0.3/plugins/messages-task/experienceplan/experienceplan.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/experienceplan/experienceplan.h 2021-04-14 01:27:20.000000000 +0000 @@ -47,6 +47,7 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: void setupComponent(); diff -Nru ukui-control-center-2.0.3/plugins/messages-task/multitask/multitask.cpp ukui-control-center-3.0.3/plugins/messages-task/multitask/multitask.cpp --- ukui-control-center-2.0.3/plugins/messages-task/multitask/multitask.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/multitask/multitask.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -34,6 +34,7 @@ Multitask::~Multitask() { delete ui; + ui = nullptr; } QString Multitask::get_plugin_name(){ diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/appdetail.cpp ukui-control-center-3.0.3/plugins/messages-task/notice/appdetail.cpp --- ukui-control-center-2.0.3/plugins/messages-task/notice/appdetail.cpp 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/appdetail.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -1,5 +1,5 @@ #include "appdetail.h" - +#include "CloseButton/closebutton.h" #include #include "ui_appdetail.h" @@ -10,22 +10,17 @@ extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); AppDetail::AppDetail(QString Name,QString key, QGSettings *gsettings, QWidget *parent) : - QDialog(parent),appKey(key),m_gsettings(gsettings), appName(Name), - ui(new Ui::AppDetail) + QDialog(parent), ui(new Ui::AppDetail), appName(Name), appKey(key), + m_gsettings(gsettings) { -// qDebug()<<"name is------>"<setupUi(this); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); + setWindowTitle(appName); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - initUiStatus(); -// initGSettings(); initComponent(); initConnect(); } @@ -33,22 +28,10 @@ AppDetail::~AppDetail() { delete ui; + ui = nullptr; } -void AppDetail::initUiStatus(){ - -// ui->frame->setStyleSheet("QFrame#frame{background: #ffffff; border: none; border-radius: 6px;}"); - -// ui->enableWidget->setStyleSheet("QWidget#enableWidget{background: #F4F4F4; border-radius: 6px;}"); -// ui->numberWidget->setStyleSheet("QWidget#numberWidget{background: #F4F4F4; border-radius: 6px;}"); -// ui->numberWidget->setStyleSheet("QWidget#numberWidget{background: #F4F4F4; border-radius: 6px;}"); - - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); -// ui->closeBtn->setStyleSheet("QPushButton#closeBtn{background: #ffffff; border: none; border-radius: 6px;}" -// "QPushButton:hover:!pressed#closeBtn{background: #FA6056; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}" -// "QPushButton:hover:pressed#closeBtn{background: #E54A50; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}"); +void AppDetail::initUiStatus() { enablebtn = new SwitchButton; ui->enableLayout->addWidget(enablebtn); @@ -64,19 +47,12 @@ if (m_gsettings) { bool judge = m_gsettings->get(MESSAGES_KEY).toBool(); QString numvalue = m_gsettings->get(MAXIMINE_KEY).toString(); - -// qDebug()<<"numvalue is------->"<setChecked(judge); ui->numberComboBox->setCurrentText(numvalue); } } void AppDetail::initConnect() { - connect(ui->closeBtn, &QPushButton::clicked, [=](bool checked){ - Q_UNUSED(checked) - close(); - }); connect(ui->cancelBtn, &QPushButton::clicked, [=](bool checked){ Q_UNUSED(checked) @@ -87,7 +63,6 @@ Q_UNUSED(checked) confirmbtnSlot(); }); - } void AppDetail::paintEvent(QPaintEvent *event) { @@ -103,6 +78,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); @@ -111,7 +87,6 @@ QImage img = pixmap.toImage(); qt_blurImage(img, 10, false, false); - // 挖掉中心 pixmap = QPixmap::fromImage(img); QPainter pixmapPainter2(&pixmap); @@ -131,14 +106,6 @@ } -//void AppDetail::initGSettings() { -// if(QGSettings::isSchemaInstalled(NOTICE_ORIGIN_SCHEMA)) { - -// QByteArray orid(NOTICE_ORIGIN_SCHEMA); -// m_gsettings = new QGSettings(orid); -// } -//} - void AppDetail::confirmbtnSlot() { //TODO: get gsetting may invalid, so program will throw crash error if (m_gsettings) { diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/appdetail.h ukui-control-center-3.0.3/plugins/messages-task/notice/appdetail.h --- ukui-control-center-2.0.3/plugins/messages-task/notice/appdetail.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/appdetail.h 2021-04-14 01:27:20.000000000 +0000 @@ -8,9 +8,9 @@ #include "SwitchButton/switchbutton.h" #define MESSAGES_KEY "messages" -#define VOICE_KEY "voice" +#define VOICE_KEY "voice" #define MAXIMINE_KEY "maximize" -#define NAME_KEY "name" +#define NAME_KEY "name" namespace Ui { class AppDetail; @@ -35,12 +35,10 @@ void initUiStatus(); void initComponent(); void initConnect(); -// void initGSettings(); protected: void paintEvent(QPaintEvent *); - private slots: void confirmbtnSlot(); }; diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/appdetail.ui ukui-control-center-3.0.3/plugins/messages-task/notice/appdetail.ui --- ukui-control-center-2.0.3/plugins/messages-task/notice/appdetail.ui 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/appdetail.ui 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 460 - 400 + 350 @@ -19,13 +19,13 @@ 460 - 400 + 350 460 - 400 + 350 @@ -45,7 +45,7 @@ 0 - 9 + 24 @@ -56,6 +56,12 @@ QFrame::Raised + + 9 + + + 32 + @@ -65,6 +71,13 @@ 8 + + + App + + + + Qt::Horizontal @@ -77,35 +90,9 @@ - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - - - TextLabel - - - - @@ -246,7 +233,7 @@ 6 - 32 + 30 diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/appdialog.cpp ukui-control-center-3.0.3/plugins/messages-task/notice/appdialog.cpp --- ukui-control-center-2.0.3/plugins/messages-task/notice/appdialog.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/appdialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -11,4 +11,5 @@ AppDialog::~AppDialog() { delete ui; + ui = nullptr; } diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/notice.cpp ukui-control-center-3.0.3/plugins/messages-task/notice/notice.cpp --- ukui-control-center-2.0.3/plugins/messages-task/notice/notice.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/notice.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -23,72 +23,89 @@ #include "realizenotice.h" #include "commonComponent/HoverWidget/hoverwidget.h" -#define NOTICE_SCHEMA "org.ukui.control-center.notice" -#define NEW_FEATURE_KEY "show-new-feature" -#define ENABLE_NOTICE_KEY "enable-notice" +#define NOTICE_SCHEMA "org.ukui.control-center.notice" +#define NEW_FEATURE_KEY "show-new-feature" +#define ENABLE_NOTICE_KEY "enable-notice" #define SHOWON_LOCKSCREEN_KEY "show-on-lockscreen" -#define DESKTOPPATH "/usr/share/applications/" +#define DESKTOPPATH "/usr/share/applications/" -Notice::Notice() +Notice::Notice() : mFirstLoad(true) { - ui = new Ui::Notice; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - appsName<<"ukui-power-statistics";//<<"kylin-video"<<"kylin-assistant"; - appsKey<<"电源管理器";//<<"麒麟影音"<<"麒麟助手"; - - ui->setupUi(pluginWidget); - - vecGsettins = new QVector(); pluginName = tr("Notice"); pluginType = NOTICEANDTASKS; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - ui->newfeatureWidget->setVisible(false); - ui->lockscreenWidget->setVisible(false); - - ui->title2Label->setContentsMargins(0,0,0,16); - ui->applistWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->applistWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - setupGSettings(); - setupComponent(); - initNoticeStatus(); - initOriNoticeStatus(); } Notice::~Notice() { - delete ui; - if (!vecGsettins) { - delete vecGsettins; - } - - if (!nSetting) { - delete nSetting; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + qDeleteAll(vecGsettins); + vecGsettins.clear(); } } -QString Notice::get_plugin_name(){ +QString Notice::get_plugin_name() { return pluginName; } -int Notice::get_plugin_type(){ +int Notice::get_plugin_type() { return pluginType; } -QWidget * Notice::get_plugin_ui(){ +QWidget * Notice::get_plugin_ui() { + if (mFirstLoad) { + ui = new Ui::Notice; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + appsName<<"ukui-power-statistics"; + appsKey<<"电源管理器"; + + ui->setupUi(pluginWidget); + + mFirstLoad = false; + + ui->newfeatureWidget->setVisible(false); + ui->lockscreenWidget->setVisible(false); + + ui->title2Label->setContentsMargins(0, 0, 0, 16); + ui->applistWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + initTitleLabel(); + initSearchText(); + setupGSettings(); + setupComponent(); + initNoticeStatus(); + initOriNoticeStatus(); + } return pluginWidget; } -void Notice::plugin_delay_control(){ +void Notice::plugin_delay_control() { + +} + +const QString Notice::name() const { + return QStringLiteral("notice"); } -void Notice::setupComponent(){ +void Notice::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); +} + +void Notice::initSearchText() { + //~ contents_path /notice/Set notice type of operation center + ui->noticeLabel->setText(tr("Set notice type of operation center")); + //~ contents_path /notice/Notice Origin + ui->title2Label->setText(tr("Notice Origin")); +} + +void Notice::setupComponent() { newfeatureSwitchBtn = new SwitchButton(pluginWidget); enableSwitchBtn = new SwitchButton(pluginWidget); lockscreenSwitchBtn = new SwitchButton(pluginWidget); @@ -111,11 +128,11 @@ void Notice::setupGSettings() { if(QGSettings::isSchemaInstalled(NOTICE_SCHEMA)) { QByteArray id(NOTICE_SCHEMA); - nSetting = new QGSettings(id); + nSetting = new QGSettings(id, QByteArray(), this); } } -void Notice::initNoticeStatus(){ +void Notice::initNoticeStatus() { newfeatureSwitchBtn->blockSignals(true); enableSwitchBtn->blockSignals(true); lockscreenSwitchBtn->blockSignals(true); @@ -125,23 +142,17 @@ newfeatureSwitchBtn->blockSignals(false); enableSwitchBtn->blockSignals(false); lockscreenSwitchBtn->blockSignals(false); - - setHiddenNoticeApp(enableSwitchBtn->isChecked()); } void Notice::initOriNoticeStatus() { - initGSettings(); - for (int i = 0; i < appsName.length(); i++) - { + for (int i = 0; i < appsName.length(); i++) { QByteArray ba = QString(DESKTOPPATH + appsName.at(i) + ".desktop").toUtf8(); GDesktopAppInfo * audioinfo = g_desktop_app_info_new_from_filename(ba.constData()); QString appname = g_app_info_get_name(G_APP_INFO(audioinfo)); -// qDebug()<<"notify appname is------------->"<setFrameShape(QFrame::Shape::Box); baseWidget->setAttribute(Qt::WA_DeleteOnClose); @@ -156,7 +167,6 @@ devWidget->setMaximumWidth(960); devWidget->setMinimumHeight(50); devWidget->setMaximumHeight(50); -// devWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); QHBoxLayout * devHorLayout = new QHBoxLayout(); devHorLayout->setSpacing(8); @@ -177,8 +187,7 @@ } iconBtn->setIcon(QIcon::fromTheme(iconame)); - - QLabel * nameLabel = new QLabel(); + QLabel * nameLabel = new QLabel(pluginWidget); QSizePolicy nameSizePolicy = nameLabel->sizePolicy(); nameSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); nameSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); @@ -186,7 +195,7 @@ nameLabel->setScaledContents(true); nameLabel->setText(appname); - SwitchButton *appSwitch = new SwitchButton(); + SwitchButton *appSwitch = new SwitchButton(pluginWidget); devHorLayout->addWidget(iconBtn); devHorLayout->addWidget(nameLabel); @@ -202,10 +211,10 @@ baseWidget->setLayout(baseVerLayout); QListWidgetItem * item = new QListWidgetItem(ui->applistWidget); - item->setSizeHint(QSize(502, 52)); + item->setFlags(Qt::NoItemFlags); + item->setSizeHint(QSize(QSizePolicy::Expanding, 52)); ui->applistWidget->setItemWidget(item, baseWidget); -// QString availablepath = findFreePath(); QList listChar = listExistsCustomNoticePath(); @@ -214,42 +223,39 @@ QString path; for (int j = 0; j < listChar.length(); j++) { - path =QString("%1%2").arg(NOTICE_ORIGIN_PATH).arg(QString(listChar.at(j))); - settings = new QGSettings(id, path.toLatin1().data()); - vecGsettins->append(settings); + path = QString("%1%2").arg(NOTICE_ORIGIN_PATH).arg(QString(listChar.at(j))); + settings = new QGSettings(id, path.toLatin1().data(), this); + vecGsettins.append(settings); QStringList keys = settings->keys(); if (keys.contains(static_cast(NAME_KEY))) { QString appName = settings->get(NAME_KEY).toString(); if ( appsKey.at(i) == appName) { -// qDebug() <<" keys is----->name"<get(MESSAGES_KEY).toBool(); appSwitch->setChecked(isCheck); break; } } + settings = nullptr; } - connect(devWidget, &HoverWidget::enterWidget, this, [=](QString name){ + connect(devWidget, &HoverWidget::enterWidget, this, [=](QString name) { Q_UNUSED(name) devWidget->setStyleSheet("QWidget#hovorWidget{background-color: rgba(61,107,229,40%);border-radius:4px;}"); - }); - connect(devWidget, &HoverWidget::leaveWidget, this, [=](QString name){ + connect(devWidget, &HoverWidget::leaveWidget, this, [=](QString name) { Q_UNUSED(name) devWidget->setStyleSheet("QWidget#hovorWidget{background: palette(button);border-radius:4px;}"); }); - connect(devWidget, &HoverWidget::widgetClicked, this, [=](QString name){ -// qDebug()<<"clicked widget--------->"<exec(); }); - connect(settings, &QGSettings::changed, [=](QString key){ -// qDebug()<<"settings key is--->"<(MESSAGES_KEY) == key) { bool judge = settings->get(MESSAGES_KEY).toBool(); appSwitch->setChecked(judge); @@ -261,16 +267,11 @@ changeAppstatus(checked, appname, appSwitch); }); - connect(appSwitch, &SwitchButton::checkedChanged, [=](bool checked){ - QStringList keys = settings->keys(); - QString name = settings->get(NAME_KEY).toString(); + connect(appSwitch, &SwitchButton::checkedChanged, [=](bool checked) { settings->set(MESSAGES_KEY, checked); }); - - -// delete newSettings; -// delete settings; } + setHiddenNoticeApp(enableSwitchBtn->isChecked()); } @@ -285,20 +286,21 @@ bool isExist = false; for (int j = 0; j < listChar.length(); j++) { - path =QString("%1%2").arg(NOTICE_ORIGIN_PATH).arg(QString(listChar.at(j))); + path = QString("%1%2").arg(NOTICE_ORIGIN_PATH).arg(QString(listChar.at(j))); settings = new QGSettings(id, path.toLatin1().data()); QStringList keys = settings->keys(); if (keys.contains(static_cast(NAME_KEY))) { QString appName = settings->get(NAME_KEY).toString(); - if ( appsKey.at(i) == appName) { + if (appsKey.at(i) == appName) { isExist = true; } } + delete settings; + settings = nullptr; } if (!isExist) { path = findFreePath(); - qDebug()<<"not contains newSettings ----->path"<keys(); if (keys.contains(static_cast(NAME_KEY)) && @@ -306,19 +308,15 @@ newSettings->set(NAME_KEY, appsKey.at(i)); newSettings->set(MESSAGES_KEY, true); } - } - - if (newSettings) { delete newSettings; + newSettings = nullptr; } } - } void Notice::changeAppstatus(bool checked, QString name, SwitchButton *appBtn) { - /* - * if master swtich is off, record app's pre status - */ + + // 记录应用之前状态 bool judge; if (!checked) { judge = appBtn->isChecked(); @@ -330,11 +328,11 @@ } } -void Notice::setHiddenNoticeApp(bool status) -{ - if (status) { - ui->applistWidget->setVisible(true); - } else { - ui->applistWidget->setVisible(false); +void Notice::setHiddenNoticeApp(bool status) { + + // To prevent jitter, need to be optimized + for (int i = 0; i < ui->applistWidget->count(); i++) { + QListWidgetItem * item = ui->applistWidget->item(i); + item->setHidden(!status); } } diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/notice.h ukui-control-center-3.0.3/plugins/messages-task/notice/notice.h --- ukui-control-center-2.0.3/plugins/messages-task/notice/notice.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/notice.h 2021-04-14 01:27:20.000000000 +0000 @@ -25,20 +25,11 @@ #include #include #include - #include #include #include "SwitchButton/switchbutton.h" - -//typedef _NoticeEntry NoticeEntry; -//struct _NoticeEntry : QObjectUserData{ -//// int keyval; -// QString gsSchema; -// QString keyStr; -//}; - /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ @@ -70,7 +61,10 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + void initTitleLabel(); + void initSearchText(); void setupComponent(); void setupGSettings(); void initNoticeStatus(); @@ -97,6 +91,8 @@ QGSettings * oriSettings; QStringList appsName; QStringList appsKey; - QVector *vecGsettins; + QVector vecGsettins; + + bool mFirstLoad; }; #endif // NOTICE_H diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/notice.pro ukui-control-center-3.0.3/plugins/messages-task/notice/notice.pro --- ukui-control-center-2.0.3/plugins/messages-task/notice/notice.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/notice.pro 2021-04-14 01:27:20.000000000 +0000 @@ -4,6 +4,7 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) TEMPLATE = lib CONFIG += plugin @@ -50,4 +51,4 @@ appdetail.ui \ notice.ui -INSTALLS += target \ No newline at end of file +INSTALLS += target diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/notice.ui ukui-control-center-3.0.3/plugins/messages-task/notice/notice.ui --- ukui-control-center-2.0.3/plugins/messages-task/notice/notice.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/notice.ui 2021-04-14 01:27:20.000000000 +0000 @@ -44,6 +44,9 @@ + + 0 + 0 @@ -61,7 +64,23 @@ - + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 6 + + + + + + 0 @@ -69,7 +88,7 @@ - Set the type of notice in the operation center + Set notice type of operation center diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/realizenotice.cpp ukui-control-center-3.0.3/plugins/messages-task/notice/realizenotice.cpp --- ukui-control-center-2.0.3/plugins/messages-task/notice/realizenotice.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/realizenotice.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -63,7 +63,6 @@ } if (i == MAX_CUSTOM_SHORTCUTS){ -// qDebug() << "Keyboard Shortcuts" << "Too many custom shortcuts"; return ""; } diff -Nru ukui-control-center-2.0.3/plugins/messages-task/notice/realizenotice.h ukui-control-center-3.0.3/plugins/messages-task/notice/realizenotice.h --- ukui-control-center-2.0.3/plugins/messages-task/notice/realizenotice.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/notice/realizenotice.h 2021-04-14 01:27:20.000000000 +0000 @@ -37,20 +37,20 @@ #include } -#define NOTICE_SCHEMA "org.ukui.control-center.notice" -#define NEW_FEATURE_KEY "show-new-feature" -#define ENABLE_NOTICE_KEY "enable-notice" -#define SHOWON_LOCKSCREEN_KEY "show-on-lockscreen" - -#define NOTICE_ORIGIN_SCHEMA "org.ukui.control-center.noticeorigin" -#define NOTICE_ORIGIN_PATH "/org/ukui/control-center/noticeorigin/" - -#define MAX_SHORTCUTS 1000 - -#define MESSAGES_KEY "messages" -#define VOICE_KEY "voice" -#define MAXIMINE_KEY "maximize" -#define NAME_KEY "name" +#define NOTICE_SCHEMA "org.ukui.control-center.notice" +#define NEW_FEATURE_KEY "show-new-feature" +#define ENABLE_NOTICE_KEY "enable-notice" +#define SHOWON_LOCKSCREEN_KEY "show-on-lockscreen" + +#define NOTICE_ORIGIN_SCHEMA "org.ukui.control-center.noticeorigin" +#define NOTICE_ORIGIN_PATH "/org/ukui/control-center/noticeorigin/" + +#define MAX_SHORTCUTS 1000 + +#define MESSAGES_KEY "messages" +#define VOICE_KEY "voice" +#define MAXIMINE_KEY "maximize" +#define NAME_KEY "name" #define MAX_CUSTOM_SHORTCUTS 1000 diff -Nru ukui-control-center-2.0.3/plugins/messages-task/search/search.cpp ukui-control-center-3.0.3/plugins/messages-task/search/search.cpp --- ukui-control-center-2.0.3/plugins/messages-task/search/search.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/search/search.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,359 @@ +#include "search.h" +#include "ui_search.h" + +Search::Search() +{ + //~ contents_path /search/Search + m_plugin_name = tr("Search"); + m_plugin_type = NOTICEANDTASKS; + initUi(); + setupConnection(); + m_dirSettings = new QSettings(QDir::homePath() + CONFIG_FILE, QSettings::NativeFormat, this); + m_dirSettings->setIniCodec(QTextCodec::codecForName("UTF-8")); + initBlockDirsList(); +} + +Search::~Search() +{ + if (m_gsettings) { + delete m_gsettings; + m_gsettings = nullptr; + } +} + +QString Search::get_plugin_name() +{ + return m_plugin_name; +} + +int Search::get_plugin_type() +{ + return m_plugin_type; +} + +QWidget *Search::get_plugin_ui() +{ + ui = new Ui::Search; + m_plugin_widget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(m_plugin_widget); + + const QByteArray id(UKUI_SEARCH_SCHEMAS); + if (QGSettings::isSchemaInstalled(id)) { + m_gsettings = new QGSettings(id, QByteArray(), this); + //按钮状态初始化 + if (m_gsettings->keys().contains(SEARCH_METHOD_KEY)) { + //当前是否使用索引搜索/暴力搜索 + bool is_index_search_on = m_gsettings->get(SEARCH_METHOD_KEY).toBool(); + m_searchMethodBtn->setChecked(is_index_search_on); + } else { + m_searchMethodBtn->setEnabled(false); + } + if (m_gsettings->keys().contains(WEB_ENGINE_KEY)) { + //当前网页搜索的搜索引擎 + QString engine = m_gsettings->get(WEB_ENGINE_KEY).toString(); + m_webEngineFrame->mCombox->setCurrentIndex(m_webEngineFrame->mCombox->findData(engine)); + } else { + m_webEngineFrame->mCombox->setEnabled(false); + } + //监听gsettings值改变,更新控制面板UI + connect(m_gsettings, &QGSettings::changed, this, [ = ](const QString &key) { + if (key == SEARCH_METHOD_KEY) { + bool is_index_search_on = m_gsettings->get(SEARCH_METHOD_KEY).toBool(); + m_searchMethodBtn->blockSignals(true); + m_searchMethodBtn->setChecked(is_index_search_on); + m_searchMethodBtn->blockSignals(false); + } else if (key == WEB_ENGINE_KEY) { + QString engine = m_gsettings->get(WEB_ENGINE_KEY).toString(); + m_webEngineFrame->mCombox->blockSignals(true); + m_webEngineFrame->mCombox->setCurrentIndex(m_webEngineFrame->mCombox->findData(engine)); + m_webEngineFrame->mCombox->blockSignals(false); + } + }); + connect(m_searchMethodBtn, &SwitchButton::checkedChanged, this, [ = ](bool checked) { + if (m_gsettings && m_gsettings->keys().contains(SEARCH_METHOD_KEY)) { + m_gsettings->set(SEARCH_METHOD_KEY, checked); + } + }); + connect(m_webEngineFrame->mCombox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { + if (m_gsettings && m_gsettings->keys().contains(WEB_ENGINE_KEY)) { + m_gsettings->set(WEB_ENGINE_KEY, m_webEngineFrame->mCombox->currentData().toString()); + } + }); + } else { + qCritical() << UKUI_SEARCH_SCHEMAS << " not installed!\n"; + m_searchMethodBtn->setEnabled(false); + m_webEngineFrame->mCombox->setEnabled(false); + } + return m_plugin_widget; +} + +void Search::plugin_delay_control() +{ + +} + +const QString Search::name() const +{ + return QStringLiteral("search"); +} + +/** + * @brief Search::initUi 初始化此插件UI + */ +void Search::initUi() +{ + QFont font; + font.setPixelSize(18); + m_plugin_widget = new QWidget; + m_mainLyt = new QVBoxLayout(m_plugin_widget); + m_plugin_widget->setLayout(m_mainLyt); + //设置搜索模式部分的ui + m_methodTitleLabel = new QLabel(m_plugin_widget); + m_methodTitleLabel->setText(tr("Create Index")); + m_methodTitleLabel->setFont(font); + m_descLabel = new QLabel(m_plugin_widget); + m_descLabel->setText(tr("Creating index can help you getting results quickly.")); + m_searchMethodFrame = new QFrame(m_plugin_widget); + m_searchMethodFrame->setFrameShape(QFrame::Shape::Box); + m_searchMethodFrame->setFixedHeight(56); + m_searchMethodFrame->setMinimumWidth(550); + m_searchMethodFrame->setMaximumWidth(960); + m_searchMethodLyt = new QHBoxLayout(m_searchMethodFrame); + m_searchMethodFrame->setLayout(m_searchMethodLyt); + m_searchMethodLabel = new QLabel(m_searchMethodFrame); + m_searchMethodLabel->setText(tr("Create Index")); + m_searchMethodBtn = new SwitchButton(m_searchMethodFrame); + m_searchMethodLyt->addWidget(m_searchMethodLabel); + m_searchMethodLyt->addStretch(); + m_searchMethodLyt->addWidget(m_searchMethodBtn); + m_mainLyt->addWidget(m_methodTitleLabel); + m_mainLyt->addWidget(m_descLabel); + m_mainLyt->addWidget(m_searchMethodFrame); + //设置黑名单文件夹部分的ui + m_blockDirTitleLabel = new QLabel(m_plugin_widget); + m_blockDirTitleLabel->setText(tr("Block Folders")); + m_blockDirTitleLabel->setFont(font); + m_blockDirDescLabel = new QLabel(m_plugin_widget); + m_blockDirDescLabel->setWordWrap(true); + m_blockDirDescLabel->setText(tr("Following folders will not be searched. You can set it by adding and removing folders.")); + m_blockDirsFrame = new QFrame(m_plugin_widget); + m_blockDirsFrame->setFrameShape(QFrame::Shape::NoFrame); + m_blockDirsLyt = new QVBoxLayout(m_blockDirsFrame); + m_blockDirsFrame->setLayout(m_blockDirsLyt); + m_blockDirsLyt->setContentsMargins(0, 0, 0, 0); + m_blockDirsLyt->setSpacing(2); + m_addBlockDirWidget = new HoverWidget("", m_plugin_widget); + m_addBlockDirWidget->setObjectName("addBlockDirWidget"); + m_addBlockDirWidget->setStyleSheet("HoverWidget#addBlockDirWidget{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addBlockDirWidget{background: #3D6BE5; border-radius: 4px;}"); + m_addBlockDirWidget->setFixedHeight(50); + m_addBlockDirWidget->setMaximumWidth(960); + m_addBlockDirIcon = new QLabel(m_addBlockDirWidget); + m_addBlockDirIcon->setPixmap(QIcon(":/img/titlebar/add.svg").pixmap(12, 12)); + m_addBlockDirLabel = new QLabel(m_addBlockDirWidget); + m_addBlockDirLabel->setText(tr("Choose folder")); + m_addBlockDirLyt = new QHBoxLayout(m_addBlockDirWidget); + m_addBlockDirWidget->setLayout(m_addBlockDirLyt); + m_addBlockDirLyt->addWidget(m_addBlockDirIcon); + m_addBlockDirLyt->addWidget(m_addBlockDirLabel); + m_addBlockDirLyt->addStretch(); + m_mainLyt->addSpacing(30); + m_mainLyt->addWidget(m_blockDirTitleLabel); + m_mainLyt->addWidget(m_blockDirDescLabel); + m_mainLyt->addWidget(m_blockDirsFrame); + m_mainLyt->addWidget(m_addBlockDirWidget); + //设置网页搜索引擎部分的ui + m_webEngineLabel = new QLabel(m_plugin_widget); + m_webEngineLabel->setFont(font); + m_webEngineLabel->setText(tr("Web Engine")); + m_webEngineFrame = new ComboxFrame(tr("Default web searching engine"), m_plugin_widget); + m_webEngineFrame->setFixedHeight(56); + m_webEngineFrame->setMinimumWidth(550); + m_webEngineFrame->setMaximumWidth(960); + m_webEngineFrame->mCombox->insertItem(0, QIcon(":/img/plugins/search/baidu.svg"), tr("baidu"), "baidu"); + m_webEngineFrame->mCombox->insertItem(1, QIcon(":/img/plugins/search/sougou.svg"), tr("sougou"), "sougou"); + m_webEngineFrame->mCombox->insertItem(2, QIcon(":/img/plugins/search/360.svg"), tr("360"), "360"); + m_mainLyt->addSpacing(30); + m_mainLyt->addWidget(m_webEngineLabel); + m_mainLyt->addWidget(m_webEngineFrame); + m_mainLyt->addStretch(); + m_mainLyt->setContentsMargins(0, 0, 40, 0); +} + +/** + * @brief Search::getBlockDirs 从配置文件获取黑名单并将黑名单列表传入 + */ +void Search::getBlockDirs() +{ + m_blockDirs.clear(); + if (m_dirSettings) + m_blockDirs = m_dirSettings->allKeys(); +} + +/** + * @brief Search::setBlockDir 尝试写入新的黑名单文件夹 + * @param dirPath 待添加到黑名单的文件夹路径 + * @param is_add 是否是在添加黑名单 + * @return 0成功 !0添加失败的错误代码 + */ +int Search::setBlockDir(const QString &dirPath, const bool &is_add) +{ + if (!is_add) { + if (dirPath.isEmpty()) { + return ReturnCode::PathEmpty; + } + //删除黑名单目录 + m_dirSettings->remove(dirPath); + removeBlockDirFromList(dirPath); + return ReturnCode::Succeed; + } + if (!dirPath.startsWith("/home")) { + return ReturnCode::NotInHomeDir; + } + + QString pathKey = dirPath.right(dirPath.length() - 1); + + for (QString dir : m_blockDirs) { + if (pathKey == dir) { + return ReturnCode::HasBeenBlocked; + } + + if (pathKey.startsWith(dir)) { + return ReturnCode::ParentExist; + } + + //有它的子文件夹已被添加,删除这些子文件夹 + if (dir.startsWith(pathKey)) { + m_dirSettings->remove(dir); + removeBlockDirFromList(dir); + } + } + m_dirSettings->setValue(pathKey, "0"); + appendBlockDirToList(dirPath); + return ReturnCode::Succeed; +} + +/** + * @brief Search::initBlockDirsList 初始化黑名单列表 + */ +void Search::initBlockDirsList() +{ + getBlockDirs(); + foreach (QString path, m_blockDirs) { + QString wholePath = QString("/%1").arg(path); + if (QFileInfo(wholePath).isDir() && path.startsWith("home")) { + appendBlockDirToList(wholePath); + } + } +} + +///** +// * @brief Search::refreshBlockDirsList +// */ +//void Search::refreshBlockDirsList() +//{ + +//} + +void Search::appendBlockDirToList(const QString &path) +{ + HoverWidget * dirWidget = new HoverWidget(path, m_blockDirsFrame); + dirWidget->setObjectName(path); + dirWidget->setMinimumSize(550,50); + dirWidget->setMaximumSize(960,50); + dirWidget->setAttribute(Qt::WA_DeleteOnClose); + QHBoxLayout * dirWidgetLyt = new QHBoxLayout(dirWidget); + dirWidgetLyt->setSpacing(8); + dirWidgetLyt->setContentsMargins(0, 0, 0, 0); + dirWidget->setLayout(dirWidgetLyt); + QFrame * dirFrame = new QFrame(dirWidget); + dirFrame->setFrameShape(QFrame::Shape::Box); + dirFrame->setFixedHeight(50); + QHBoxLayout * dirFrameLayout = new QHBoxLayout(dirFrame); + dirFrameLayout->setSpacing(16); + dirFrameLayout->setContentsMargins(16, 0, 16, 0); + QLabel * iconLabel = new QLabel(dirFrame); + QLabel * pathLabel = new QLabel(dirFrame); + dirFrameLayout->addWidget(iconLabel); + iconLabel->setPixmap(QIcon::fromTheme("inode-directory").pixmap(QSize(24, 24))); + pathLabel->setText(path); + dirFrameLayout->addWidget(pathLabel); + dirFrameLayout->addStretch(); + QPushButton * delBtn = new QPushButton(dirWidget); + delBtn->setText(tr("delete")); + delBtn->hide(); + connect(delBtn, &QPushButton::clicked, this, [ = ]() { + setBlockDir(path, false); + getBlockDirs(); + }); + connect(dirWidget, &HoverWidget::enterWidget, this, [ = ]() { + delBtn->show(); + }); + connect(dirWidget, &HoverWidget::leaveWidget, this, [ = ]() { + delBtn->hide(); + }); + dirWidgetLyt->addWidget(dirFrame); + dirWidgetLyt->addWidget(delBtn); + m_blockDirsLyt->addWidget(dirWidget); +} + +void Search::removeBlockDirFromList(const QString &path) +{ + HoverWidget * delDirWidget = m_blockDirsFrame->findChild(path); + if (delDirWidget) { + qDebug() << "Delete folder succeed! path = " << path; + delDirWidget->close(); + } +} + +void Search::setupConnection() +{ + connect(m_addBlockDirWidget, &HoverWidget::widgetClicked, this, &Search::onBtnAddFolderClicked); +} + +void Search::onBtnAddFolderClicked() +{ + QFileDialog * fileDialog = new QFileDialog(m_plugin_widget); +// fileDialog->setFileMode(QFileDialog::Directory); //允许查看文件和文件夹,但只允许选择文件夹 + fileDialog->setFileMode(QFileDialog::DirectoryOnly); //只允许查看文件夹 +// fileDialog->setViewMode(QFileDialog::Detail); + fileDialog->setDirectory(QDir::homePath()); + fileDialog->setNameFilter(tr("Directories")); + fileDialog->setWindowTitle(tr("select blocked folder")); + fileDialog->setLabelText(QFileDialog::Accept, tr("Select")); + fileDialog->setLabelText(QFileDialog::LookIn, tr("Position: ")); + fileDialog->setLabelText(QFileDialog::FileName, tr("FileName: ")); + fileDialog->setLabelText(QFileDialog::FileType, tr("FileType: ")); + fileDialog->setLabelText(QFileDialog::Reject, tr("Cancel")); + if(fileDialog->exec() != QDialog::Accepted) { + fileDialog->deleteLater(); + return; + } + QString selectedDir = 0; + selectedDir = fileDialog->selectedFiles().first(); + qDebug() << "Selected a folder in onBtnAddClicked(): " << selectedDir; + int returnCode = setBlockDir(selectedDir, true); + switch (returnCode) { + case ReturnCode::Succeed : + qDebug() << "Add blocked folder succeed! path = " << selectedDir; + getBlockDirs(); + break; + case ReturnCode::PathEmpty : + qWarning() << "Add blocked folder failed, choosen path is empty! path = " << selectedDir; + QMessageBox::warning(m_plugin_widget, tr("Warning"), tr("Add blocked folder failed, choosen path is empty!")); + break; + case ReturnCode::NotInHomeDir : + qWarning() << "Add blocked folder failed, it is not in home path! path = " << selectedDir; + QMessageBox::warning(m_plugin_widget, tr("Warning"), tr("Add blocked folder failed, it is not in home path!")); + break; + case ReturnCode::ParentExist : + qWarning() << "Add blocked folder failed, its parent dir is exist! path = " << selectedDir; + QMessageBox::warning(m_plugin_widget, tr("Warning"), tr("Add blocked folder failed, its parent dir is exist!")); + break; + case ReturnCode::HasBeenBlocked : + qWarning() << "Add blocked folder failed, it has been already blocked! path = " << selectedDir; + QMessageBox::warning(m_plugin_widget, tr("Warning"), tr("Add blocked folder failed, it has been already blocked!")); + break; + default: + break; + } +} diff -Nru ukui-control-center-2.0.3/plugins/messages-task/search/search.h ukui-control-center-3.0.3/plugins/messages-task/search/search.h --- ukui-control-center-2.0.3/plugins/messages-task/search/search.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/search/search.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,100 @@ +#ifndef SEARCH_H +#define SEARCH_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "HoverWidget/hoverwidget.h" +#include "shell/interface.h" +#include "ComboxFrame/comboxframe.h" + +#define UKUI_SEARCH_SCHEMAS "org.ukui.search.settings" +#define SEARCH_METHOD_KEY "indexSearch" +#define WEB_ENGINE_KEY "webEngine" +//TODO +#define CONFIG_FILE "/.config/org.ukui/ukui-search/ukui-search-block-dirs.conf" + +namespace Ui { +class Search; +} + +enum ReturnCode { + Succeed, + PathEmpty, + NotInHomeDir, + ParentExist, + HasBeenBlocked +}; + +class Search : public QObject, CommonInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") + Q_INTERFACES(CommonInterface) + +public: + explicit Search(); + ~Search(); + + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + +private: + Ui::Search *ui; + + QWidget * m_plugin_widget = nullptr; + QString m_plugin_name = ""; + int m_plugin_type = 0; + + QGSettings * m_gsettings = nullptr; + + void initUi(); + QVBoxLayout * m_mainLyt = nullptr; + //设置搜索模式 + QLabel * m_methodTitleLabel = nullptr; + QLabel * m_descLabel = nullptr; + QFrame * m_searchMethodFrame = nullptr; + QHBoxLayout * m_searchMethodLyt = nullptr; + QLabel * m_searchMethodLabel = nullptr; + SwitchButton * m_searchMethodBtn = nullptr; + //设置黑名单 + QLabel * m_blockDirTitleLabel = nullptr; + QLabel * m_blockDirDescLabel = nullptr; + QFrame * m_blockDirsFrame = nullptr; + QVBoxLayout * m_blockDirsLyt = nullptr; + HoverWidget * m_addBlockDirWidget = nullptr; + QLabel * m_addBlockDirIcon = nullptr; + QLabel * m_addBlockDirLabel = nullptr; + QHBoxLayout * m_addBlockDirLyt = nullptr; + + QStringList m_blockDirs; + QSettings * m_dirSettings = nullptr; + void getBlockDirs(); + int setBlockDir(const QString &dirPath, const bool &is_add = true); + void appendBlockDirToList(const QString &path); + void removeBlockDirFromList(const QString &path); + void initBlockDirsList(); +// void refreshBlockDirsList(); + //设置搜索引擎 + QLabel * m_webEngineLabel = nullptr; + ComboxFrame * m_webEngineFrame = nullptr; + + void setupConnection(); + +private slots: + void onBtnAddFolderClicked(); +}; + +#endif // SEARCH_H diff -Nru ukui-control-center-2.0.3/plugins/messages-task/search/search.pro ukui-control-center-3.0.3/plugins/messages-task/search/search.pro --- ukui-control-center-2.0.3/plugins/messages-task/search/search.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/search/search.pro 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,45 @@ +QT += widgets + +#greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +include(../../../env.pri) +include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) +include($$PROJECT_COMPONENTSOURCE/comboxframe.pri) +include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) + +TEMPLATE = lib +CONFIG += plugin + +TARGET = $$qtLibraryTarget(search) +DESTDIR = ../.. +target.path = $${PLUGIN_INSTALL_DIRS} + +CONFIG += link_pkgconfig \ + C++11 +PKGCONFIG += gio-2.0 \ + gio-unix-2.0 \ + +INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE \ + $$PROJECT_ROOTDIR \ + /usr/include/dconf + +LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -ldconf + + +CONFIG += c++11 \ + link_pkgconfig \ + +PKGCONFIG += gsettings-qt \ + +DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + search.cpp + +HEADERS += \ + search.h + +FORMS += \ + search.ui + +INSTALLS += target diff -Nru ukui-control-center-2.0.3/plugins/messages-task/search/search.ui ukui-control-center-3.0.3/plugins/messages-task/search/search.ui --- ukui-control-center-2.0.3/plugins/messages-task/search/search.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/messages-task/search/search.ui 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,19 @@ + + + Search + + + + 0 + 0 + 784 + 630 + + + + Form + + + + + diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/kylin_network_interface.c ukui-control-center-3.0.3/plugins/network/netconnect/kylin_network_interface.c --- ukui-control-center-2.0.3/plugins/network/netconnect/kylin_network_interface.c 2020-05-28 06:44:33.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/kylin_network_interface.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,140 +0,0 @@ -#include "kylin_network_interface.h" - -#include - -//获取所有网络连接 -//获取当前活动网络连接 - -activecon *kylin_network_get_activecon_info(char *path) -{ - char *chr = "nmcli connection show -active > "; - char *cmd = (char *) malloc(strlen(chr) + strlen(path) + 1); - strcpy(cmd, chr); - strcat(cmd, path); - 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");} - 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!"); - - } - 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; -} diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/kylin_network_interface.h ukui-control-center-3.0.3/plugins/network/netconnect/kylin_network_interface.h --- ukui-control-center-2.0.3/plugins/network/netconnect/kylin_network_interface.h 2020-05-28 06:44:33.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/kylin_network_interface.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -#ifndef KYLIN_NETWORK_INTERFACE_H -#define KYLIN_NETWORK_INTERFACE_H - -#include -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C"{ -#endif - -typedef struct -{ - char *con_name;//活动网络连接名称 - char *type;//活动网络连接类型 - char *dev;//活动网络所属设备 -}activecon;//存放当前活动网络连接 - -activecon *kylin_network_get_activecon_info(char *path); - -#ifdef __cplusplus -} - -#endif // KYLIN_NETWORK_INTERFACE_H - -#endif - diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/netconnect.cpp ukui-control-center-3.0.3/plugins/network/netconnect/netconnect.cpp --- ukui-control-center-2.0.3/plugins/network/netconnect/netconnect.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/netconnect.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -20,312 +20,366 @@ #include "netconnect.h" #include "ui_netconnect.h" -#include "kylin_network_interface.h" - +#include "commonComponent/HoverBtn/hoverbtn.h" +#include "../shell/utils/utils.h" #include #include #include -#include -#include +#include #include +#include +#include - +#define ITEMHEIGH 50 #define CONTROL_CENTER_WIFI "org.ukui.control-center.wifi.switch" -NetConnect::NetConnect():m_wifiList(new Wifi) -{ - ui = new Ui::NetConnect; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Netconnect"); +const QString KWifiSymbolic = "network-wireless-signal-excellent"; +const QString KWifiLockSymbolic = "network-wireless-secure-signal-excellent"; +const QString KWifiGood = "network-wireless-signal-good"; +const QString KWifiLockGood = "network-wireless-secure-signal-good"; +const QString KWifiOK = "network-wireless-signal-ok"; +const QString KWifiLockOK = "network-wireless-secure-signal-ok"; +const QString KWifiLow = "network-wireless-signal-low"; +const QString KWifiLockLow = "network-wireless-secure-signal-low"; +const QString KLanSymbolic = ":/img/plugins/netconnect/eth.svg"; +const QString NoNetSymbolic = ":/img/plugins/netconnect/nonet.svg"; + +const QString KWifi6LockSymbolic = ":/img/plugins/netconnect/wifi6-full-pwd.svg"; +const QString KWifi6LockGood = ":/img/plugins/netconnect/wifi6-high-pwd.svg"; +const QString KWifi6LockOK = ":/img/plugins/netconnect/wifi6-medium-pwd.svg"; +const QString KWifi6LockLow = ":/img/plugins/netconnect/wifi6-low-pwd.svg"; + +const QString KWifi6ProLockSymbolic = ":/img/plugins/netconnect/wifi6+-full-pwd.svg"; +const QString KWifi6ProLockGood = ":/img/plugins/netconnect/wifi6+-high-pwd.svg"; +const QString KWifi6ProLockOK = ":/img/plugins/netconnect/wifi6+-medium-pwd.svg"; +const QString KWifi6ProLockLow = ":/img/plugins/netconnect/wifi6+-low-pwd.svg"; + +bool sortByVal(const QPair &l, const QPair &r) { + return (l.second < r.second); +} +NetConnect::NetConnect() : mFirstLoad(true) { + pluginName = tr("Connect"); pluginType = NETWORK; +} - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); +NetConnect::~NetConnect() { + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } + delete m_interface; +} - ui->detailBtn->setText(tr("Network settings")); +QString NetConnect::get_plugin_name() { + return pluginName; +} - wifiBtn = new SwitchButton(pluginWidget); +int NetConnect::get_plugin_type() { + return pluginType; +} - ui->openWIifLayout->addWidget(wifiBtn); +QWidget *NetConnect::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::NetConnect; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + refreshTimer = new QTimer(); + qDBusRegisterMetaType>(); + m_interface = new QDBusInterface("com.kylin.network", "/com/kylin/network", + "com.kylin.network", + QDBusConnection::sessionBus()); + if(!m_interface->isValid()) { + qWarning() << qPrintable(QDBusConnection::sessionBus().lastError().message()); + } + initTitleLabel(); + initSearchText(); + initComponent(); + } + return pluginWidget; +} - initComponent(); +void NetConnect::plugin_delay_control() { -// getNetList(); } -NetConnect::~NetConnect() -{ - delete ui; - delete m_gsettings; - // TODO: A segment error will be reported after delete -// if (wifiBtn) { -// delete wifiBtn; -// } -} +const QString NetConnect::name() const { -QString NetConnect::get_plugin_name(){ - return pluginName; + return QStringLiteral("netconnect"); } -int NetConnect::get_plugin_type(){ - return pluginType; +void NetConnect::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); } -QWidget *NetConnect::get_plugin_ui(){ - return pluginWidget; +void NetConnect::initSearchText() { + ui->detailBtn->setText(tr("Network settings")); + //~ contents_path /netconnect/Netconnect Status + ui->titleLabel->setText(tr("Netconnect Status")); + //~ contents_path /netconnect/open wifi + ui->openLabel->setText(tr("open wifi")); } -void NetConnect::plugin_delay_control(){ +void NetConnect::initComponent() { + wifiBtn = new SwitchButton(pluginWidget); + ui->openWIifLayout->addWidget(wifiBtn); -} + mWlanDetail = new NetDetail(true, pluginWidget); + mLanDetail = new NetDetail(false, pluginWidget); -void NetConnect::initComponent(){ + ui->detailLayOut->addWidget(mWlanDetail); + ui->detailLayOut->addWidget(mLanDetail); - const QByteArray id(CONTROL_CENTER_WIFI); - if(QGSettings::isSchemaInstalled(id)) { -// qDebug()<<"isSchemaInstalled"<setVisible(false); + mWlanDetail->setVisible(false); - // 监听key的value是否发生了变化 - connect(m_gsettings, &QGSettings::changed, this, [=] (const QString &key) { -// qDebug()<<"status changed ------------>"<setChecked(judge); - } - }); - } + // 接收到系统创建网络连接的信号时刷新可用网络列表 + QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/NetworkManager/Settings"), "org.freedesktop.NetworkManager.Settings", "NewConnection", this, SLOT(getNetList(void))); + // 接收到系统删除网络连接的信号时刷新可用网络列表 + QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/NetworkManager/Settings"), "org.freedesktop.NetworkManager.Settings", "ConnectionRemoved", this, SLOT(getNetList(void))); + // 接收到系统更改网络连接属性时把判断是否已刷新的bool值置为false + QDBusConnection::systemBus().connect(QString(), QString("/org/freedesktop/NetworkManager"), "org.freedesktop.NetworkManager", "PropertiesChanged", this, SLOT(netPropertiesChangeSlot(QMap))); + connect(m_interface, SIGNAL(getWifiListFinished()), this, SLOT(getNetList())); + connect(refreshTimer, SIGNAL(timeout()), this, SLOT(refreshNetInfoTimerSlot())); + connect(m_interface,SIGNAL(configurationChanged()), this, SLOT(refreshNetInfoSlot())); - //详细设置按钮connect - connect(ui->detailBtn, &QPushButton::clicked, this, [=](bool checked){ + connect(ui->RefreshBtn, &QPushButton::clicked, this, [=](bool checked) { Q_UNUSED(checked) - runExternalApp(); + setWifiBtnDisable(); + QTimer::singleShot(5*1000, this, [ = ]() { //超时时间 + if (!ui->RefreshBtn->isEnabled()) { + ui->RefreshBtn->setEnabled(true); + ui->RefreshBtn->setText(tr("Refresh")); + } + }); + if (m_interface) { + m_interface->call("requestRefreshWifiList"); + } }); - connect(ui->RefreshBtn, &QPushButton::clicked, this, [=](bool checked){ + connect(ui->detailBtn, &QPushButton::clicked, this, [=](bool checked) { Q_UNUSED(checked) - clearContent(); - ui->waitLabel->setVisible(true); - ui->statuswaitLabel->setVisible(true); - ui->RefreshBtn->setEnabled(false); - wifiBtn->setEnabled(false); - QTimer::singleShot(1*1000,this,SLOT(getNetList())); + runExternalApp(); }); if (getwifiisEnable()) { wifiBtn->setChecked(getInitStatus()); } - connect(wifiBtn, &SwitchButton::checkedChanged, this,[=](bool checked){ - clearContent(); - ui->waitLabel->setVisible(true); - ui->statuswaitLabel->setVisible(true); - ui->RefreshBtn->setEnabled(false); - wifiBtn->setEnabled(false); - + connect(wifiBtn, &SwitchButton::checkedChanged, this,[=](bool checked) { wifiBtn->blockSignals(true); wifiSwitchSlot(checked); wifiBtn->blockSignals(false); + if (m_interface) { + m_interface->call("requestRefreshWifiList"); + } }); ui->RefreshBtn->setEnabled(false); wifiBtn->setEnabled(false); + ui->openWifiFrame->setVisible(false); emit ui->RefreshBtn->clicked(true); - ui->verticalLayout_2->setContentsMargins(0,0,32,0); + ui->verticalLayout_2->setContentsMargins(0, 0, 32, 0); +} + +void NetConnect::refreshNetInfoTimerSlot() { + refreshTimer->start(); } -void NetConnect::rebuildNetStatusComponent(QString iconPath, QString netName){ - ////构建Widget - QWidget * baseWidget = new QWidget(); - baseWidget->setAttribute(Qt::WA_DeleteOnClose); - - QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget); - baseVerLayout->setSpacing(0); - baseVerLayout->setContentsMargins(0, 0, 0, 2); - - QFrame * devFrame = new QFrame(baseWidget); - devFrame->setFrameShape(QFrame::Shape::Box); - devFrame->setMinimumWidth(550); - devFrame->setMaximumWidth(960); - devFrame->setMinimumHeight(50); - devFrame->setMaximumHeight(50); - -// devFrame->setFixedHeight(50); -// devFrame->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - QHBoxLayout * devHorLayout = new QHBoxLayout(devFrame); - devHorLayout->setSpacing(8); - devHorLayout->setContentsMargins(16, 0, 0, 0); - - QLabel * iconLabel = new QLabel(devFrame); - QSizePolicy iconSizePolicy = iconLabel->sizePolicy(); - iconSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); - iconSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); - iconLabel->setSizePolicy(iconSizePolicy); - iconLabel->setScaledContents(true); - iconLabel->setPixmap(QPixmap(iconPath)); - - QLabel * nameLabel = new QLabel(devFrame); - QSizePolicy nameSizePolicy = nameLabel->sizePolicy(); - nameSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); - nameSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); - nameLabel->setSizePolicy(nameSizePolicy); - nameLabel->setScaledContents(true); - if ("No Net" != netName) { - nameLabel->setText(netName); - } - - QLabel * statusLabel = new QLabel(devFrame); - QSizePolicy statusSizePolicy = statusLabel->sizePolicy(); - statusSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); - statusSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); - statusLabel->setSizePolicy(statusSizePolicy); - statusLabel->setScaledContents(true); - if ("No Net" != netName) { - statusLabel->setText(tr("connected")); +void NetConnect::refreshNetInfoSlot() { + refreshTimer->stop(); + emit ui->RefreshBtn->clicked(true); + if (mLanDetail->isVisible()) { + mLanDetail->setVisible(false); + } else if (mWlanDetail->isVisible()) { + mWlanDetail->setVisible(false); + } +} +void NetConnect::rebuildNetStatusComponent(QString iconPath, QString netName) { + bool hasNet = false; + if (netName == "无连接" || netName == "No net") { + hasNet = true; + } + HoverBtn * deviceItem; + if (hasNet || Utils::isWayland()) { + deviceItem = new HoverBtn(netName, false, pluginWidget); } else { - statusLabel->setText(tr("No network")); + deviceItem = new HoverBtn(netName, true, pluginWidget); } + deviceItem->mPitLabel->setText(netName); + if (!hasNet) { + deviceItem->mDetailLabel->setText(tr("Connected")); + } else { + deviceItem->mDetailLabel->setText(""); + } + QIcon searchIcon = QIcon::fromTheme(iconPath); + deviceItem->mPitIcon->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); - devHorLayout->addWidget(iconLabel); - devHorLayout->addWidget(nameLabel); - devHorLayout->addWidget(statusLabel); - devHorLayout->addStretch(); - - devFrame->setLayout(devHorLayout); - - baseVerLayout->addWidget(devFrame); - baseVerLayout->addStretch(); + deviceItem->mAbtBtn->setMinimumWidth(100); + deviceItem->mAbtBtn->setText(tr("Detail")); - baseWidget->setLayout(baseVerLayout); + connect(deviceItem->mAbtBtn, &QPushButton::clicked, this, [=] { + netDetailSlot(deviceItem->mName); + }); - ui->statusLayout->addWidget(baseWidget); + ui->statusLayout->addWidget(deviceItem); } void NetConnect::getNetList() { + wifiBtn->blockSignals(true); + wifiBtn->setChecked(getInitStatus()); + wifiBtn->blockSignals(false); + bool isWayland = false; + if (Utils::isWayland()) { + isWayland = true; + } + QDBusReply> reply = m_interface->call("getWifiList"); + if (!reply.isValid()) { + qWarning() << "value method called failed!"; + } + this->TlanList = execGetLanList(); + getWifiListDone(reply, this->TlanList, isWayland); + + for (int i = 0; i < reply.value().length(); i++) { + QString wifiName; + if (reply.value().at(i).at(0) == "--") { + continue; + } + if (isWayland) { + wifiName = reply.value().at(i).at(0) + reply.value().at(i).at(5); + } else { + wifiName = reply.value().at(i).at(0); + } - bool wifiSt = getwifiisEnable(); - if (!wifiSt) { - wifiBtn->setChecked(wifiSt); + if (reply.value().at(i).at(2) != NULL && reply.value().at(i).at(2) != "--") { + wifiName += "lock"; + } + QString signal = reply.value().at(i).at(1); + wifiLists.insert(wifiName,this->setSignal(signal)); } - wifiBtn->setEnabled(wifiSt); - this->TlanList = execGetLanList(); - pThread = new QThread; - pNetWorker = new NetconnectWork; - - connect(pNetWorker, &NetconnectWork::wifiGerneral,this,[&](QStringList list){ - this->TwifiList = list; - getWifiListDone(this->TwifiList, this->TlanList); - QMap::iterator iter = this->wifiList.begin(); - QString iconamePah; - while(iter != this->wifiList.end()) { - if (!wifiBtn->isChecked()){ - break; - } - iconamePah= ":/img/plugins/netconnect/wifi" + QString::number(iter.value())+".svg"; - rebuildAvailComponent(iconamePah , iter.key()); - iter++; - } - - for(int i = 0; i < this->lanList.length(); i++) { ; - iconamePah= ":/img/plugins/netconnect/eth.svg"; - rebuildAvailComponent(iconamePah , lanList.at(i)); + QMap::iterator iterator = this->wifiLists.begin(); + QVector> vector; + QString iconamePath; + while (iterator != this->wifiLists.end()) { + vector.push_back(qMakePair(iterator.key(), iterator.value())); + iterator++; + } + qSort(vector.begin(), vector.end(), sortByVal); + for (int i = 0; i < vector.size(); i++) { + if (!wifiBtn->isChecked()) { + break; + } + bool isLock = vector[i].first.contains("lock"); + QString wifiName = isLock ? vector[i].first.remove("lock") : vector[i].first; + if (isWayland) { + int category = wifiName.right(1).toInt(); + wifiName = wifiName.left(wifiName.size() - 1); + iconamePath = wifiIcon(isLock, vector[i].second, category); + } else { + iconamePath = wifiIcon(isLock, vector[i].second); } + rebuildAvailComponent(iconamePath, wifiName); + } - }); - connect(pNetWorker, &NetconnectWork::workerComplete,this, [=]{ - pThread->quit(); - pThread->wait(); - }); - pNetWorker->moveToThread(pThread); - connect(pThread, &QThread::started, pNetWorker, &NetconnectWork::run); - connect(pThread, &QThread::finished, this, [=]{ - bool wifiSt = getwifiisEnable(); - wifiBtn->setEnabled(wifiSt); - ui->RefreshBtn->setEnabled(true); + for (int i = 0; i < this->lanList.length(); i++) { + rebuildAvailComponent(KLanSymbolic , lanList.at(i)); + } + setNetDetailVisible(); +} - ui->waitLabel->setVisible(false); - ui->statuswaitLabel->setVisible(false); - }); - connect(pThread, &QThread::finished, pNetWorker, &NetconnectWork::deleteLater); - pThread->start(); +void NetConnect::netPropertiesChangeSlot(QMap property) { + if (property.keys().contains("WirelessEnabled")) { + setWifiBtnDisable(); + if (m_interface) { + m_interface->call("requestRefreshWifiList"); + } + } } -void NetConnect::rebuildAvailComponent(QString iconPath, QString netName){ +void NetConnect::netDetailSlot(QString netName) { + foreach (ActiveConInfo netInfo, mActiveInfo) { + if (!netInfo.strConName.compare(netName, Qt::CaseInsensitive)) { + if (!netInfo.strConType.compare("802-3-ethernet", Qt::CaseInsensitive)) { + mIsLanVisible = !mIsLanVisible; + mLanDetail->setSSID(netInfo.strConName); + mLanDetail->setProtocol(netInfo.strConType); + mLanDetail->setIPV4(netInfo.strIPV4Address); + mLanDetail->setIPV4Dns(netInfo.strIPV4Dns); + mLanDetail->setIPV4Gateway(netInfo.strIPV4GateWay); + mLanDetail->setIPV4Mask(netInfo.strIPV4Prefix); + mLanDetail->setIPV6(netInfo.strIPV6Address); + mLanDetail->setIPV6Prefix(netInfo.strIPV6Prefix); + + mLanDetail->setIPV6Gt(netInfo.strIPV6GateWay); + mLanDetail->setIPV6(netInfo.strIPV6GateWay); + mLanDetail->setMac(netInfo.strMac); + mLanDetail->setBandWidth(netInfo.strBandWidth); + + mLanDetail->setVisible(mIsLanVisible); + } else { + mIsWlanVisible = !mIsWlanVisible; + + mWlanDetail->setSSID(netInfo.strConName); + mWlanDetail->setProtocol(netInfo.strConType); + mWlanDetail->setSecType(netInfo.strSecType); + mWlanDetail->setHz(netInfo.strHz); + mWlanDetail->setChan(netInfo.strChan); + mWlanDetail->setSpeed(netInfo.strSpeed); + mWlanDetail->setIPV4(netInfo.strIPV4Address); + mWlanDetail->setIPV4Mask(netInfo.strIPV4Prefix); + mWlanDetail->setIPV4Dns(netInfo.strIPV4Dns); + mWlanDetail->setIPV4Gateway(netInfo.strIPV4GateWay); + mWlanDetail->setIPV6(netInfo.strIPV6Address); + mWlanDetail->setIPV6Prefix(netInfo.strIPV6Prefix); + mWlanDetail->setIPV6Gt(netInfo.strIPV6GateWay); + mWlanDetail->setMac(netInfo.strMac); + mWlanDetail->setBandWidth(netInfo.strBandWidth); + + mWlanDetail->setVisible(mIsWlanVisible); + } + } + } +} - ////构建Widget - QWidget * baseWidget = new QWidget(); - baseWidget->setAttribute(Qt::WA_DeleteOnClose); - - QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget); - baseVerLayout->setSpacing(0); - baseVerLayout->setContentsMargins(0, 0, 0, 2); - - QFrame * devFrame = new QFrame(baseWidget); - devFrame->setFrameShape(QFrame::Shape::Box); - devFrame->setMinimumWidth(550); - devFrame->setMaximumWidth(960); - devFrame->setMinimumHeight(50); - devFrame->setMaximumHeight(50); - -// devFrame->setFixedHeight(50); -// devFrame->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - QHBoxLayout * devHorLayout = new QHBoxLayout(devFrame); - devHorLayout->setSpacing(8); - devHorLayout->setContentsMargins(16, 0, 0, 0); - - QLabel * iconLabel = new QLabel(devFrame); - QSizePolicy iconSizePolicy = iconLabel->sizePolicy(); - iconSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); - iconSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); - iconLabel->setSizePolicy(iconSizePolicy); - iconLabel->setScaledContents(true); - iconLabel->setPixmap(QPixmap(iconPath)); - - QLabel * nameLabel = new QLabel(devFrame); - QSizePolicy nameSizePolicy = nameLabel->sizePolicy(); - nameSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); - nameSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); - nameLabel->setSizePolicy(nameSizePolicy); - nameLabel->setScaledContents(true); - nameLabel->setText(netName); - -// QLabel * statusLabel = new QLabel(devFrame); -// QSizePolicy statusSizePolicy = statusLabel->sizePolicy(); -// statusSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); -// statusSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); -// statusLabel->setSizePolicy(statusSizePolicy); -// statusLabel->setScaledContents(true); -// statusLabel->setText(netName); - - devHorLayout->addWidget(iconLabel); - devHorLayout->addWidget(nameLabel); -// devHorLayout->addWidget(statusLabel); - devHorLayout->addStretch(); - - devFrame->setLayout(devHorLayout); - - baseVerLayout->addWidget(devFrame); -// baseVerLayout->addStretch(); +void NetConnect::rebuildAvailComponent(QString iconPath, QString netName) { + HoverBtn * wifiItem = new HoverBtn(netName, false, pluginWidget); + wifiItem->mPitLabel->setText(netName); + + QIcon searchIcon = QIcon::fromTheme(iconPath); + if (iconPath != KLanSymbolic && iconPath != NoNetSymbolic) { + wifiItem->mPitIcon->setProperty("useIconHighlightEffect", 0x10); + } + wifiItem->mPitIcon->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(24, 24)))); + wifiItem->mAbtBtn->setMinimumWidth(100); + wifiItem->mAbtBtn->setText(tr("Connect")); -// baseWidget->setLayout(baseVerLayout); + connect(wifiItem->mAbtBtn, &QPushButton::clicked, this, [=] { + runKylinmApp(); + }); - ui->availableLayout->addWidget(baseWidget); + ui->availableLayout->addWidget(wifiItem); } - -void NetConnect::runExternalApp(){ +void NetConnect::runExternalApp() { QString cmd = "nm-connection-editor"; QProcess process(this); process.startDetached(cmd); } -bool NetConnect::getwifiisEnable() -{ +void NetConnect::runKylinmApp() { + QString cmd = "kylin-nm"; + QProcess process(this); + process.startDetached(cmd); +} + +bool NetConnect::getwifiisEnable() { QDBusInterface m_interface( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.NetworkManager", @@ -338,7 +392,7 @@ QList obj_paths = obj_reply.value(); - foreach (QDBusObjectPath obj_path, obj_paths){ + foreach (QDBusObjectPath obj_path, obj_paths) { QDBusInterface interface( "org.freedesktop.NetworkManager", obj_path.path(), "org.freedesktop.DBus.Introspectable", @@ -349,17 +403,17 @@ qDebug()<<"execute dbus method 'Introspect' is invalid in func getObjectPath()"; } - if(reply.value().indexOf("org.freedesktop.NetworkManager.Device.Wired") != -1){ - } else if (reply.value().indexOf("org.freedesktop.NetworkManager.Device.Wireless") != -1){ + if(reply.value().indexOf("org.freedesktop.NetworkManager.Device.Wired") != -1) { + + } else if (reply.value().indexOf("org.freedesktop.NetworkManager.Device.Wireless") != -1) { return true; } } return false ; } - -QStringList NetConnect::execGetLanList(){ - QProcess *lanPro = new QProcess(); +QStringList NetConnect::execGetLanList() { + QProcess *lanPro = new QProcess(this); QString shellOutput = ""; lanPro->start("nmcli -f type,device,name connection show"); lanPro->waitForFinished(); @@ -367,151 +421,254 @@ shellOutput += output; QStringList slist = shellOutput.split("\n"); -// qDebug()<<"lanslist--------------->"<"< m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled"); + if (m_result.isValid()) { + bool status = m_result.value().toBool(); + return status; + } else { + qDebug()<<"org.freedesktop.NetworkManager get invalid"< getwifislist, QStringList getlanList, bool isWayland) { + clearContent(); + mActiveInfo.clear(); + QString speed = getWifiSpeed(); + if (!speed.contains("/") && secondCount < 1) { + QTimer::singleShot(1000,this, [=] { + getWifiSpeed(); + secondCount ++; + }); + } else { + if (getActiveConInfo(mActiveInfo) == -1 || speed == "/" && firstCount < 4 && !getWifiStatus()) { + QTimer::singleShot(500,this, [=] { + getNetList(); + firstCount++; + }); + } else { + firstCount = 0; + secondCount = 0; + bool isNullSpeed = false; + if (!speed.contains("/")) { + speed = "null/" + speed; + } else if (speed == "/") { + isNullSpeed = true; } - index ++; - } -// qDebug()<<"now wifi is----->"<setSignal(getwifislist.at(i).at(1))); + } + } + } + if (!getlanList.isEmpty()) { + lanList.clear(); + connectedLan.clear(); + + int indexLan = 0; + while (indexLan < mActiveInfo.size()) { + if (mActiveInfo[indexLan].strConType == "ethernet" + || mActiveInfo[indexLan].strConType == "802-3-ethernet"){ + actLanName = mActiveInfo[indexLan].strConName; + break; + } + indexLan ++; + } - QStringList wnames; - int count = 0; - for(int i = 1; i < getwifislist.size(); i ++) { - QString line = getwifislist.at(i); - QString wsignal = line.mid(0, indexName).trimmed(); - QString wname = line.mid(indexName).trimmed(); + // 填充可用网络列表 + QString headLine = getlanList.at(0); + 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"); + } - bool isContinue = false; - foreach (QString addName, wnames) { - // 重复的网络名称,跳过不处理 - if(addName == wname){ isContinue = true; } + for (int i =1 ;i < getlanList.length(); i++) { + QString line = getlanList.at(i); + QString ltype = line.mid(0, indexDevice).trimmed(); + QString nname = line.mid(indexName).trimmed(); + if (ltype != "wifi" && ltype != "" && ltype != "--") { + this->lanList << nname; + } + } } - if(isContinue){ continue; } + if (!this->connectedWifi.isEmpty()) { + QMap::iterator iter = this->connectedWifi.begin(); - if(wname != "" && wname != "--"){ - int strength = this->setSignal(wsignal); - wifiList.insert(wname, strength); + QString connectedWifiName = iter.key(); + int strength = iter.value(); - if(wname == actWifiName) { - connectedWifi.insert(wname, strength); + bool isLock = connectedWifiName.contains("lock"); + connectedWifiName = isLock ? connectedWifiName.remove("lock") : connectedWifiName; + QString iconamePah; + if (isWayland) { + int category = connectedWifiName.right(1).toInt(); + connectedWifiName = connectedWifiName.left(connectedWifiName.size() - 1); + iconamePah = wifiIcon(isLock, strength, category); + } else { + iconamePah = wifiIcon(isLock, strength); } - wnames.append(wname); + rebuildNetStatusComponent(iconamePah, connectedWifiName); + } + if (!this->actLanName.isEmpty()) { + QString lanIconamePah = KLanSymbolic; + rebuildNetStatusComponent(lanIconamePah, this->actLanName); } - } - } - - if(!getlanList.isEmpty()){ - lanList.clear(); - connectedLan.clear(); -// qDebug()<<"the net type is----->"<connectedWifi.isEmpty() && this->actLanName.isEmpty()) { + rebuildNetStatusComponent(NoNetSymbolic , tr("No net")); } - indexLan ++; } -// qDebug()<<"actLanName is-------->"<actLanName<"<lanList << nname; - } - } -// qDebug()<<"lanList is-------------->"<start("iw dev wlan0 link"); + lanPro->waitForFinished(); + output = lanPro->readAll(); + foreach (QString line, output.split("\n")) { + line.replace(QRegExp("[\\s]+"), ""); + slist.append(line); } - if (!this->connectedWifi.isEmpty()){ - QMap::iterator iter = this->connectedWifi.begin(); - QString iconamePah = ":/img/plugins/netconnect/wifi" + QString::number(iter.value())+".svg"; -// qDebug()<<"name is=------------>"<actLanName.isEmpty()){ - QString lanIconamePah= ":/img/plugins/netconnect/eth.svg"; - rebuildNetStatusComponent(lanIconamePah, this->actLanName); -// qDebug()<<"name is=------------>"<actLanName; + QString uSpeed; + QString dSpeed; + for (int i = 0; i < rxSpeed.length(); i++) { + if (rxSpeed.at(i) == ".") { + break; + } else if (rxSpeed.at(i).toLatin1() >= '0' && rxSpeed.at(i).toLatin1() <= '9'){ + uSpeed.append(rxSpeed.at(i)); + } } - - if (this->connectedWifi.isEmpty() && this->actLanName.isEmpty()) { - rebuildNetStatusComponent(":/img/plugins/netconnect/nonet.svg" , "No Net"); + for (int i = 0; i < txSpeed.length(); i++) { + if (txSpeed.at(i) == ".") { + break; + } else if (txSpeed.at(i).toLatin1() >= '0' && txSpeed.at(i).toLatin1() <= '9'){ + dSpeed.append(txSpeed.at(i)); + } } + if (uSpeed == "" && dSpeed == "") { + return "/"; + } else if (uSpeed == "" && dSpeed != "") { + return dSpeed; + } + return uSpeed + "/" + dSpeed; } -bool NetConnect::getSwitchStatus(QString key){ -// qDebug()<<"key is------------->"<start("nmcli -f in-use,chan device wifi"); + lanPro->waitForFinished(); + QString output = lanPro->readAll(); + foreach (QString line, output.split("\n")) { + line.replace(QRegExp("[\\s]+"), ""); + slist.append(line); + } + for (int i = 0; i < slist.length(); i++) { + QString str = slist.at(i); + if (str.contains("*")) { + isHas = true; + } } - const QStringList list = m_gsettings->keys(); - if (!list.contains(key)) { - return true; + if (isHas) { + for (int i = 0; i < slist.length(); i++) { + QString str = slist.at(i); + if (str.contains("*")) { + str.remove("*"); + prefreChan = str; + return str; + } + } + } else { + return prefreChan; } - bool res = m_gsettings->get(key).toBool(); - return res; } - -bool NetConnect::getInitStatus() -{ +bool NetConnect::getInitStatus() { QDBusInterface interface( "org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus() ); - //获取当前wifi是否连接 + // 获取当前wifi是否打开 QDBusReply m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled"); - if (m_result.isValid()){ + if (m_result.isValid()) { bool status = m_result.value().toBool(); return status; } else { @@ -520,28 +677,24 @@ } } -void NetConnect::clearContent() -{ +void NetConnect::clearContent() { if (ui->availableLayout->layout() != NULL) { QLayoutItem* item; - while ((item = ui->availableLayout->layout()->takeAt( 0 )) != NULL ) - { + while ((item = ui->availableLayout->layout()->takeAt(0)) != NULL ) { delete item->widget(); delete item; + item = nullptr; } -// delete ui->availableLayout->layout(); } if (ui->statusLayout->layout() != NULL) { QLayoutItem* item; - while ((item = ui->statusLayout->layout()->takeAt( 0 )) != NULL ) - { + while ((item = ui->statusLayout->layout()->takeAt(0)) != NULL) { delete item->widget(); delete item; + item = nullptr; } -// delete ui->availableLayout->layout(); } -// ui->statusListWidget->clear(); this->connectedLan.clear(); this->connectedWifi.clear(); @@ -552,42 +705,247 @@ this->TwifiList.clear(); } -//get wifi's strength +void NetConnect::setWifiBtnDisable() { + ui->RefreshBtn->setText(tr("Refreshing...")); + ui->RefreshBtn->setEnabled(false); + wifiBtn->setEnabled(false); + ui->openWifiFrame->setVisible(false); +} + +void NetConnect::setNetDetailVisible() { + bool wifiSt = getwifiisEnable(); + wifiBtn->setEnabled(wifiSt); + ui->openWifiFrame->setVisible(wifiSt); + ui->RefreshBtn->setEnabled(true); + ui->RefreshBtn->setText(tr("Refresh")); + + if (!mActiveInfo.count()) { + this->mWlanDetail->setVisible(false); + this->mLanDetail->setVisible(false); + } else if (1 == mActiveInfo.count()){ + if (mActiveInfo.at(0).strConType.contains("802-11-wireless", Qt::CaseSensitive)) { + this->mLanDetail->setVisible(false); + } else { + this->mWlanDetail->setVisible(false); + } + } +} + +QList NetConnect::getDbusMap(const QDBusMessage &dbusMessage) { + QList outArgsIpv4 = dbusMessage.arguments(); + QVariant firstIpv4 = outArgsIpv4.at(0); + QDBusVariant dbvFirstIpv4 = firstIpv4.value(); + QVariant vFirstIpv4 = dbvFirstIpv4.variant(); + + const QDBusArgument &dbusArgIpv4 = vFirstIpv4.value(); + QList mDatasIpv4; + dbusArgIpv4 >> mDatasIpv4; + + return mDatasIpv4; +} + +QString NetConnect::wifiIcon(bool isLock, int strength, int category) { + switch (category) { + case 0: + switch (strength) { + case 1: + return isLock ? KWifiLockSymbolic : KWifiSymbolic; + case 2: + return isLock ? KWifiLockGood : KWifiGood; + case 3: + return isLock ? KWifiLockOK : KWifiOK; + case 4: + return isLock ? KWifiLockLow : KWifiLow; + default: + return ""; + } + case 1: + switch (strength) { + case 1: + return KWifi6LockSymbolic; + case 2: + return KWifi6LockGood; + case 3: + return KWifi6LockOK; + case 4: + return KWifi6LockLow; + default: + return ""; + } + case 2: + switch (strength) { + case 1: + return KWifi6ProLockSymbolic; + case 2: + return KWifi6ProLockGood; + case 3: + return KWifi6ProLockOK; + case 4: + return KWifi6ProLockLow; + default: + return ""; + } + default: + return ""; + } +} + +QString NetConnect::wifiIcon(bool isLock, int strength) { + switch (strength) { + case 1: + return isLock ? KWifiLockSymbolic : KWifiSymbolic; + case 2: + return isLock ? KWifiLockGood : KWifiGood; + case 3: + return isLock ? KWifiLockOK : KWifiOK; + case 4: + return isLock ? KWifiLockLow : KWifiLow; + default: + return ""; + } +} + int NetConnect::setSignal(QString lv) { int signal = lv.toInt(); -// qDebug()<<"signal is---------->"< 75){ + if (signal > 75) { signalLv = 1; - } - if(signal > 55 && signal <= 75){ + } else if (signal > 55 && signal <= 75) { signalLv = 2; - } - if(signal > 35 && signal <= 55){ + } else if (signal > 35 && signal <= 55) { signalLv = 3; - } - if(signal > 15 && signal <= 35){ - signalLv = 4; - } - if(signal <= 15){ + } else if (signal <= 35) { signalLv = 4; } return signalLv; } -void NetConnect::wifiSwitchSlot(bool signal){ - if(!m_gsettings) { - return ; - } - const QStringList list = m_gsettings->keys(); - if (!list.contains("switch")) { - return ; - } - m_gsettings->set("switch",signal); +void NetConnect::wifiSwitchSlot(bool status) { - QTimer::singleShot(2*1000,this,SLOT(getNetList())); + QString wifiStatus = status ? "on" : "off"; + QString program = "nmcli"; + QStringList arg; + arg << "radio" << "wifi" << wifiStatus; + QProcess *nmcliCmd = new QProcess(this); + nmcliCmd->start(program, arg); + nmcliCmd->waitForStarted(); } +int NetConnect::getActiveConInfo(QList& qlActiveConInfo) { + ActiveConInfo activeNet; + + + QDBusInterface interface( "org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager", + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus() ); + 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(); + const QDBusArgument &dbusArgs = vFirst.value(); + + QDBusObjectPath objPath; + dbusArgs.beginArray(); + + while (!dbusArgs.atEnd()) { + dbusArgs >> objPath; + QDBusInterface interfacePro("org.freedesktop.NetworkManager", + objPath.path(), + "org.freedesktop.NetworkManager.Connection.Active", + QDBusConnection::systemBus()); + QVariant replyType = interfacePro.property("Type"); + QVariant replyUuid = interfacePro.property("Uuid"); + QVariant replyId = interfacePro.property("Id"); + + activeNet.strConName = replyId.toString(); + activeNet.strConType = replyType.toString(); + activeNet.strConUUID = replyUuid.toString(); + + QString replyIPV4Path = interfacePro.property("Ip4Config") + .value() + .path(); + //如果此时获取的path 为 "/" ,说明出现异常,则需要进行异常处理 + // IPV4信息 + if (replyIPV4Path == "/") { + return -1; + } else { + QDBusInterface IPV4ifc("org.freedesktop.NetworkManager", + replyIPV4Path, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + + QDBusMessage replyIpv4 = IPV4ifc.call("Get", "org.freedesktop.NetworkManager.IP4Config", "AddressData"); + QList datasIpv4 = getDbusMap(replyIpv4); + + if (!datasIpv4.isEmpty()) { + activeNet.strIPV4Address = datasIpv4.at(0).value("address").toString(); + activeNet.strIPV4Prefix = datasIpv4.at(0).value("prefix").toString(); + } + QDBusMessage replyIPV4Dns = IPV4ifc.call("Get", "org.freedesktop.NetworkManager.IP4Config", "NameserverData"); + QList datasIpv4Dns = getDbusMap(replyIPV4Dns); + if (!datasIpv4Dns.isEmpty()) { + activeNet.strIPV4Dns = datasIpv4Dns.at(0).value("address").toString(); + } + + QDBusMessage replyIPV4Gt = IPV4ifc.call("Get", "org.freedesktop.NetworkManager.IP4Config", "Gateway"); + + QVariant ipv4Gt = replyIPV4Gt.arguments().at(0) + .value() + .variant(); + + + activeNet.strIPV4GateWay = ipv4Gt.toString(); + + // IPV6信息 + QString replyIpv6Path = interfacePro.property("Ip6Config") + .value() + .path(); + + QDBusInterface IPV6ifc("org.freedesktop.NetworkManager", + replyIpv6Path, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + QDBusMessage replyIPV6 = IPV6ifc.call("Get", "org.freedesktop.NetworkManager.IP6Config", "AddressData"); + QList dataIPV6 = getDbusMap(replyIPV6); + if (!dataIPV6.isEmpty()) { + activeNet.strIPV6Address = dataIPV6.at(0).value("address").toString(); + activeNet.strIPV6Prefix = dataIPV6.at(0).value("prefix").toString(); + } + + QDBusMessage replyIPV6Gt = IPV6ifc.call("Get", "org.freedesktop.NetworkManager.IP6Config", "GateWay"); + QVariant IPV6Gt = replyIPV6Gt.arguments().at(0) + .value() + .variant(); + activeNet.strIPV6GateWay = IPV6Gt.toString().isEmpty() ? activeNet.strIPV6Address : IPV6Gt.toString(); + + // 设备信息 + auto replyDevicesPaths = interfacePro.property("Devices") + .value>(); + + if (!activeNet.strConType.compare("802-3-ethernet", Qt::CaseInsensitive)) { + QDBusInterface netDeviceifc("org.freedesktop.NetworkManager", + replyDevicesPaths.at(0).path(), + "org.freedesktop.NetworkManager.Device.Wired", + QDBusConnection::systemBus()); + activeNet.strBandWidth = netDeviceifc.property("Speed").toString(); + activeNet.strMac = netDeviceifc.property("HwAddress").toString().toLower(); + } else { + QDBusInterface netDeviceifc("org.freedesktop.NetworkManager", + replyDevicesPaths.at(0).path(), + "org.freedesktop.NetworkManager.Device.Wireless", + QDBusConnection::systemBus()); + activeNet.strBandWidth = netDeviceifc.property("Bitrate").toString(); + activeNet.strMac = netDeviceifc.property("HwAddress").toString().toLower(); + } + qlActiveConInfo.append(activeNet); + } + + } + dbusArgs.endArray(); + return 1; +} diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/netconnect.h ukui-control-center-3.0.3/plugins/network/netconnect/netconnect.h --- ukui-control-center-2.0.3/plugins/network/netconnect/netconnect.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/netconnect.h 2021-05-20 13:08:14.000000000 +0000 @@ -30,12 +30,22 @@ #include #include +#include #include +#include +#include +#include +#include + +#include +#include +#include +#include -#include "wifi.h" #include "netconnectwork.h" #include "shell/interface.h" #include "SwitchButton/switchbutton.h" +#include "netdetail.h" enum { DISCONNECTED, @@ -59,6 +69,26 @@ class NetConnect; } +typedef struct ActiveConInfo_s { + QString strConName; + QString strConUUID; + QString strConType; + QString strSecType; + QString strChan; + QString strSpeed; + QString strMac; + QString strHz; + + QString strIPV4Address; + QString strIPV4Prefix; + QString strIPV4Dns; + QString strIPV4GateWay; + + QString strBandWidth; + QString strIPV6Address; + QString strIPV6GateWay; + QString strIPV6Prefix; +}ActiveConInfo; class NetConnect : public QObject, CommonInterface { @@ -74,57 +104,90 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: - void initComponent(); + void initTitleLabel(); + void initSearchText(); + void initComponent(); void rebuildNetStatusComponent(QString iconPath, QString netName); void rebuildAvailComponent(QString iconpath, QString netName); void runExternalApp(); + void runKylinmApp(); bool getwifiisEnable(); -private: - Ui::NetConnect *ui; + int getActiveConInfo(QList& qlActiveConInfo); - QString pluginName; - int pluginType; - QWidget * pluginWidget; +private: + Ui::NetConnect *ui; - SwitchButton *wifiBtn; + QString pluginName; + int pluginType; + QWidget *pluginWidget; - QMap connectedWifi; - QMap wifiList; //wifi list - QStringList lanList; // list of wired network - QString connectedLan; - QGSettings *m_gsettings = nullptr; - - Wifi *m_wifiList; - QThread *pThread; - NetconnectWork *pNetWorker; - QStringList TwifiList; - QStringList TlanList; - - QString actLanName; + QDBusInterface *m_interface = nullptr; + SwitchButton *wifiBtn; + QMap connectedWifi; + QMap wifiList; + QMap wifiLists; + QThread *pThread; + NetconnectWork *pNetWorker; + + QString connectedLan; + QString actLanName; + + QStringList TwifiList; + QStringList TlanList; + QStringList lanList; + + bool mFirstLoad; + + bool mIsLanVisible = false; + bool mIsWlanVisible = false; + + NetDetail *mWlanDetail; + NetDetail *mLanDetail; + + QList mActiveInfo; + QTimer *refreshTimer; + QString prefreChan; + int firstCount = 0; + int secondCount = 0; private: - int setSignal(QString lv); //get wifi's strength + int setSignal(QString lv); QStringList execGetLanList(); - void getWifiListDone(QStringList wifislist, QStringList lanList); - bool getSwitchStatus(QString key); - - /* - * the wifi's origin status - */ - bool getInitStatus(); - - // clear the lan and wifi list - void clearContent(); - + void getWifiListDone(QVector wifislist, QStringList lanList, bool getWifiListDone); + QString geiWifiChan(); + QString getWifiSpeed(); + bool getInitStatus(); + bool getWifiStatus(); + + void clearContent(); + + void deleteNetworkDone(QString); + void addNetworkDone(QString); + void _buildWidgetForItem(QString); + void initNetworkMap(); + void setWifiBtnDisable(); + void setNetDetailVisible(); // 设置网络刷新状态 + QString wifiIcon(bool isLock, int strength,int category); + QString wifiIcon(bool isLock, int strength); + QList getDbusMap(const QDBusMessage &dbusMessage); private slots: - void wifiSwitchSlot(bool signal); + void wifiSwitchSlot(bool status); void getNetList(); + void netPropertiesChangeSlot(QMap property); + void netDetailSlot(QString netName); + void refreshNetInfoTimerSlot(); + void refreshNetInfoSlot(); +signals: + void refresh(); }; +Q_DECLARE_METATYPE(QList); + #endif // NETCONNECT_H diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/netconnect.pro ukui-control-center-3.0.3/plugins/network/netconnect/netconnect.pro --- ukui-control-center-2.0.3/plugins/network/netconnect/netconnect.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/netconnect.pro 2021-04-14 01:27:20.000000000 +0000 @@ -6,6 +6,7 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) +include($$PROJECT_COMPONENTSOURCE/hoverbtn.pri) QT += widgets network dbus gui core TEMPLATE = lib @@ -29,16 +30,14 @@ #DEFINES += QT_DEPRECATED_WARNINGS SOURCES += \ - kylin_network_interface.c \ netconnect.cpp \ netconnectwork.cpp \ - wifi.cpp + netdetail.cpp HEADERS += \ - kylin_network_interface.h \ netconnect.h \ netconnectwork.h \ - wifi.h + netdetail.h FORMS += \ netconnect.ui diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/netconnect.ui ukui-control-center-3.0.3/plugins/network/netconnect/netconnect.ui --- ukui-control-center-2.0.3/plugins/network/netconnect/netconnect.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/netconnect.ui 2021-04-14 01:27:20.000000000 +0000 @@ -43,6 +43,22 @@
+ + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 12 + + + + + 1 @@ -50,46 +66,7 @@ - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 20 - - - - Waitting... - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + @@ -193,18 +170,18 @@ 18 - 16 + 0 9 - 16 + 0 - + 118 @@ -244,48 +221,6 @@ - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 20 - - - - Waitting... - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - @@ -297,7 +232,7 @@ - 120 + 16777215 36 diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/netconnectwork.cpp ukui-control-center-3.0.3/plugins/network/netconnect/netconnectwork.cpp --- ukui-control-center-2.0.3/plugins/network/netconnect/netconnectwork.cpp 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/netconnectwork.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -1,5 +1,8 @@ #include "netconnectwork.h" +#include +#include + NetconnectWork::NetconnectWork() { @@ -10,15 +13,36 @@ } void NetconnectWork::run() { - QProcess *wifiPro = new QProcess(); - wifiPro->start("nmcli -f signal,ssid device wifi"); + if (!getWifiIsOpen()) { + + emit wifiGerneral(QStringList()); + return; + } + QProcess *wifiPro = new QProcess(this); + wifiPro->start("nmcli -f signal,security,chan,freq,ssid device wifi"); wifiPro->waitForFinished(); QString shellOutput = ""; QString output = wifiPro->readAll(); shellOutput += output; QStringList slist = shellOutput.split("\n"); -// qDebug()<<"slist is--------->"< m_result = interface.call("Get", "org.freedesktop.NetworkManager", "WirelessEnabled"); + + if (m_result.isValid()) { + bool status = m_result.value().toBool(); + return status; + } else { + qDebug()<<"org.freedesktop.NetworkManager get invalid"< #include - -#include "wifi.h" +#include +#include class NetconnectWork : public QObject { @@ -16,9 +16,11 @@ public: void run(); +private: + bool getWifiIsOpen(); + Q_SIGNALS: void wifiGerneral(QStringList wifiList); - void workerComplete(); }; #endif // NETCONNECTWORK_H diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/netdetail.cpp ukui-control-center-3.0.3/plugins/network/netconnect/netdetail.cpp --- ukui-control-center-2.0.3/plugins/network/netconnect/netdetail.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/netdetail.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,112 @@ +#include "netdetail.h" + +NetDetail::NetDetail(bool isWlan, QWidget *parent) : mIsWlan(isWlan), QFrame(parent) { + this->setFrameShape(QFrame::Shape::Box); + this->setMaximumWidth(960); + initUI(); +} + +void NetDetail::setSSID(const QString &ssid) { + this->mSSID->setText(ssid); +} + +void NetDetail::setProtocol(const QString &protocol) { + this->mProtocol->setText(protocol); +} + +void NetDetail::setSecType(const QString &secType) { + this->mSecType->setText(secType); +} + +void NetDetail::setHz(const QString &hz) { + this->mHz->setText(hz); +} + +void NetDetail::setChan(const QString &chan) { + this->mChan->setText(chan); +} + +void NetDetail::setSpeed(const QString &speed) { + this->mSpeed->setText(speed); +} + +void NetDetail::setBandWidth(const QString &bd) { + this->mBandWidth->setText(bd); +} + +void NetDetail::setIPV4(const QString &ipv4) { + this->mIPV4->setText(ipv4); +} + +void NetDetail::setIPV4Dns(const QString &ipv4Dns) { + this->mIPV4Dns->setText(ipv4Dns); +} + +void NetDetail::setIPV4Mask(const QString &netMask) { + this->mIPV4Mask->setText(netMask); +} + +void NetDetail::setIPV4Gateway(const QString &gateWay) { + this->mIPV4Gt->setText(gateWay); +} + +void NetDetail::setIPV6(const QString &ipv6) { + this->mIPV6->setText(ipv6); +} + +void NetDetail::setIPV6Prefix(const QString &prefix) { + this->mIPV6Prefix->setText(prefix); +} + +void NetDetail::setIPV6Gt(const QString &gateWay) { + this->mIPV6Gt->setText(gateWay); +} + +void NetDetail::setMac(const QString &mac) { + this->mMac->setText(mac); +} + +void NetDetail::initUI() { + + mDetailLayout = new QFormLayout(this); + mDetailLayout->setContentsMargins(41, 0, 0, 0); + + mSSID = new QLabel(this); + mProtocol = new QLabel(this); + mSecType = new QLabel(this); + mHz = new QLabel(this); + mChan = new QLabel(this); + mSpeed = new QLabel(this); + + mBandWidth = new QLabel(this); + mIPV4 = new QLabel(this); + mIPV4Dns = new QLabel(this); + mIPV4Gt = new QLabel(this); + mIPV4Mask = new QLabel(this); + + mIPV6 = new QLabel(this); + mIPV6Prefix= new QLabel(this); + mIPV6Gt = new QLabel(this); + mMac = new QLabel(this); + + + mDetailLayout->addRow(tr("SSID:"), mSSID); + mDetailLayout->addRow(tr("Protocol"), mProtocol); + if (mIsWlan) { + mDetailLayout->addRow(tr("Security Type:"), mSecType); + mDetailLayout->addRow(tr("Hz:"), mHz); + mDetailLayout->addRow(tr("Chan:"), mChan); + mDetailLayout->addRow(tr("Link Speed(rx/tx)"), mSpeed); + } + + mDetailLayout->addRow(tr("BandWidth:"), mBandWidth); + mDetailLayout->addRow(tr("IPV4:"), mIPV4); + mDetailLayout->addRow(tr("IPV4 Dns:"), mIPV4Dns); + mDetailLayout->addRow(tr("IPV4 GateWay:"), mIPV4Gt); + mDetailLayout->addRow(tr("IPV4 Prefix:"), mIPV4Mask); + mDetailLayout->addRow(tr("IPV6:"), mIPV6); + mDetailLayout->addRow(tr("IPV6 Prefix:"), mIPV6Prefix); + mDetailLayout->addRow(tr("IPV6 GateWay:"), mIPV6Gt); + mDetailLayout->addRow(tr("Mac:"), mMac); + +} diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/netdetail.h ukui-control-center-3.0.3/plugins/network/netconnect/netdetail.h --- ukui-control-center-2.0.3/plugins/network/netconnect/netdetail.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/netdetail.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,58 @@ +#ifndef NETDETAIL_H +#define NETDETAIL_H + +#include +#include +#include +#include + +class NetDetail : public QFrame +{ + Q_OBJECT +public: + NetDetail(bool isWlan, QWidget *parent = nullptr); + + void setSSID(const QString &ssid); + void setSpeed(const QString &speed); + void setProtocol(const QString &protocol); + void setSecType(const QString &secType); + void setHz(const QString &hz); + void setChan(const QString &chan); + void setBandWidth(const QString &chan); + void setIPV4(const QString &ipv4); + void setIPV4Dns(const QString &ipv4Dns); + void setIPV4Mask(const QString &netMask); + void setIPV4Gateway(const QString &gateWay); + void setIPV6(const QString &ipv6); + void setIPV6Prefix(const QString &prefix); + void setIPV6Gt(const QString &gateWay); + void setMac(const QString &mac); + +private: + void initUI(); + +public: + QLabel *mSSID; + QLabel *mSpeed; + QLabel *mProtocol; + QLabel *mSecType; + QLabel *mHz; + QLabel *mChan; + QLabel *mBandWidth; + QLabel *mIPV4; + QLabel *mIPV4Gt; + QLabel *mIPV4Dns; + QLabel *mIPV4Mask; + + QLabel *mIPV6; + QLabel *mIPV6Prefix; + QLabel *mIPV6Gt; + + QLabel *mMac; + +private: + QFormLayout *mDetailLayout; + bool mIsWlan; +}; + +#endif // NETDETAIL_H diff -Nru ukui-control-center-2.0.3/plugins/network/netconnect/wifi.cpp ukui-control-center-3.0.3/plugins/network/netconnect/wifi.cpp --- ukui-control-center-2.0.3/plugins/network/netconnect/wifi.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/netconnect/wifi.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -#include "wifi.h" - -Wifi::Wifi() -{ - -} - -QStringList Wifi::getWifiList() { - QProcess *wifiPro = new QProcess(); - QString shellOutput = ""; - wifiPro->start("nmcli -f signal,ssid device wifi"); - wifiPro->waitForFinished(); - QString output = wifiPro->readAll(); - shellOutput += output; - QStringList slist = shellOutput.split("\n"); - -// emit getWifiListFinished(slist); -// qDebug()<<"wifilist--------------->"< -#include -#include - -class Wifi -{ -public: - Wifi(); - - QStringList getWifiList(); -}; - -#endif // WIFI_H diff -Nru ukui-control-center-2.0.3/plugins/network/proxy/certificationdialog.cpp ukui-control-center-3.0.3/plugins/network/proxy/certificationdialog.cpp --- ukui-control-center-2.0.3/plugins/network/proxy/certificationdialog.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/proxy/certificationdialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -42,7 +42,9 @@ CertificationDialog::~CertificationDialog() { delete ui; + ui = nullptr; delete cersettings; + cersettings = nullptr; } void CertificationDialog::component_init(){ diff -Nru ukui-control-center-2.0.3/plugins/network/proxy/proxy.cpp ukui-control-center-3.0.3/plugins/network/proxy/proxy.cpp --- ukui-control-center-2.0.3/plugins/network/proxy/proxy.cpp 2020-05-28 06:44:33.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/proxy/proxy.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -41,74 +41,82 @@ #define PROXY_HOST_KEY "host" #define PROXY_PORT_KEY "port" -Proxy::Proxy() +Proxy::Proxy() : mFirstLoad(true) { ui = new Ui::Proxy; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Proxy"); pluginType = NETWORK; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - settingsCreate = false; - - const QByteArray id(PROXY_SCHEMA); - const QByteArray idd(HTTP_PROXY_SCHEMA); - const QByteArray iddd(HTTPS_PROXY_SCHEMA); - const QByteArray iid(FTP_PROXY_SCHEMA); - const QByteArray iiid(SOCKS_PROXY_SCHEMA); - - setupStylesheet(); - setupComponent(); - - if (QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(idd) && - QGSettings::isSchemaInstalled(iddd) && QGSettings::isSchemaInstalled(iid) && - QGSettings::isSchemaInstalled(iiid)){ - - settingsCreate = true; - proxysettings = new QGSettings(id); - httpsettings = new QGSettings(idd); - securesettings = new QGSettings(iddd); - ftpsettings = new QGSettings(iid); - sockssettings = new QGSettings(iiid); - - setupConnect(); - initProxyModeStatus(); - initAutoProxyStatus(); - initManualProxyStatus(); - initIgnoreHostStatus(); - } else { - qCritical() << "Xml needed by Proxy is not installed"; - } - } Proxy::~Proxy() { - delete ui; - - if (settingsCreate){ - delete proxysettings; - delete httpsettings; - delete securesettings; - delete ftpsettings; - delete sockssettings; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + + if (settingsCreate){ + delete proxysettings; + proxysettings = nullptr; + delete httpsettings; + httpsettings = nullptr; + delete securesettings; + securesettings = nullptr; + delete ftpsettings; + ftpsettings = nullptr; + delete sockssettings; + sockssettings = nullptr; + } } } -QString Proxy::get_plugin_name(){ +QString Proxy::get_plugin_name() { return pluginName; } -int Proxy::get_plugin_type(){ +int Proxy::get_plugin_type() { return pluginType; } -QWidget *Proxy::get_plugin_ui(){ +QWidget *Proxy::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + settingsCreate = false; + + const QByteArray id(PROXY_SCHEMA); + const QByteArray idd(HTTP_PROXY_SCHEMA); + const QByteArray iddd(HTTPS_PROXY_SCHEMA); + const QByteArray iid(FTP_PROXY_SCHEMA); + const QByteArray iiid(SOCKS_PROXY_SCHEMA); + + initTitleLabel(); + initSearchText(); + setupStylesheet(); + setupComponent(); + + if (QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(idd) && + QGSettings::isSchemaInstalled(iddd) && QGSettings::isSchemaInstalled(iid) && + QGSettings::isSchemaInstalled(iiid)){ + + settingsCreate = true; + proxysettings = new QGSettings(id); + httpsettings = new QGSettings(idd); + securesettings = new QGSettings(iddd); + ftpsettings = new QGSettings(iid); + sockssettings = new QGSettings(iiid); + + setupConnect(); + initProxyModeStatus(); + initAutoProxyStatus(); + initManualProxyStatus(); + initIgnoreHostStatus(); + } else { + qCritical() << "Xml needed by Proxy is not installed"; + } + } return pluginWidget; } @@ -116,35 +124,26 @@ } -void Proxy::setupStylesheet(){ +const QString Proxy::name() const { -// pluginWidget->setStyleSheet("background: #ffffff;"); + return QStringLiteral("proxy"); +} -// ui->autoWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); -// ui->urlWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); -// ui->urlLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); - -// ui->manualWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px}"); -// ui->httpWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px}"); -// ui->httpHostLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); -// ui->httpPortLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); -// ui->cetificationBtn->setStyleSheet("QPushButton{background: #ffffff; border: none; border-radius: 4px;}"); - -// ui->httpsWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px}"); -// ui->httpsHostLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); -// ui->httpsPortLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); - -// ui->ftpWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px}"); -// ui->ftpHostLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); -// ui->ftpPortLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); - -// ui->socksWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px}"); -// ui->socksHostLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); -// ui->socksPortLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); +void Proxy::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); +} -// ui->ignoreHostsWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px}"); -// ui->ignoreHostTextEdit->setStyleSheet("QTextEdit{background: #ffffff; border: none; border-radius: 4px; font-size: 14px; color: #000000;}"); +void Proxy::initSearchText() { + //~ contents_path /proxy/Auto proxy + ui->autoLabel->setText(tr("Auto proxy")); + //~ contents_path /proxy/Manual proxy + ui->manualLabel->setText(tr("Manual proxy")); +} +void Proxy::setupStylesheet(){ } void Proxy::setupComponent(){ @@ -158,6 +157,8 @@ manualSwitchBtn->setObjectName("manual"); ui->manualHorLayout->addWidget(manualSwitchBtn); + ui->cetificationBtn->hide(); + //QLineEdit 设置数据 GSData httpHostData; httpHostData.schema = HTTP_PROXY_SCHEMA; @@ -214,10 +215,10 @@ connect(ui->ftpPortLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); connect(ui->socksPortLineEdit, &QLineEdit::textChanged, this, [=](const QString &txt){manualProxyTextChanged(txt);}); - connect(ui->cetificationBtn, &QPushButton::clicked, [=](bool checked){ - Q_UNUSED(checked) - showCertificationDialog(); - }); +// connect(ui->cetificationBtn, &QPushButton::clicked, [=](bool checked){ +// Q_UNUSED(checked) +// showCertificationDialog(); +// }); connect(ui->ignoreHostTextEdit, &QTextEdit::textChanged, this, [=](){ QString text = ui->ignoreHostTextEdit->toPlainText(); QStringList hostStringList = text.split(";"); @@ -361,6 +362,7 @@ setting->set(key, QVariant(txt)); delete setting; + setting = nullptr; } void Proxy::proxyModeChangedSlot(bool checked){ diff -Nru ukui-control-center-2.0.3/plugins/network/proxy/proxy.h ukui-control-center-3.0.3/plugins/network/proxy/proxy.h --- ukui-control-center-2.0.3/plugins/network/proxy/proxy.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/proxy/proxy.h 2021-04-14 01:27:20.000000000 +0000 @@ -80,8 +80,11 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); + void initSearchText(); void setupStylesheet(); void setupComponent(); void setupConnect(); @@ -115,7 +118,7 @@ QGSettings * sockssettings; bool settingsCreate; - + bool mFirstLoad; public slots: void proxyModeChangedSlot(bool checked); diff -Nru ukui-control-center-2.0.3/plugins/network/proxy/proxy.ui ukui-control-center-3.0.3/plugins/network/proxy/proxy.ui --- ukui-control-center-2.0.3/plugins/network/proxy/proxy.ui 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/proxy/proxy.ui 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 800 - 722 + 724 @@ -118,7 +118,7 @@ 16 - + 0 @@ -335,7 +335,7 @@ 16 - + 0 @@ -422,13 +422,13 @@ - 98 + 115 0 - 98 + 115 16777215 @@ -499,22 +499,6 @@ - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 8 - 20 - - - - - @@ -605,13 +589,13 @@ - 98 + 115 0 - 98 + 115 16777215 @@ -753,13 +737,13 @@ - 98 + 115 0 - 98 + 115 16777215 @@ -901,13 +885,13 @@ - 98 + 115 0 - 98 + 115 16777215 diff -Nru ukui-control-center-2.0.3/plugins/network/vino/sharemain.cpp ukui-control-center-3.0.3/plugins/network/vino/sharemain.cpp --- ukui-control-center-2.0.3/plugins/network/vino/sharemain.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/vino/sharemain.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,266 @@ +/* -*- 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 "sharemain.h" + +#include +#include +#include + +#include +#include + +ShareMain::ShareMain(QWidget *parent) : + QWidget(parent) +{ + mVlayout = new QVBoxLayout(this); + mVlayout->setContentsMargins(0, 0, 32, 0); + initUI(); + initConnection(); + initTitleLabel(); +} + +ShareMain::~ShareMain() +{ +} + +void ShareMain::initTitleLabel() +{ + QFont font; + font.setPixelSize(18); + mShareTitleLabel->setFont(font); +} + +void ShareMain::initUI() +{ + mShareTitleLabel = new QLabel(tr("Share"), this); + + mEnableFrame = new QFrame(this); + mEnableFrame->setFrameShape(QFrame::Shape::Box); + mEnableFrame->setMinimumSize(550, 50); + mEnableFrame->setMaximumSize(960, 50); + + QHBoxLayout *enableHLayout = new QHBoxLayout(); + + mEnableBtn = new SwitchButton(this); + mEnableLabel = new QLabel(tr("Allow others to view your desktop"), this); + enableHLayout->addWidget(mEnableLabel); + enableHLayout->addStretch(); + enableHLayout->addWidget(mEnableBtn); + + mEnableFrame->setLayout(enableHLayout); + + mViewFrame = new QFrame(this); + mViewFrame->setFrameShape(QFrame::Shape::Box); + mViewFrame->setMinimumSize(550, 50); + mViewFrame->setMaximumSize(960, 50); + + QHBoxLayout *viewHLayout = new QHBoxLayout(); + + mViewBtn = new SwitchButton(this); + mViewLabel = new QLabel(tr("Allow connection to control screen"), this); + viewHLayout->addWidget(mViewLabel); + viewHLayout->addStretch(); + viewHLayout->addWidget(mViewBtn); + + mViewFrame->setLayout(viewHLayout); + + mSecurityTitleLabel = new QLabel(tr("Security"), this); + + mSecurityFrame = new QFrame(this); + mSecurityFrame->setFrameShape(QFrame::Shape::Box); + mSecurityFrame->setMinimumSize(550, 50); + mSecurityFrame->setMaximumSize(960, 50); + + QHBoxLayout *secHLayout = new QHBoxLayout(); + + mAccessBtn = new SwitchButton(this); + mAccessLabel = new QLabel(tr("You must confirm every visit for this machine"), this); + secHLayout->addWidget(mAccessLabel); + secHLayout->addStretch(); + secHLayout->addWidget(mAccessBtn); + + mSecurityFrame->setLayout(secHLayout); + + mSecurityPwdFrame = new QFrame(this); + mSecurityPwdFrame->setFrameShape(QFrame::Shape::Box); + mSecurityPwdFrame->setMinimumSize(550, 50); + mSecurityPwdFrame->setMaximumSize(960, 50); + + QHBoxLayout *pwdHLayout = new QHBoxLayout(); + + mPwdBtn = new SwitchButton(this); + mPwdsLabel = new QLabel(tr("Require user to enter this password: "), this); + + // mHintLabel = new QLabel(tr("Password can not be blank"), this); + mHintLabel = new QLabel(this); + mHintLabel->setStyleSheet("color:red;"); + + mPwdLineEdit = new QLineEdit(this); + pwdHLayout->addWidget(mPwdsLabel); + pwdHLayout->addStretch(); + pwdHLayout->addWidget(mPwdLineEdit); + pwdHLayout->addStretch(); + pwdHLayout->addWidget(mHintLabel); + pwdHLayout->addWidget(mPwdBtn); + + mSecurityPwdFrame->setLayout(pwdHLayout); + + mVlayout->addWidget(mShareTitleLabel); + mVlayout->addWidget(mEnableFrame); + mVlayout->addWidget(mViewFrame); + + mVlayout->addWidget(mSecurityTitleLabel); + mVlayout->addWidget(mSecurityFrame); + mVlayout->addWidget(mSecurityPwdFrame); + + mVlayout->addStretch(); +} + +void ShareMain::initConnection() +{ + QByteArray id(kVinoSchemas); + if (QGSettings::isSchemaInstalled(id)) { + mVinoGsetting = new QGSettings(kVinoSchemas, QByteArray(), this); + + initEnableStatus(); + + connect(mEnableBtn, &SwitchButton::checkedChanged, this, &ShareMain::enableSlot); + connect(mViewBtn, &SwitchButton::checkedChanged, this, &ShareMain::viewBoxSlot); + connect(mAccessBtn, &SwitchButton::checkedChanged, this, &ShareMain::accessSlot); + connect(mPwdBtn, &SwitchButton::checkedChanged, this, &ShareMain::pwdEnableSlot); + connect(mPwdLineEdit, &QLineEdit::textChanged, this, &ShareMain::pwdInputSlot); + } +} + +void ShareMain::initEnableStatus() +{ + bool isShared = mVinoGsetting->get(kVinoViewOnlyKey).toBool(); + bool secPwd = mVinoGsetting->get(kVinoPromptKey).toBool(); + QString pwd = mVinoGsetting->get(kAuthenticationKey).toString(); + QString secpwd = mVinoGsetting->get(kVncPwdKey).toString(); + + mAccessBtn->setChecked(secPwd); + mViewBtn->setChecked(!isShared); + if (pwd == "vnc") { + mPwdBtn->setChecked(true); + mHintLabel->setVisible(true); + mPwdLineEdit->setText(QByteArray::fromBase64(secpwd.toLatin1())); + + if (secpwd == NULL) { + mHintLabel->setText(tr("Password can not be blank")); + } else if (QByteArray::fromBase64(secpwd.toLatin1()).length() == 8) { + mHintLabel->setText(tr("Password length must be less than or equal to 8")); + } + } else { + mPwdBtn->setChecked(false); + mPwdLineEdit->setVisible(false); + mHintLabel->setVisible(false); + } + + QProcess *process = new QProcess; + + process->start("systemctl", QStringList() << "--user" << "is-active" << "vino-server.service"); + process->waitForFinished(); + + setFrameVisible((process->readAllStandardOutput().replace("\n", "") == "active")); + delete process; +} + +void ShareMain::setFrameVisible(bool visible) +{ + mEnableBtn->setChecked(visible); + + mViewFrame->setVisible(visible); + mSecurityFrame->setVisible(visible); + mSecurityPwdFrame->setVisible(visible); + mSecurityTitleLabel->setVisible(visible); +} + +void ShareMain::setVinoService(bool status) +{ + QDBusInterface vinoIfc("org.ukui.SettingsDaemon.Sharing", + "/org/ukui/SettingsDaemon/Sharing", + "org.ukui.SettingsDaemon.Sharing", + QDBusConnection::sessionBus()); + if (vinoIfc.isValid()) { + if (status) { + vinoIfc.call("EnableService", "vino-server"); + } else { + vinoIfc.call("DisableService", "vino-server"); + } + } +} + +void ShareMain::enableSlot(bool status) +{ + setFrameVisible(status); + setVinoService(status); +} + +void ShareMain::viewBoxSlot(bool status) +{ + mVinoGsetting->set(kVinoViewOnlyKey, !status); +} + +void ShareMain::accessSlot(bool status) +{ + if (status) { + mVinoGsetting->set(kVinoPromptKey, true); + } else { + mVinoGsetting->set(kVinoPromptKey, false); + } +} + +void ShareMain::pwdEnableSlot(bool status) +{ + if (status) { + mVinoGsetting->set(kAuthenticationKey, "vnc"); + mPwdLineEdit->setVisible(true); + mHintLabel->setVisible(true); + } else { + mPwdLineEdit->setVisible(false); + mHintLabel->setVisible(false); + mVinoGsetting->set(kAuthenticationKey, "none"); + } +} + +void ShareMain::pwdInputSlot(const QString &pwd) +{ + if (pwd.length() <= 7 && !pwd.isEmpty()) { + mHintLabel->setText(tr("")); + mHintLabel->setVisible(false); + QByteArray text = pwd.toLocal8Bit(); + QByteArray secPwd = text.toBase64(); + mVinoGsetting->set(kVncPwdKey, secPwd); + } else if (pwd.isEmpty() && mPwdLineEdit->text().isEmpty()) { + mHintLabel->setText(tr("Password can not be blank")); + mHintLabel->setVisible(true); + QByteArray text = pwd.toLocal8Bit(); + QByteArray secPwd = text.toBase64(); + mVinoGsetting->set(kVncPwdKey, secPwd); + } else { + mHintLabel->setText(tr("Password length must be less than or equal to 8")); + mHintLabel->setVisible(true); + mPwdLineEdit->setText(pwd.mid(0, 8)); + QByteArray text = pwd.mid(0, 8).toLocal8Bit(); + QByteArray secPwd = text.toBase64(); + mVinoGsetting->set(kVncPwdKey, secPwd); + } +} diff -Nru ukui-control-center-2.0.3/plugins/network/vino/sharemain.h ukui-control-center-3.0.3/plugins/network/vino/sharemain.h --- ukui-control-center-2.0.3/plugins/network/vino/sharemain.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/vino/sharemain.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,110 @@ +/* -*- 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 SHAREMAIN_H +#define SHAREMAIN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "SwitchButton/switchbutton.h" + +const QByteArray kVinoSchemas = "org.gnome.Vino"; +const QString kVinoViewOnlyKey = "view-only"; +const QString kVinoPromptKey = "prompt-enabled"; +const QString kAuthenticationKey = "authentication-methods"; +const QString kVncPwdKey = "vnc-password"; + +const QByteArray kUkccVnoSchmas = "org.ukui.control-center.vino"; +const QString kUkccPromptKey = "remote"; + +enum RequestPwd { + NOPWD, + NEEDPWD +}; + +class ShareMain : public QWidget +{ + Q_OBJECT +public: + ShareMain(QWidget *parent = nullptr); + ~ShareMain(); + +private: + QFrame *mEnableFrame; + QFrame *mViewFrame; + QFrame *mSecurityFrame; + QFrame *mSecurityPwdFrame; + QFrame *mNoticeWFrame; + QFrame *mNoticeOFrame; + QFrame *mNoticeNFrame; + + SwitchButton *mEnableBtn; // 允许其他人查看桌面 + SwitchButton *mViewBtn; // 允许连接控制屏幕 + SwitchButton *mAccessBtn; // 为本机确认每次访问 + SwitchButton *mPwdBtn; // 要求用户输入密码 + + QRadioButton *mNoticeWBtn; + QRadioButton *mNoticeOBtn; + QRadioButton *mNoticeNBtn; + + QLabel *mShareTitleLabel; + QLabel *mEnableLabel; + QLabel *mViewLabel; + QLabel *mSecurityTitleLabel; + QLabel *mAccessLabel; + QLabel *mPwdsLabel; + QLabel *mNoticeTitleLabel; + QLabel *mNoticeWLabel; + QLabel *mNoticeOLabel; + QLabel *mNoticeNLabel; + QLabel *mHintLabel; + + QLineEdit *mPwdLineEdit; + + QVBoxLayout *mVlayout; + + QGSettings *mVinoGsetting; + +private: + void initTitleLabel(); + void initUI(); + void initConnection(); + void initShareStatus(bool isConnnect, bool isPwd); + void initEnableStatus(); + void setFrameVisible(bool visible); + void setVinoService(bool status); + +private slots: + void enableSlot(bool status); + void viewBoxSlot(bool status); + void accessSlot(bool status); + void pwdEnableSlot(bool status); + void pwdInputSlot(const QString &pwd); +}; + +#endif // SHAREMAIN_H diff -Nru ukui-control-center-2.0.3/plugins/network/vino/vino.cpp ukui-control-center-3.0.3/plugins/network/vino/vino.cpp --- ukui-control-center-2.0.3/plugins/network/vino/vino.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/vino/vino.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -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 "vino.h" + +Vino::Vino() : mFirstLoad(true) +{ + pluginName = tr("Vino"); + pluginType = NETWORK; +} + +Vino::~Vino() +{ +} + +QString Vino::get_plugin_name() +{ + return pluginName; +} + +int Vino::get_plugin_type() +{ + return pluginType; +} + +QWidget *Vino::get_plugin_ui() +{ + if (mFirstLoad) { + mFirstLoad = false; + // will delete by takewidget + pluginWidget = new ShareMain; + } + + return pluginWidget; +} + +void Vino::plugin_delay_control() +{ +} + +const QString Vino::name() const +{ + return QStringLiteral("vino"); +} diff -Nru ukui-control-center-2.0.3/plugins/network/vino/vino.h ukui-control-center-3.0.3/plugins/network/vino/vino.h --- ukui-control-center-2.0.3/plugins/network/vino/vino.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/vino/vino.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,53 @@ +/* -*- 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 VINO_H +#define VINO_H + +#include +#include +#include + +#include "shell/interface.h" +#include "sharemain.h" + +class Vino : public QObject, CommonInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") + Q_INTERFACES(CommonInterface) + +public: + Vino(); + ~Vino(); + + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + +private: + QString pluginName; + int pluginType; + ShareMain* pluginWidget; + bool mFirstLoad; + +}; +#endif // VINO_H diff -Nru ukui-control-center-2.0.3/plugins/network/vino/vino.pro ukui-control-center-3.0.3/plugins/network/vino/vino.pro --- ukui-control-center-2.0.3/plugins/network/vino/vino.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/vino/vino.pro 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,41 @@ +include(../../../env.pri) +include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) +QT += widgets + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets dbus + +TEMPLATE = lib +CONFIG += plugin link_pkgconfig +PKGCONFIG += gsettings-qt + +TARGET = $$qtLibraryTarget(vino) +DESTDIR = ../.. +target.path = $${PLUGIN_INSTALL_DIRS} + +INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE\ + $$PROJECT_ROOTDIR \ + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked 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 it uses 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 += \ + sharemain.cpp \ + vino.cpp + +HEADERS += \ + sharemain.h \ + vino.h + +FORMS += + +# Default rules for deployment. +INSTALLS += target diff -Nru ukui-control-center-2.0.3/plugins/network/vpn/vpn.cpp ukui-control-center-3.0.3/plugins/network/vpn/vpn.cpp --- ukui-control-center-2.0.3/plugins/network/vpn/vpn.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/vpn/vpn.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -23,30 +23,18 @@ #include #include -Vpn::Vpn() +Vpn::Vpn() : mFirstLoad(true) { - ui = new Ui::Vpn; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Vpn"); pluginType = NETWORK; - -// ui->addFrame->installEventFilter(this); - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); -// pluginWidget->setStyleSheet("background: #ffffff;"); - -// ui->widget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - - initComponent(); - } Vpn::~Vpn() { - delete ui; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } } QString Vpn::get_plugin_name(){ @@ -58,6 +46,16 @@ } QWidget *Vpn::get_plugin_ui(){ + if (mFirstLoad) { + mFirstLoad = false; + ui = new Ui::Vpn; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + initTitleLabel(); + initComponent(); + } return pluginWidget; } @@ -65,12 +63,18 @@ } -void Vpn::initComponent(){ -// ui->addBtn->setIcon(QIcon("://img/plugins/vpn/add.png")); -// ui->addBtn->setIconSize(QSize(48, 48)); -// ui->addBtn->setStyleSheet("QPushButton{background-color:transparent;}"); +const QString Vpn::name() const { + return QStringLiteral("vpn"); +} +void Vpn::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); +} + +void Vpn::initComponent(){ addWgt = new HoverWidget(""); addWgt->setObjectName("addwgt"); addWgt->setMinimumSize(QSize(580, 50)); @@ -80,28 +84,18 @@ QHBoxLayout *addLyt = new QHBoxLayout; QLabel * iconLabel = new QLabel(); + //~ contents_path /vpn/Add vpn connect QLabel * textLabel = new QLabel(tr("Add vpn connect")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); + iconLabel->setProperty("useIconHighlightEffect", true); + iconLabel->setProperty("iconHighlightEffectMode", 1); + addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); addWgt->setLayout(addLyt); - // 悬浮改变Widget状态 - connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(base);"); - - }); - // 还原状态 - connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(windowText);"); - }); - connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname){ runExternalApp(); }); @@ -115,18 +109,3 @@ QProcess process(this); process.startDetached(cmd); } - -//bool Vpn::eventFilter(QObject *watched, QEvent *event) -//{ -// if (watched == ui->addFrame){ -// if (event->type() == QEvent::MouseButtonPress){ -// QMouseEvent * mouseEvent = static_cast(event); -// if (mouseEvent->button() == Qt::LeftButton){ -// runExternalApp(); -// return true; -// } else -// return false; -// } -// } -// return QObject::eventFilter(watched, event); -//} diff -Nru ukui-control-center-2.0.3/plugins/network/vpn/vpn.h ukui-control-center-3.0.3/plugins/network/vpn/vpn.h --- ukui-control-center-2.0.3/plugins/network/vpn/vpn.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/vpn/vpn.h 2021-04-14 01:27:20.000000000 +0000 @@ -45,8 +45,10 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); void initComponent(); void runExternalApp(); @@ -62,6 +64,8 @@ QWidget * pluginWidget; HoverWidget * addWgt; + bool mFirstLoad; + }; #endif // VPN_H diff -Nru ukui-control-center-2.0.3/plugins/network/vpn/vpn.ui ukui-control-center-3.0.3/plugins/network/vpn/vpn.ui --- ukui-control-center-2.0.3/plugins/network/vpn/vpn.ui 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/network/vpn/vpn.ui 2021-04-14 01:27:20.000000000 +0000 @@ -27,7 +27,7 @@ - 16 + 12 0 diff -Nru ukui-control-center-2.0.3/plugins/personalized/desktop/desktop.cpp ukui-control-center-3.0.3/plugins/personalized/desktop/desktop.cpp --- ukui-control-center-2.0.3/plugins/personalized/desktop/desktop.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/desktop/desktop.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -23,98 +23,99 @@ #include #include "SwitchButton/switchbutton.h" #include "realizedesktop.h" +#include "commonComponent/listDelegate/listdelegate.h" #include #include +#include +#include +#include +#include +#include +#include -//#define DESKTOP_SCHEMA "org.ukui.peony.desktop" -#define DESKTOP_SCHEMA "org.ukui.control-center.desktop" +#define DESKTOP_SCHEMA "org.ukui.control-center.desktop" #define COMPUTER_VISIBLE_KEY "computer-icon-visible" -#define HOME_VISIBLE_KEY "home-icon-visible" -#define NETWORK_VISIBLE_KEY "network-icon-visible" -#define TRASH_VISIBLE_KEY "trash-icon-visible" -#define VOLUMES_VISIBLE_KEY "volumes-visible" +#define HOME_VISIBLE_KEY "home-icon-visible" +#define NETWORK_VISIBLE_KEY "network-icon-visible" +#define TRASH_VISIBLE_KEY "trash-icon-visible" +#define VOLUMES_VISIBLE_KEY "volumes-visible" #define MENU_FULL_SCREEN_KEY "menufull-screen" -#define COMPUTER_LOCK_KEY "computer-icon-locking" -#define PERSONAL_LOCK_KEY "personal-icon-locking" -#define SETTINGS_LOCK_KEY "settings-icon-locking" -#define TRASH_LOCK_KEY "trash-icon-locking" +#define COMPUTER_LOCK_KEY "computer-icon-locking" +#define PERSONAL_LOCK_KEY "personal-icon-locking" +#define SETTINGS_LOCK_KEY "settings-icon-locking" +#define TRASH_LOCK_KEY "trash-icon-locking" -Desktop::Desktop() +Desktop::Desktop() : mFirstLoad(true) { - ui = new Ui::Desktop; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Desktop"); pluginType = PERSONALIZED; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title3Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->menuLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - ui->titleLabel->setVisible(false); -// ui->title2Label->setVisible(false); - - ui->deskComputerFrame->setVisible(false); - ui->deskTrashFrame->setVisible(false); - ui->deskHomeFrame->setVisible(false); - ui->deskVolumeFrame->setVisible(false); - ui->deskNetworkFrame->setVisible(false); - - ui->titleLabel->setVisible(false); -// ui->title2Label->setVisible(false); - - ui->deskComputerFrame->setVisible(false); - ui->deskTrashFrame->setVisible(false); - ui->deskHomeFrame->setVisible(false); - ui->deskVolumeFrame->setVisible(false); - ui->deskNetworkFrame->setVisible(false); - - ui->title2Label->hide(); - ui->fullScreenMenuFrame->setVisible(false); - - vecGsettings = new QVector(); - const QByteArray id(DESKTOP_SCHEMA); - if (QGSettings::isSchemaInstalled(id)) { - dSettings = new QGSettings(id); - } - - - initTranslation(); - setupComponent(); - setupConnect(); - initVisibleStatus(); - initLockingStatus(); - initTraySettings(); } Desktop::~Desktop() { - delete ui; - - if (!dSettings ){ - delete dSettings; - } - - if (!vecGsettings) { - delete vecGsettings; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + qDeleteAll(vecGsettings); + vecGsettings.clear(); } } -QString Desktop::get_plugin_name(){ +QString Desktop::get_plugin_name() { return pluginName; } -int Desktop::get_plugin_type(){ +int Desktop::get_plugin_type() { return pluginType; } -QWidget *Desktop::get_plugin_ui(){ +QWidget *Desktop::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::Desktop; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + ui->listWidget->setItemDelegate(new ListDelegate(this)); + + ui->titleLabel->setVisible(false); + + ui->deskComputerFrame->setVisible(false); + ui->deskTrashFrame->setVisible(false); + ui->deskHomeFrame->setVisible(false); + ui->deskVolumeFrame->setVisible(false); + ui->deskNetworkFrame->setVisible(false); + + ui->titleLabel->setVisible(false); + + ui->deskComputerFrame->setVisible(false); + ui->deskTrashFrame->setVisible(false); + ui->deskHomeFrame->setVisible(false); + ui->deskVolumeFrame->setVisible(false); + ui->deskNetworkFrame->setVisible(false); + + ui->title2Label->hide(); + ui->fullScreenMenuFrame->setVisible(false); + + const QByteArray id(DESKTOP_SCHEMA); + if (QGSettings::isSchemaInstalled(id)) { + dSettings = new QGSettings(id, QByteArray(), this); + } + cmd = QSharedPointer(new QProcess()); + initTitleLabel(); + initSearchText(); + initTranslation(); + setupComponent(); + setupConnect(); + initVisibleStatus(); + initLockingStatus(); + initTraySettings(); + } return pluginWidget; } @@ -122,17 +123,28 @@ } -void Desktop::initTranslation() { - transMap.insert("blueman", "蓝牙"); - transMap.insert("fcitx", "输入法"); - transMap.insert("indicator-china-weather", "麒麟天气"); - transMap.insert("explorer.exe", "微信"); - transMap.insert("ukui-flash-disk", "U盘管理工具"); - transMap.insert("kylin-nm", "网络工具"); - transMap.insert("ukui-volume-control-applet-qt", "音量控制"); - transMap.insert("ukui-sidebar", "侧边栏"); - transMap.insert("ukui-power-manager-tray", "电源管理"); +const QString Desktop::name() const { + + return QStringLiteral("desktop"); +} + +void Desktop::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title3Label->setFont(font); + ui->title2Label->setFont(font); + ui->menuLabel->setFont(font); +} +void Desktop::initSearchText() { + //~ contents_path /desktop/Icon Show On Desktop + ui->titleLabel->setText(tr("Icon Show On Desktop")); + //~ contents_path /desktop/Tray icon + ui->title3Label->setText(tr("Tray icon")); +} + +void Desktop::initTranslation() { iconMap.insert("ukui-volume-control-applet-qt", "audio-card"); iconMap.insert("kylin-nm", "network-workgroup"); iconMap.insert("indicator-china-weather", "indicator-china-weather"); @@ -141,14 +153,15 @@ iconMap.insert("fcitx", "fcitx"); iconMap.insert("blueman", "preferences-system-bluetooth"); iconMap.insert("kylin-video", "kylin-video"); + iconMap.insert("kylin-screenshoot", "kylin-screenshoot"); + iconMap.insert("Onboard", "onboard"); - disList<<"ukui-sidebar"<<"update-notifier"<<"software-update-available" + disList<<"ukui-sidebar"<<"kylin-nm"<<"ukui-volume-control-applet-qt"<<"update-notifier"<<"software-update-available" <<"blueman-tray"<<"ukui-power-manager"<<"ukui-settings-daemon"<<"blueman-applet" - <<"ErrorApplication"<<"livepatch"; - + <<"ErrorApplication"<<"livepatch" << "mktip"; } -void Desktop::setupComponent(){ +void Desktop::setupComponent() { ui->deskComputerLabel->setPixmap(QPixmap("://img/plugins/desktop/computer.png")); ui->deskHomeLabel->setPixmap(QPixmap("://img/plugins/desktop/homefolder.png")); @@ -191,7 +204,6 @@ menuSettingSwitchBtn = new SwitchButton(pluginWidget); ui->menuSettingHorLayout->addWidget(menuSettingSwitchBtn); - } void Desktop::setupConnect(){ @@ -202,29 +214,43 @@ connect(deskVolumeSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked){dSettings->set(VOLUMES_VISIBLE_KEY, checked);}); connect(deskNetworkSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked){dSettings->set(NETWORK_VISIBLE_KEY, checked);}); - connect(fullMenuSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ + connect(fullMenuSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked) { if (keys.contains("menufullScreen")) { dSettings->set(MENU_FULL_SCREEN_KEY, checked); } - }); - connect(menuComputerSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ + + connect(menuComputerSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked) { dSettings->set(COMPUTER_LOCK_KEY, checked); }); - connect(menuFilesystemSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ + + connect(menuFilesystemSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked) { if (keys.contains("personalIconLocking")) { dSettings->set(PERSONAL_LOCK_KEY, checked); } }); - connect(menuSettingSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ + + connect(menuSettingSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked) { dSettings->set(SETTINGS_LOCK_KEY, checked); }); - connect(menuTrashSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked){ + + connect(menuTrashSwitchBtn, &SwitchButton::checkedChanged, [=](bool checked) { dSettings->set(TRASH_LOCK_KEY, checked); }); + + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), + QString("org.freedesktop.kylinssoclient.interface"), + "keyChanged", this, SLOT(slotCloudAccout(QString))); +} + +void Desktop::slotCloudAccout(const QString &key) { + if (key == "ukui-menu") { + initVisibleStatus(); + initLockingStatus(); + } } -void Desktop::initVisibleStatus(){ +void Desktop::initVisibleStatus() { deskComputerSwitchBtn->blockSignals(true); deskHomeSwitchBtn->blockSignals(true); deskTrashSwitchBtn->blockSignals(true); @@ -244,13 +270,12 @@ deskNetworkSwitchBtn->blockSignals(false); } -void Desktop::initLockingStatus(){ +void Desktop::initLockingStatus() { menuComputerSwitchBtn->blockSignals(true); menuFilesystemSwitchBtn->blockSignals(true); menuSettingSwitchBtn->blockSignals(true); menuTrashSwitchBtn->blockSignals(true); - QStringList keys = dSettings->keys(); if (keys.contains("menufullScreen")) { fullMenuSwitchBtn->setChecked(dSettings->get(MENU_FULL_SCREEN_KEY).toBool()); @@ -271,12 +296,17 @@ } void Desktop::initTrayStatus(QString name, QIcon icon, QGSettings *gsettings) { - const QString locale = QLocale::system().name(); + QMap desktopMap = desktopConver(name); + if (desktopMap.isEmpty()) { + return; + } + nameList.append(name); QVBoxLayout * baseVerLayout = new QVBoxLayout(); baseVerLayout->setSpacing(1); - QFrame * devFrame = new QFrame(); + QFrame * devFrame = new QFrame(pluginWidget); + devFrame->setObjectName(name); devFrame->setFrameShape(QFrame::Shape::Box); devFrame->setMinimumWidth(550); devFrame->setMaximumWidth(960); @@ -287,32 +317,30 @@ devHorLayout->setSpacing(8); devHorLayout->setContentsMargins(16, 0, 16, 0); - QPushButton * iconBtn = new QPushButton(); + QPushButton * iconBtn = new QPushButton(pluginWidget); iconBtn->setStyleSheet("QPushButton{background-color:transparent;border-radius:4px}" "QPushButton:hover{background-color: transparent ;color:transparent;}"); -// iconBtn->setFlat(true); QSizePolicy iconSizePolicy = iconBtn->sizePolicy(); iconSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); iconSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); iconBtn->setSizePolicy(iconSizePolicy); iconBtn->setIconSize(QSize(32, 32)); + if (icon.isNull()) { + icon = desktopMap.values().at(0).isNull() ? QIcon::fromTheme("application-x-desktop") : desktopMap.values().at(0); + } iconBtn->setIcon(icon); - QLabel * nameLabel = new QLabel(); + QLabel * nameLabel = new QLabel(pluginWidget); QSizePolicy nameSizePolicy = nameLabel->sizePolicy(); nameSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); nameSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); nameLabel->setSizePolicy(nameSizePolicy); nameLabel->setScaledContents(true); - if ("zh_CN" == locale && transMap.contains(name)) { - nameLabel->setText(transMap.value(name)); - } else { - nameLabel->setText(name); - } + nameLabel->setText(desktopMap.keys().at(0)); - SwitchButton *appSwitch = new SwitchButton(); + SwitchButton *appSwitch = new SwitchButton(pluginWidget); if (disList.contains(name)) { appSwitch->setEnabled(false); } @@ -326,7 +354,12 @@ baseVerLayout->addWidget(devFrame); baseVerLayout->addStretch(); - ui->trayVBoxLayout->addWidget(devFrame); + QListWidgetItem * item = new QListWidgetItem(ui->listWidget); + + item->setSizeHint(QSize(QSizePolicy::Fixed, 50)); + item->setFlags(Qt::ItemFlag::ItemIsSelectable); + item->setData(Qt::UserRole, QVariant(name)); + ui->listWidget->setItemWidget(item, devFrame); QString status = gsettings->get(TRAY_ACTION_KEY).toString(); if ("tray" == status) { @@ -346,24 +379,39 @@ }); } - void Desktop::initTraySettings() { QString action; QString name; int winID; - QIcon icon; QList trayList = listExistsCustomDesktopPath(); -// qDebug()<<"path is------------->"<listWidget->setSpacing(1); + ui->listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + for (int i = 0; i < trayList.length(); i++) { const QByteArray id(TRAY_SCHEMA); QGSettings * traySettings = nullptr; QString path = QString("%1%2").arg(TRAY_SCHEMA_PATH).arg(QString(trayList.at(i)));; - if (QGSettings::isSchemaInstalled(id)) { traySettings = new QGSettings(id, path.toLatin1().data()); - vecGsettings->append(traySettings); + + connect(traySettings, &QGSettings::changed, this, [=] (const QString &key) { + + QString status = traySettings->get(key).toString(); + if ("action" == key) { + QString status = traySettings->get(key).toString(); + QString itemName = traySettings->get(TRAY_NAME_KEY).toString(); + if ("freeze" == status) { + removeTrayItem(itemName); + } else if(!nameList.contains(itemName)) { + addTrayItem(traySettings); + } + } + }); + vecGsettings << traySettings; QStringList keys = traySettings->keys(); if (keys.contains(static_cast(TRAY_NAME_KEY)) && @@ -371,20 +419,162 @@ name = traySettings->get(TRAY_NAME_KEY).toString(); action = traySettings->get(TRAY_ACTION_KEY).toString(); winID = traySettings->get(TRAY_BINDING_KEY).toInt(); -// show(winID); } -// qDebug()<<"name is-------------->"<listWidget->setFixedHeight(itemCount * 55); +} + +QMap Desktop::desktopConver(QString processName) { + + QMap desktopMap; + if (isFileExist("/etc/xdg/autostart/"+processName + ".desktop") || + isFileExist("/usr/share/applications/"+processName+".desktop")) { + QString autoName = desktopToName("/etc/xdg/autostart/"+processName+".desktop"); + QIcon autoIcon = desktopToIcon("/etc/xdg/autostart/"+processName+".desktop"); + QString appName = desktopToName("/usr/share/applications/"+processName+".desktop"); + QIcon appIcon = desktopToIcon("/usr/share/applications/"+processName+".desktop"); + if (autoName != "") { + desktopMap.insert(autoName, autoIcon); + } else if (appName != "") { + desktopMap.insert(appName, appIcon); + } + } else if (isFileExist("/etc/xdg/autostart/" + processName.toLower() + ".desktop") || + isFileExist("/usr/share/applications/" + processName.toLower() + ".desktop")){ + QString autoName = desktopToName("/etc/xdg/autostart/" + processName.toLower() + ".desktop"); + QIcon autoIcon = desktopToIcon("/etc/xdg/autostart/" + processName.toLower() + ".desktop"); + + QString appName = desktopToName("/usr/share/applications/" + processName.toLower() + ".desktop"); + QIcon appIcon = desktopToIcon("/usr/share/applications/" + processName.toLower() + ".desktop"); + if (autoName != "") { + desktopMap.insert(autoName, autoIcon); + } else if (appName != "") { + desktopMap.insert(appName, appIcon); + } + } else { + connect(cmd.get(), &QProcess::readyReadStandardOutput, this, [&]() { + desktopMap = readOuputSlot(); + }); + // 异常处理 + connect(cmd.get() , SIGNAL(readyReadStandardError()) , this , SLOT(readErrorSlot())); + + QString inputCmd = QString("grep -nr %1 /usr/share/applications/ /etc/xdg/autostart/\n").arg(processName); + cmd->start(inputCmd); + cmd->waitForFinished(-1); + } + return desktopMap; +} + +bool Desktop::isFileExist(QString fullFileName) { + QFileInfo fileInfo(fullFileName); + if (fileInfo.isFile()) { + return true; + } + return false; +} + +void Desktop::removeTrayItem(QString itemName) { + for (int i = 0; i < ui->listWidget->count(); i++) { + QListWidgetItem * item = ui->listWidget->item(i); + QString value = item->data(Qt::UserRole).toString(); + if (value == itemName) { + ui->listWidget->takeItem(i); + break; + } + } + + for (int i = 0; i < nameList.length(); i++) { + if (nameList.at(i) == itemName) { + nameList.removeAt(i); + ui->listWidget->setFixedHeight(ui->listWidget->height() - 55); + break; + } + } +} + +void Desktop::addTrayItem(QGSettings * trayGSetting) { + + QString name = trayGSetting->get(TRAY_NAME_KEY).toString(); + QString action = trayGSetting->get(TRAY_ACTION_KEY).toString(); + + if (!("" == name || "freeze" == action || disList.contains(name))){ + QIcon icon; + if (!iconMap[name].isEmpty()) { + icon = QIcon::fromTheme(iconMap[name]); + } else { + icon = QIcon::fromTheme("application-x-desktop"); + } + initTrayStatus(name, icon, trayGSetting); + ui->listWidget->setFixedHeight(ui->listWidget->height() + 55); + } +} + +QString Desktop::desktopToName(QString desktopfile) { + const QString locale = QLocale::system().name(); + const QString localeName = locale != "en_US" ? "Name[" + locale +"]" : "Name"; + const QString genericName = "GenericName[" + locale +"]"; + QSettings desktopSettings(desktopfile, QSettings::IniFormat); + + desktopSettings.setIniCodec(QTextCodec::codecForName("UTF-8")); + desktopSettings.beginGroup("Desktop Entry"); + + QString desktopName = desktopSettings.value(localeName, "").toString(); + if (desktopName.isEmpty()) { + desktopName = desktopSettings.value(genericName, "").toString(); + } + + desktopSettings.endGroup(); + return desktopName; +} + +QIcon Desktop::desktopToIcon(const QString &desktopfile) { + QSettings desktopSettings(desktopfile, QSettings::IniFormat); + + desktopSettings.setIniCodec(QTextCodec::codecForName("UTF-8")); + desktopSettings.beginGroup("Desktop Entry"); + + QString iconName = desktopSettings.value("Icon", "").toString(); + + desktopSettings.endGroup(); + return QIcon::fromTheme(iconName); +} + +QMap Desktop::readOuputSlot() { + QString str; + QMap desktopMap; + QFile file("/tmp/desktopprocess.txt"); + QString output=cmd->readAllStandardOutput().data(); + + // 打开文件,不存在则创建 + file.open(QIODevice::ReadWrite | QIODevice::Text); + file.write(output.toUtf8()); + file.close(); + + file.open(QIODevice::ReadWrite | QIODevice::Text); + while (!file.atEnd()) { + QByteArray line = file.readLine(); + str = line; + if(str.contains(".desktop:") && str.contains(":Exec")){ + str = str.section(".desktop", 0, 0)+".desktop"; + desktopMap.insert(desktopToName(str), desktopToIcon(str)); + } + } + file.close(); + file.remove(); + return desktopMap; +} + +void Desktop::readErrorSlot() { + qWarning() << "read desktop file name failed"; } diff -Nru ukui-control-center-2.0.3/plugins/personalized/desktop/desktop.h ukui-control-center-3.0.3/plugins/personalized/desktop/desktop.h --- ukui-control-center-2.0.3/plugins/personalized/desktop/desktop.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/desktop/desktop.h 2021-04-14 01:27:20.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include "shell/interface.h" @@ -51,7 +52,10 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + void initTitleLabel(); + void initSearchText(); void initTranslation(); void setupComponent(); void setupConnect(); @@ -59,6 +63,11 @@ void initLockingStatus(); void initTrayStatus(QString name, QIcon icon, QGSettings *gsettings); void initTraySettings(); + void clearContent(); + +private: + QMap desktopConver(QString processName); + bool isFileExist(QString fullFileName); private: Ui::Desktop *ui; @@ -66,10 +75,11 @@ int pluginType; QString pluginName; QWidget * pluginWidget; - QVector *vecGsettings; + QVector vecGsettings; QMap transMap; // transaltion Map QMap iconMap; QStringList disList; + QStringList nameList; SwitchButton * deskComputerSwitchBtn; SwitchButton * deskTrashSwitchBtn; @@ -85,6 +95,18 @@ QGSettings * dSettings; + QSharedPointer cmd; + + bool mFirstLoad; + +private slots: + void removeTrayItem(QString itemName); + void addTrayItem(QGSettings * trayGSetting); + QString desktopToName(QString desktopfile); + QIcon desktopToIcon(const QString &desktopfile); + QMap readOuputSlot(); + void readErrorSlot(); + void slotCloudAccout(const QString &key); }; #endif // DESKTOP_H diff -Nru ukui-control-center-2.0.3/plugins/personalized/desktop/desktop.pro ukui-control-center-3.0.3/plugins/personalized/desktop/desktop.pro --- ukui-control-center-2.0.3/plugins/personalized/desktop/desktop.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/desktop/desktop.pro 2021-04-14 01:27:20.000000000 +0000 @@ -6,8 +6,9 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) +include($$PROJECT_COMPONENTSOURCE/listdelegate.pri) -QT += widgets x11extras +QT += widgets x11extras dbus TEMPLATE = lib CONFIG += plugin diff -Nru ukui-control-center-2.0.3/plugins/personalized/desktop/desktop.ui ukui-control-center-3.0.3/plugins/personalized/desktop/desktop.ui --- ukui-control-center-2.0.3/plugins/personalized/desktop/desktop.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/desktop/desktop.ui 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 795 - 797 + 814 @@ -52,22 +52,6 @@ - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 8 - - - - - 2 @@ -635,6 +619,22 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 12 + + + + + 2 @@ -1023,11 +1023,20 @@ - - - 2 + + + + 550 + 0 + - + + + 960 + 16777215 + + + diff -Nru ukui-control-center-2.0.3/plugins/personalized/fonts/fonts.cpp ukui-control-center-3.0.3/plugins/personalized/fonts/fonts.cpp --- ukui-control-center-2.0.3/plugins/personalized/fonts/fonts.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/fonts/fonts.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -21,7 +21,7 @@ #include "ui_fonts.h" #include - +#include #include #define N 3 @@ -30,144 +30,164 @@ #define LARGE 1.50 -#define INTERFACE_SCHEMA "org.mate.interface" -#define DOC_FONT_KEY "document-font-name" //用于阅读文档的默认字体的名称 -#define GTK_FONT_KEY "font-name" //gkt+使用的默认字体 -#define MONOSPACE_FONT_KEY "monospace-font-name" //用于终端等处的等宽字体 - -#define MARCO_SCHEMA "org.gnome.desktop.wm.preferences" -#define TITLEBAR_FONT_KEY "titlebar-font" //描述窗口标题栏字体的字符串。只有在"titlebar-uses-system-font"为false时有效 - - -//#define PEONY_SCHEMA "org.ukui.peony.desktop" -//#define PEONY_FONT_KEY "font" //桌面上图标描述所用的字体 - -#define STYLE_FONT_SCHEMA "org.ukui.style" -#define SYSTEM_FONT_EKY "system-font-size" -#define SYSTEM_NAME_KEY "system-font" - -#define FONT_RENDER_SCHEMA "org.ukui.font-rendering" -#define ANTIALIASING_KEY "antialiasing" //绘制字形时使用反锯齿类型 -#define HINTING_KEY "hinting" //绘制字形时使用微调的类型 -#define RGBA_ORDER_KEY "rgba-order" //LCD屏幕上次像素的顺序;仅在反锯齿设为"rgba"时有用 -#define DPI_KEY "dpi" //将字体尺寸转换为像素值时所用的分辨率,以每英寸点数为单位 - +#define INTERFACE_SCHEMA "org.mate.interface" +#define DOC_FONT_KEY "document-font-name" // 用于阅读文档的默认字体的名称 +#define GTK_FONT_KEY "font-name" // gkt+使用的默认字体 +#define MONOSPACE_FONT_KEY "monospace-font-name" // 用于终端等处的等宽字体 + +#define MARCO_SCHEMA "org.gnome.desktop.wm.preferences" +#define TITLEBAR_FONT_KEY "titlebar-font" // 描述窗口标题栏字体的字符串。只有在"titlebar-uses-system-font"为false时有效 + +#define STYLE_FONT_SCHEMA "org.ukui.style" +#define SYSTEM_FONT_EKY "system-font-size" +#define SYSTEM_NAME_KEY "system-font" + +#define FONT_RENDER_SCHEMA "org.ukui.font-rendering" +#define ANTIALIASING_KEY "antialiasing" // 绘制字形时使用反锯齿类型 +#define HINTING_KEY "hinting" // 绘制字形时使用微调的类型 +#define RGBA_ORDER_KEY "rgba-order" // LCD屏幕上次像素的顺序;仅在反锯齿设为"rgba"时有用 +#define DPI_KEY "dpi" // 将字体尺寸转换为像素值时所用的分辨率,以每英寸点数为单位 + +QList defaultsizeList = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72}; +const QString kErrorFont = "Noto Serif Tibetan"; +const QString kErrorStardFont = "Standard Symbols"; /* 设置字体,每套字体包括5个部件,应用程序字体、文档字体、等宽字体、桌面字体和窗口标题字体。 字体设置为预设值,每套字体除大小不固定,其他字体类别固定。 */ typedef struct _FontInfo FontInfo; -struct _FontInfo{ +struct _FontInfo { QString type; QString gtkfont; QString docfont; QString monospacefont; -// QString peonyfont; QString titlebarfont; int gtkfontsize; int docfontsize; int monospacefontsize; -// int peonyfontsize; int titlebarfontsize; }; FontInfo defaultfontinfo; //字体效果 -typedef enum{ +typedef enum { ANTIALIASING_NONE, ANTIALIASING_GRAYSCALE, ANTIALIASING_RGBA }Antialiasing; -typedef enum{ +typedef enum { HINT_NONE, HINT_SLIGHT, HINT_MEDIUM, HINT_FULL }Hinting; -struct FontEffects{ +struct FontEffects { Antialiasing antial; Hinting hinting; }; Q_DECLARE_METATYPE(FontEffects) -QList defaultsizeList = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72}; - -Fonts::Fonts() +Fonts::Fonts() : mFirstLoad(true) { - ui = new Ui::Fonts; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Fonts"); pluginType = PERSONALIZED; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - settingsCreate = false; - - setupStylesheet(); - - - // const QByteArray iddd(PEONY_SCHEMA); - // peonysettings = new QGSettings(iddd); - - const QByteArray styleID(STYLE_FONT_SCHEMA); - const QByteArray id(INTERFACE_SCHEMA); - const QByteArray idd(MARCO_SCHEMA); - const QByteArray iid(FONT_RENDER_SCHEMA); - - if (QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(iid) && QGSettings::isSchemaInstalled(idd) && - QGSettings::isSchemaInstalled(styleID)){ - settingsCreate = true; - marcosettings = new QGSettings(idd); - ifsettings = new QGSettings(id); - rendersettings = new QGSettings(iid); - stylesettings = new QGSettings(styleID); - - _getDefaultFontinfo(); - setupComponent(); - setupConnect(); - initFontStatus(); - } - } Fonts::~Fonts() { - delete ui; - if (settingsCreate){ - delete ifsettings; - delete marcosettings; - // delete peonysettings; - delete rendersettings; - delete stylesettings; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + if (settingsCreate){ + delete ifsettings; + ifsettings = nullptr; + delete marcosettings; + marcosettings = nullptr; + delete rendersettings; + rendersettings = nullptr; + delete stylesettings; + stylesettings = nullptr; + } } - } -QString Fonts::get_plugin_name(){ +QString Fonts::get_plugin_name() { return pluginName; } -int Fonts::get_plugin_type(){ +int Fonts::get_plugin_type() { return pluginType; } -QWidget *Fonts::get_plugin_ui(){ +QWidget *Fonts::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::Fonts; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + settingsCreate = false; + initTitleLabel(); + initSearchText(); + setupStylesheet(); + + const QByteArray styleID(STYLE_FONT_SCHEMA); + const QByteArray id(INTERFACE_SCHEMA); + const QByteArray idd(MARCO_SCHEMA); + const QByteArray iid(FONT_RENDER_SCHEMA); + + if (QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(iid) && QGSettings::isSchemaInstalled(idd) && + QGSettings::isSchemaInstalled(styleID)) { + settingsCreate = true; + marcosettings = new QGSettings(idd); + ifsettings = new QGSettings(id); + rendersettings = new QGSettings(iid); + stylesettings = new QGSettings(styleID); + + _getDefaultFontinfo(); + setupComponent(); + setupConnect(); + initFontStatus(); + } + } return pluginWidget; } -void Fonts::plugin_delay_control(){ +void Fonts::plugin_delay_control() { + +} + +const QString Fonts::name() const { + + return QStringLiteral("fonts"); +} + +void Fonts::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); +} + +void Fonts::initSearchText() { + //~ contents_path /fonts/Font size + ui->fontSizeLabel->setText(tr("Font size")); + //~ contents_path /fonts/Fonts select + ui->fontSizeLabel->setText(tr("Fonts select")); + //~ contents_path /fonts/Font size + ui->fontSizeLabel->setText(tr("Font size")); } void Fonts::setupStylesheet(){ + ui->advancedBtn->setVisible(false); + ui->advancedFrame->setVisible(false); ui->titleSecondLabel->setVisible(false); ui->sampleBtn1->setVisible(false); ui->sampleBtn2->setVisible(false); @@ -179,55 +199,48 @@ QStringList fontScale; fontScale<< tr("11") << tr("12") << tr("13") << tr("14") << tr("15") - <setRange(1,8); + uslider->setRange(1,6); uslider->setTickInterval(1); uslider->setPageStep(1); ui->fontLayout->addWidget(uslider); - ui->fontLayout->addSpacing(8); - -// ui->fontSizeSlider->setMinimum(100); -// ui->fontSizeSlider->setMaximum(275); -// ui->fontSizeSlider->setSingleStep(25); -// ui->fontSizeSlider->setPageStep(25); -// ui->fontSizeSlider->setTickPosition(QSlider::TicksBelow); + ui->fontLayout->addSpacing(1); //导入系统字体列表 QStringList fontfamiles = fontdb.families(); for (QString font : fontfamiles){ - ////通用设置 - //字体 - ui->fontSelectComBox->addItem(font); + + if (!font.startsWith(kErrorFont, Qt::CaseInsensitive) && + !font.startsWith(kErrorStardFont, Qt::CaseInsensitive)) { + ui->fontSelectComBox->addItem(font); + } + //等宽字体 - ui->monoSelectComBox->addItem(font); - ////高级设置 + if (font.contains("Mono")) + ui->monoSelectComBox->addItem(font); + //高级设置 // gtk default ui->defaultFontComBox->addItem(font); //doc font ui->docFontComBox->addItem(font); - // peony font -// ui->peonyFontComBox->addItem(font); //monospace font ui->monoFontComBox->addItem(font); //title font ui->titleFontComBox->addItem(font); } - ////导入字体大小列表 - //获取当前字体 + // 获取当前字体 QStringList gtkfontStrList = _splitFontNameSize(ifsettings->get(GTK_FONT_KEY).toString()); QStringList docfontStrList = _splitFontNameSize(ifsettings->get(DOC_FONT_KEY).toString()); QStringList monospacefontStrList = _splitFontNameSize(ifsettings->get(MONOSPACE_FONT_KEY).toString()); -// QStringList peonyfontStrList = _splitFontNameSize(peonysettings->get(PEONY_FONT_KEY).toString()); QStringList titlebarfontStrList = _splitFontNameSize(marcosettings->get(TITLEBAR_FONT_KEY).toString()); QList gtksizeList = fontdb.pointSizes(gtkfontStrList.at(0)); QList docsizeList = fontdb.pointSizes(docfontStrList.at(0)); QList monosizeList = fontdb.pointSizes(monospacefontStrList.at(0)); -// QList peonysizeList = fontdb.pointSizes(peonyfontStrList.at(0)); QList titlesizeList = fontdb.pointSizes(titlebarfontStrList.at(0)); if (gtksizeList.length() == 0) @@ -249,10 +262,6 @@ if (size >=11 && size <= 18) ui->MonoSizeComBox->addItem(QString::number(size)); } -// if (peonysizeList.length() == 0) -// peonysizeList = defaultsizeList; -// for (int size : peonysizeList) -// ui->peonySizeComBox->addItem(QString::number(size)); if (titlesizeList.length() == 0) titlesizeList = defaultsizeList; for (int size : titlesizeList) { @@ -276,9 +285,7 @@ ui->sampleBtn2->setProperty("userData", QVariant::fromValue(example2)); ui->sampleBtn3->setProperty("userData", QVariant::fromValue(example3)); ui->sampleBtn4->setProperty("userData", QVariant::fromValue(example4)); - // setSampleButton(ui->sampleBtn1); - } void Fonts::setSampleButton(QPushButton *button){ @@ -299,18 +306,10 @@ } void Fonts::setupConnect(){ -// connect(uslider, &QSlider::sliderReleased, [=]{ -// int value = uslider->value(); - -// int setup = value / 25; int overage = value % 25; - -// if (overage > 12) -// ui->fontSizeSlider->setSliderPosition(ui->fontSizeSlider->singleStep() * (setup + 1)); -// else -// ui->fontSizeSlider->setSliderPosition(ui->fontSizeSlider->singleStep() * setup); -// }); + connectToServer(); connect(uslider, &QSlider::valueChanged, [=](int value){ int size = sliderConvertToSize(value); + //获取当前字体信息 _getCurrentFontInfo(); //设置字体大小 @@ -319,8 +318,8 @@ ifsettings->set(DOC_FONT_KEY, QVariant(QString("%1 %2").arg(docfontStrList.at(0)).arg(size))); ifsettings->set(MONOSPACE_FONT_KEY, QVariant(QString("%1 %2").arg(monospacefontStrList.at(0)).arg(size))); stylesettings->set(SYSTEM_FONT_EKY, QVariant(QString("%1").arg(size))); -// peonysettings->set(PEONY_FONT_KEY, QVariant(QString("%1 %2").arg(peonyfontStrList[0]).arg(defaultfontinfo.monospacefontsize * level))); marcosettings->set(TITLEBAR_FONT_KEY, QVariant(QString("%1 %2").arg(titlebarfontStrList.at(0)).arg(size))); + fontKwinSlot(); }); connect(ui->fontSelectComBox, &QComboBox::currentTextChanged, [=](QString text){ @@ -328,13 +327,13 @@ _getCurrentFontInfo(); ifsettings->set(GTK_FONT_KEY, QVariant(QString("%1 %2").arg(text).arg(gtkfontStrList.at(1)))); ifsettings->set(DOC_FONT_KEY, QVariant(QString("%1 %2").arg(text).arg(docfontStrList.at(1)))); -// peonysettings->set(PEONY_FONT_KEY, QVariant(QString("%1 %2").arg(text).arg(peonyfontStrList.at(1)))); stylesettings->set(SYSTEM_NAME_KEY, QVariant(QString("%1").arg(text))); marcosettings->set(TITLEBAR_FONT_KEY, QVariant(QString("%1 %2").arg(text).arg(titlebarfontStrList.at(1)))); //给更新高级字体配置 initAdvancedFontStatus(); + fontKwinSlot(); }); connect(ui->monoSelectComBox, &QComboBox::currentTextChanged, [=](QString text){ //获取当前字体信息 @@ -387,7 +386,7 @@ marcosettings->set(TITLEBAR_FONT_KEY, QVariant(QString("%1 %2").arg(ui->titleFontComBox->currentText()).arg(text))); }); - ////绑定信号 + //绑定信号 //字体效果按钮 #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) connect(ui->sampleBtnGroup, static_cast(&QButtonGroup::buttonClicked), [=](QAbstractButton * button){ @@ -455,7 +454,6 @@ ui->defaultFontComBox->blockSignals(true); ui->docFontComBox->blockSignals(true); ui->monoFontComBox->blockSignals(true); -// ui->peonyFontComBox->blockSignals(true); ui->titleFontComBox->blockSignals(true); //初始化高级字体ComBox @@ -468,36 +466,30 @@ currentmonofont = "DejaVu Sans Mono"; } ui->monoFontComBox->setCurrentText(currentmonofont); -// ui->peonyFontComBox->setCurrentText(peonyfontStrList.at(0)); ui->titleFontComBox->setCurrentText(titlebarfontStrList.at(0)); //释放信号 ui->defaultFontComBox->blockSignals(false); ui->docFontComBox->blockSignals(false); ui->monoFontComBox->blockSignals(false); -// ui->peonyFontComBox->blockSignals(false); ui->titleFontComBox->blockSignals(false); //阻塞字体大小ComBox信号 ui->defaultSizeComBox->blockSignals(true); ui->docSizeComBox->blockSignals(true); ui->MonoSizeComBox->blockSignals(true); -// ui->peonySizeComBox->blockSignals(true); ui->titleSizeComBox->blockSignals(true); ui->defaultSizeComBox->setCurrentText(gtkfontStrList.at(1)); ui->docSizeComBox->setCurrentText(docfontStrList.at(1)); ui->MonoSizeComBox->setCurrentText(monospacefontStrList.at(1)); -// ui->peonySizeComBox->setCurrentText(peonyfontStrList.at(1)); ui->titleSizeComBox->setCurrentText(titlebarfontStrList.at(1)); //阻塞字体大小ComBox信号 ui->defaultSizeComBox->blockSignals(false); ui->docSizeComBox->blockSignals(false); ui->MonoSizeComBox->blockSignals(false); -// ui->peonySizeComBox->blockSignals(false); ui->titleSizeComBox->blockSignals(false); - } void Fonts::initSampleFontStatus(){ @@ -559,19 +551,6 @@ defaultfontinfo.monospacefontsize = atoi(&font_value[length -2]); g_variant_unref(value); - //PEONY -// GSettings * peonygsettings; -// peonygsettings = g_settings_new(PEONY_SCHEMA); -// value = g_settings_get_default_value(peonygsettings, PEONY_FONT_KEY); -// size = g_variant_get_size(value); -// font_value = g_variant_get_string(value, &size); -// length = (gint)strlen(font_value); -// if (font_value[length -2] == ' ') -// defaultfontinfo.peonyfontsize = atoi(&font_value[length -1]); -// else -// defaultfontinfo.peonyfontsize = atoi(&font_value[length -2]); -// g_variant_unref(value); - //TITLE GSettings * marcogsettings; marcogsettings = g_settings_new(MARCO_SCHEMA); @@ -586,7 +565,6 @@ g_variant_unref(value); g_object_unref(ifgsettings); -// g_object_unref(peonygsettings); g_object_unref(marcogsettings); } @@ -594,7 +572,6 @@ gtkfontStrList = _splitFontNameSize(ifsettings->get(GTK_FONT_KEY).toString()); docfontStrList = _splitFontNameSize(ifsettings->get(DOC_FONT_KEY).toString()); monospacefontStrList = _splitFontNameSize(ifsettings->get(MONOSPACE_FONT_KEY).toString()); -// peonyfontStrList = _splitFontNameSize(peonysettings->get(PEONY_FONT_KEY).toString()); titlebarfontStrList = _splitFontNameSize(marcosettings->get(TITLEBAR_FONT_KEY).toString()); } @@ -691,19 +668,53 @@ } void Fonts::resetDefault(){ - //reset font + // Reset font ifsettings->reset(GTK_FONT_KEY); ifsettings->reset(DOC_FONT_KEY); ifsettings->reset(MONOSPACE_FONT_KEY); -// peonysettings->reset(PEONY_FONT_KEY); marcosettings->reset(TITLEBAR_FONT_KEY); stylesettings->set(SYSTEM_FONT_EKY, 11); stylesettings->reset(SYSTEM_NAME_KEY); - //reset font render + // Reset font render rendersettings->reset(ANTIALIASING_KEY); rendersettings->reset(HINTING_KEY); - //更新全部状态 + // 更新全部状态 initFontStatus(); + fontKwinSlot(); +} + +void Fonts::connectToServer(){ + m_cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", + "/org/kylinssoclient/path", + "org.freedesktop.kylinssoclient.interface", + QDBusConnection::sessionBus()); + if (!m_cloudInterface->isValid()) + { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), QString("org.freedesktop.kylinssoclient.interface"), "keyChanged", this, SLOT(keyChangedSlot(QString))); + // 将以后所有DBus调用的超时设置为 milliseconds + m_cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} + +void Fonts::keyChangedSlot(const QString &key) { + if(key == "font") { + initFontStatus(); + } +} + +void Fonts::fontKwinSlot() { + const int fontSize = sliderConvertToSize(uslider->value()); + const QString fontType = ui->fontSelectComBox->currentText(); + qDebug() << fontSize << fontType; + QDBusMessage message =QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "slotFontChange"); + QList args; + args.append(fontSize); + args.append(fontType); + message.setArguments(args); + QDBusConnection::sessionBus().send(message); } diff -Nru ukui-control-center-2.0.3/plugins/personalized/fonts/fonts.h ukui-control-center-3.0.3/plugins/personalized/fonts/fonts.h --- ukui-control-center-2.0.3/plugins/personalized/fonts/fonts.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/fonts/fonts.h 2021-04-14 01:27:20.000000000 +0000 @@ -20,7 +20,6 @@ #ifndef FONTS_H #define FONTS_H - #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include "shell/interface.h" #include "Uslider/uslider.h" @@ -64,8 +64,11 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); + void initSearchText(); void setupStylesheet(); void setupComponent(); void setupConnect(); @@ -86,6 +89,8 @@ int fontConvertToSlider(const int size) const; int sliderConvertToSize(const int value) const; + void connectToServer(); + private: Ui::Fonts *ui; @@ -105,13 +110,19 @@ QStringList peonyfontStrList; QStringList titlebarfontStrList; + QDBusInterface *m_cloudInterface; QFontDatabase fontdb; +public Q_SLOTS: + void keyChangedSlot(const QString &key); + +private: + void fontKwinSlot(); private: bool settingsCreate; + bool mFirstLoad; QGSettings * stylesettings; Uslider * uslider; - }; #endif // FONTS_H diff -Nru ukui-control-center-2.0.3/plugins/personalized/fonts/fonts.pro ukui-control-center-3.0.3/plugins/personalized/fonts/fonts.pro --- ukui-control-center-2.0.3/plugins/personalized/fonts/fonts.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/fonts/fonts.pro 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/uslider.pri) -QT += widgets +QT += widgets dbus TEMPLATE = lib CONFIG += plugin diff -Nru ukui-control-center-2.0.3/plugins/personalized/fonts/fonts.ui ukui-control-center-3.0.3/plugins/personalized/fonts/fonts.ui --- ukui-control-center-2.0.3/plugins/personalized/fonts/fonts.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/fonts/fonts.ui 2021-04-14 01:27:20.000000000 +0000 @@ -25,10 +25,7 @@ Fonts - - - 10 - + 0 @@ -38,9 +35,6 @@ 32 - - 30 - @@ -68,7 +62,7 @@ 20 - 6 + 10 @@ -162,174 +156,136 @@ - + - 550 - 100 + 960 + 60 + + QFrame::Box + + + QFrame::Raised + + + + + + 0 + + + + + + 0 + 0 + + + + + 140 + 0 + + + + + 140 + 16777215 + + + + Fonts select + + + + + + + + 400 + 0 + + + + + 16777215 + 32 + + + + + + + + + + + + + + 960 - 100 + 60 QFrame::Box - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - + + QFrame::Raised + + - + - 9 - - - 16 - - - 0 - - - 16 - - 0 - - - 0 + + + + 0 + 0 + - - - - - 0 - 0 - - - - - 140 - 0 - - - - - 140 - 16777215 - - - - Fonts select - - - - - - - - 400 - 0 - - - - - 16777215 - 32 - - - - - - - - - - - - 541 + 140 0 - 1677215 + 140 16777215 - - Qt::Horizontal + + Mono font - - - 0 + + + + 400 + 0 + - - - - - 0 - 0 - - - - - 140 - 0 - - - - - 140 - 16777215 - - - - Monospace font - - - - - - - - 400 - 0 - - - - - 1677215 - 32 - - - - - - - - + + + 1677215 + 32 + + + + + + @@ -337,6 +293,45 @@ + + + 0 + + + + + + 120 + 36 + + + + + 1200 + 36 + + + + Reset to default + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + Qt::Vertical @@ -1123,45 +1118,6 @@ - - - 0 - - - - - - 120 - 36 - - - - - 1200 - 36 - - - - Reset to default - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - Qt::Vertical diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/buildpicunitsworker.cpp ukui-control-center-3.0.3/plugins/personalized/screenlock/buildpicunitsworker.cpp --- ukui-control-center-2.0.3/plugins/personalized/screenlock/buildpicunitsworker.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/buildpicunitsworker.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -29,9 +29,17 @@ BuildPicUnitsWorker::~BuildPicUnitsWorker() { + delete xmlHandleObj; + xmlHandleObj = nullptr; } void BuildPicUnitsWorker::run(){ + //构建xmlhandle对象 + xmlHandleObj = new XmlHandle(); + + //解析壁纸数据,如果本地xml文件不存在则自动构建 + xmlHandleObj->init(); + //获取本地壁纸列表 QMap wholeBgInfo = BgFileParse::bgFileReader(); for (BgInfo sinBfInfo : wholeBgInfo){ diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/buildpicunitsworker.h ukui-control-center-3.0.3/plugins/personalized/screenlock/buildpicunitsworker.h --- ukui-control-center-2.0.3/plugins/personalized/screenlock/buildpicunitsworker.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/buildpicunitsworker.h 2021-04-14 01:27:20.000000000 +0000 @@ -24,6 +24,7 @@ #include #include "bgfileparse.h" +#include "xmlhandle.h" class BuildPicUnitsWorker : public QObject { @@ -33,9 +34,12 @@ explicit BuildPicUnitsWorker(); ~BuildPicUnitsWorker(); -public: void run(); +private: + XmlHandle * xmlHandleObj; + + Q_SIGNALS: void pixmapGeneral(QPixmap pixmap, BgInfo bginfo); void workerComplete(); diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/pictureunit.cpp ukui-control-center-3.0.3/plugins/personalized/screenlock/pictureunit.cpp --- ukui-control-center-2.0.3/plugins/personalized/screenlock/pictureunit.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/pictureunit.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -18,17 +18,23 @@ * */ #include "pictureunit.h" - +#include #include "MaskWidget/maskwidget.h" - +#include PictureUnit::PictureUnit() { _filename = ""; - + QColor highLightColor = palette().color(QPalette::Highlight); + QString stringColor = QString("rgb(%1,%2,%3)") + .arg(highLightColor.red()) + .arg(highLightColor.green()) + .arg(highLightColor.blue()); + hoverStyleSheet = QString("border-width: 3px;border-style: solid;border-color: %1;").arg(stringColor); + clickedStyleSheet = QString("border-width: 6px;border-style: solid;border-color: %1;").arg(stringColor);; setAttribute(Qt::WA_DeleteOnClose); setFixedSize(QSize(166, 110)); setScaledContents(true); - + clickedFlag = false; MaskWidget * maskWidget = new MaskWidget(this); maskWidget->setGeometry(0, 0, this->width(), this->height()); } @@ -46,3 +52,29 @@ emit clicked(_filename); // QLabel::mousePressEvent(event); } + +void PictureUnit::enterEvent(QEvent *e) +{ + Q_UNUSED(e) + if(getClickedFlag() == false) + { + setFrameShape (QFrame::Box); + setStyleSheet(hoverStyleSheet); + } +} +void PictureUnit::leaveEvent(QEvent *e) +{ + Q_UNUSED(e) + if(getClickedFlag() == false) + setStyleSheet("border-width: 0px;"); +} + +bool PictureUnit::getClickedFlag() +{ + return clickedFlag; +} + +void PictureUnit::changeClickedFlag(bool flag) +{ + clickedFlag = flag; +} diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/pictureunit.h ukui-control-center-3.0.3/plugins/personalized/screenlock/pictureunit.h --- ukui-control-center-2.0.3/plugins/personalized/screenlock/pictureunit.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/pictureunit.h 2021-04-14 01:27:20.000000000 +0000 @@ -22,7 +22,7 @@ #include #include - +#include class PictureUnit : public QLabel { Q_OBJECT @@ -30,16 +30,21 @@ public: explicit PictureUnit(); ~PictureUnit(); - + public: void setFilenameText(QString fn); - + void changeClickedFlag(bool flag); + bool getClickedFlag(); + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + QString clickedStyleSheet; protected: void mousePressEvent(QMouseEvent * e); private: QString _filename; - + bool clickedFlag; + QString hoverStyleSheet; Q_SIGNALS: void clicked(QString filename); diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/screenlock.cpp ukui-control-center-3.0.3/plugins/personalized/screenlock/screenlock.cpp --- ukui-control-center-2.0.3/plugins/personalized/screenlock/screenlock.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/screenlock.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -19,76 +19,101 @@ */ #include "screenlock.h" #include "ui_screenlock.h" +#include "bgfileparse.h" +#include "pictureunit.h" +#include "MaskWidget/maskwidget.h" #include #include - -#define BGPATH "/usr/share/backgrounds/" -#define SCREENLOCK_BG_SCHEMA "org.ukui.screensaver" -#define SCREENLOCK_BG_KEY "background" -#define SCREENLOCK_DELAY_KEY "lock-delay" -#define SCREENLOCK_LOCK_KEY "lock-enabled" -#define SCREENLOCK_ACTIVE_KEY "idle-activation-enabled" +#include +#include +#include + +#define BGPATH "/usr/share/backgrounds/" +#define SCREENLOCK_BG_SCHEMA "org.ukui.screensaver" +#define SCREENLOCK_BG_KEY "background" +#define SCREENLOCK_DELAY_KEY "lock-delay" +#define SCREENLOCK_LOCK_KEY "lock-enabled" +#define SCREENLOCK_ACTIVE_KEY "idle-activation-enabled" #define MATE_BACKGROUND_SCHEMAS "org.mate.background" -#define FILENAME "picture-filename" - -#include "bgfileparse.h" -#include "pictureunit.h" -#include "MaskWidget/maskwidget.h" +#define FILENAME "picture-filename" +const QString kylinUrl = "https://www.ubuntukylin.com/wallpaper.html"; -Screenlock::Screenlock() +Screenlock::Screenlock() : mFirstLoad(true) { - ui = new Ui::Screenlock; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Screenlock"); pluginType = PERSONALIZED; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title1Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - const QByteArray id(SCREENLOCK_BG_SCHEMA); - lSetting = new QGSettings(id); - - - setupComponent(); - setupConnect(); - initScreenlockStatus(); - - lockbgSize = QSize(400, 240); + prePicUnit = nullptr; } Screenlock::~Screenlock() { - delete ui; - delete lSetting; - delete lockSetting; - delete lockLoginSettings; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } } -QString Screenlock::get_plugin_name(){ +QString Screenlock::get_plugin_name() +{ return pluginName; } -int Screenlock::get_plugin_type(){ +int Screenlock::get_plugin_type() +{ return pluginType; } -QWidget *Screenlock::get_plugin_ui(){ +QWidget *Screenlock::get_plugin_ui() +{ + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::Screenlock; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); + ui->title1Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); + ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); + + const QByteArray id(SCREENLOCK_BG_SCHEMA); + lSetting = new QGSettings(id, QByteArray(), this); + + connectToServer(); + initSearchText(); + setupComponent(); + setupConnect(); + initScreenlockStatus(); + + lockbgSize = QSize(400, 240); + } return pluginWidget; } -void Screenlock::plugin_delay_control(){ +void Screenlock::plugin_delay_control() +{ + +} + +const QString Screenlock::name() const +{ + return QStringLiteral("screenlock"); +} +void Screenlock::initSearchText() { + //~ contents_path /screenlock/Show picture of screenlock on screenlogin + ui->loginpicLabel->setText(tr("Show picture of screenlock on screenlogin")); + //~ contents_path /screenlock/Lock screen when screensaver boot + ui->activepicLabel->setText(tr("Lock screen when screensaver boot")); } -void Screenlock::setupComponent(){ - QString filename = QDir::homePath() + "/.config/ukui/ukui-control-center.conf"; - lockSetting = new QSettings(filename, QSettings::IniFormat); +void Screenlock::setupComponent() +{ + mUKCConfig = QDir::homePath() + "/.config/ukui/ukui-control-center.conf"; + lockSetting = new QSettings(mUKCConfig, QSettings::IniFormat, this); //锁屏延时暂时不可用,屏蔽 ui->enableFrame->hide(); @@ -99,7 +124,7 @@ } QString lockfilename = "/var/lib/lightdm-data/" + name + "/ukui-greeter.conf"; - lockLoginSettings = new QSettings(lockfilename, QSettings::IniFormat); + lockLoginSettings = new QSettings(lockfilename, QSettings::IniFormat, this); QStringList scaleList; scaleList<< tr("1m") << tr("5m") << tr("10m") << tr("30m") << tr("45m") @@ -112,9 +137,6 @@ ui->lockhorizontalLayout->addWidget(uslider); - ui->browserLocalwpBtn->hide(); - ui->browserOnlinewpBtn->hide(); - loginbgSwitchBtn = new SwitchButton(pluginWidget); ui->loginbgHorLayout->addWidget(loginbgSwitchBtn); loginbgSwitchBtn->setChecked(getLockStatus()); @@ -130,13 +152,12 @@ lockSwitchBtn->setChecked(status); } - connect(lockSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked){ + connect(lockSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked) { if (lockKey) { lSetting->set(SCREENLOCK_LOCK_KEY, checked); } }); - connect(lSetting, &QGSettings::changed, this, [=](QString key) { if ("idleActivationEnabled" == key) { bool judge = lSetting->get(key).toBool(); @@ -160,14 +181,13 @@ ui->backgroundsWidget->setLayout(flowLayout); } -void Screenlock::setupConnect(){ -// ui->delaySlider->setMinimum(1); -// ui->delaySlider->setMaximum(120); - connect(loginbgSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked){ +void Screenlock::setupConnect() +{ + connect(loginbgSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked) { setLockBackground(checked); }); - connect(uslider, &QSlider::valueChanged, [&](int value){ + connect(uslider, &QSlider::valueChanged, [&](int value) { QStringList keys = lSetting->keys(); if (keys.contains("lockDelay")) { lSetting->set(SCREENLOCK_DELAY_KEY, convertToLocktime(value)); @@ -177,13 +197,19 @@ QStringList keys = lSetting->keys(); if (keys.contains("lockDelay")) { int value = lockConvertToSlider(lSetting->get(SCREENLOCK_DELAY_KEY).toInt()); - uslider->setValue(value); } + + connect(ui->browserLocalwpBtn, &QPushButton::clicked, this, &Screenlock::setScreenLockBgSlot); + + connect(ui->browserOnlinewpBtn, &QPushButton::clicked, [=] { + QDesktopServices::openUrl(QUrl(kylinUrl)); + }); } -void Screenlock::initScreenlockStatus(){ - //获取当前锁屏壁纸 +void Screenlock::initScreenlockStatus() +{ + // 获取当前锁屏壁纸 QString bgStr = lSetting->get(SCREENLOCK_BG_KEY).toString(); if (bgStr.isEmpty()) { if (QGSettings::isSchemaInstalled(MATE_BACKGROUND_SCHEMAS)) { @@ -194,25 +220,37 @@ ui->previewLabel->setPixmap(QPixmap(bgStr).scaled(ui->previewLabel->size())); - //遮罩 - MaskWidget * maskWidget = new MaskWidget(ui->previewLabel); - maskWidget->setGeometry(0, 0, ui->previewLabel->width(), ui->previewLabel->height()); - - //使用线程解析本地壁纸文件;获取壁纸单元 + // 使用线程解析本地壁纸文件;获取壁纸单元 pThread = new QThread; pWorker = new BuildPicUnitsWorker; connect(pWorker, &BuildPicUnitsWorker::pixmapGeneral, this, [=](QPixmap pixmap, BgInfo bgInfo){ - //设置当前锁屏壁纸的预览 - if (bgInfo.filename == bgStr){ - ui->previewLabel->setPixmap(QPixmap(bgStr).scaled(ui->previewLabel->size())); - } - - //线程中构建控件传递会报告event无法install 的警告 + // 线程中构建控件传递会报告event无法install 的警告 PictureUnit * picUnit = new PictureUnit; picUnit->setPixmap(pixmap); picUnit->setFilenameText(bgInfo.filename); + // 选定当前锁屏壁纸 + if (bgInfo.filename == bgStr){ + ui->previewLabel->setPixmap(QPixmap(bgStr).scaled(ui->previewLabel->size())); + if (prePicUnit != nullptr) { + prePicUnit->changeClickedFlag(false); + prePicUnit->setStyleSheet("border-width: 0px;"); + } + picUnit->changeClickedFlag(true); + prePicUnit = picUnit; + picUnit->setFrameShape(QFrame::Box); + picUnit->setStyleSheet(picUnit->clickedStyleSheet); + } + connect(picUnit, &PictureUnit::clicked, [=](QString filename){ + if (prePicUnit != nullptr) { + prePicUnit->changeClickedFlag(false); + prePicUnit->setStyleSheet("border-width: 0px;"); + } + picUnit->changeClickedFlag(true); + prePicUnit = picUnit; + picUnit->setFrameShape(QFrame::Box); + picUnit->setStyleSheet(picUnit->clickedStyleSheet); ui->previewLabel->setPixmap(QPixmap(filename).scaled(ui->previewLabel->size())); lSetting->set(SCREENLOCK_BG_KEY, filename); setLockBackground(loginbgSwitchBtn->isChecked()); @@ -221,34 +259,29 @@ flowLayout->addWidget(picUnit); }); connect(pWorker, &BuildPicUnitsWorker::workerComplete, [=]{ - pThread->quit(); //退出事件循环 - pThread->wait(); //释放资源 + pThread->quit(); // 退出事件循环 + pThread->wait(); // 释放资源 }); pWorker->moveToThread(pThread); connect(pThread, &QThread::started, pWorker, &BuildPicUnitsWorker::run); - connect(pThread, &QThread::finished, this, [=]{ + connect(pThread, &QThread::finished, this, [=] { }); connect(pThread, &QThread::finished, pWorker, &BuildPicUnitsWorker::deleteLater); pThread->start(); - //设置登录界面背景开关 - - - //设置锁屏时间,屏保激活后多久锁定屏幕 + // 设置锁屏时间,屏保激活后多久锁定屏幕 int lDelay = lSetting->get(SCREENLOCK_DELAY_KEY).toInt(); -// ui->delaySlider->blockSignals(true); -// ui->delaySlider->setValue(lDelay); -// ui->delaySlider->blockSignals(false); uslider->blockSignals(true); uslider->setValue(lockConvertToSlider(lDelay)); uslider->blockSignals(false); } -int Screenlock::convertToLocktime(const int value) { +int Screenlock::convertToLocktime(const int value) +{ switch (value) { case 1: return 1; @@ -280,7 +313,8 @@ } } -int Screenlock::lockConvertToSlider(const int value) { +int Screenlock::lockConvertToSlider(const int value) +{ switch (value) { case 1: return 1; @@ -312,15 +346,20 @@ } } +//设置登录界面显示锁屏壁纸 void Screenlock::setLockBackground(bool status) { QString bgStr; + struct stat fileStat; if (lSetting && status) { - bgStr= lSetting->get(SCREENLOCK_BG_KEY).toString(); + bgStr = lSetting->get(SCREENLOCK_BG_KEY).toString(); + stat(bgStr.toStdString().c_str(),&fileStat); + if (fileStat.st_uid != 0) { //在普通用户下 + bgStr = copyLoginFile(bgStr); + } } else if (!status) { bgStr = ""; } - lockSetting->beginGroup("ScreenLock"); lockSetting->setValue("lockStatus", status); lockSetting->endGroup(); @@ -332,8 +371,104 @@ bool Screenlock::getLockStatus() { + if (!QFile::exists(mUKCConfig)) { + setLockBackground(true); + } + lockSetting->beginGroup("ScreenLock"); + lockSetting->sync(); bool status = lockSetting->value("lockStatus").toBool(); lockSetting->endGroup(); return status; } + +void Screenlock::connectToServer() +{ + m_cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", + "/org/kylinssoclient/path", + "org.freedesktop.kylinssoclient.interface", + QDBusConnection::sessionBus()); + if (!m_cloudInterface->isValid()) + { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), QString("org.freedesktop.kylinssoclient.interface"), "keyChanged", this, SLOT(keyChangedSlot(QString))); + // 将以后所有DBus调用的超时设置为 milliseconds + m_cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} + +void Screenlock::keyChangedSlot(const QString &key) +{ + if(key == "ukui-screensaver") { + if(!bIsCloudService) + bIsCloudService = true; + QString bgStr = lSetting->get(SCREENLOCK_BG_KEY).toString(); + if (bgStr.isEmpty()) { + if (QGSettings::isSchemaInstalled(MATE_BACKGROUND_SCHEMAS)) { + QGSettings * bgGsetting = new QGSettings(MATE_BACKGROUND_SCHEMAS, QByteArray(), this); + bgStr = bgGsetting->get(FILENAME).toString(); + } + } + + ui->previewLabel->setPixmap(QPixmap(bgStr).scaled(ui->previewLabel->size())); + QStringList keys = lSetting->keys(); + if (keys.contains("lockEnabled")) { + bool status = lSetting->get(SCREENLOCK_LOCK_KEY).toBool(); + lockSwitchBtn->setChecked(status); + } + loginbgSwitchBtn->setChecked(getLockStatus()); + } +} + +void Screenlock::setScreenLockBgSlot() +{ + QStringList filters; + filters<(g_get_user_special_dir(G_USER_DIRECTORY_PICTURES)))); + fd.setAcceptMode(QFileDialog::AcceptOpen); + fd.setViewMode(QFileDialog::List); + fd.setNameFilters(filters); + fd.setFileMode(QFileDialog::ExistingFile); + fd.setWindowTitle(tr("select custom wallpaper file")); + fd.setLabelText(QFileDialog::Accept, tr("Select")); + fd.setLabelText(QFileDialog::LookIn, tr("Position: ")); + fd.setLabelText(QFileDialog::FileName, tr("FileName: ")); + fd.setLabelText(QFileDialog::FileType, tr("FileType: ")); + fd.setLabelText(QFileDialog::Reject, tr("Cancel")); + + if (fd.exec() != QDialog::Accepted) + return; + QString selectedfile; + selectedfile = fd.selectedFiles().first(); + + QStringList fileRes = selectedfile.split("/"); + + QProcess * process = new QProcess(this); + QString program("cp"); + QStringList arguments; + arguments << selectedfile ; + arguments << "/tmp"; + process->start(program, arguments); + + lSetting->set(SCREENLOCK_BG_KEY, selectedfile); + setLockBackground(loginbgSwitchBtn->isChecked()); + if (prePicUnit != nullptr) { //去掉选定标记 + prePicUnit->changeClickedFlag(false); + prePicUnit->setStyleSheet("border-width: 0px;"); + } +} + +QString Screenlock::copyLoginFile(QString fileName) { + QString name = qgetenv("USER"); + if (name.isEmpty()) { + name = qgetenv("USERNAME"); + } + QString loginFilename = "/var/lib/lightdm-data/" + name + "/" + "loginBackground"; + QProcess process; + QString loginCmd = QString("cp %1 %2").arg(fileName).arg(loginFilename); + process.startDetached(loginCmd); + return loginFilename; +} diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/screenlock.h ukui-control-center-3.0.3/plugins/personalized/screenlock/screenlock.h --- ukui-control-center-2.0.3/plugins/personalized/screenlock/screenlock.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/screenlock.h 2021-05-20 13:08:14.000000000 +0000 @@ -27,6 +27,7 @@ #include #include #include +#include #include "shell/interface.h" #include "SwitchButton/switchbutton.h" @@ -34,7 +35,16 @@ #include "Uslider/uslider.h" #include "buildpicunitsworker.h" +#include "pictureunit.h" +#ifdef signals +#undef signals +#endif + +extern "C" { +#include +#include +} namespace Ui { class Screenlock; @@ -50,11 +60,13 @@ Screenlock(); ~Screenlock(); - QString get_plugin_name() Q_DECL_OVERRIDE; - int get_plugin_type() Q_DECL_OVERRIDE; - QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + void initSearchText(); void setupComponent(); void setupConnect(); void initScreenlockStatus(); @@ -64,30 +76,46 @@ int lockConvertToSlider(const int value); void setLockBackground(bool status); bool getLockStatus(); + void connectToServer(); + QString copyLoginFile(QString fileName); private: Ui::Screenlock *ui; QString pluginName; int pluginType; - QWidget * pluginWidget; + QWidget *pluginWidget; - SwitchButton * loginbgSwitchBtn; - SwitchButton * lockSwitchBtn; + SwitchButton *loginbgSwitchBtn; // 显示锁屏壁纸在登录页面 + SwitchButton *lockSwitchBtn; // 激活屏保时锁定屏幕 - Uslider * uslider; + Uslider *uslider; - QGSettings * lSetting; - QSettings * lockSetting; //锁屏状态QSettings - QSettings * lockLoginSettings; + QGSettings *lSetting; + QSettings *lockSetting; // 锁屏状态QSettings + QSettings *lockLoginSettings; QSize lockbgSize; - QThread * pThread; + QThread *pThread; + + QDBusInterface *m_cloudInterface; + bool bIsCloudService; + + FlowLayout *flowLayout; + + BuildPicUnitsWorker *pWorker; + PictureUnit *prePicUnit; + + bool mFirstLoad; + + QString mUKCConfig; - FlowLayout * flowLayout; +public Q_SLOTS: + void keyChangedSlot(const QString &key); - BuildPicUnitsWorker * pWorker; +private slots: + void setScreenLockBgSlot(); }; #endif // SCREENLOCK_H diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/screenlock.pro ukui-control-center-3.0.3/plugins/personalized/screenlock/screenlock.pro --- ukui-control-center-2.0.3/plugins/personalized/screenlock/screenlock.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/screenlock.pro 2021-04-14 01:27:20.000000000 +0000 @@ -10,7 +10,7 @@ include($$PROJECT_COMPONENTSOURCE/maskwidget.pri) include($$PROJECT_COMPONENTSOURCE/uslider.pri) -QT += widgets xml +QT += widgets xml dbus TEMPLATE = lib CONFIG += plugin @@ -31,7 +31,7 @@ CONFIG += link_pkgconfig \ C++11 PKGCONFIG += gsettings-qt \ -#PKGCONFIG += gio-2.0 \ + gio-2.0 \ # gio-unix-2.0 #DEFINES += QT_DEPRECATED_WARNINGS @@ -40,13 +40,15 @@ bgfileparse.cpp \ buildpicunitsworker.cpp \ pictureunit.cpp \ - screenlock.cpp + screenlock.cpp \ + xmlhandle.cpp HEADERS += \ bgfileparse.h \ buildpicunitsworker.h \ pictureunit.h \ - screenlock.h + screenlock.h \ + xmlhandle.h FORMS += \ screenlock.ui diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/screenlock.ui ukui-control-center-3.0.3/plugins/personalized/screenlock/screenlock.ui --- ukui-control-center-2.0.3/plugins/personalized/screenlock/screenlock.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/screenlock.ui 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 673 - 664 + 978 @@ -77,6 +77,9 @@ + + 13 + @@ -138,6 +141,12 @@ + + + 16777215 + 50 + + Screenlock Set @@ -185,7 +194,7 @@ 0 - + 0 @@ -257,7 +266,7 @@ 0 - + 0 @@ -376,7 +385,14 @@ - + + + + 0 + 345 + + + @@ -400,7 +416,7 @@ 16 - + 132 @@ -414,12 +430,12 @@ - Browser online wp + Browser local wp - + 132 @@ -433,7 +449,7 @@ - Browser local wp + Browser online wp diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/xmlhandle.cpp ukui-control-center-3.0.3/plugins/personalized/screenlock/xmlhandle.cpp --- ukui-control-center-2.0.3/plugins/personalized/screenlock/xmlhandle.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/xmlhandle.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,283 @@ +/* -*- 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 "xmlhandle.h" + +#include + +XmlHandle::XmlHandle() +{ + localconf = QString("%1/%2/%3").arg(QDir::homePath()).arg(".config/ukui").arg("wallpaper.xml"); +} + +XmlHandle::~XmlHandle() +{ +} + +void XmlHandle::init(){ + + // + wallpapersMap.clear(); + + QFile file(localconf); + //如果用户本地壁纸XML文件不存在,创建 + if (!file.exists()){ + QStringList files = _getXmlFiles(WALLPAPERDIR); + + for (int num = 0; num < files.length(); num++){ + xmlreader(files[num]); + } + _xmlGenerate(); + + //创建完成,清空QMap + wallpapersMap.clear(); + } + //重新解析本地壁纸信息,并填充QMap + xmlreader(localconf); + +} + +QStringList XmlHandle::_getXmlFiles(QString path){ + xmlDir = QDir(path); + QStringList xmlfilesStringList; + + foreach (QString filename, xmlDir.entryList(QDir::Files)) { + if (filename.endsWith(".xml")) + xmlfilesStringList.append(QString("%1/%2").arg(WALLPAPERDIR).arg(filename)); + } + return xmlfilesStringList; +} + +void XmlHandle::xmlreader(QString filename){ + QFile file(filename); + if (!file.open(QFile::ReadOnly | QFile::Text)){ + QMap > tmpMap; + qDebug() << "Error Open XML File When Reader Xml: " << file.errorString(); +// return tmpMap; + return; + } + + //旧清理数据 +// wpMap.clear(); +// headMap.clear(); + + QMap headMap; + + QXmlStreamReader reader; + reader.setDevice(&file); + + while (!reader.atEnd()) { + QXmlStreamReader::TokenType nType = reader.readNext(); + switch (nType) { + case QXmlStreamReader::StartDocument: { + QString versionStr = reader.documentVersion().toString(); + QString encodingStr = reader.documentEncoding().toString(); + headMap.insert("version", versionStr); + headMap.insert("encoding", encodingStr); + break; + } + case QXmlStreamReader::DTD: { + QString dtdStr = reader.text().toString(); + QString dtdnameStr = reader.dtdName().toString(); + QString dtdsystemidStr = reader.dtdSystemId().toString(); + headMap.insert("doctype", dtdnameStr); + headMap.insert("system", dtdsystemidStr); + break; + } + case QXmlStreamReader::Comment: { + QString commentStr = reader.text().toString(); + break; + } + case QXmlStreamReader::StartElement: { + QString elementnameStr = reader.name().toString(); + if (elementnameStr == "wallpapers"){ //根元素 + _parseWallpaper(reader); + } + break; + } + case QXmlStreamReader::EndDocument: { + break; + } + default: + break; + } + } + wallpapersMap.insert("head", headMap); + + if (reader.hasError()){ + qDebug() << QString::fromLocal8Bit("msg: %1; line: %2; column: %3; char shift: %4").arg(reader.errorString()).arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.characterOffset()); + } + file.close(); + +// return wallpapersMap; +} + +QMap > XmlHandle::requireXmlData(){ + return wallpapersMap; +} + +void XmlHandle::_parseWallpaper(QXmlStreamReader &reader){ + QMap wpMap; + while (!reader.atEnd()) { + reader.readNext(); + if (reader.isStartElement()){ + QString elementnameStr = reader.name().toString(); + if (elementnameStr == "wallpaper"){ + wpMap.clear(); + QXmlStreamAttributes wp_attributes = reader.attributes(); + if (wp_attributes.hasAttribute("deleted")){ + QString deletedStr = wp_attributes.value("deleted").toString(); + wpMap.insert("deleted", deletedStr); + } + } + else if (elementnameStr == "name"){ + QXmlStreamAttributes name_attributes = reader.attributes(); + if (name_attributes.hasAttribute("xml:lang")){ + QString langStr = name_attributes.value("xml:lang").toString(); + wpMap.insert("name.zh_CN", reader.readElementText()); + } + else + wpMap.insert("name", reader.readElementText()); + } + else + wpMap.insert(elementnameStr, reader.readElementText()); + } + else if (reader.isEndElement()){ + QString elementnameStr = reader.name().toString(); + if (elementnameStr == "wallpaper"){ + QString filename = QString(wpMap.find("filename").value()); + QFile file(filename); + if (!filename.endsWith("xml") && file.exists()) //slide show not append and file must exist! + wallpapersMap.insert(QString(wpMap.find("filename").value()), wpMap); + } + else if (elementnameStr == "wallpapers"){ + break; + } + } + } +} + +void XmlHandle::_xmlGenerate(){ + QFile file(localconf); + if (!file.open(QFile::WriteOnly | QFile::Text)){ + qDebug() << "Error Open XML file when generate local xml: " << file.errorString(); + return; + } + + QMap currentheadMap; + currentheadMap = (QMap)wallpapersMap.find("head").value(); + + QXmlStreamWriter writer; + writer.setDevice(&file); + writer.setAutoFormatting(true); //自动格式化 +// writer.setCodec(headMap.find("encoding")); + writer.writeStartDocument(QString(currentheadMap.find("version").value()), false); + + //DTD + writer.writeDTD(QString::fromLocal8Bit("").arg(currentheadMap.find("doctype").value()).arg(currentheadMap.find("system").value())); + + //BODY + writer.writeStartElement("wallpapers"); + QMap >::iterator its = wallpapersMap.begin(); + for (; its != wallpapersMap.end(); its++){ + if (QString(its.key()) == "head") //跳过xml的头信息 + continue; + + QMap sourceMap = (QMap)its.value(); + QMap::iterator it = sourceMap.begin(); + + writer.writeStartElement("wallpaper"); + if (sourceMap.contains("deleted")) + writer.writeAttribute("deleted", QString(sourceMap.find("deleted").value())); + else + writer.writeAttribute("deleted", "false"); + + if (sourceMap.contains("artist")) + writer.writeTextElement("artist", QString(sourceMap.find("artist").value())); + else + writer.writeTextElement("artist", "(none)"); + for(; it != sourceMap.end(); it++){ + if (it.key() == "deleted") + continue; + if (it.key() == "name") + continue; + if (it.key() == "name.zh_CN") + writer.writeTextElement("name", QString(it.value())); + else + writer.writeTextElement(QString(it.key()), QString(it.value())); + } + writer.writeEndElement(); + } + + writer.writeEndElement(); + writer.writeEndDocument(); + + file.close(); +} + +void XmlHandle::xmlUpdate(QMap > wallpaperinfosMap){ + QFile file(localconf); + if (!file.open(QFile::WriteOnly | QFile::Text)){ + qDebug() << "Error Open XML File When Update Local Xml: " << file.errorString(); + return; + } + + if (0 == wallpaperinfosMap.count()){ + qDebug() << "Error QMap Empty"; + return; + } + + QMap currentheadMap; + currentheadMap = wallpaperinfosMap.find("head").value(); + + QXmlStreamWriter writer; + writer.setDevice(&file); + writer.setAutoFormatting(true); //自动格式化 +// writer.setCodec(headMap.find("encoding")); + writer.writeStartDocument(QString(currentheadMap.find("version").value()), false); + + //DTD + writer.writeDTD(QString::fromLocal8Bit("").arg(currentheadMap.find("doctype").value()).arg(currentheadMap.find("system").value())); + + //BODY + writer.writeStartElement("wallpapers"); + QMap >::iterator its = wallpaperinfosMap.begin(); + for (; its != wallpaperinfosMap.end(); its++){ + if (QString(its.key()) == "head") + continue; + + QMap sourceMap = (QMap)its.value(); + QMap::iterator it = sourceMap.begin(); + + writer.writeStartElement("wallpaper"); + writer.writeAttribute("deleted", QString(sourceMap.find("deleted").value())); + + for(; it != sourceMap.end(); it++){ + if (it.key() == "deleted") + continue; + writer.writeTextElement(QString(it.key()), QString(it.value())); + } + + writer.writeEndElement(); + } + writer.writeEndElement(); + writer.writeEndDocument(); + + file.close(); +} diff -Nru ukui-control-center-2.0.3/plugins/personalized/screenlock/xmlhandle.h ukui-control-center-3.0.3/plugins/personalized/screenlock/xmlhandle.h --- ukui-control-center-2.0.3/plugins/personalized/screenlock/xmlhandle.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screenlock/xmlhandle.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,59 @@ +/* -*- 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 XMLHANDLE_H +#define XMLHANDLE_H + +#include +#include +#include +#include +#include +#include + +#define WALLPAPERDIR "/usr/share/ukui-background-properties" + +class XmlHandle{ + +public: + XmlHandle(); + ~XmlHandle(); + +public: + void init(); + void xmlreader(QString filename); + void xmlUpdate(QMap> wallpaperinfosMap); + QMap > requireXmlData(); + +public: + QString localconf; + +private: + QDir xmlDir; + +private: + QStringList _getXmlFiles(QString path); + void _parseWallpaper(QXmlStreamReader &reader); + void _xmlGenerate(); + + QMap> wallpapersMap; + +}; + +#endif // XMLHANDLE_H diff -Nru ukui-control-center-2.0.3/plugins/personalized/screensaver/screensaver.cpp ukui-control-center-3.0.3/plugins/personalized/screensaver/screensaver.cpp --- ukui-control-center-2.0.3/plugins/personalized/screensaver/screensaver.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screensaver/screensaver.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -35,6 +35,10 @@ #define SESSION_SCHEMA "org.ukui.session" #define IDLE_DELAY_KEY "idle-delay" +#define BACKGROUND_SCHEMA "org.mate.background" + +const QString BACK_FILENAME_KEY = "pictureFilename"; + #define IDLEMIN 1 #define IDLEMAX 120 #define IDLESTEP 1 @@ -56,83 +60,83 @@ } -Screensaver::Screensaver() +Screensaver::Screensaver() : mFirstLoad(true) { - ui = new Ui::Screensaver; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Screensaver"); pluginType = PERSONALIZED; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - -// pluginWidget->setStyleSheet("background: #ffffff;"); - - ui->previewWidget->setStyleSheet("#previewWidget{background: black; border-radius: 6px;}"); - ui->previewWidget->setAutoFillBackground(true); - -// mPreviewWidget = new PreviewWidget; -// mPreviewWidget->resize(400,222); -// QBoxLayout *mPreviewLayout = new QBoxLayout(QBoxLayout::TopToBottom); -// mPreviewLayout->addWidget(mPreviewWidget); -// ui->previewWidget->setLayout(mPreviewLayout); - -// ui->enableWidget->setStyleSheet("QWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); - -// ui->programWidget->setStyleSheet("QWidget#programWidget{background: #F4F4F4;}"); -// ui->programLabel->setStyleSheet("QLabel{background: #F4F4F4;}"); - -// ui->idleWidget->setStyleSheet("QWidget{background: #F4F4F4; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); -// ui->idleLineEdit->setStyleSheet("QLineEdit{background: #ffffff; border-radius: 0px;}"); - -// ui->lockWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - - process = new QProcess(); - - _acquireThemeinfoList(); - initComponent(); - initEnableBtnStatus(); - initThemeStatus(); - initIdleSliderStatus(); - -// init_theme_info_map(); -// component_init(); -// status_init(); } -Screensaver::~Screensaver() -{ - delete ui; - delete process; - process = nullptr; - if (!screenlock_settings) { - delete screenlock_settings; +Screensaver::~Screensaver() { + if (!mFirstLoad) { + delete ui; + ui = nullptr; + delete process; + process = nullptr; } } -QString Screensaver::get_plugin_name(){ +QString Screensaver::get_plugin_name() { return pluginName; } -int Screensaver::get_plugin_type(){ +int Screensaver::get_plugin_type() { return pluginType; } -QWidget *Screensaver::get_plugin_ui(){ +QWidget *Screensaver::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::Screensaver; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + ui->previewWidget->setStyleSheet("#previewWidget{background: black;}"); + ui->previewWidget->setAutoFillBackground(true); + + process = new QProcess(); + + initTitleLabel(); + initSearchText(); + _acquireThemeinfoList(); + initComponent(); + initEnableBtnStatus(); + initThemeStatus(); + initIdleSliderStatus(); + } return pluginWidget; } -void Screensaver::plugin_delay_control(){ +void Screensaver::plugin_delay_control() { // 初始化屏保预览Widget initPreviewWidget(); } -void Screensaver::initComponent(){ +const QString Screensaver::name() const { + + return QStringLiteral("screensaver"); +} + +void Screensaver::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); +} + +void Screensaver::initSearchText() { + //~ contents_path /screensaver/Enable screensaver + ui->enableLabel->setText(tr("Enable screensaver")); + //~ contents_path /screensaver/Screensaver program + ui->programLabel->setText(tr("Screensaver program")); + //~ contents_path /screensaver/idle time + ui->idleLabel->setText(tr("idle time")); +} + +void Screensaver::initComponent() { if (QGSettings::isSchemaInstalled(SCREENSAVER_SCHEMA)) { const QByteArray id(SCREENSAVER_SCHEMA); - screenlock_settings = new QGSettings(id); + screenlock_settings = new QGSettings(id, QByteArray(), this); connect(screenlock_settings, &QGSettings::changed, [=](QString key) { if (key == "lockEnabled") { @@ -144,11 +148,11 @@ }); } - if(QGSettings::isSchemaInstalled(SESSION_SCHEMA)) { + if (QGSettings::isSchemaInstalled(SESSION_SCHEMA)) { qSessionSetting = new QGSettings(SESSION_SCHEMA, QByteArray(), this); } - if(QGSettings::isSchemaInstalled(SCREENSAVER_SCHEMA)) { + if (QGSettings::isSchemaInstalled(SCREENSAVER_SCHEMA)) { qScreenSaverSetting = new QGSettings(SCREENSAVER_SCHEMA, QByteArray(), this); } @@ -169,7 +173,7 @@ ui->comboBox->addItem(tr("Blank_Only")); // ui->comboBox->addItem(tr("Random")); QMap::iterator it = infoMap.begin(); - for (int index = 2; it != infoMap.end(); it++, index++){ + for (int index = 2; it != infoMap.end(); it++, index++) { SSThemeInfo info = (SSThemeInfo)it.value(); ui->comboBox->addItem(info.name); ui->comboBox->setItemData(index, QVariant::fromValue(info)); @@ -188,11 +192,6 @@ ui->lockhorizontalLayout->addWidget(uslider); ui->lockhorizontalLayout->addSpacing(15); -// ui->idleSlider->setMinimum(IDLEMIN); -// ui->idleSlider->setMaximum(IDLEMAX); -// ui->idleSlider->setSingleStep(IDLESTEP); -// ui->idleSlider->setPageStep(IDLESTEP); - connect(enableSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked) { screensaver_settings = g_settings_new(SCREENSAVER_SCHEMA); g_settings_set_boolean(screensaver_settings, ACTIVE_KEY, checked); @@ -202,40 +201,22 @@ g_object_unref(screensaver_settings); }); - connect(qScreenSaverSetting, &QGSettings::changed, this, [=](const QString key){ + connect(qScreenSaverSetting, &QGSettings::changed, this, [=](const QString key) { if ("idleActivationEnabled" == key) { auto status = qScreenSaverSetting->get(ACTIVE_KEY).toBool(); enableSwitchBtn->setChecked(status); } }); - -// connect(lockSwitchBtn, &SwitchButton::checkedChanged, this, [=](bool checked){ -// //REVIEW*** g_object_unref faild -// // screensaver_settings = g_settings_new(SCREENSAVER_SCHEMA); -// // g_settings_set_boolean(screensaver_settings, LOCK_KEY, status); -// // if (screensaver_settings) -// // g_object_unref(screensaver_settings); -// const QByteArray ba(SCREENSAVER_SCHEMA); -// QGSettings * settings = new QGSettings(ba); -// settings->set(LOCK_KEY, checked); -// delete settings; -// }); - -// connect(uslider, &QSlider::valueChanged, this, [=](int value){ -// //刷新分钟显示 -// ui->idleLineEdit->blockSignals(true); -// ui->idleLineEdit->setText(QString::number(value)); -// ui->idleLineEdit->blockSignals(false); -// }); - connect(uslider, &QSlider::valueChanged, this, [=]{ + connect(uslider, &QSlider::valueChanged, this, [=] { int value = convertToLocktime(uslider->value()); session_settings = g_settings_new(SESSION_SCHEMA); g_settings_set_int(session_settings, IDLE_DELAY_KEY, value); g_object_unref(session_settings); }); + connectToServer(); - connect(qSessionSetting, &QGSettings::changed, this,[=](const QString& key){ + connect(qSessionSetting, &QGSettings::changed, this,[=](const QString& key) { if ("idleDelay" == key) { auto value = qSessionSetting->get(key).toInt(); uslider->setValue(lockConvertToSlider(value)); @@ -244,17 +225,16 @@ connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(themesComboxChanged(int))); - - connect(ui->previewWidget, &QWidget::destroyed, this, [=]{ + connect(ui->previewWidget, &QWidget::destroyed, this, [=] { closeScreensaver(); }); } -void Screensaver::initPreviewWidget(){ +void Screensaver::initPreviewWidget() { startupScreensaver(); } -void Screensaver::initEnableBtnStatus(){ +void Screensaver::initEnableBtnStatus() { const QByteArray ba(SCREENSAVER_SCHEMA); QGSettings * settings = new QGSettings(ba); @@ -273,18 +253,17 @@ locked = settings->get(LOCK_KEY).toBool(); initLockBtnStatus(locked); - delete settings; - + settings = nullptr; } -void Screensaver::initLockBtnStatus(bool status){ +void Screensaver::initLockBtnStatus(bool status) { lockSwitchBtn->blockSignals(true); lockSwitchBtn->setChecked(status); lockSwitchBtn->blockSignals(false); } -void Screensaver::initThemeStatus(){ +void Screensaver::initThemeStatus() { int mode; char * name; @@ -300,10 +279,10 @@ mode = g_settings_get_enum(screensaver_settings, MODE_KEY); - if (mode == MODE_DEFAULT_UKUI){ + if (mode == MODE_DEFAULT_UKUI) { ui->comboBox->setCurrentIndex(0); //UKUI } - else if (mode == MODE_BLANK_ONLY){ + else if (mode == MODE_BLANK_ONLY) { ui->comboBox->setCurrentIndex(1); //Black_Only } // else if (mode == MODE_RANDOM){ @@ -312,18 +291,19 @@ else{ gchar ** strv; strv = g_settings_get_strv(screensaver_settings, THEMES_KEY); - if (strv != NULL){ + if (strv != NULL) { name = g_strdup(strv[0]); QString dest = (infoMap.find(name) != infoMap.end()) ? infoMap.value(name).name : ""; - if (dest == "") - ui->comboBox->setCurrentIndex(1); // - else + if (dest == "") { + ui->comboBox->setCurrentIndex(1); + } else { ui->comboBox->setCurrentText(dest); - } - else + } + } else { ui->comboBox->setCurrentIndex(1); //no data, default Blank_Only + } g_strfreev(strv); } g_object_unref(screensaver_settings); @@ -331,7 +311,7 @@ ui->comboBox->blockSignals(false); } -void Screensaver::initIdleSliderStatus(){ +void Screensaver::initIdleSliderStatus() { int minutes; session_settings = g_settings_new(SESSION_SCHEMA); minutes = g_settings_get_int(session_settings, IDLE_DELAY_KEY); @@ -340,57 +320,14 @@ uslider->setValue(lockConvertToSlider(minutes)); uslider->blockSignals(false); -// ui->idleSlider->blockSignals(true); -// ui->idleSlider->setValue(minutes); -// ui->idleSlider->blockSignals(false); - -// ui->idleLineEdit->blockSignals(true); -// ui->idleLineEdit->setText(QString::number(minutes)); -// ui->idleLineEdit->blockSignals(true); - g_object_unref(session_settings); } -void Screensaver::component_init(){ - - //设置屏保预览widget的背景为黑色 -// mPreviewWidget->setStyleSheet("#previewWidget{background: black}"); - - // -// activeswitchbtn = new SwitchButton(); -// activeswitchbtn->setAttribute(Qt::WA_DeleteOnClose); -// ui->activeHLayout->addWidget(activeswitchbtn); -// ui->activeHLayout->addStretch(); - -// lockswitchbtn = new SwitchButton(); -// lockswitchbtn->setAttribute(Qt::WA_DeleteOnClose); -// ui->lockHLayout->addWidget(lockswitchbtn); -// ui->lockHLayout->addStretch(); - -// ui->comboBox->addItem(tr("Blank_Only")); -// ui->comboBox->addItem(tr("Random")); - -// QMap::iterator it = infoMap.begin(); -// for (int itemsindex = 2; it != infoMap.end(); it++, itemsindex++){ -// SSThemeInfo info = (SSThemeInfo)it.value(); -// ui->comboBox->addItem(info.name); -// ui->comboBox->setItemData(itemsindex, QVariant::fromValue(info)); -// } +void Screensaver::component_init() { - //init slider -// int min = 1; -// int max = 120; -// int singlestep = 1; - -// ui->idleSlider->setMinimum(min); -// ui->idleSlider->setMaximum(max); -// ui->idleSlider->setSingleStep(singlestep); -// ui->idleSlider->installEventFilter(this); - -// connect(this, SIGNAL(kill_signals()), this, SLOT(kill_screensaver_preview())); } -void Screensaver::status_init(){ +void Screensaver::status_init() { int mode; char * name; @@ -398,102 +335,70 @@ screensaver_settings = g_settings_new(SCREENSAVER_SCHEMA); mode = g_settings_get_enum(screensaver_settings, MODE_KEY); - if (mode == MODE_DEFAULT_UKUI){ + if (mode == MODE_DEFAULT_UKUI) { ui->comboBox->setCurrentIndex(0); //UKUI } - else if(mode == MODE_BLANK_ONLY){ + else if(mode == MODE_BLANK_ONLY) { ui->comboBox->setCurrentIndex(1); //Black_Only } - else if (mode == MODE_RANDOM){ + else if (mode == MODE_RANDOM) { ui->comboBox->setCurrentIndex(2); //Random - } - else{ + } else { gchar ** strv; strv = g_settings_get_strv(screensaver_settings, THEMES_KEY); - if (strv != NULL){ + if (strv != NULL) { name = g_strdup(strv[0]); SSThemeInfo info = (SSThemeInfo)infoMap.find(name).value(); ui->comboBox->setCurrentText(info.name); - } - else + } else { ui->comboBox->setCurrentIndex(0); //no data, default Blank_Only + } g_strfreev(strv); } - //init -// bool activation; bool lockable; -// activation = g_settings_get_boolean(screensaver_settings, ACTIVE_KEY); -// activeswitchbtn->setChecked(activation); -// if (activation){ -// lockable = g_settings_get_boolean(screensaver_settings, LOCK_KEY); -// lockswitchbtn->setChecked(lockable); -// ui->widget->show(); -// } -// else{ -// lockswitchbtn->setChecked(false); -// ui->widget->hide(); -// } - g_object_unref(screensaver_settings); //获取空闲时间 int minutes; minutes = g_settings_get_int(session_settings, IDLE_DELAY_KEY); uslider->setValue(lockConvertToSlider(minutes)); -// ui->idleSlider->setValue(minutes); -// ui->idleLabel->setText(QString("%1%2").arg(minutes).arg(tr("minutes"))); - - //获取功能列表 -// PublicData * publicdata = new PublicData(); -// QStringList tmpList = publicdata->subfuncList[SYSTEM]; - - //connect -// connect(ui->powerBtn, &QPushButton::clicked, this, [=]{pluginWidget->emitting_toggle_signal(tmpList.at(2), SYSTEM, 0);}); - -// connect(uslider, SIGNAL(sliderReleased()), this, SLOT(slider_released_slot())); //改gsettings -// connect(activeswitchbtn, SIGNAL(checkedChanged(bool)), this, SLOT(activebtn_changed_slot(bool))); -// connect(lockswitchbtn, SIGNAL(checkedChanged(bool)), this, SLOT(lockbtn_changed_slot(bool))); connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(combobox_changed_slot(int))); connect(mPreviewWidget, SIGNAL(destroyed(QObject*)), this, SLOT(kill_screensaver_preview())); -// delete publicdata; } -void Screensaver::startupScreensaver(){ +void Screensaver::startupScreensaver() { //关闭屏保 closeScreensaver(); qDebug() << Q_FUNC_INFO << ui->previewWidget->winId(); - if (ui->comboBox->currentIndex() == 0){//UKUI + if (ui->comboBox->currentIndex() == 0) {//UKUI QStringList args; args << "-window-id" << QString::number(ui->previewWidget->winId()); //启动屏保 process->startDetached(screensaver_bin, args); runStringList.append(screensaver_bin); - } - else if (ui->comboBox->currentIndex() == 1){//黑屏 + } else if (ui->comboBox->currentIndex() == 1) {//黑屏 ui->previewWidget->update(); } // else if (ui->comboBox->currentIndex() == 2){//随机 // ui->previewWidget->update(); // } - else{//屏保 - + else {// 屏保 SSThemeInfo info = ui->comboBox->currentData().value(); QStringList args; args << "-window-id" << QString::number(ui->previewWidget->winId()); - //启动屏保 + // 启动屏保 process->startDetached(info.exec, args); runStringList.append(info.exec); } - } -void Screensaver::closeScreensaver(){ +void Screensaver::closeScreensaver() { //杀死分离启动的屏保预览程序 - if (!runStringList.isEmpty()){ + if (!runStringList.isEmpty()) { process->start(QString("killall"), runStringList); process->waitForStarted(); process->waitForFinished(2000); @@ -502,22 +407,19 @@ } } -void Screensaver::kill_and_start(){ +void Screensaver::kill_and_start() { emit kill_signals(); //如果有屏保先杀死 - if (ui->comboBox->currentIndex() == 0){//UKUI + if (ui->comboBox->currentIndex() == 0) {//UKUI QStringList args; args << "-window-id" << QString::number(mPreviewWidget->winId()); //启动屏保 process->startDetached(screensaver_bin, args); runStringList.append(screensaver_bin); - } - else if (ui->comboBox->currentIndex() == 1){//黑屏 + } else if (ui->comboBox->currentIndex() == 1) {//黑屏 mPreviewWidget->update(); - } - else if (ui->comboBox->currentIndex() == 2){//随机 + } else if (ui->comboBox->currentIndex() == 2) {//随机 mPreviewWidget->update(); - } - else{//屏保 + } else {//屏保 SSThemeInfo info = ui->comboBox->currentData().value(); QStringList args; args << "-window-id" << QString::number(mPreviewWidget->winId()); @@ -527,7 +429,6 @@ } } - int Screensaver::convertToLocktime(const int value) { switch (value) { case 1: @@ -594,46 +495,33 @@ -void Screensaver::set_idle_gsettings_value(int value){ +void Screensaver::set_idle_gsettings_value(int value) { g_settings_set_int(session_settings, IDLE_DELAY_KEY, value); } -void Screensaver::slider_released_slot(){ +void Screensaver::slider_released_slot() { int minutes; // minutes = ui->idleSlider->value(); minutes = convertToLocktime(uslider->value()); set_idle_gsettings_value(minutes); } -void Screensaver::lockbtn_changed_slot(bool status){ - //REVIEW*** setchecked(false) -> g_object_unref faild -// screensaver_settings = g_settings_new(SCREENSAVER_SCHEMA); -// g_settings_set_boolean(screensaver_settings, LOCK_KEY, status); -// if (screensaver_settings) -// g_object_unref(screensaver_settings); +void Screensaver::lockbtn_changed_slot(bool status) { const QByteArray ba(SCREENSAVER_SCHEMA); QGSettings * settings = new QGSettings(ba); settings->set(LOCK_KEY, status); delete settings; + settings = nullptr; } -void Screensaver::activebtn_changed_slot(bool status){ +void Screensaver::activebtn_changed_slot(bool status) { screensaver_settings = g_settings_new(SCREENSAVER_SCHEMA); g_settings_set_boolean(screensaver_settings, ACTIVE_KEY, status); -// if (status){ -// ui->widget->show(); -// } -// else{ -// lockswitchbtn->setChecked(false); -// ui->widget->hide(); - -// } g_object_unref(screensaver_settings); - } -void Screensaver::themesComboxChanged(int index){ +void Screensaver::themesComboxChanged(int index) { char ** strv = NULL; @@ -658,22 +546,19 @@ //刷新预览 startupScreensaver(); - } -void Screensaver::combobox_changed_slot(int index){ +void Screensaver::combobox_changed_slot(int index) { char ** strv = NULL; screensaver_settings = g_settings_new(SCREENSAVER_SCHEMA); - if (index == 0){ //ukui + if (index == 0) { //ukui g_settings_set_enum(screensaver_settings, MODE_KEY, MODE_DEFAULT_UKUI); - } - else if (index == 1){ //Blank_Only + } else if (index == 1) { //Blank_Only qDebug()<<"this is Blan_only----------------->"<::iterator it = infoMap.begin(); - for (; it != infoMap.end(); it++){ + for (; it != infoMap.end(); it++) { QString id = QString(it.key()); valueStringList.append(id); } settings->set(THEMES_KEY, QVariant(valueStringList)); delete settings; - } - else{ + settings = nullptr; + } else { g_settings_set_enum(screensaver_settings, MODE_KEY, MODE_SINGLE); //获取当前屏保的id QVariant variant = ui->comboBox->itemData(index); @@ -706,10 +591,6 @@ qDebug() << Q_FUNC_INFO << "wxy-----------" <start(QString("killall"), killList); @@ -729,13 +610,13 @@ // } } -SSThemeInfo Screensaver::_info_new(const char *path){ +SSThemeInfo Screensaver::_info_new(const char *path) { SSThemeInfo info; GKeyFile * keyfile; char * name, * exec; keyfile = g_key_file_new(); - if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, NULL)){ + if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, NULL)) { g_key_file_free (keyfile); return info; } @@ -752,13 +633,13 @@ return info; } -SSThemeInfo Screensaver::_newThemeinfo(const char * path){ +SSThemeInfo Screensaver::_newThemeinfo(const char * path) { SSThemeInfo info; GKeyFile * keyfile; char * name, * exec; keyfile = g_key_file_new(); - if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, NULL)){ + if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, NULL)) { g_key_file_free (keyfile); return info; } @@ -776,7 +657,7 @@ return info; } -void Screensaver::_acquireThemeinfoList(){ +void Screensaver::_acquireThemeinfoList() { GDir * dir; const char * name; @@ -798,7 +679,7 @@ g_dir_close(dir); } -void Screensaver::init_theme_info_map(){ +void Screensaver::init_theme_info_map() { GDir * dir; const char * name; @@ -819,3 +700,25 @@ } g_dir_close(dir); } + +void Screensaver::connectToServer(){ + m_cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", + "/org/kylinssoclient/path", + "org.freedesktop.kylinssoclient.interface", + QDBusConnection::sessionBus()); + if (!m_cloudInterface->isValid()) + { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), QString("org.freedesktop.kylinssoclient.interface"), "keyChanged", this, SLOT(keyChangedSlot(QString))); + // 将以后所有DBus调用的超时设置为 milliseconds + m_cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} + +void Screensaver::keyChangedSlot(const QString &key) { + if(key == "ukui-screensaver") { + initThemeStatus(); + } +} diff -Nru ukui-control-center-2.0.3/plugins/personalized/screensaver/screensaver.h ukui-control-center-3.0.3/plugins/personalized/screensaver/screensaver.h --- ukui-control-center-2.0.3/plugins/personalized/screensaver/screensaver.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screensaver/screensaver.h 2021-04-14 01:27:20.000000000 +0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "shell/interface.h" @@ -75,9 +76,6 @@ } protected: void paintEvent(QPaintEvent *e); -// void showEvent(QShowEvent *e); -// void moveEvent(QMoveEvent *e); -// void hideEvent(QHideEvent *e); }; class Screensaver : public QObject, CommonInterface @@ -94,8 +92,11 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); + void initSearchText(); void initComponent(); void initPreviewWidget(); void initEnableBtnStatus(); @@ -120,6 +121,7 @@ private: int convertToLocktime(const int value); int lockConvertToSlider(const int value); + void connectToServer(); private: Ui::Screensaver *ui; @@ -130,10 +132,6 @@ SwitchButton * enableSwitchBtn; SwitchButton * lockSwitchBtn; - /* - SwitchButton * activeswitchbtn; - SwitchButton * lockswitchbtn; - */ QMap infoMap; @@ -142,6 +140,7 @@ QGSettings * screenlock_settings = nullptr; QGSettings * qSessionSetting = nullptr; QGSettings * qScreenSaverSetting = nullptr; + QGSettings * qBgSetting = nullptr; QProcess * process; @@ -153,6 +152,10 @@ Uslider * uslider; + QDBusInterface *m_cloudInterface; + + bool mFirstLoad; + private: SSThemeInfo _info_new(const char * path); void init_theme_info_map(); @@ -164,6 +167,7 @@ void lockbtn_changed_slot(bool status); void slider_released_slot(); void kill_screensaver_preview(); + void keyChangedSlot(const QString &key); Q_SIGNALS: void kill_signals(); diff -Nru ukui-control-center-2.0.3/plugins/personalized/screensaver/screensaver.pro ukui-control-center-3.0.3/plugins/personalized/screensaver/screensaver.pro --- ukui-control-center-2.0.3/plugins/personalized/screensaver/screensaver.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screensaver/screensaver.pro 2021-04-14 01:27:20.000000000 +0000 @@ -8,7 +8,7 @@ include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/uslider.pri) -QT += widgets +QT += widgets dbus TEMPLATE = lib CONFIG += plugin diff -Nru ukui-control-center-2.0.3/plugins/personalized/screensaver/screensaver.ui ukui-control-center-3.0.3/plugins/personalized/screensaver/screensaver.ui --- ukui-control-center-2.0.3/plugins/personalized/screensaver/screensaver.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/screensaver/screensaver.ui 2021-04-14 01:27:20.000000000 +0000 @@ -82,14 +82,14 @@ - 400 - 222 + 300 + 180 - 400 - 222 + 300 + 180 @@ -173,7 +173,7 @@ 16 - + 0 @@ -250,7 +250,7 @@ - 182 + 16777215 16777215 @@ -263,13 +263,13 @@ - 345 + 300 0 - 345 + 16777215 30 @@ -278,19 +278,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -347,7 +334,7 @@ 16 - + 0 diff -Nru ukui-control-center-2.0.3/plugins/personalized/theme/cursor/cursortheme.cpp ukui-control-center-3.0.3/plugins/personalized/theme/cursor/cursortheme.cpp --- ukui-control-center-2.0.3/plugins/personalized/theme/cursor/cursortheme.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/theme/cursor/cursortheme.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -139,8 +139,9 @@ } -void CursorTheme::setCursorName(qulonglong cursor, const QString &name) const -{ +void CursorTheme::setCursorName(qulonglong cursor, const QString &name) const { + Q_UNUSED(cursor) + Q_UNUSED(name) #ifdef HAVE_XFIXES if (haveXfixes()) diff -Nru ukui-control-center-2.0.3/plugins/personalized/theme/myslider.cpp ukui-control-center-3.0.3/plugins/personalized/theme/myslider.cpp --- ukui-control-center-2.0.3/plugins/personalized/theme/myslider.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/theme/myslider.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,19 @@ +#include "myslider.h" +#include +#include + + +MySlider::MySlider(QWidget *parent):QSlider (parent){} +MySlider::~MySlider(){} + +//重写鼠标点击事件 +void MySlider::mousePressEvent(QMouseEvent *ev) +{ + QSlider::mousePressEvent(ev); + int currentx = ev->pos().x(); + int value = (currentx /(double)this->width())*(this->maximum() - this->minimum()) + this->minimum(); + this->setValue(value); +} + + + diff -Nru ukui-control-center-2.0.3/plugins/personalized/theme/myslider.h ukui-control-center-3.0.3/plugins/personalized/theme/myslider.h --- ukui-control-center-2.0.3/plugins/personalized/theme/myslider.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/theme/myslider.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,16 @@ +#ifndef MYSLIDER_H +#define MYSLIDER_H + +#include +#include + +class MySlider : public QSlider +{ +public: + MySlider(QWidget *parent = nullptr); + ~MySlider(); + void mousePressEvent(QMouseEvent *ev); + +}; + +#endif // MYSLIDER_H diff -Nru ukui-control-center-2.0.3/plugins/personalized/theme/theme.cpp ukui-control-center-3.0.3/plugins/personalized/theme/theme.cpp --- ukui-control-center-2.0.3/plugins/personalized/theme/theme.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/theme/theme.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -21,61 +21,61 @@ #include "ui_theme.h" #include +#include +#include +#include #include "SwitchButton/switchbutton.h" - -#include "themewidget.h" -#include "widgetgroup.h" #include "cursor/xcursortheme.h" - #include "../../../shell/customstyle.h" +#include "../../../shell/utils/utils.h" -#include -#include -#include -/** - * GTK主题 - */ +// GTK主题 #define THEME_GTK_SCHEMA "org.mate.interface" -#define MODE_GTK_KEY "gtk-theme" -/* GTK图标主题 */ -#define ICON_GTK_KEY "icon-theme" - -/** - * QT主题 - */ -#define THEME_QT_SCHEMA "org.ukui.style" -#define MODE_QT_KEY "style-name" -#define THEME_TRAN_KEY "menu-transparency" -#define PEONY_TRAN_KEY "peony-side-bar-transparency" - -/* QT图标主题 */ -#define ICON_QT_KEY "icon-theme-name" - -/** - * 窗口管理器Marco主题 - */ -#define MARCO_SCHEMA "org.gnome.desktop.wm.preferences" +#define MODE_GTK_KEY "gtk-theme" + +// GTK图标主题 +#define ICON_GTK_KEY "icon-theme" + +// QT主题 +#define THEME_QT_SCHEMA "org.ukui.style" +#define MODE_QT_KEY "style-name" +#define THEME_TRAN_KEY "menu-transparency" +#define PEONY_TRAN_KEY "peony-side-bar-transparency" + +// QT图标主题 +#define ICON_QT_KEY "icon-theme-name" + +// 窗口管理器Marco主题 +#define MARCO_SCHEMA "org.gnome.desktop.wm.preferences" #define MARCO_THEME_KEY "theme" -#define ICONTHEMEPATH "/usr/share/icons/" -#define SYSTHEMEPATH "/usr/share/themes/" +#define ICONTHEMEPATH "/usr/share/icons/" +#define SYSTHEMEPATH "/usr/share/themes/" #define CURSORS_THEMES_PATH "/usr/share/icons/" #define CURSOR_THEME_SCHEMA "org.ukui.peripherals-mouse" -#define CURSOR_THEME_KEY "cursor-theme" +#define CURSOR_THEME_KEY "cursor-theme" #define ICONWIDGETHEIGH 74 -/** - * 透明度设置 - */ -#define PERSONALSIE_SCHEMA "org.ukui.control-center.personalise" -#define PERSONALSIE_TRAN_KEY "transparency" +// 透明度设置 +#define PERSONALSIE_SCHEMA "org.ukui.control-center.personalise" +#define PERSONALSIE_TRAN_KEY "transparency" #define PERSONALSIE_BLURRY_KEY "blurry" +#define PERSONALSIE_EFFECT_KEY "effect" +#define PERSONALSIE_SAVE_TRAN_KEY "save-transparency" + +const QString kDefCursor = "DMZ-White"; +const QString UbuntuVesionEnhance = "20.10"; +const QString kXder = "XRender"; + +const int transparency = 75; +//保存关闭特效模式之前的透明度 +int save_trans = 0; -const QString defCursor = "DMZ-White"; -const int transparency = 95; +const QStringList effectList {"blur", "kwin4_effect_translucency", "kwin4_effect_maximize", "zoom"}; +const QStringList kIconsList {"computer", "user-trash", "folder", "ukui-control-center", "kylin-software-center", "kylin-video", "kylin-assistant"}; namespace { @@ -106,75 +106,38 @@ ui = new Ui::Theme; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Theme"); pluginType = PERSONALIZED; + ui->setupUi(pluginWidget); - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - settingsCreate = false; + setupGSettings(); + initTitleLabel(); + initSearchText(); - const QByteArray id(THEME_GTK_SCHEMA); - const QByteArray idd(THEME_QT_SCHEMA); - const QByteArray iid(CURSOR_THEME_SCHEMA); - const QByteArray iiid(PERSONALSIE_SCHEMA); - if (QGSettings::isSchemaInstalled(iiid)) { - personliseGsettings = new QGSettings(iiid); - } - //设置组件 + // 设置组件 setupComponent(); - - // init kwin settings setupSettings(); - - if (QGSettings::isSchemaInstalled(id) && QGSettings::isSchemaInstalled(idd) - && QGSettings::isSchemaInstalled(iid)){ - gtkSettings = new QGSettings(id); - qtSettings = new QGSettings(idd); - curSettings = new QGSettings(iid); - - settingsCreate = true; - - initThemeMode(); - initIconTheme(); - initCursorTheme(); -// initEffectSettings(); - initConnection(); - } else { - qCritical() << THEME_GTK_SCHEMA << "or" << THEME_QT_SCHEMA << "or" << CURSOR_THEME_SCHEMA << "not installed\n"; - } - + initThemeMode(); + initIconTheme(); + initCursorTheme(); + initConnection(); } Theme::~Theme() { delete ui; - if (settingsCreate){ - delete gtkSettings; - delete qtSettings; - delete curSettings; - } - if (kwinSettings ){ - delete kwinSettings; - } - if (kwinGsettings) { - delete kwinGsettings; - } - if (personliseGsettings) { - delete personliseGsettings; - } + ui = nullptr; } -QString Theme::get_plugin_name(){ +QString Theme::get_plugin_name() { return pluginName; } -int Theme::get_plugin_type(){ +int Theme::get_plugin_type() { return pluginType; } -QWidget *Theme::get_plugin_ui(){ +QWidget *Theme::get_plugin_ui() { return pluginWidget; } @@ -182,14 +145,45 @@ } +const QString Theme::name() const { + + return QStringLiteral("theme"); +} + +void Theme::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->iconLabel->setFont(font); + ui->controlLabel->setFont(font); + ui->cursorLabel->setFont(font); +} + +void Theme::initSearchText() { + //~ contents_path /theme/Theme Mode + ui->titleLabel->setText(tr("Theme Mode")); + //~ contents_path /theme/Icon theme + ui->iconLabel->setText(tr("Icon theme")); + //~ contents_path /theme/Cursor theme + ui->cursorLabel->setText(tr("Cursor theme")); + //~ contents_path /theme/Performance mode + ui->perforLabel->setText(tr("Performance mode")); + //~ contents_path /theme/Transparency + ui->transparencyLabel->setText(tr("Transparency")); +} + void Theme::setupSettings() { QString filename = QDir::homePath() + "/.config/ukui-kwinrc"; - kwinSettings = new QSettings(filename, QSettings::IniFormat); + kwinSettings = new QSettings(filename, QSettings::IniFormat, this); + QStringList keys = kwinSettings->childGroups(); kwinSettings->beginGroup("Plugins"); - bool kwin = kwinSettings->value("blurEnabled", kwin).toBool(); + if (!kwinSettings->childKeys().contains("blurEnabled")) { + kwin = true; + } + kwinSettings->endGroup(); effectSwitchBtn->setChecked(kwin); @@ -204,17 +198,40 @@ } else { ui->transFrame->setVisible(false); } + + if (keys.contains("Compositing")) { + kwinSettings->beginGroup("Compositing"); + QString xder; + bool kwinOG = false; + bool kwinEN = true; + xder = kwinSettings->value("Backend", xder).toString(); + kwinOG = kwinSettings->value("OpenGLIsUnsafe", kwinOG).toBool(); + kwinEN = kwinSettings->value("Enabled", kwinEN).toBool(); + if (xder == kXder || kwinOG || !kwinEN) { + ui->effectFrame->setVisible(false); + ui->transFrame->setVisible(false); + ui->effectLabel->setVisible(false); + personliseGsettings->set(PERSONALSIE_EFFECT_KEY, false); + } else { + ui->lowLabel->setPixmap(QPixmap("://img/plugins/theme/opacitylow.svg")); + ui->highlabel->setPixmap(QPixmap("://img/plugins/theme/opacityhigh.svg")); + } + kwinSettings->endGroup(); + }else { + ui->lowLabel->setPixmap(QPixmap("://img/plugins/theme/opacitylow.svg")); + ui->highlabel->setPixmap(QPixmap("://img/plugins/theme/opacityhigh.svg")); + } } -void Theme::setupComponent(){ +void Theme::setupComponent() { - ui->lightButton->hide(); + ui->lightButton->setVisible(getSystemVersion()); //隐藏现阶段不支持功能 ui->controlLabel->hide(); ui->controlWidget->hide(); ui->defaultButton->setProperty("value", "ukui-default"); -// ui->lightButton->setProperty("value", "ukui-default"); + ui->lightButton->setProperty("value", "ukui-light"); ui->darkButton->setProperty("value", "ukui-dark"); buildThemeModeBtn(ui->defaultButton, tr("Default"), "default"); @@ -222,24 +239,13 @@ buildThemeModeBtn(ui->darkButton, tr("Dark"), "dark"); ui->tranSlider->setRange(35, 100); - ui->tranSlider->setTickInterval(5); - ui->tranSlider->setPageStep(5); - ui->tranSlider->setValue(static_cast(personliseGsettings->get(PERSONALSIE_TRAN_KEY).toDouble() * 100)); - ui->tranLabel->setText(QString::number(static_cast(ui->tranSlider->value())/100.0)); - connect(ui->tranSlider, &QSlider::valueChanged, [=](int value){ - if(i!=(static_cast(value)/5)/20.0){ - ui->tranSlider->setSingleStep(5); - personliseGsettings->set(PERSONALSIE_TRAN_KEY,(static_cast(value)/5)/20.0); - qtSettings->set(THEME_TRAN_KEY, value); - qtSettings->set(PEONY_TRAN_KEY, value); - ui->tranLabel->setText(QString::number((static_cast(value)/5)/20.0)); - i=(static_cast(value)/5)/20.0; - } + ui->tranSlider->setValue(static_cast(personliseGsettings->get(PERSONALSIE_TRAN_KEY).toDouble() * 100.0)); + connect(ui->tranSlider, &QSlider::valueChanged, this, [=]() { + personliseGsettings->set(PERSONALSIE_TRAN_KEY,(static_cast(ui->tranSlider->value()) / 100.0)); + qtSettings->set(THEME_TRAN_KEY, ui->tranSlider->value()); + qtSettings->set(PEONY_TRAN_KEY, ui->tranSlider->value()); }); - setupControlTheme(); -// ui->effectLabel->hide(); -// ui->effectWidget->hide(); //构建并填充特效开关按钮 effectSwitchBtn = new SwitchButton(pluginWidget); @@ -247,18 +253,10 @@ ui->kwinFrame->setVisible(false); ui->transFrame->setVisible(true); - -#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) - ui->transFrame->setVisible(false); - ui->effectFrame->setVisible(false); -#else -#endif } void Theme::buildThemeModeBtn(QPushButton *button, QString name, QString icon){ - //设置默认按钮 -// button->setStyleSheet("QPushButton{background: #ffffff; border: none;}"); - + // 设置默认按钮 QVBoxLayout * baseVerLayout = new QVBoxLayout(button); baseVerLayout->setSpacing(8); baseVerLayout->setMargin(0); @@ -308,74 +306,79 @@ button->setLayout(baseVerLayout); } -void Theme::initThemeMode(){ - //监听主题改变 - connect(qtSettings, &QGSettings::changed, this, [=](const QString &key){ +void Theme::initThemeMode() { + // 获取当前主题 + QString currentThemeMode = qtSettings->get(MODE_QT_KEY).toString(); + if ("ukui-white" == currentThemeMode || "ukui-default" == currentThemeMode) { + ui->themeModeBtnGroup->buttonClicked(ui->defaultButton); + } else if ("ukui-dark" == currentThemeMode || "ukui-black" == currentThemeMode){ + ui->themeModeBtnGroup->buttonClicked(ui->darkButton); + } else { + ui->themeModeBtnGroup->buttonClicked(ui->lightButton); + } + + qApp->setStyle(new InternalStyle("ukui")); + + // 监听主题改变 + connect(qtSettings, &QGSettings::changed, this, [=](const QString &key) { if (key == "styleName") { - //获取当前主题 + // 获取当前主题 QString currentThemeMode = qtSettings->get(key).toString(); - writeKwinSettings(true, currentThemeMode); for (QAbstractButton * button : ui->themeModeBtnGroup->buttons()){ QVariant valueVariant = button->property("value"); + if ("ukui-black" == currentThemeMode) { + currentThemeMode = "ukui-dark"; + } else if("ukui-white" == currentThemeMode) { + currentThemeMode = "ukui-default"; + } if (valueVariant.isValid() && valueVariant.toString() == currentThemeMode) { + disconnect(ui->themeModeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(themeBtnClickSlot(QAbstractButton*))); button->click(); + connect(ui->themeModeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(themeBtnClickSlot(QAbstractButton*))); } } + qApp->setStyle(new InternalStyle("ukui")); } }); - //获取当前主题 - QString currentThemeMode = qtSettings->get(MODE_QT_KEY).toString(); - qApp->setStyle(new InternalStyle(currentThemeMode)); - //设置界面 - for (QAbstractButton * button : ui->themeModeBtnGroup->buttons()){ - QVariant valueVariant = button->property("value"); - if (valueVariant.isValid() && valueVariant.toString() == currentThemeMode) - button->click(); -// button->setChecked(true); - } - -#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - connect(ui->themeModeBtnGroup, static_cast(&QButtonGroup::buttonClicked), [=](QAbstractButton * button){ -#else - connect(ui->themeModeBtnGroup, QOverload::of(&QButtonGroup::buttonClicked), this, [=](QAbstractButton * button){ -#endif -// //设置主题 - QString themeMode = button->property("value").toString(); - QString currentThemeMode = qtSettings->get(MODE_QT_KEY).toString(); - + connect(gtkSettings,&QGSettings::changed,this,[=] (const QString &key) { + if(key == "iconTheme") { + QString icoName = qtSettings->get(ICON_QT_KEY).toString(); + setCheckStatus(ui->iconThemeVerLayout, icoName, ICON); + } + }); - qApp->setStyle(new InternalStyle(themeMode)); - if (QString::compare(currentThemeMode, themeMode)){ - QString tmpMode; - if ("ukui-dark" == themeMode) { - tmpMode = "ukui-black"; - } else { - tmpMode = "ukui-white"; - } - gtkSettings->set(MODE_GTK_KEY, tmpMode); + connect(curSettings,&QGSettings::changed,this,[=](const QString &key) { + if(key == "cursorTheme") { + QString cursorTheme = curSettings->get(CURSOR_THEME_KEY).toString(); + setCheckStatus(ui->cursorVerLayout, cursorTheme, CURSOR); + } + }); - QtConcurrent::run([=](){ - qtSettings->set(MODE_QT_KEY, themeMode); - }); - writeKwinSettings(true, themeMode); - } + connect(personliseGsettings, &QGSettings::changed,this,[=] (const QString &key) { + if(key == "effect") { + bool effectEnabled = personliseGsettings->get("effect").toBool(); + effectSwitchBtn->setChecked(effectEnabled); + } }); + + connect(ui->themeModeBtnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(themeBtnClickSlot(QAbstractButton*))); } -void Theme::initIconTheme(){ - //获取当前图标主题(以QT为准,后续可以对比GTK两个值) +void Theme::initIconTheme() { + // 获取当前图标主题(以QT为准,后续可以对比GTK两个值) QString currentIconTheme = qtSettings->get(ICON_QT_KEY).toString(); - //构建图标主题Widget Group,方便更新选中/非选中状态 - WidgetGroup * iconThemeWidgetGroup = new WidgetGroup; + // 构建图标主题Widget Group,方便更新选中/非选中状态 + iconThemeWidgetGroup = new WidgetGroup; connect(iconThemeWidgetGroup, &WidgetGroup::widgetChanged, [=](ThemeWidget * preWidget, ThemeWidget * curWidget){ - if (preWidget) + if (preWidget) { preWidget->setSelectedStatus(false); + } curWidget->setSelectedStatus(true); QString value = curWidget->getValue(); - //设置图标主题 + // 设置图标主题 qtSettings->set(ICON_QT_KEY, value); gtkSettings->set(ICON_GTK_KEY, value); }); @@ -384,25 +387,33 @@ QDir themesDir = QDir(ICONTHEMEPATH); foreach (QString themedir, themesDir.entryList(QDir::Dirs)) { - if (themedir.startsWith("ukui-icon-theme-")){ + + if ((Utils::isCommunity() && (!themedir.compare("ukui") || !themedir.compare("ukui-classical"))) + || (!Utils::isCommunity() && themedir.startsWith("ukui-icon-theme-"))) { QDir appsDir = QDir(ICONTHEMEPATH + themedir + "/48x48/apps/"); + QDir placesDir = QDir(ICONTHEMEPATH + themedir + "/48x48/places/"); + QDir devicesDir = QDir(ICONTHEMEPATH + themedir + "/48x48/devices/"); + if ("ukui-icon-theme-basic" == themedir) { + continue; + } appsDir.setFilter(QDir::Files | QDir::NoSymLinks); - QStringList appIconsList = appsDir.entryList(); - + devicesDir.setFilter(QDir::Files | QDir::NoSymLinks); + placesDir.setFilter(QDir::Files | QDir::NoSymLinks); QStringList showIconsList; - for (int i = 0; i < appIconsList.size(); i++){ - if (i%64 == 0 && i < 6 * 64){ - showIconsList.append(appsDir.path() + "/" + appIconsList.at(i)); - } + for (int i = 0; i < kIconsList.size(); i++) { + showIconsList.append(devicesDir.path() + "/" + kIconsList.at(i)); + showIconsList.append(placesDir.path() + "/" + kIconsList.at(i)); + showIconsList.append(appsDir.path() + "/" + kIconsList.at(i)); + } - ThemeWidget * widget = new ThemeWidget(QSize(48, 48), dullTranslation(themedir.section("-", -1, -1, QString::SectionSkipEmpty)), showIconsList); -// widget->setFrameShape(QFrame::Shape::Box); + ThemeWidget * widget = new ThemeWidget(QSize(48, 48), dullTranslation(themedir.section("-", -1, -1, QString::SectionSkipEmpty)), showIconsList, pluginWidget); widget->setValue(themedir); - //加入Layout + + // 加入Layout ui->iconThemeVerLayout->addWidget(widget); - //加入WidgetGround实现获取点击前Widget + // 加入WidgetGround实现获取点击前Widget iconThemeWidgetGroup->addWidget(widget); if (themedir == currentIconTheme){ @@ -433,12 +444,8 @@ QPushButton * button = new QPushButton(ui->controlWidget); button->setFixedSize(QSize(48, 48)); button->setCheckable(true); - QString btnStyle = QString("QPushButton{background: %1; border-radius: 4px;}").arg(color); -// button->setStyleSheet(btnStyle); colorBtnGroup->addButton(button, colorStringList.indexOf(color)); - - QVBoxLayout * colorVerLayout = new QVBoxLayout(); colorVerLayout->setSpacing(0); colorVerLayout->setMargin(0); @@ -454,12 +461,8 @@ selectedColorLabel->setSizePolicy(scSizePolicy); selectedColorLabel->setScaledContents(true); selectedColorLabel->setPixmap(QPixmap("://img/plugins/theme/selected.png")); - //初始化选中图标状态 + // 初始化选中图标状态 selectedColorLabel->setVisible(button->isChecked()); -// connect(colorBtnGroup, QOverload::of(&QButtonGroup::buttonClicked), this,[=]{ -// selectedColorLabel->setVisible(button->isChecked()); -// //设置控件主题 -// }); colorHorLayout->addStretch(); colorHorLayout->addWidget(selectedColorLabel); @@ -475,25 +478,24 @@ void Theme::initCursorTheme(){ QStringList cursorThemes = _getSystemCursorThemes(); -// qDebug() << cursorThemes; - //获取当前指针主题 + // 获取当前指针主题 QString currentCursorTheme; currentCursorTheme = curSettings->get(CURSOR_THEME_KEY).toString(); - WidgetGroup * cursorThemeWidgetGroup = new WidgetGroup; + cursorThemeWidgetGroup = new WidgetGroup(this); connect(cursorThemeWidgetGroup, &WidgetGroup::widgetChanged, [=](ThemeWidget * preWidget, ThemeWidget * curWidget){ if (preWidget) preWidget->setSelectedStatus(false); curWidget->setSelectedStatus(true); QString value = curWidget->getValue(); - //设置光标主题 + // 设置光标主题 curSettings->set(CURSOR_THEME_KEY, value); + kwinCursorSlot(value); }); for (QString cursor : cursorThemes){ - QList cursorVec; QString path = CURSORS_THEMES_PATH + cursor; XCursorTheme *cursorTheme = new XCursorTheme(path); @@ -504,44 +506,52 @@ cursorVec.append(QPixmap::fromImage(image)); } - ThemeWidget * widget = new ThemeWidget(QSize(24, 24), cursor, cursorVec); -// widget->setFrameShape(QFrame::Shape::Box); + ThemeWidget * widget = new ThemeWidget(QSize(24, 24), dullCursorTranslation(cursor), cursorVec, pluginWidget); widget->setValue(cursor); - //加入Layout + // 加入Layout ui->cursorVerLayout->addWidget(widget); - //加入WidgetGround实现获取点击前Widget + // 加入WidgetGround实现获取点击前Widget cursorThemeWidgetGroup->addWidget(widget); //初始化指针主题选中界面 - if (currentCursorTheme == cursor || (currentCursorTheme.isEmpty() && cursor == defCursor)){ + if (currentCursorTheme == cursor || (currentCursorTheme.isEmpty() && cursor == kDefCursor)){ cursorThemeWidgetGroup->setCurrentWidget(widget); widget->setSelectedStatus(true); } else { widget->setSelectedStatus(false); } - } } -void Theme::initEffectSettings(){ -// ui->effectLabel->hide(); -// ui->effectWidget->hide(); -} - void Theme::initConnection() { connect(ui->resetBtn, &QPushButton::clicked, this, &Theme::resetBtnClickSlot); connect(effectSwitchBtn, &SwitchButton::checkedChanged, [this](bool checked) { + if (!checked) { + save_trans = static_cast(personliseGsettings->get(PERSONALSIE_TRAN_KEY).toDouble() * 100.0); + personliseGsettings->set(PERSONALSIE_SAVE_TRAN_KEY, save_trans); + personliseGsettings->set(PERSONALSIE_TRAN_KEY, 1.0); + qtSettings->set(THEME_TRAN_KEY, 100); + qtSettings->set(PEONY_TRAN_KEY, 100); + ui->tranSlider->setValue(100); + } + else + { + save_trans = personliseGsettings->get(PERSONALSIE_SAVE_TRAN_KEY).toInt(); + ui->tranSlider->setValue(save_trans); + } + // 提供给外部监听特效接口 + personliseGsettings->set(PERSONALSIE_EFFECT_KEY, checked); QString currentThemeMode = qtSettings->get(MODE_QT_KEY).toString(); ui->transFrame->setVisible(checked); - writeKwinSettings(checked, currentThemeMode); + writeKwinSettings(checked, currentThemeMode, true); }); } -QStringList Theme::_getSystemCursorThemes(){ +QStringList Theme::_getSystemCursorThemes() { QStringList themes; QDir themesDir(CURSORS_THEMES_PATH); @@ -549,7 +559,6 @@ foreach (QString dirname, themesDir.entryList(QDir::Dirs)){ if (dirname == "." || dirname == "..") continue; -// QString fullpath(CURSORS_THEMES_PATH + dirname); QDir themeDir(CURSORS_THEMES_PATH + dirname + "/cursors/"); if (themeDir.exists()) themes.append(dirname); @@ -558,119 +567,231 @@ return themes; } -QString Theme::dullTranslation(QString str){ +bool Theme::getSystemVersion() { + QString versionPath = "/etc/os-release"; + QStringList osRes = readFile(versionPath); + QString version; + + for (QString str : osRes) { + if (str.contains("VERSION_ID=")) { + int index = str.indexOf("VERSION_ID="); + int startIndex = index + 12; + int length = str.length() - startIndex - 1; + version = str.mid(startIndex, length); + } + } + if (UbuntuVesionEnhance == version) { + return true; + } + return false; +} + +QStringList Theme::readFile(QString filepath) { + QStringList fileCont; + QFile file(filepath); + if (file.exists()) { + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << "ReadFile() failed to open" << filepath; + return QStringList(); + } + QTextStream textStream(&file); + while (!textStream.atEnd()) { + QString line= textStream.readLine(); + line.remove('\n'); + fileCont<beginGroup("Mouse"); + mouseSettings->setValue("cursorTheme", value); + mouseSettings->endGroup(); + + delete mouseSettings; + mouseSettings = nullptr; + + QDBusMessage message = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange"); + QList args; + args.append(5); + args.append(0); + message.setArguments(args); + QDBusConnection::sessionBus().send(message); +} + +QString Theme::dullCursorTranslation(QString str) { + if (!QString::compare(str, "blue-crystal")){ + return QObject::tr("blue-crystal"); + } else if (!QString::compare(str, "dark-sense")) { + return QObject::tr("dark-sense"); + } else if (!QString::compare(str, "DMZ-Black")) { + return QObject::tr("DMZ-Black"); + } else if (!QString::compare(str, "DMZ-White")) { + return QObject::tr("DMZ-White"); + } else { + return str; + } +} + +QString Theme::getCursorName() { + return curSettings->get(CURSOR_THEME_KEY).toString(); +} + +QString Theme::dullTranslation(QString str) { if (!QString::compare(str, "basic")){ return QObject::tr("basic"); - } else if (!QString::compare(str, "classical")){ + } else if (!QString::compare(str, "classical")) { return QObject::tr("classical"); - } else if (!QString::compare(str, "default")){ + } else if (!QString::compare(str, "default")) { + return QObject::tr("default"); + } else if (!QString::compare(str, "fashion")) { + return QObject::tr("fashion"); + } else { return QObject::tr("default"); - } else - return QObject::tr("Unknown"); + } } -// reset all of themes, include cursor, icon,and etc... +// 重置设置 void Theme::resetBtnClickSlot() { - // reset theme(because MODE_QT_KEY's default is null, use "SET" to reset default key ) -// QString theme = "ukui-default"; -// qtSettings->set(MODE_QT_KEY, theme); -// gtkSettings->set(MODE_GTK_KEY, theme); -// emit ui->defaultButton->clicked(); emit ui->themeModeBtnGroup->buttonClicked(ui->defaultButton); - ui->tranSlider->setValue(transparency); - -// ui->defaultButton->setChecked(true); - - // reset cursor default theme - QString cursorTheme = "DMZ-White"; - curSettings->set(CURSOR_THEME_KEY,cursorTheme); + // 重置光标主题 + curSettings->reset(CURSOR_THEME_KEY); + QString cursorTheme = kDefCursor; + QString defaultCursor = getCursorName(); + if (defaultCursor.isEmpty()) { + curSettings->set(CURSOR_THEME_KEY, kDefCursor); + } else { + cursorTheme = defaultCursor; + } + kwinCursorSlot(cursorTheme); - //reset icon default theme qtSettings->reset(ICON_QT_KEY); - qtSettings->reset(THEME_TRAN_KEY); - qtSettings->reset(PEONY_TRAN_KEY); - gtkSettings->reset(ICON_GTK_KEY); - ui->tranSlider->setValue(transparency); + if (ui->effectFrame->isVisible()) { + effectSwitchBtn->setChecked(true); + qtSettings->reset(THEME_TRAN_KEY); + qtSettings->reset(PEONY_TRAN_KEY); + gtkSettings->reset(ICON_GTK_KEY); + personliseGsettings->reset(PERSONALSIE_TRAN_KEY); + ui->tranSlider->setValue(transparency); + } - clearLayout(ui->iconThemeVerLayout->layout(), true); - clearLayout(ui->cursorVerLayout->layout(), true); + QString icoName = qtSettings->get(ICON_QT_KEY).toString(); - initThemeMode(); - initIconTheme(); - initCursorTheme(); + setCheckStatus(ui->iconThemeVerLayout, icoName, ICON); + setCheckStatus(ui->cursorVerLayout, cursorTheme, CURSOR); } -void Theme::writeKwinSettings(bool change, QString theme, int effect) { +void Theme::writeKwinSettings(bool change, QString theme, bool effect) { + Q_UNUSED(theme); + Q_UNUSED(effect); - QString th = ""; - if ("ukui-default" == theme) { - th = "__aurorae__svg__Ukui-classic"; - } else if ("ukui-dark" == theme){ - th = "__aurorae__svg__Ukui-classic-dark"; - } if (!change) { - kwinSettings->clear(); kwinSettings->beginGroup("Plugins"); - kwinSettings->setValue("blurEnabled",false); - kwinSettings->setValue("contrastEnabled",false); - kwinSettings->setValue("kwin4_effect_dialogparentEnabled",false); - kwinSettings->setValue("kwin4_effect_fadingpopupsEnabled",false); - kwinSettings->setValue("kwin4_effect_frozenappEnabled",false); - kwinSettings->setValue("kwin4_effect_loginEnabled",false); - kwinSettings->setValue("kwin4_effect_logoutEnabled",false); - kwinSettings->setValue("kwin4_effect_maximizeEnabled",false); - kwinSettings->setValue("kwin4_effect_maximizeEnabled",false); - kwinSettings->setValue("kwin4_effect_morphingpopupsEnabled",false); - kwinSettings->setValue("kwin4_effect_squashEnabled",false); - kwinSettings->setValue("kwin4_effect_translucencyEnabled",false); - kwinSettings->setValue("presentwindowsEnabled",false); - kwinSettings->setValue("screenedgeEnabled",false); - kwinSettings->setValue("slideEnabled",false); - kwinSettings->setValue("slidingpopupsEnabled",false); - kwinSettings->setValue("zoomEnabled",false); + kwinSettings->setValue("blurEnabled", false); + kwinSettings->setValue("kwin4_effect_maximizeEnabled", false); + kwinSettings->setValue("kwin4_effect_translucencyEnabled", false); + kwinSettings->setValue("zoomEnabled", false); kwinSettings->endGroup(); +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) + +#else + for (int i = 0; i < effectList.length(); i++) { + QDBusMessage message = QDBusMessage::createMethodCall("org.ukui.KWin", + "/Effects", + "org.ukui.kwin.Effects", + "unloadEffect"); + message << effectList.at(i); + QDBusConnection::sessionBus().send(message); + } +#endif } else { - kwinSettings->clear(); kwinSettings->beginGroup("Plugins"); - kwinSettings->setValue("blurEnabled",true); + kwinSettings->setValue("blurEnabled", true); + kwinSettings->setValue("kwin4_effect_maximizeEnabled", true); + kwinSettings->setValue("kwin4_effect_translucencyEnabled", true); + kwinSettings->setValue("zoomEnabled", true); kwinSettings->endGroup(); - } - - if (!th.isEmpty()) { - kwinSettings->beginGroup("org.kde.kdecoration2"); - kwinSettings->setValue("theme", th); - kwinSettings->setValue("library", "org.ukui.kwin.aurorae"); - kwinSettings->endGroup(); - } - - kwinSettings->sync(); - -#if QT_VERSION <= QT_VERSION_CHECK(5,12,0) +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) #else - QDBusMessage message = QDBusMessage::createSignal("/KWin", "org.ukui.KWin", "reloadConfig"); - QDBusConnection::sessionBus().send(message); + // 开启模糊特效: + for (int i = 0; i < effectList.length(); i++) { + + QDBusMessage message = QDBusMessage::createMethodCall("org.ukui.KWin", + "/Effects", + "org.ukui.kwin.Effects", + "loadEffect"); + message << effectList.at(i); + QDBusConnection::sessionBus().send(message); + } #endif + + } + kwinSettings->sync(); } -void Theme::clearLayout(QLayout* mlayout, bool deleteWidgets) -{ - if ( mlayout->layout() != NULL ) - { - QLayoutItem* item; - while ( ( item = mlayout->layout()->takeAt( 0 ) ) != NULL ) - { - delete item->widget(); - delete item; +void Theme::themeBtnClickSlot(QAbstractButton *button) { + // 设置主题 + QString themeMode = button->property("value").toString(); + QString currentThemeMode = qtSettings->get(MODE_QT_KEY).toString(); + + if (QString::compare(currentThemeMode, themeMode)){ + QString tmpMode; + if ("ukui-dark" == themeMode) { + tmpMode = "ukui-black"; + } else { + tmpMode = "ukui-white"; + } + gtkSettings->set(MODE_GTK_KEY, tmpMode); + + qtSettings->set(MODE_QT_KEY, themeMode); + } +} + +void Theme::setCheckStatus(QLayout *mlayout, QString checkName, ThemeType type) { + QLayoutItem *item; + if (mlayout->layout() != NULL ) { + int size = mlayout->layout()->count(); + for (int i = 0; i < size; i++) { + item = mlayout->layout()->itemAt(i); + ThemeWidget *themeWdt = static_cast(item->widget()); + themeWdt->setSelectedStatus(false); + if (themeWdt->getValue() == checkName) { + themeWdt->setSelectedStatus(true); + if (type == ICON) { + iconThemeWidgetGroup->setCurrentWidget(themeWdt); + } else { + cursorThemeWidgetGroup->setCurrentWidget(themeWdt); + } + } } } } -double Theme::convertToTran(const int value) -{ +double Theme::convertToTran(const int value) { switch (value) { case 1: return 0.2; @@ -693,17 +814,16 @@ } } -int Theme::tranConvertToSlider(const double value) -{ +int Theme::tranConvertToSlider(const double value) { if (0.2 == value) { return 1; - } else if (0.4 == value){ + } else if (0.4 == value) { return 2; - } else if (0.6 == value){ + } else if (0.6 == value) { return 3; - } else if (0.8 == value){ + } else if (0.8 == value) { return 4; - } else if (1.0 == value){ + } else if (1.0 == value) { return 5; } else { return 5; diff -Nru ukui-control-center-2.0.3/plugins/personalized/theme/theme.h ukui-control-center-3.0.3/plugins/personalized/theme/theme.h --- ukui-control-center-2.0.3/plugins/personalized/theme/theme.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/theme/theme.h 2021-04-14 01:27:20.000000000 +0000 @@ -23,19 +23,19 @@ #include #include #include - #include #include - -#include "shell/interface.h" -#include "commonComponent/Uslider/uslider.h" - #include #include #include #include #include +#include +#include "shell/interface.h" +#include "commonComponent/Uslider/uslider.h" +#include "themewidget.h" +#include "widgetgroup.h" class QPushButton; class SwitchButton; @@ -53,6 +53,31 @@ Q_INTERFACES(CommonInterface) public: + enum ThemeType { ICON, CURSOR}; + +private: + Ui::Theme *ui; + + QString pluginName; + int pluginType; + QWidget *pluginWidget; + + QGSettings *gtkSettings; + QGSettings *qtSettings; + QGSettings *curSettings; + QSettings *kwinSettings; + QSettings *themeSettings; + QGSettings *kwinGsettings = nullptr; + QGSettings *personliseGsettings = nullptr; + + SwitchButton *effectSwitchBtn; + + bool settingsCreate; + + WidgetGroup *cursorThemeWidgetGroup; + WidgetGroup *iconThemeWidgetGroup; + +public: Theme(); ~Theme(); double i=0; @@ -60,15 +85,16 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; -public: + void initTitleLabel(); + void initSearchText(); void setupSettings(); void setupComponent(); void initThemeMode(); void initIconTheme(); void setupControlTheme(); void initCursorTheme(); - void initEffectSettings(); void initConnection(); void buildThemeModeBtn(QPushButton * button, QString name, QString icon); @@ -78,37 +104,21 @@ QStringList _getSystemCursorThemes(); private: - void clearLayout(QLayout* mlayout, bool deleteWidgets); + void setCheckStatus(QLayout* mlayout, QString checkName, ThemeType type); double convertToTran(const int value); int tranConvertToSlider(const double value); + bool getSystemVersion(); + QStringList readFile(QString filepath); + void setupGSettings(); + void kwinCursorSlot(QString value); -private: - Ui::Theme *ui; - - QString pluginName; - int pluginType; - QWidget * pluginWidget; - - QGSettings * gtkSettings; - QGSettings * qtSettings; - QGSettings * curSettings; - QSettings * kwinSettings; - QGSettings * kwinGsettings = nullptr; - QGSettings * personliseGsettings = nullptr; - - SwitchButton * effectSwitchBtn; - - WidgetGroup * iconThemeWidgetGroup; - - bool settingsCreate; -// Uslider * uslider; -// Uslider * kwinSlider; + QString dullCursorTranslation(QString str); + QString getCursorName(); private slots: void resetBtnClickSlot(); - // write the kwin's configuration - void writeKwinSettings(bool change, QString theme, int effect = 0); - + void writeKwinSettings(bool change, QString theme, bool effect = false); + void themeBtnClickSlot(QAbstractButton *button); }; #endif // THEME_H diff -Nru ukui-control-center-2.0.3/plugins/personalized/theme/theme.pro ukui-control-center-3.0.3/plugins/personalized/theme/theme.pro --- ukui-control-center-2.0.3/plugins/personalized/theme/theme.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/theme/theme.pro 2021-05-20 13:08:14.000000000 +0000 @@ -7,7 +7,7 @@ include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/uslider.pri) -QT += widgets KConfigCore KI18n x11extras concurrent +QT += widgets KConfigCore KI18n x11extras concurrent dbus TEMPLATE = lib CONFIG += plugin \ @@ -31,6 +31,7 @@ SOURCES += \ cursor/cursortheme.cpp \ cursor/xcursortheme.cpp \ + myslider.cpp \ theme.cpp \ themewidget.cpp \ widgetgroup.cpp \ @@ -40,6 +41,7 @@ cursor/config-X11.h \ cursor/cursortheme.h \ cursor/xcursortheme.h \ + myslider.h \ theme.h \ themewidget.h \ widgetgroup.h \ diff -Nru ukui-control-center-2.0.3/plugins/personalized/theme/theme.ui ukui-control-center-3.0.3/plugins/personalized/theme/theme.ui --- ukui-control-center-2.0.3/plugins/personalized/theme/theme.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/theme/theme.ui 2021-05-20 13:08:14.000000000 +0000 @@ -96,7 +96,7 @@ 0 - 0 + 16 0 @@ -262,7 +262,7 @@ - + 0 @@ -275,6 +275,22 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 12 + + + + + @@ -394,7 +410,7 @@ - + 0 @@ -407,6 +423,22 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 12 + + + + + @@ -464,6 +496,22 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 12 + + + + + @@ -514,7 +562,7 @@ 6 - + 0 @@ -592,21 +640,28 @@ 6 - + Transparency - + + + + + + + + Qt::Horizontal - + @@ -742,6 +797,13 @@ + + + MySlider + QSlider +
myslider.h
+
+
diff -Nru ukui-control-center-2.0.3/plugins/personalized/theme/themewidget.cpp ukui-control-center-3.0.3/plugins/personalized/theme/themewidget.cpp --- ukui-control-center-2.0.3/plugins/personalized/theme/themewidget.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/theme/themewidget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -36,11 +36,8 @@ setMaximumWidth(960); setAttribute(Qt::WA_DeleteOnClose); -// setStyleSheet("background: palette(button); border-radius: 6px;"); - pValue = ""; - QHBoxLayout * mainHorLayout = new QHBoxLayout(this); mainHorLayout->setSpacing(16); mainHorLayout->setContentsMargins(16, 0, 16, 0); @@ -75,6 +72,9 @@ for (QString icon : iStringList){ QLabel * label = new QLabel(this); label->setFixedSize(iSize); + if(QPixmap(icon).isNull()){ + continue; + }; label->setPixmap(QPixmap(icon)); iconHorLayout->addWidget(label); } @@ -98,11 +98,8 @@ setMaximumWidth(960); setAttribute(Qt::WA_DeleteOnClose); -// setStyleSheet("background: palette(button); border-radius: 6px;"); - pValue = ""; - QHBoxLayout * mainHorLayout = new QHBoxLayout(this); mainHorLayout->setSpacing(16); mainHorLayout->setContentsMargins(16, 0, 16, 0); @@ -125,10 +122,10 @@ QLabel * nameLabel = new QLabel(this); QSizePolicy nameSizePolicy = nameLabel->sizePolicy(); - nameSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); + nameSizePolicy.setHorizontalPolicy(QSizePolicy::Preferred); nameSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); nameLabel->setSizePolicy(nameSizePolicy); - nameLabel->setFixedWidth(102); + nameLabel->setMinimumWidth(130); nameLabel->setText(name); QHBoxLayout * iconHorLayout = new QHBoxLayout; diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/colordialog.cpp ukui-control-center-3.0.3/plugins/personalized/wallpaper/colordialog.cpp --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/colordialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/colordialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -20,6 +20,8 @@ #include "colordialog.h" #include "ui_colordialog.h" #include "colorsquare.h" +#include "MaskWidget/maskwidget.h" +#include "CloseButton/closebutton.h" extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); @@ -36,6 +38,7 @@ { qDebug()<<"this is color destructor:" << endl; delete ui; + ui = nullptr; } void ColorDialog::paintEvent(QPaintEvent *event) @@ -53,6 +56,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); @@ -92,6 +96,9 @@ QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); colorSquare->setSizePolicy(sizePolicy); ui->horizontalLayout_2->addWidget(colorSquare); + // 遮罩 + MaskWidget * maskWidget = new MaskWidget(colorSquare); + maskWidget->setGeometry(0, 0, colorSquare->width(), colorSquare->height()); // 垂直渐变滑动条 gradientSlider = new GradientSlider(this); @@ -167,8 +174,8 @@ // CloseBtn ui->closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic")); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); +// ui->closeBtn->setProperty("useIconHighlightEffect", true); +// ui->closeBtn->setProperty("iconHighlightEffectMode", 1); //取消按钮默认主题灰色背景 QPalette palette = ui->closeBtn->palette(); QColor ColorPlaceholderText(255,255,255,0); @@ -186,7 +193,7 @@ void ColorDialog::signalsBind() { qDebug() << "signals bind"; - connect(ui->closeBtn, &QPushButton::clicked, [=](bool checked){ + connect(ui->closeBtn, &CloseButton::clicked, [=](bool checked){ Q_UNUSED(checked) close(); }); diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/colordialog.ui ukui-control-center-3.0.3/plugins/personalized/wallpaper/colordialog.ui --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/colordialog.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/colordialog.ui 2021-04-14 01:27:20.000000000 +0000 @@ -199,7 +199,7 @@ G
- + 100 @@ -262,11 +262,11 @@
- + - 358 - 10 + 355 + 13 32 32 @@ -288,6 +288,13 @@ + + + CloseButton + QPushButton +
CloseButton/closebutton.h
+
+
diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/colorpreview.h ukui-control-center-3.0.3/plugins/personalized/wallpaper/colorpreview.h --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/colorpreview.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/colorpreview.h 2021-04-14 01:27:20.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef COLORPREVIEW_H #define COLORPREVIEW_H - +#include #include class ColorPreview : public QWidget diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/colorsquare.cpp ukui-control-center-3.0.3/plugins/personalized/wallpaper/colorsquare.cpp --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/colorsquare.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/colorsquare.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * */ + #include "colorsquare.h" ColorSquare::ColorSquare(QWidget *parent) : @@ -137,8 +138,8 @@ painter.setBrush(Qt::NoBrush); double maxDist = nSquareWidth; // 绘制圆形光标 - painter.drawEllipse(QPointF(colorX*maxDist, - colorY*maxDist), + painter.drawEllipse(QPointF(sat*maxDist, + val*maxDist), selectorWidth, selectorWidth); } diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/pictureunit.cpp ukui-control-center-3.0.3/plugins/personalized/wallpaper/pictureunit.cpp --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/pictureunit.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/pictureunit.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -25,6 +25,14 @@ { _filename = ""; + QColor highLightColor = palette().color(QPalette::Highlight); + QString stringColor = QString("rgb(%1,%2,%3)") + .arg(highLightColor.red()) + .arg(highLightColor.green()) + .arg(highLightColor.blue()); + hoverStyleSheet = QString("border-width: 3px;border-style: solid;border-color: %1;").arg(stringColor); + clickedStyleSheet = QString("border-width: 6px;border-style: solid;border-color: %1;").arg(stringColor); + clickedFlag = false; setAttribute(Qt::WA_DeleteOnClose); setFixedSize(QSize(166, 110)); setScaledContents(true); @@ -50,3 +58,27 @@ emit clicked(_filename); // QLabel::mousePressEvent(event); } + +void PictureUnit::enterEvent(QEvent *e) +{ + if(getClickedFlag() == false) + { + setFrameShape (QFrame::Box); + setStyleSheet(hoverStyleSheet); + } +} +void PictureUnit::leaveEvent(QEvent *e) +{ + if(getClickedFlag() == false) + setStyleSheet("border-width: 0px;"); +} + +bool PictureUnit::getClickedFlag() +{ + return clickedFlag; +} + +void PictureUnit::changeClickedFlag(bool flag) +{ + clickedFlag = flag; +} \ No newline at end of file diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/pictureunit.h ukui-control-center-3.0.3/plugins/personalized/wallpaper/pictureunit.h --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/pictureunit.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/pictureunit.h 2021-04-14 01:27:20.000000000 +0000 @@ -22,7 +22,7 @@ #include #include - +#include class PictureUnit : public QLabel { @@ -35,15 +35,19 @@ public: void setFilenameText(QString fn); QString filenameText(); - + void changeClickedFlag(bool flag); + bool getClickedFlag(); + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); public: QString _filename; - + QString clickedStyleSheet; protected: void mousePressEvent(QMouseEvent * e); - - +private: + bool clickedFlag; + QString hoverStyleSheet; Q_SIGNALS: void clicked(QString filename); diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/wallpaper.cpp ukui-control-center-3.0.3/plugins/personalized/wallpaper/wallpaper.cpp --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/wallpaper.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/wallpaper.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -27,13 +27,17 @@ #include #include #include +#include +#include const QString kylinUrl = "https://www.ubuntukylin.com/wallpaper.html"; +const QString kylinBackgroundName1 = "/usr/share/backgrounds/warty-final-ubuntukylin.jpg"; +const QString kylinBackgroundName2 = "/usr/share/backgrounds/aurora.jpg"; enum{ - PICTURE, //图片背景 - COLOR, //纯色背景 - SLIDESHOW //幻灯片背景 + PICTURE, // 图片背景 + COLOR, // 纯色背景 + SLIDESHOW // 幻灯片背景 }; #define ITEMWIDTH 182 @@ -42,84 +46,110 @@ #define COLORITEMWIDTH 56 #define COLORITEMHEIGH 56 -Wallpaper::Wallpaper() +Wallpaper::Wallpaper() : mFirstLoad(true) { - ui = new Ui::Wallpaper; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Background"); pluginType = PERSONALIZED; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - settingsCreate = false; - //初始化控件 - setupComponent(); - //初始化gsettings - const QByteArray id(BACKGROUND); - if (QGSettings::isSchemaInstalled(id)){ - settingsCreate = true; - - bgsettings = new QGSettings(id); - setupConnect(); - initBgFormStatus(); - } - //构建xmlhandle对象 - xmlhandleObj = new XmlHandle(); + prePicUnit = nullptr; } Wallpaper::~Wallpaper() { - delete ui; - if (settingsCreate){ - delete bgsettings; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + delete xmlhandleObj; + xmlhandleObj = nullptr; } - delete xmlhandleObj; } -QString Wallpaper::get_plugin_name(){ +QString Wallpaper::get_plugin_name() { return pluginName; } -int Wallpaper::get_plugin_type(){ +int Wallpaper::get_plugin_type() { return pluginType; } -QWidget *Wallpaper::get_plugin_ui(){ +QWidget *Wallpaper::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::Wallpaper; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + settingsCreate = false; + initTitleLabel(); + initSearchText(); + // 初始化控件 + setupComponent(); + // 初始化gsettings + const QByteArray id(BACKGROUND); + if (QGSettings::isSchemaInstalled(id)){ + settingsCreate = true; + + bgsettings = new QGSettings(id, QByteArray(), this); + setupConnect(); + initBgFormStatus(); + } + // 构建xmlhandle对象 + xmlhandleObj = new XmlHandle(); + } return pluginWidget; } void Wallpaper::plugin_delay_control(){ } +const QString Wallpaper::name() const { + + return QStringLiteral("wallpaper"); +} + +void Wallpaper::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); +} + +void Wallpaper::initSearchText() { + //~ contents_path /wallpaper/Select from + ui->selectLabel->setText(tr("Select from")); + //~ contents_path /wallpaper/Browser local wp + ui->browserLocalwpBtn->setText(tr("Browser local wp")); + //~ contents_path /wallpaper/Browser online wp + ui->browserOnlinewpBtn->setText(tr("Browser online wp")); + //~ contents_path /wallpaper/Reset to default + ui->resetBtn->setText(tr("Reset to default")); +} + void Wallpaper::setupComponent(){ -// ui->browserLocalwpBtn->hide(); -// ui->browserOnlinewpBtn->hide(); - //背景形式 + QString name = qgetenv("USER"); + if (name.isEmpty()) { + name = qgetenv("USERNAME"); + } + + QString lockfilename = "/var/lib/lightdm-data/" + name + "/ukui-greeter.conf"; + mLockLoginSettings = new QSettings(lockfilename, QSettings::IniFormat, this); + + // 背景形式 QStringList formList; formList << tr("picture") << tr("color")/* << tr("slideshow")*/ ; -// ui->formComBox->addItems(formList); ui->formComBox->addItem(formList.at(0), PICTURE); ui->formComBox->addItem(formList.at(1), COLOR); -// ui->formComBox->addItem(formList.at(2), SLIDESHOW); - - //预览遮罩 - MaskWidget * maskWidget = new MaskWidget(ui->previewLabel); - maskWidget->setGeometry(0, 0, ui->previewLabel->width(), ui->previewLabel->height()); - ///图片背景 + // 图片背景 picFlowLayout = new FlowLayout(ui->picListWidget); picFlowLayout->setContentsMargins(0, 0, 0, 0); ui->picListWidget->setLayout(picFlowLayout); - //纯色背景 + // 纯色背景 colorFlowLayout = new FlowLayout(ui->colorListWidget); colorFlowLayout->setContentsMargins(0, 0, 0, 0); ui->colorListWidget->setLayout(colorFlowLayout); - colWgt = new HoverWidget(""); colWgt->setObjectName("colWgt"); colWgt->setMinimumSize(QSize(580, 50)); @@ -151,7 +181,7 @@ iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: palette(windowText);"); }); - + // 打开自定义颜色面板 connect(colWgt, &HoverWidget::widgetClicked,[=](QString mname){ Q_UNUSED(mname); colordialog = new ColorDialog(); @@ -159,35 +189,41 @@ colordialog->exec(); }); - - //壁纸放置方式 - ui->picOptionsComBox->addItem(tr("wallpaper"), "wallpaper"); - ui->picOptionsComBox->addItem(tr("centered"), "centered"); - ui->picOptionsComBox->addItem(tr("scaled"), "scaled"); - ui->picOptionsComBox->addItem(tr("stretched"), "stretched"); - ui->picOptionsComBox->addItem(tr("zoom"), "zoom"); - ui->picOptionsComBox->addItem(tr("spanned"), "spanned"); - - //屏蔽背景放置方式无效 - ui->picOptionsComBox->hide(); - ui->picOptionsLabel->hide(); - - //屏蔽纯色背景的确定按钮 - ui->cancelBtn->hide(); - ui->certainBtn->hide(); } void Wallpaper::setupConnect(){ //使用线程构建本地壁纸文件;获取壁纸压缩QPixmap pThread = new QThread; pObject = new WorkerObject; + QString bgFileName = bgsettings->get(FILENAME).toString(); connect(pObject, &WorkerObject::pixmapGenerate, this, [=](QPixmap pixmap, QString filename){ PictureUnit * picUnit = new PictureUnit; picUnit->setPixmap(pixmap); picUnit->setFilenameText(filename); + if (bgFileName == filename || \ + (bgFileName == kylinBackgroundName1 && filename == kylinBackgroundName2)) { + if (prePicUnit != nullptr) { + prePicUnit->changeClickedFlag(false); + prePicUnit->setStyleSheet("border-width: 0px;"); + } + picUnit->changeClickedFlag(true); + prePicUnit = picUnit; + picUnit->setFrameShape(QFrame::Box); + picUnit->setStyleSheet(picUnit->clickedStyleSheet); + } + connect(picUnit, &PictureUnit::clicked, [=](QString fn){ -// ui->previewLabel->setPixmap(pixmap.scaled(ui->previewLabel->size())); + if(prePicUnit != nullptr) + { + prePicUnit->changeClickedFlag(false); + prePicUnit->setStyleSheet("border-width: 0px;"); + } + picUnit->changeClickedFlag(true); + prePicUnit = picUnit; + picUnit->setFrameShape(QFrame::Box); + picUnit->setStyleSheet(picUnit->clickedStyleSheet); bgsettings->set(FILENAME, fn); + setLockBackground(""); ui->previewStackedWidget->setCurrentIndex(PICTURE); }); @@ -202,37 +238,27 @@ pObject->moveToThread(pThread); connect(pThread, &QThread::started, pObject, &WorkerObject::run); - connect(pThread, &QThread::finished, this, [=]{ -// if (ui->formComBox->currentIndex() == PICTURE){ - //设置当前壁纸放置方式 -// if (wallpaperinfosMap.contains(filename)){ -// QMap currentwpMap = wallpaperinfosMap.value(filename); -// if (currentwpMap.contains("options")){ -// QString opStr = QString::fromLocal8Bit("%1").arg(currentwpMap.value("options")); -// ui->picOptionsComBox->blockSignals(true); -// ui->picOptionsComBox->setCurrentText(tr("%1").arg(opStr)); -// ui->picOptionsComBox->blockSignals(false); -// } -// } -// } + connect(pThread, &QThread::finished, this, [=](){ + + }); + connect(pThread, &QThread::finished, pObject, &WorkerObject::deleteLater); pThread->start(); - connect(ui->picOptionsComBox, SIGNAL(currentTextChanged(QString)), this, SLOT(wpOptionsChangedSlot(QString))); connect(ui->browserLocalwpBtn, &QPushButton::clicked, [=]{ showLocalWpDialog(); }); - connect(ui->browserOnlinewpBtn, &QPushButton::clicked, [=]{ QDesktopServices::openUrl(QUrl(kylinUrl)); }); + connect(ui->resetBtn, SIGNAL(clicked(bool)), this, SLOT(resetDefaultWallpaperSlot())); - ///纯色背景 + // 纯色背景 QStringList colors; colors << "#2d7d9a" << "#018574" << "#107c10" << "#10893e" << "#038387" << "#486860" << "#525e54" << "#7e735f" << "#4c4a48" << "#000000"; @@ -245,14 +271,14 @@ button->setStyleSheet(btnQss); connect(button, &QPushButton::clicked, [=]{ - QString widgetQss = QString("QWidget{background: %1; border-radius: 6px;}").arg(color); ui->previewWidget->setStyleSheet(widgetQss); - ///设置系统纯色背景 + // 设置系统纯色背景 bgsettings->set(FILENAME, ""); bgsettings->set(PRIMARY, QVariant(color)); bgsettings->set(SECONDARY, QVariant(color)); + setLockBackground(color); ui->previewStackedWidget->setCurrentIndex(COLOR); }); @@ -269,9 +295,10 @@ int currentPage = ui->formComBox->currentData(Qt::UserRole).toInt(); ui->substackedWidget->setCurrentIndex(currentPage); - if (currentPage == PICTURE){ - - } else if (currentPage == COLOR){ + if (currentPage == COLOR){ + ui->wallpaperWidget->setMaximumHeight(600); + } else if (currentPage == PICTURE) { + ui->wallpaperWidget->setMaximumHeight(16777215); } }); @@ -326,7 +353,7 @@ int current = 0; - //设置当前背景形式 + // 设置当前背景形式 if (filename.isEmpty()){ current = COLOR; } else if (filename.endsWith("xml")){ @@ -354,76 +381,58 @@ showComponent(currentIndex); } -void Wallpaper::showComponent(int index){ - if (PICTURE == index){ //图片 -// ui->picOptionsComBox->show(); -// ui->picOptionsLabel->show(); - } else if (COLOR == index){ //纯色 -// ui->picOptionsComBox->hide(); -// ui->picOptionsLabel->hide(); - } else { //幻灯片 +void Wallpaper::showComponent(int index) { + Q_UNUSED(index); +} - } +void Wallpaper::setLockBackground(QString bg) { + mLockLoginSettings->beginGroup("greeter"); + mLockLoginSettings->setValue("color", bg); + mLockLoginSettings->endGroup(); } void Wallpaper::initPreviewStatus(){ - //设置图片背景的预览效果 + // 设置图片背景的预览效果 QString filename = bgsettings->get(FILENAME).toString(); -// qDebug()<<"preview pic is---------->"<previewLabel->setPixmap(QPixmap(".TEMP.bmp").scaled(ui->previewLabel->size())); + } + else + { ui->previewLabel->setPixmap(QPixmap(filename).scaled(ui->previewLabel->size())); -// } - - //设置纯色背景的预览效果 + } + // 设置纯色背景的预览效果 QString color = bgsettings->get(PRIMARY).toString(); if (!color.isEmpty()){ - QString widgetQss = QString("QWidget{background: %1; border-radius: 6px;}").arg(color); + QString widgetQss = QString("QWidget{background: %1;}").arg(color); ui->previewWidget->setStyleSheet(widgetQss); } } +// 自定义颜色面板选定颜色 void Wallpaper::colorSelectedSlot(QColor color){ qDebug() << "colorSelectedSlot" << color << color.name(); - QString widgetQss = QString("QWidget{background: %1; border-radius: 6px;}").arg(color.name()); + QString widgetQss = QString("QWidget{background: %1;}").arg(color.name()); ui->previewWidget->setStyleSheet(widgetQss); - ///设置系统纯色背景 + // 设置系统纯色背景 bgsettings->set(FILENAME, ""); bgsettings->set(PRIMARY, QVariant(color.name())); + setLockBackground(color.name()); ui->previewStackedWidget->setCurrentIndex(COLOR); } void Wallpaper::wpOptionsChangedSlot(QString op){ - //获取当前选中的壁纸 -// QListWidgetItem * currentitem = ui->listWidget->currentItem(); -// QString filename = currentitem->data(Qt::UserRole).toString(); - - bgsettings->set(OPTIONS, ui->picOptionsComBox->currentData().toString()); - - //更新xml数据 -// if (wallpaperinfosMap.contains(filename)){ -// wallpaperinfosMap[filename]["options"] = op; -// } - + Q_UNUSED(op) //将改动保存至文件 xmlhandleObj->xmlUpdate(wallpaperinfosMap); } -void Wallpaper::setlistview(){ - //初始化listview -// ui->listView->setFocusPolicy(Qt::NoFocus); -// ui->listView->setAutoFillBackground(true); -// ui->listView->setIconSize(QSize(160, 100)); -// ui->listView->setResizeMode(QListView::Adjust); -// ui->listView->setModel(&wpListModel); -// ui->listView->setViewMode(QListView::IconMode); -// ui->listView->setSpacing(5); -} - void Wallpaper::setModeldata(){ QMap >::iterator iters = wallpaperinfosMap.begin(); for (int row = 0; iters != wallpaperinfosMap.end(); iters++, row++){ @@ -453,15 +462,50 @@ g_object_unref(wpgsettings); bgsettings->set(FILENAME, QVariant(QString(dwp))); + setClickedPic(kylinBackgroundName2);//默认背景图片和aurora.jpg一样,暂时特殊标记 } void Wallpaper::showLocalWpDialog(){ - QString filters = "Wallpaper files(*.png *.jpg)"; + QStringList filters; + filters< usb_list = fd.sidebarUrls(); + int sidebarNum = 8;// 最大添加U盘数,可以自己定义 + QString home_path = QDir::homePath().section("/", -1, -1); + QString mnt = "/media/" + home_path + "/"; + QDir mntDir(mnt); + mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + QFileInfoList file_list = mntDir.entryInfoList(); + QList mntUrlList; + for (int i = 0; i < sidebarNum && i < file_list.size(); ++i) { + QFileInfo fi = file_list.at(i); + mntUrlList << QUrl("file://" + fi.filePath()); + } + + QFileSystemWatcher m_fileSystemWatcher(&fd); + m_fileSystemWatcher.addPath("/media/" + home_path + "/"); + connect(&m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, &fd, + [=, &sidebarNum, &mntUrlList, &usb_list, &fd](const QString path) { + QDir m_wmntDir(path); + m_wmntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); + QFileInfoList m_wfilist = m_wmntDir.entryInfoList(); + mntUrlList.clear(); + for (int i = 0; i < sidebarNum && i < m_wfilist.size(); ++i) { + QFileInfo m_fi = m_wfilist.at(i); + mntUrlList << QUrl("file://" + m_fi.filePath()); + } + fd.setSidebarUrls(usb_list + mntUrlList); + fd.update(); + }); + + connect(&fd, &QFileDialog::finished, &fd, [=, &usb_list, &fd]() { + fd.setSidebarUrls(usb_list); + }); + fd.setDirectory(QString(const_cast(g_get_user_special_dir(G_USER_DIRECTORY_PICTURES)))); fd.setAcceptMode(QFileDialog::AcceptOpen); fd.setViewMode(QFileDialog::List); - fd.setNameFilter(filters); + fd.setNameFilters(filters); fd.setFileMode(QFileDialog::ExistingFile); fd.setWindowTitle(tr("select custom wallpaper file")); fd.setLabelText(QFileDialog::Accept, tr("Select")); @@ -470,6 +514,8 @@ fd.setLabelText(QFileDialog::FileType, tr("FileType: ")); fd.setLabelText(QFileDialog::Reject, tr("Cancel")); + fd.setSidebarUrls(usb_list + mntUrlList); + if (fd.exec() != QDialog::Accepted) return; QString selectedfile; @@ -487,16 +533,17 @@ QString bgfile = "/tmp/" + fileRes.at(fileRes.length() - 1); // TODO: chinese and space support -// if (g_file_test(selectedfile.toLatin1().data(), G_FILE_TEST_EXISTS)) { - bgsettings->set(FILENAME, QVariant(bgfile)); -// } else { -// bgsettings->reset(FILENAME); -// } + bgsettings->set(FILENAME, selectedfile); + if (prePicUnit != nullptr) { //去掉选定标记 + prePicUnit->changeClickedFlag(false); + prePicUnit->setStyleSheet("border-width: 0px;"); + } } void Wallpaper::add_custom_wallpaper(){ QString filters = "Wallpaper files(*.png *.jpg)"; QFileDialog fd; + fd.setDirectory(QString(const_cast(g_get_user_special_dir(G_USER_DIRECTORY_PICTURES)))); fd.setAcceptMode(QFileDialog::AcceptOpen); fd.setViewMode(QFileDialog::List); @@ -509,20 +556,13 @@ fd.setLabelText(QFileDialog::FileType, tr("FileType: ")); fd.setLabelText(QFileDialog::Reject, tr("Cancel")); - if (fd.exec() != QDialog::Accepted) - return; QString selectedfile; selectedfile = fd.selectedFiles().first(); - QSize IMAGE_SIZE(160, 120); - QPixmap pixmap = QPixmap(selectedfile).scaled(IMAGE_SIZE); -// append_item(pixmap, selectedfile); - if (wallpaperinfosMap.contains(selectedfile)){ wallpaperinfosMap[selectedfile]["deleted"] = "false"; - } - else{ + } else { QMap tmpinfo; tmpinfo.insert("artist", "(none)"); tmpinfo.insert("deleted", "false"); @@ -536,32 +576,26 @@ } xmlhandleObj->xmlUpdate(wallpaperinfosMap); - - if (picWpItemMap.contains(selectedfile)){ -// ui->listWidget->setCurrentItem(picWpItemMap.find(selectedfile).value()); - } - } void Wallpaper::del_wallpaper(){ - //获取当前选中的壁纸 -// QListWidgetItem * currentitem = ui->listWidget->currentItem(); -// QString filename = currentitem->data(Qt::UserRole).toString(); - - //更新xml数据 -// if (wallpaperinfosMap.contains(filename)){ -// wallpaperinfosMap[filename]["deleted"] = "true"; - -// int row = ui->listWidget->row(currentitem); - -// int nextrow = ui->listWidget->count() - 1 - row ? row + 1 : row - 1; - -// ui->listWidget->setCurrentItem(ui->listWidget->item(nextrow)); - -// ui->listWidget->takeItem(row); - -// } - -// 将改动保存至文件 + // 将改动保存至文件 xmlhandleObj->xmlUpdate(wallpaperinfosMap); } + +void Wallpaper::setClickedPic(QString fileName) { + for (int i = picFlowLayout->count() - 1; i >= 0; --i) { + QLayoutItem *it = picFlowLayout->itemAt(i); + PictureUnit *picUnit = static_cast(it->widget()); + if (fileName == picUnit->filenameText()) { + if (prePicUnit != nullptr) { + prePicUnit->changeClickedFlag(false); + prePicUnit->setStyleSheet("border-width: 0px;"); + } + picUnit->changeClickedFlag(true); + prePicUnit = picUnit; + picUnit->setFrameShape(QFrame::Box); + picUnit->setStyleSheet(picUnit->clickedStyleSheet); + } + } +} diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/wallpaper.h ukui-control-center-3.0.3/plugins/personalized/wallpaper/wallpaper.h --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/wallpaper.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/wallpaper.h 2021-05-20 13:08:14.000000000 +0000 @@ -30,6 +30,7 @@ #include #include +#include #include "shell/interface.h" #include "FlowLayout/flowlayout.h" @@ -40,7 +41,7 @@ #include "simplethread.h" #include "workerobject.h" #include "colordialog.h" - +#include "pictureunit.h" /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ @@ -55,15 +56,15 @@ #define BACKGROUND "org.mate.background" -//图片文件路径 +// 图片文件路径 #define FILENAME "picture-filename" -//图片不透明度 +// 图片不透明度 #define OPACITY "picture-opacity" -//图片放置方式 +// 图片放置方式 #define OPTIONS "picture-options" -//主色 +// 主色 #define PRIMARY "primary-color" -//副色 +// 副色 #define SECONDARY "secondary-color" namespace Ui { @@ -84,8 +85,11 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: + void initTitleLabel(); + void initSearchText(); void setupComponent(); void setupConnect(); void initBgFormStatus(); @@ -96,9 +100,13 @@ void showComponent(int index); + void setClickedPic(QString fileName); private: - Ui::Wallpaper *ui; + void setLockBackground(QString bg); +private: + Ui::Wallpaper *ui; + PictureUnit * prePicUnit; QString pluginName; int pluginType; QWidget * pluginWidget; @@ -116,13 +124,13 @@ XmlHandle * xmlhandleObj; ColorDialog * colordialog; QGSettings * bgsettings; + QSettings *mLockLoginSettings; QString localwpconf; QMap delItemsMap; CustdomItemModel wpListModel; //尝试mode view - void setlistview(); void setModeldata(); private: @@ -131,15 +139,14 @@ QMap picWpItemMap; -private: bool settingsCreate; + bool mFirstLoad; public slots: void resetDefaultWallpaperSlot(); void wpOptionsChangedSlot(QString op); void colorSelectedSlot(QColor color); -public slots: void add_custom_wallpaper(); void del_wallpaper(); }; diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/wallpaper.pro ukui-control-center-3.0.3/plugins/personalized/wallpaper/wallpaper.pro --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/wallpaper.pro 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/wallpaper.pro 2021-04-14 01:27:20.000000000 +0000 @@ -8,6 +8,7 @@ include($$PROJECT_COMPONENTSOURCE/maskwidget.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) QT += widgets xml dbus diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/wallpaper.ui ukui-control-center-3.0.3/plugins/personalized/wallpaper/wallpaper.ui --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/wallpaper.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/wallpaper.ui 2021-04-14 01:27:20.000000000 +0000 @@ -7,9 +7,15 @@ 0 0 800 - 710 + 895 + + + 0 + 0 + + 0 @@ -42,7 +48,13 @@ 48 - + + + + 0 + 0 + + 550 @@ -74,7 +86,7 @@ - 24 + 16 10 @@ -106,6 +118,9 @@ 180 + + 1 + @@ -266,7 +281,7 @@ 16 - + 0 @@ -297,38 +312,6 @@ - - - - - 0 - 0 - - - - Picture options - - - - - - - - 144 - 0 - - - - - 16777215 - 30 - - - - - - - @@ -349,7 +332,7 @@ - 1 + 0 @@ -369,7 +352,14 @@ 0 - + + + + 0 + 345 + + + @@ -398,7 +388,7 @@ - 132 + 150 36 @@ -417,7 +407,7 @@ - 132 + 150 36 @@ -433,23 +423,10 @@ - - - Qt::Horizontal - - - - 434 - 33 - - - - - - 132 + 150 36 @@ -522,109 +499,6 @@ - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - - - - - 0 - 60 - - - - - 16777215 - 60 - - - - - - - - - - - 100 - 36 - - - - - 100 - 36 - - - - Cancel - - - - - - - - 100 - 36 - - - - - 100 - 36 - - - - Ok - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - -
@@ -636,6 +510,19 @@
+ + + + Qt::Vertical + + + + 20 + 40 + + + + diff -Nru ukui-control-center-2.0.3/plugins/personalized/wallpaper/workerobject.cpp ukui-control-center-3.0.3/plugins/personalized/wallpaper/workerobject.cpp --- ukui-control-center-2.0.3/plugins/personalized/wallpaper/workerobject.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/personalized/wallpaper/workerobject.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -32,6 +32,7 @@ WorkerObject::~WorkerObject() { delete xmlHandleObj; + xmlHandleObj = nullptr; } void WorkerObject::run(){ diff -Nru ukui-control-center-2.0.3/plugins/plugins.pro ukui-control-center-3.0.3/plugins/plugins.pro --- ukui-control-center-2.0.3/plugins/plugins.pro 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/plugins.pro 2021-05-20 13:08:14.000000000 +0000 @@ -1,8 +1,11 @@ TEMPLATE = subdirs SUBDIRS = \ + devices/bluetooth \ devices/shortcut \ messages-task/experienceplan \ messages-task/notice \ + messages-task/search \ + network/vino \ system/defaultapp \ system/power \ system/autoboot \ @@ -26,6 +29,8 @@ security-updates/securitycenter \ security-updates/backup \ security-updates/update \ +# security-updates/upgrade \ messages-task/about \ + system/touchscreen \ time-language/datetime \ time-language/area diff -Nru ukui-control-center-2.0.3/plugins/security-updates/backup/backup.cpp ukui-control-center-3.0.3/plugins/security-updates/backup/backup.cpp --- ukui-control-center-2.0.3/plugins/security-updates/backup/backup.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/backup/backup.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -24,15 +24,18 @@ #include #include +#include "../../../shell/utils/utils.h" + #ifdef signals #undef signals #endif extern "C" { #include +#include } -Backup::Backup() +Backup::Backup() : mFirstLoad(true) { ui = new Ui::Backup; pluginWidget = new QWidget; @@ -41,96 +44,105 @@ pluginName = tr("Backup"); pluginType = UPDATE; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); -// pluginWidget->setStyleSheet("background: #ffffff;"); - -// ui->backupLabel->setStyleSheet("QLabel{color: #A6000000;}"); -// ui->restoreLabel->setStyleSheet("QLabel{color: #A6000000;}"); - -// ui->backBtn->setStyleSheet("QPushButton{background: #E9E9E9; border: none; border-radius: 4px;}"); -// ui->restoreBtn->setStyleSheet("QPushButton{background: #E9E9E9; border: none; border-radius: 4px;}"); - - connect(ui->backBtn, &QPushButton::clicked, this, [=](bool checked){ - Q_UNUSED(checked) - btnClicked(); - }); - - connect(ui->restoreBtn, &QPushButton::clicked, this, [=](bool checked){ - Q_UNUSED(checked) - btnClicked(); - }); } Backup::~Backup() { - delete ui; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } } -QString Backup::get_plugin_name(){ +QString Backup::get_plugin_name() +{ return pluginName; } -int Backup::get_plugin_type(){ +int Backup::get_plugin_type() +{ return pluginType; } -QWidget *Backup::get_plugin_ui(){ +QWidget *Backup::get_plugin_ui() +{ + if (mFirstLoad) { + mFirstLoad = false; + initTitleLabel(); + initConnection(); + } return pluginWidget; } -void Backup::plugin_delay_control(){ +void Backup::plugin_delay_control() +{ +} +const QString Backup::name() const +{ + return QStringLiteral("backup"); } -void Backup::btnClicked(){ - QString cmd = "/usr/bin/deja-dup"; +void Backup::initTitleLabel() +{ + //~ contents_path /backup/Backup + ui->titleLabel->setText(tr("Backup")); + //~ contents_path /backup/Restore + ui->title2Label->setText(tr("Restore")); + + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); +} - QString versionPath = "/etc/os-release"; - QStringList osRes = readFile(versionPath); - QString version; - - for (QString str : osRes) { - if (str.contains("PRETTY_NAME=")) { - int index = str.indexOf("PRETTY_NAME="); - int startIndex = index + 13; - int length = str.length() - startIndex - 1; - version = str.mid(startIndex, length); - } +void Backup::initConnection() +{ + if (Utils::isCommunity()) { + connect(ui->backBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + communitySlot(); + }); + + connect(ui->restoreBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + communitySlot(); + }); + } else { + connect(ui->backBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + btnClickedSlot(); + }); + + connect(ui->restoreBtn, &QPushButton::clicked, this, [=](bool checked){ + Q_UNUSED(checked) + restoreSlot(); + }); } +} - if (version == "Kylin V10" || version == "Kylin V10.1") { - QString desktopfp = "/usr/share/applications/yhkylin-backup-tools.desktop"; - GDesktopAppInfo *desktopAppInfo = g_desktop_app_info_new_from_filename(desktopfp.toLocal8Bit().data()); - g_app_info_launch(G_APP_INFO(desktopAppInfo), nullptr, nullptr, nullptr); - g_object_unref(desktopAppInfo); - return; - } +void Backup::btnClickedSlot() +{ + QString desktopfp = "/usr/share/applications/yhkylin-backup-tools.desktop"; + GDesktopAppInfo *desktopAppInfo = g_desktop_app_info_new_from_filename(desktopfp.toLocal8Bit().data()); + g_app_info_launch(G_APP_INFO(desktopAppInfo), nullptr, nullptr, nullptr); + g_object_unref(desktopAppInfo); +} - QProcess process(this); - process.startDetached(cmd); +void Backup::restoreSlot() +{ + QString desktopfp = "/usr/share/applications/yhkylin-backup-tools.desktop"; + GDesktopAppInfo *desktopAppInfo = g_desktop_app_info_new_from_filename(desktopfp.toLocal8Bit().data()); + + GList *arg = NULL; + arg = g_list_append(arg, gpointer("--restore")); + g_app_info_launch_uris(G_APP_INFO(desktopAppInfo), arg, nullptr, nullptr); + g_object_unref(desktopAppInfo); } -QStringList Backup::readFile(QString filepath) +void Backup::communitySlot() { - QStringList fileCont; - QFile file(filepath); - if(file.exists()) { - if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "ReadFile() failed to open" << filepath; - return QStringList(); - } - QTextStream textStream(&file); - while(!textStream.atEnd()) { - QString line= textStream.readLine(); - line.remove('\n'); - fileCont< 0 0 - 882 + 1041 710 @@ -60,7 +60,7 @@ - + 0 0 @@ -72,6 +72,9 @@ true + + true + @@ -102,7 +105,7 @@ - 120 + 16777215 36 @@ -151,7 +154,7 @@ - View a list of backed-upfiles to restore backed up files to the system + View a list of backed-upfiles to backed up files to the system true @@ -186,7 +189,7 @@ - 120 + 16777215 36 diff -Nru ukui-control-center-2.0.3/plugins/security-updates/recovery/recovery.cpp ukui-control-center-3.0.3/plugins/security-updates/recovery/recovery.cpp --- ukui-control-center-2.0.3/plugins/security-updates/recovery/recovery.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/recovery/recovery.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -34,6 +34,7 @@ Recovery::~Recovery() { delete ui; + ui = nullptr; } QString Recovery::get_plugin_name(){ diff -Nru ukui-control-center-2.0.3/plugins/security-updates/securitycenter/securitycenter.cpp ukui-control-center-3.0.3/plugins/security-updates/securitycenter/securitycenter.cpp --- ukui-control-center-2.0.3/plugins/security-updates/securitycenter/securitycenter.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/securitycenter/securitycenter.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -5,62 +5,111 @@ #include #include #include - #include - #include +#include - -BlockWidget::BlockWidget(){ +BlockWidget::BlockWidget() +{ setFixedSize(QSize(260, 80)); initComponent(); } -BlockWidget::~BlockWidget(){ +BlockWidget::~BlockWidget() +{ } void BlockWidget::initComponent(){ QHBoxLayout * mainVerLayout = new QHBoxLayout(this); mainVerLayout->setSpacing(12); - mainVerLayout->setMargin(0); - - logoLabel = new QLabel; + mainVerLayout->setMargin(8); + logoLabel = new QLabel(this); logoLabel->setFixedSize(QSize(48, 48)); - QVBoxLayout * textHorLayout = new QVBoxLayout; - textHorLayout->setSpacing(6); - - titleLable = new QLabel; - detailLabel = new QLabel; - + textHorLayout->setSpacing(10); + titleLable = new QLabel(this); + titleLable->setObjectName("Sec"); + detailLabel = new QLabel(this); + detailLabel->setAlignment(Qt::AlignTop); + detailLabel->setFixedHeight(32); + QFont font; + font.setBold(true); + font.setPixelSize(18); + titleLable->setFont(font); + font.setPixelSize(14); + font.setBold(false); + detailLabel->setFont(font); textHorLayout->addStretch(); textHorLayout->addWidget(titleLable); textHorLayout->addWidget(detailLabel); textHorLayout->addStretch(); - mainVerLayout->addWidget(logoLabel); mainVerLayout->addLayout(textHorLayout); - setLayout(mainVerLayout); } -void BlockWidget::setupComponent(QString logo, QString title, QString detail, QString cmd){ - logoLabel->setPixmap(QPixmap(logo).scaled(logoLabel->size())); +void BlockWidget::setupComponent(QString normal_icon ,QString hover_icon, QString title, QString detail, QString cmd){ + m_normalIcon = normal_icon; + m_hoverIcon = hover_icon; + logoLabel->setPixmap(QPixmap(normal_icon).scaled(logoLabel->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); titleLable->setText(title); - detailLabel->setText(detail); + + QString detaildec = detail; + QFontMetrics fontMetrics(detailLabel->font()); + int fontSize = fontMetrics.width(detail); + if (fontSize > detailLabel->width()) { + detailLabel->setText(fontMetrics.elidedText(detail, Qt::ElideRight, detailLabel->width())); + detailLabel->setToolTip(detaildec); + } else { + detailLabel->setText(detaildec); + detailLabel->setToolTip(""); + } + + m_curIndex = 0; + m_showText = detail + " "; + // m_charWidth = fontMetrics().width("。"); + m_labelWidth = m_charWidth * (m_showText.length() - 4); _cmd = cmd; } +void BlockWidget::scrollLabel(){ + timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, &BlockWidget::updateIndex); + timer->start(200); +} + +void BlockWidget::updateIndex() +{ + m_curIndex++; + if (m_curIndex*m_charWidth > m_labelWidth){ + m_curIndex = 0; + } + this->detailLabel->update(); +} + void BlockWidget::enterEvent(QEvent *event){ //style - + m_charWidth = fontMetrics().width("。"); + m_labelWidth = m_charWidth * m_showText.length(); + scrollLabel(); + logoLabel->setPixmap(QPixmap(m_hoverIcon).scaled(logoLabel->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + setBackgroundRole(QPalette::Highlight); + setAutoFillBackground(true); + setStyleSheet("background:palette(Highlight);" + "border-radius:6px;"); QWidget::enterEvent(event); } void BlockWidget::leaveEvent(QEvent *event){ - //style - + timer->stop(); + m_curIndex = 0; + this->detailLabel->update(); + setBackgroundRole(QPalette::Base); + setAutoFillBackground(true); + setStyleSheet("background:palette(Base);" + "border-radius:6px;"); + logoLabel->setPixmap(QPixmap(m_normalIcon).scaled(logoLabel->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); QWidget::leaveEvent(event); } @@ -72,6 +121,28 @@ QWidget::mousePressEvent(event); } +bool BlockWidget::eventFilter(QObject *watched, QEvent *event) +{ + if(watched == this->detailLabel && event->type() == QEvent::Paint && m_labelWidth > 280) + { + this->detailLabel->setText(""); + showPaint(); //响应函数 + } + else if(m_labelWidth <= 280){ + this->detailLabel->setText(m_showText); + } + QWidget::eventFilter(watched,event); + return true; +} + +//实现响应函数 +void BlockWidget::showPaint() +{ + QPainter painter(this->detailLabel); + painter.drawText(0, 20, m_showText.mid(m_curIndex)); + painter.drawText(m_labelWidth - m_charWidth*m_curIndex, 20, m_showText.left(m_curIndex)); +} + //子类化一个QWidget,为了能够使用样式表,则需要提供paintEvent事件。 //这是因为QWidget的paintEvent()是空的,而样式表要通过paint被绘制到窗口中。 void BlockWidget::paintEvent(QPaintEvent *event){ @@ -82,27 +153,21 @@ style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } -SecurityCenter::SecurityCenter() +SecurityCenter::SecurityCenter() : mFirstLoad(true) { ui = new Ui::SecurityCenter; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - - pluginName = tr("SecurityCenter"); + pluginName = tr("Security Center"); pluginType = UPDATE; - initComponent(); - connect(ui->pushButton, &QPushButton::clicked, [=]{ - QString cmd = "/usr/sbin/ksc-defender"; - runExternalApp(cmd); - }); } SecurityCenter::~SecurityCenter() { - delete ui; + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } } QString SecurityCenter::get_plugin_name(){ @@ -114,6 +179,22 @@ } QWidget * SecurityCenter::get_plugin_ui(){ + if (mFirstLoad) { + mFirstLoad = false; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + + initTitleLabel(); + initSearchText(); + initComponent(); + + connect(ui->pushButton, &QPushButton::clicked, [=]{ + QString cmd = "/usr/sbin/ksc-defender"; + runExternalApp(cmd); + }); + } return pluginWidget; } @@ -121,63 +202,104 @@ } -void SecurityCenter::initComponent(){ - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); +const QString SecurityCenter::name() const { + + return QStringLiteral("securitycenter"); +} +void SecurityCenter::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); +} + +void SecurityCenter::initSearchText() { + //~ contents_path /securitycenter/Computer Security Overview + ui->titleLabel->setText(tr("Computer Security Overview")); +} + +void SecurityCenter::initComponent(){ //设置布局 flowLayout = new FlowLayout; flowLayout->setContentsMargins(0, 0, 0, 0); ui->modulesWidget->setLayout(flowLayout); - BlockWidget * kysecWidget = new BlockWidget(); - kysecWidget->setupComponent(":/img/plugins/securitycenter/kysec.png", \ - tr("Virus Protection"), \ - tr("Protect system from threats"), \ - "/usr/sbin/ksc-defender --virus-protect"); - - BlockWidget * netWidget = new BlockWidget(); - netWidget->setupComponent(":/img/plugins/securitycenter/net.png", \ - tr("Network Protection"), \ - tr("Setup app that can access web"), \ - "/usr/sbin/ksc-defender --net-protect"); - - BlockWidget * protectWidget = new BlockWidget(); - protectWidget->setupComponent(":/img/plugins/securitycenter/protect.png", \ - tr("App Execution Control"), \ - tr("App install and exe protection"), \ - "/usr/sbin/ksc-defender --exec-ctrl"); + BlockWidget * account_sec_Widget = new BlockWidget(); + account_sec_Widget->setupComponent(":/img/plugins/securitycenter/user_48.png", \ + ":/img/plugins/securitycenter/user_48_white.png",\ + //~ contents_path /securitycenter/Account Security + tr("Account Security"), \ + tr("Protect account and login security"), \ + "/usr/sbin/ksc-defender --account-sec"); + BlockWidget * baseline_ctrl_Widget = new BlockWidget(); + baseline_ctrl_Widget->setupComponent(":/img/plugins/securitycenter/icon_scanning_b48@1x.png", \ + ":/img/plugins/securitycenter/icon_scanning_w48@1x.png",\ + //~ contents_path /securitycenter/Safety check-up + tr("Safety check-up"), \ + tr("Detect abnormal configuration"), \ + "/usr/sbin/ksc-defender --baseline-ctrl"); + + BlockWidget * virus_protect_Widget = new BlockWidget(); + virus_protect_Widget->setupComponent(":/img/plugins/securitycenter/protect_48.png", \ + ":/img/plugins/securitycenter/protect_48_white.png",\ + //~ contents_path /securitycenter/Virus defense + tr("Virus defense"), \ + tr("Real time protection from virus threat"), \ + "/usr/sbin/ksc-defender --virus-protect"); + + BlockWidget * exec_ctrl_Widget = new BlockWidget(); + exec_ctrl_Widget->setupComponent(":/img/plugins/securitycenter/kysec_48.png", \ + ":/img/plugins/securitycenter/kysec_48_white.png",\ + //~ contents_path /securitycenter/App protection + tr("App protection"), \ + tr("App install"), \ + "/usr/sbin/ksc-defender --exec-ctrl"); + + + BlockWidget * net_protect_Widget = new BlockWidget(); + net_protect_Widget->setupComponent(":/img/plugins/securitycenter/net_48.png", \ + ":/img/plugins/securitycenter/net_48_white.png",\ + //~ contents_path /securitycenter/Net protection + tr("Net protection"), \ + tr("Manage and control network"), \ + "/usr/sbin/ksc-defender --net-protect"); + + BlockWidget * security_setting_Widget = new BlockWidget(); + security_setting_Widget->setupComponent(":/img/plugins/securitycenter/set2px.png", \ + ":/img/plugins/securitycenter/set2@2x_1.png",\ + //~ contents_path /securitycenter/Secure Config + tr("Secure Config"), \ + tr("Simple Config"), \ + "/usr/sbin/ksc-defender --security-setting"); + + flowLayout->addWidget(account_sec_Widget); + flowLayout->addWidget(baseline_ctrl_Widget); + flowLayout->addWidget(virus_protect_Widget); + flowLayout->addWidget(net_protect_Widget); + flowLayout->addWidget(exec_ctrl_Widget); + flowLayout->addWidget(security_setting_Widget); - BlockWidget * userWidget = new BlockWidget(); - userWidget->setupComponent(":/img/plugins/securitycenter/user.png", \ - tr("Account Security"), \ - tr("Protect account and login security"), \ - "/usr/sbin/ksc-defender --account-sec"); - - flowLayout->addWidget(kysecWidget); - flowLayout->addWidget(netWidget); - flowLayout->addWidget(protectWidget); - flowLayout->addWidget(userWidget); - - connect(kysecWidget, &BlockWidget::bwClicked, [=](QString cmd){ + connect(account_sec_Widget, &BlockWidget::bwClicked, [=](QString cmd){ runExternalApp(cmd); }); - connect(netWidget, &BlockWidget::bwClicked, [=](QString cmd){ + connect(baseline_ctrl_Widget, &BlockWidget::bwClicked, [=](QString cmd){ runExternalApp(cmd); }); - connect(protectWidget, &BlockWidget::bwClicked, [=](QString cmd){ + connect(virus_protect_Widget, &BlockWidget::bwClicked, [=](QString cmd){ runExternalApp(cmd); }); - connect(userWidget, &BlockWidget::bwClicked, [=](QString cmd){ + connect(net_protect_Widget, &BlockWidget::bwClicked, [=](QString cmd){ + runExternalApp(cmd); + }); + connect(exec_ctrl_Widget, &BlockWidget::bwClicked, [=](QString cmd){ + runExternalApp(cmd); + }); + connect(security_setting_Widget, &BlockWidget::bwClicked, [=](QString cmd){ runExternalApp(cmd); }); - - } -void SecurityCenter::runExternalApp(QString cmd){ - - qDebug() << "cmd:" << cmd; - +void SecurityCenter::runExternalApp(QString cmd) { QProcess process(this); process.startDetached(cmd); } diff -Nru ukui-control-center-2.0.3/plugins/security-updates/securitycenter/securitycenter.h ukui-control-center-3.0.3/plugins/security-updates/securitycenter/securitycenter.h --- ukui-control-center-2.0.3/plugins/security-updates/securitycenter/securitycenter.h 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/securitycenter/securitycenter.h 2021-04-14 01:27:20.000000000 +0000 @@ -6,8 +6,8 @@ #include #include - #include +#include #include "shell/interface.h" #include "FlowLayout/flowlayout.h" @@ -25,7 +25,7 @@ ~BlockWidget(); public: void initComponent(); - void setupComponent(QString logo, QString title, QString detail, QString cmd); + void setupComponent(QString normal_icon ,QString hover_icon, QString title, QString detail, QString cmd); public: QString _cmd; @@ -34,15 +34,28 @@ QLabel * titleLable; QLabel * detailLabel; + int m_charWidth; + int m_curIndex; + int m_labelWidth; + QString m_showText; + QString m_normalIcon; + QString m_hoverIcon; + QTimer *timer; + void scrollLabel(); + void updateIndex(); + void showPaint(); + protected: virtual void enterEvent(QEvent * event); virtual void leaveEvent(QEvent * event); + virtual bool eventFilter(QObject *watched, QEvent *event); virtual void paintEvent(QPaintEvent * event); virtual void mousePressEvent(QMouseEvent * event); Q_SIGNALS: void bwClicked(QString _cmd); + void indexChanged(); }; @@ -61,15 +74,17 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: FlowLayout * flowLayout; public: + void initTitleLabel(); + void initSearchText(); void initComponent(); void runExternalApp(QString cmd); - private: Ui::SecurityCenter *ui; @@ -78,5 +93,7 @@ int pluginType; QWidget * pluginWidget; + bool mFirstLoad; + }; #endif // SECURITYCENTER_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/securitycenter/securitycenter.ui ukui-control-center-3.0.3/plugins/security-updates/securitycenter/securitycenter.ui --- ukui-control-center-2.0.3/plugins/security-updates/securitycenter/securitycenter.ui 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/securitycenter/securitycenter.ui 2021-04-14 01:27:20.000000000 +0000 @@ -13,7 +13,7 @@ SecurityCenter - + 0 @@ -60,41 +60,64 @@ 0 - - - 16 - - - 10 - + - - - - 0 - 0 - + + + 0 - - Summarize + + 10 - - - - - - - 0 - 0 - - - - Recognize the current security of the system, and can take the necessary settings - - + + + + + 0 + 0 + + + + Computer Security Overview + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 8 + + + + + + + + + 0 + 0 + + + + Understand current computer security situation and take measures + + + + + + 8 + diff -Nru ukui-control-center-2.0.3/plugins/security-updates/update/update.cpp ukui-control-center-3.0.3/plugins/security-updates/update/update.cpp --- ukui-control-center-2.0.3/plugins/security-updates/update/update.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/update/update.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -41,6 +41,7 @@ Update::~Update() { delete ui; + ui = nullptr; } QString Update::get_plugin_name(){ @@ -59,7 +60,14 @@ } +const QString Update::name() const { + + return QStringLiteral("update"); +} + void Update::ui_init(){ + //~ contents_path /update/System Update + ui->titleLabel->setText(tr("System Update")); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); QString filename = QDir::homePath() + "/.config/ukccUpdate.conf"; diff -Nru ukui-control-center-2.0.3/plugins/security-updates/update/update.h ukui-control-center-3.0.3/plugins/security-updates/update/update.h --- ukui-control-center-2.0.3/plugins/security-updates/update/update.h 2020-05-28 06:44:33.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/update/update.h 2021-04-14 01:27:20.000000000 +0000 @@ -48,6 +48,7 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; void ui_init(); diff -Nru ukui-control-center-2.0.3/plugins/security-updates/update/update.ui ukui-control-center-3.0.3/plugins/security-updates/update/update.ui --- ukui-control-center-2.0.3/plugins/security-updates/update/update.ui 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/update/update.ui 2021-04-14 01:27:20.000000000 +0000 @@ -70,7 +70,7 @@ - 25 + 0 @@ -131,13 +131,10 @@ - + Qt::Horizontal - - QSizePolicy::Fixed - 40 @@ -155,7 +152,7 @@ - CheckUpdate + Check for updates false diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/config_file/need-reboot.conf ukui-control-center-3.0.3/plugins/security-updates/upgrade/config_file/need-reboot.conf --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/config_file/need-reboot.conf 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/config_file/need-reboot.conf 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,7 @@ +linux-generic +kylin-update-desktop-kernel +kylin-update-desktop-kernel-3a4000 +kylin-update-desktop-ukui +kylin-update-desktop-support +linux-meta + Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/plugins/security-updates/upgrade/image/close.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/plugins/security-updates/upgrade/image/close.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/plugins/security-updates/upgrade/image/refresh.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/plugins/security-updates/upgrade/image/refresh.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/plugins/security-updates/upgrade/image/search.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/plugins/security-updates/upgrade/image/search.png differ diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/appupdate.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/appupdate.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/appupdate.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/appupdate.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,853 @@ +#include "appupdate.h" +#include +#include +#include +#include + +#define CONFIG_FILE_PATH "/usr/share/ukui-control-center/upgrade/" + +AppUpdateWid::AppUpdateWid(AppAllMsg msg,QWidget *parent):QWidget(parent) +{ + m_updateMutual = UpdateDbus::getInstance(this); + qRegisterMetaType("AppMsg"); //注册信号槽类型 + qRegisterMetaType("AppAllMsg"); //注册信号槽类型 + appAllMsg = msg; + timer = new QTimer(); + downloadPath = QString("%1%2/").arg(DOWN_CACHE_PATH).arg(appAllMsg.name); + downloadProcess = new QProcess(); + updateAppUi(appAllMsg.name); + this->setObjectName("AppUpdateWid"); + initConnect(); +} + +AppUpdateWid::~AppUpdateWid() +{ + qDebug() << "delete->"<< appAllMsg.name; +} + +void AppUpdateWid::initConnect() +{ + connect(detaileInfo,&QPushButton::clicked,this,&AppUpdateWid::showDetails); + connect(updatelogBtn,&QPushButton::clicked,this,&AppUpdateWid::showUpdateLog); + connect(updateAPPBtn,&QPushButton::clicked,this,&AppUpdateWid::cancelOrUpdate); + connect(m_updateMutual,&UpdateDbus::transferAptProgress,this,&AppUpdateWid::showInstallStatues); + //绑定wget进程结束的信号getAppMessage + connect(downloadProcess, static_cast(&QProcess::finished), + [=] (int exitCode, QProcess::ExitStatus exitStatus) { + qDebug() << "exitcode:" << exitCode << exitStatus; + if(!isCancel) //当包存在依赖时,需要显示包的所有依赖以及自身包的总大小 + { + if(exitCode == 0) //正常下载结束 + { + qDebug() << "path:" << path; + if(QFile::exists(path)) + { + connectTimes = 0; + slotDownloadPackages(); + } + else + changeDownloadState(10); //下载过程中删除了该包,导致出现异常特殊处理 + } + else //下载异常处理 + changeDownloadState(exitCode); + } +// qDebug() << "exitcode:" << exitCode << exitStatus; + }); + connect(m_updateMutual, &UpdateDbus::copyFinish, this, &AppUpdateWid::startInstall); + connect(timer, &QTimer::timeout, this, &AppUpdateWid::calculateSpeedProgress); +} + +//函数:下载异常时调用该函数 +void AppUpdateWid::changeDownloadState(int state) +{ + if(state == 3 || state == 1) //磁盘空间不够 + { + isCancel = true; + timer->stop(); +// appVersion->setText(tr("磁盘空间不足!")); + appVersion->setText(tr("Lack of local disk space!")); + appVersion->setToolTip(""); + QIcon icon = QIcon::fromTheme("dialog-info"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(14, 14))); + appVersionIcon->setPixmap(pixmap); +// updateAPPBtn->setText(tr("更新")); + updateAPPBtn->setText(tr("Update")); + emit changeUpdateAllSignal(); + + } + else if(state == 4) //下载网络异常 + { + if(connectTimes < 20) //判断重连次数,重连20次后退出下载 + { + connectTimes += 1; + wgetDownload(urlmsg,path); + qDebug() << "exitcode:" << state << "connectTimes:" << connectTimes; + } + else + { + isCancel = true; + timer->stop(); +// appVersion->setText(tr("网络异常!")); + appVersion->setText(tr("Network abnormal!")); + appVersion->setToolTip(""); + QIcon icon = QIcon::fromTheme("dialog-info"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(16, 16))); + appVersionIcon->setPixmap(pixmap); +// updateAPPBtn->setText(tr("更新")); + updateAPPBtn->setText(tr("Update")); + emit changeUpdateAllSignal(); + } + } + + else if(state == 8) //自定义错误码,下载过程软件包被删除 + { + isCancel = true; + timer->stop(); + appVersion->setText(tr("Download failed!")); + QString str = urlmsg.name; + appVersion->setToolTip(str+tr("failed to get from the source!")); + QIcon icon = QIcon::fromTheme("dialog-info"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(16, 16))); + appVersionIcon->setPixmap(pixmap); + updateAPPBtn->hide(); + m_updateMutual->importantList.removeOne(appAllMsg.name); + m_updateMutual->failedList.append(appAllMsg.name); + emit hideUpdateBtnSignal(false); + } + else if(state == 10) //自定义错误码,下载过程软件包被删除 + { + isCancel = true; + timer->stop(); +// appVersion->setText(tr("下载失败!")); + appVersion->setText(tr("Download failed!")); +// appVersion->setToolTip(tr("下载缓存已被删除")); + appVersion->setToolTip(tr("The download cache has been removed")); + QIcon icon = QIcon::fromTheme("dialog-info"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(16, 16))); + appVersionIcon->setPixmap(pixmap); + updateAPPBtn->hide(); + m_updateMutual->importantList.removeOne(appAllMsg.name); + m_updateMutual->failedList.append(appAllMsg.name); + emit hideUpdateBtnSignal(false); + } +} + +//从列表中取出下载信息开始下载 +void AppUpdateWid::slotDownloadPackages() +{ +// qDebug() << "list:" << appAllMsg.msg.depList.length(); + if(appAllMsg.msg.depList.length() != 0) + { + QDir dir = downloadPath; + if(!dir.exists()) + { +// qDebug() << "not exists:" <setText(tr("Ready to install")); + } +} + +//开启wget断点续传 +void AppUpdateWid::wgetDownload(UrlMsg msg, QString path) +{ + QStringList args; + args.append("-c"); + args.append("-P"); + args.append(QString("%1").arg(DOWN_CACHE_PATH)); + args.append(QString("%1").arg(msg.url.remove("'"))); + args.append("-O"); + args.append(QString("%1").arg(path)); + args.append("-T"); + args.append("10"); +// args.append("--limit-rate 1"); //预留超时接口 + currentPackage = msg.fullname; + qDebug() << "currentPackage" << currentPackage << "size:" << msg.size; + downloadProcess->start("/usr/bin/wget", args); +} + +//接收后台dbus信号开始安装软件包 +void AppUpdateWid::startInstall(QString appName) +{ + if(appName == appAllMsg.name) + { +// m_updateMutual->init_cache(); + updateAPPBtn->hide(); + m_updateMutual->installAndUpgrade(appAllMsg.name); + workProcess = new QProcess(); + workProcess->start(QString("rm -r %1").arg(downloadPath)); //删除创建的目录保证缓存环境的干净 + } +} + +/* remove enter */ +void AppUpdateWid::remove_last_enter(char *p_src_in_out) +{ + if (p_src_in_out == NULL) { + return; + } + + char *p_tmp = p_src_in_out + strlen(p_src_in_out) - 1; + if (*p_tmp == '\n') { + *p_tmp = '\0'; + } + + return; +} + +/* analysis config file */ +QStringList AppUpdateWid::analysis_config_file(char *p_file_path) +{ + FILE *fd = NULL; + char p_buf[1024]; + + QStringList dst; + dst.clear(); + + memset(p_buf , 0x00 , sizeof(p_buf)); + + //printf("Info : p_file_path = [%s]\n" , p_file_path); + fd = fopen(p_file_path , "r"); + if (fd == NULL) { + printf("Error : open reboot config file fail\n"); + return dst; + } + + while (fgets(p_buf , sizeof(p_buf) , fd) != NULL) { + remove_last_enter(p_buf); + if (!strlen(p_buf)) { + memset(p_buf , 0x00 , sizeof(p_buf)); + continue; + } + + //printf("Info : config file data [%s]\n" , p_buf); + + dst << QString(p_buf); + + memset(p_buf , 0x00 , sizeof(p_buf)); + } + + return dst; +} + +//修改界面状态值 +void AppUpdateWid::showInstallStatues(QString status,QString appAptName, float progress ,QString errormsg) +{ + char p_path[1024]; + + memset(p_path , 0x00 , sizeof(p_path)); + sprintf(p_path , "%s%s" , CONFIG_FILE_PATH , "need-reboot.conf"); + QStringList reboot = analysis_config_file(p_path); + qDebug() << "Info : need reboot pkg :" << reboot; + + memset(p_path , 0x00 , sizeof(p_path)); + sprintf(p_path , "%s%s" , CONFIG_FILE_PATH , "need-logout.conf"); + QStringList logout = analysis_config_file(p_path); + qDebug() << "Info : need logout pkg :" << logout; + + if(QString::compare(appAllMsg.name,appAptName) == 0) + { + + /* 临时解决方案 , 获取系统语言环境 , 英文加悬浮框 , 中文不加 */ + QLocale locale; + + int pgs = progress; +// appVersion->setText(tr("正在安装")+"("+QString::number(pgs)+"%)"); + appVersion->setText(tr("Being installed")+"("+QString::number(pgs)+"%)"); + appVersion->setToolTip(""); + updateAPPBtn->hide(); + if(status == "apt_finish") + { + updateAPPBtn->hide(); +// appVersion->setText(tr("更新成功!")); + + if (reboot.contains(appAptName)) { + if (locale.language() == QLocale::Chinese) { + appVersion->setText(tr("Update succeeded , It is recommended that you restart later!")); + } else { + appVersion->setText(tr("Update succeeded , It is recommended that you restart later!")); + appVersion->setToolTip(tr("Update succeeded , It is recommended that you restart later!")); + } + } else if (logout.contains(appAptName)) { + if (locale.language() == QLocale::Chinese) { + appVersion->setText(tr("Update succeeded , It is recommended that you log out later and log in again!")); + } else { + appVersion->setText(tr("Update succeeded , It is recommended that you log out later and log in again!")); + appVersion->setToolTip(tr("Update succeeded , It is recommended that you log out later and log in again!")); + } + } else { + appVersion->setText(tr("Update succeeded!")); + } + + QIcon icon = QIcon::fromTheme("ukui-dialog-success"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(14, 14))); + appVersionIcon->setPixmap(pixmap); + m_updateMutual->importantList.removeOne(appAllMsg.name); + m_updateMutual->failedList.removeOne(appAllMsg.name); +// QString message = QString("%1"+tr("更新成功!")).arg(dispalyName); + QString message = QString("%1"+tr("Update succeeded!")).arg(dispalyName); + m_updateMutual->onRequestSendDesktopNotify(message); + detaileInfo->hide(); + largeWidget->hide(); + emit hideUpdateBtnSignal(true); + + } + else if(status == "apt_error") + { +// appVersion->setText(tr("更新失败!")); + appVersion->setText(tr("Update failed!")); + +// appVersion->setToolTip(tr("失败原因:")+(appNameLab->dealMessage(errormsg))); + appVersion->setToolTip(tr("Failure reason:")+ "\r\n"+(appNameLab->dealMessage(errormsg))); + m_updateMutual->importantList.removeOne(appAllMsg.name); + m_updateMutual->failedList.append(appAllMsg.name); + QIcon icon = QIcon::fromTheme("dialog-error"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(14, 14))); + appVersionIcon->setPixmap(pixmap); +// QString message = QString("%1"+tr("更新失败!")).arg(dispalyName); + QString message = QString("%1"+tr("Update failed!")).arg(dispalyName); + m_updateMutual->onRequestSendDesktopNotify(message); + emit hideUpdateBtnSignal(false); + } + } +} + +void AppUpdateWid::updateAppUi(QString name) +{ + iconNameLayout = new QHBoxLayout(); + smallHLayout = new QHBoxLayout(); + largeVLayout = new QVBoxLayout(); + appTitleWid = new QWidget(); + largeWidget = new QWidget(); + mainVLayout = new QVBoxLayout(); + QHBoxLayout *frameLayout = new QHBoxLayout(); + AppFrame = new QFrame(this); //最外层窗口适配主题样式 + AppFrame->setFrameShape(QFrame::Box); + + frameLayout->addWidget(AppFrame); + frameLayout->setContentsMargins(0,0,0,0); //更新信息之间的间距 + frameLayout->setSpacing(0); + this->setLayout(frameLayout); + + appIconName = new QLabel(this); + appIconName->setMinimumWidth(160); + appIconName->setMaximumWidth(600); + appIcon = new QLabel(appIconName); + appNameLab = new MyLabel(appIconName); +// appNameLab->setMinimumWidth(140); + appIconName->setLayout(iconNameLayout); + appIcon->setFixedSize(32,32); + iconNameLayout->setAlignment(Qt::AlignLeft); + iconNameLayout->addWidget(appIcon,1); + iconNameLayout->setSpacing(0); + iconNameLayout->addSpacing(8); + iconNameLayout->addWidget(appNameLab,10); +// iconNameLayout->addStretch(); + + appVersion = new QLabel(this); + appVersionIcon = new QLabel(this); + appVersionIcon->setFixedSize(16,16); + appVersionIcon->setPixmap(QPixmap()); + appVersion->setMinimumWidth(180); +// QIcon icon = QIcon::fromTheme("dialog-error"); +// QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(14, 14))); +// appVersionIcon->setPixmap(pixmap); + + detaileInfo = new QPushButton(this); +// detaileInfo->setText(tr("详情")); + detaileInfo->setText(tr("details")); + detaileInfo->setFixedSize(60,30); + detaileInfo->setFlat(true); + + updateAPPBtn = new QPushButton(this); +// updateAPPBtn->setText(tr("更新")); + updateAPPBtn->setText(tr("Update")); + + otherBtnLayout = new QHBoxLayout(); //版本号、详情、更细按钮布局 + otherBtnLayout->setSpacing(0); + otherBtnLayout->setMargin(0); + otherBtnLab = new QLabel(this); + otherBtnLab->setMargin(0); + otherBtnLab->setMinimumWidth(350); + otherBtnLab->setMaximumWidth(500); + otherBtnLab->setFixedHeight(60); + + + otherBtnLayout->setAlignment(Qt::AlignLeft); + otherBtnLayout->addWidget(appVersionIcon); + otherBtnLayout->addWidget(appVersion); + otherBtnLayout->addWidget(detaileInfo,1,Qt::AlignRight); + otherBtnLayout->addSpacing(10); + otherBtnLayout->addWidget(updateAPPBtn,0,Qt::AlignRight); + otherBtnLab->setLayout(otherBtnLayout); + smallHLayout->addWidget(appIconName,1); + smallHLayout->addStretch(0); + smallHLayout->addWidget(otherBtnLab,1); + smallHLayout->setSpacing(0); + smallHLayout->setContentsMargins(0,0,10,0); + appTitleWid->setLayout(smallHLayout); + + mainVLayout->addWidget(appTitleWid); + mainVLayout->setMargin(0); + mainVLayout->setSpacing(0); + someInfoEdit = new QTextEdit(this); //部分changelog 缩略显示 + someInfoEdit->setReadOnly(true); + someInfoEdit->verticalScrollBar()->setProperty("drawScrollBarGroove" , false); + QPalette pl = someInfoEdit->palette(); + someInfoEdit->setFixedHeight(120); + pl.setBrush(QPalette::Base,QBrush(QColor(255,0,0,0))); + someInfoEdit->setPalette(pl); + + //当前语言环境 + QString locale = QLocale::system().name(); + if (locale == "zh_CN") + environment=zh_cn; + + updatelogBtn = new QPushButton(this); +// updatelogBtn->setText(tr("更新日志")); + updatelogBtn->setText(tr("Update log")); + updatelogBtn->setFlat(true); + updatelog1 = new UpdateLog(); + + largeVLayout->addWidget(someInfoEdit); + largeVLayout->addWidget(updatelogBtn,0,Qt::AlignLeft); + largeVLayout->setSpacing(5); + largeVLayout->setContentsMargins(50,0,50,5); + largeWidget->setLayout(largeVLayout); +// largeWidget->setFixedHeight(80); + mainVLayout->addWidget(largeWidget); + largeWidget->hide(); +// largeWidget->setFixedHeight(120); +// appTitleWid->setFixedHeight(60) +// this->setLayout(mainVLayout); + AppFrame->setLayout(mainVLayout); + dispalyName = translationVirtualPackage(name); + appNameLab->setText(dispalyName); + if(name.contains("kylin-update-desktop-")||name == "linux-generic") + { + pkgIconPath = QString(":/img/plugins/upgrade/%1.png").arg(name); + appIcon->setPixmap(QPixmap(pkgIconPath)); + } + else{ + if(QIcon::fromTheme(name).hasThemeIcon(name)) //判断是否有主题图标并输出 + { + QIcon icon = QIcon::fromTheme(name); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(32, 32))); + appIcon->setPixmap(pixmap); + } + else + { + QIcon icon = QIcon::fromTheme("application-x-desktop"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(32, 32))); + appIcon->setPixmap(pixmap); + } + } + + QString newStrMsg = appAllMsg.availableVersion; + + if(newStrMsg.size()>16) + { +// appVersion->setText(tr("最新:")+newStrMsg); +// appVersion->setToolTip(tr("最新:")+newStrMsg); + appVersion->setText(tr("Newest:")+newStrMsg); + appVersion->setToolTip(tr("Newest:")+newStrMsg); + } + else + { +// appVersion->setText(tr("最新:")+newStrMsg); + appVersion->setText(tr("Newest:")+newStrMsg); + appVersion->setToolTip(""); + } + + + //获取并输出changelog + chlog = setDefaultDescription(appAllMsg.longDescription); + updatelog1->logContent->append(chlog); + + QTextCursor tmpCursor = updatelog1->logContent->textCursor(); + tmpCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + updatelog1->logContent->setTextCursor(tmpCursor); + +// updatelog1->logAppName->setText(dispalyName+tr("更新日志")); +// updatelog1->logAppVerson->setText(tr("最新:")+appAllMsg.availableVersion); + updatelog1->logAppName->setText(dispalyName+tr("Update log")); + updatelog1->logAppVerson->setText(tr("Newest:")+appAllMsg.availableVersion); + + + QFontMetrics fontWidth(someInfoEdit->font());//得到每个字符的宽度 + QString StrMsg = fontWidth.elidedText(chlog, Qt::ElideRight,600);//最大宽度 + someInfoEdit->append(StrMsg); + if(appAllMsg.msg.allSize == 0) + { + someInfoEdit->append(tr("Download size:")+QString(modifySizeUnit(appAllMsg.packageSize))); +// someInfoEdit->append(tr("下载大小:")+QString(modifySizeUnit(appAllMsg.packageSize))); + } + else + { +// someInfoEdit->append(tr("下载大小:")+QString(modifySizeUnit(appAllMsg.msg.allSize))); + someInfoEdit->append(tr("Download size:")+QString(modifySizeUnit(appAllMsg.msg.allSize))); + } + + if(name.contains("kylin-update-desktop")||name == "linux-generic") + { + pkgIconPath = QString(":/img/plugins/upgrade/%1.png").arg(name); + updatelog1->logAppIcon->setPixmap(QPixmap(pkgIconPath)); + } + else{ + if(QIcon::fromTheme(name).hasThemeIcon(name)) + { + QIcon icon = QIcon::fromTheme(name); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(32, 32))); + updatelog1->logAppIcon->setPixmap(pixmap); + } + else + { + QIcon icon = QIcon::fromTheme("application-x-desktop"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(32, 32))); + updatelog1->logAppIcon->setPixmap(pixmap); + } + } + //获取并输出包大小、当前版本号 + QString currentVersion = appAllMsg.version; + if(currentVersion != "") + { +// someInfoEdit->append(tr("当前版本:")+currentVersion); + someInfoEdit->append(tr("Current version:")+currentVersion); + } + +} + + +void AppUpdateWid::showDetails() +{ + if(largeWidget->isHidden()) + { + largeWidget->show(); +// detaileInfo->setText(tr("收起")); + detaileInfo->setText(tr("back")); + } + else + { + largeWidget->hide(); +// detaileInfo->setText(tr("详情")); + detaileInfo->setText(tr("details")); + } +} + +void AppUpdateWid::showUpdateLog() +{ + QRect availableGeometry = qApp->primaryScreen()->availableGeometry(); + updatelog1->move((availableGeometry.width()-updatelog1->width())/2,(availableGeometry.height()- updatelog1->height())/2); + updatelog1->exec(); +} + +void AppUpdateWid::cancelOrUpdate() +{ + if(updateAPPBtn->isHidden()) + { + return; + } + if(updateAPPBtn->text() == tr("Update")) + { + if(m_updateMutual->isPointOutNotBackup == true) + { + QMessageBox msgBox; +// msgBox.setText(tr("单个更新不会自动备份系统,如需备份,请点击全部更新。")); + msgBox.setText(tr("A single update will not automatically backup the system, if you want to backup, please click Update All.")); + msgBox.setWindowTitle(tr("Prompt information")); + msgBox.setStandardButtons(QMessageBox::YesAll + | QMessageBox::NoToAll|QMessageBox::Cancel); + msgBox.setButtonText(QMessageBox::YesAll,tr("Do not backup, continue to update")); + msgBox.setButtonText(QMessageBox::NoToAll,tr("Cancel")); + msgBox.setButtonText(QMessageBox::Cancel,tr("Cancel update")); + QCheckBox *cb = new QCheckBox(&msgBox); + msgBox.setCheckBox(cb); +// msgBox.checkBox()->setText(tr("本次更新不再提示")); + msgBox.checkBox()->setText(tr("This time will no longer prompt")); + msgBox.checkBox()->show(); + msgBox.button(QMessageBox::Cancel)->hide(); + int ret = msgBox.exec(); + if(msgBox.checkBox()->checkState() == Qt::Checked) + { + m_updateMutual->isPointOutNotBackup = false; + } + if(ret == QMessageBox::YesAll) + { + qDebug() << "立即更新!"; + updateOneApp(); + } + else if(ret == QMessageBox::NoToAll) + { + m_updateMutual->isPointOutNotBackup = true; + qDebug() << "不进行更新。"; + } + else if(ret == QMessageBox::Cancel) + { + qDebug() << "不进行更新。"; + m_updateMutual->isPointOutNotBackup = true; + + } + qDebug() << "m_updateMutual->isPointOutNotBackup = " << m_updateMutual->isPointOutNotBackup; + } + else + { + updateOneApp(); + } + } + else + { + isCancel = true; + downloadProcess->terminate(); + timer->stop(); +// updateAPPBtn->setText("更新"); + updateAPPBtn->setText(tr("Update")); +// appVersion->setText(tr("暂停中")); + appVersion->setText(tr("In the pause")); + appVersion->setToolTip(""); + emit changeUpdateAllSignal(); + } +} + +void AppUpdateWid::updateOneApp() +{ + if(appAllMsg.msg.getDepends == true) + { + if(checkSourcesType() != file){ + isCancel = false; + firstDownload = true; + slotDownloadPackages(); + timer->start(1000); //开启定时器用于计算下载速度 + // updateAPPBtn->setText(tr("取消")); + updateAPPBtn->setText(tr("Cancel")); + appVersionIcon->setPixmap(QPixmap()); + }else{ + startInstall(appAllMsg.name); //本地源直接开始安装 + appVersion->setText(tr("Ready to install")); + } + QDir dir = downloadPath; + if(!dir.isEmpty()){ + appVersion->setText(tr("Calculate the download progress")); + } + } + else + { + updateAPPBtn->hide(); +// appVersion->setText(tr("获取依赖失败!")); + appVersion->setText(tr("Get depends failed!")); + appVersion->setToolTip(""); + QIcon icon = QIcon::fromTheme("dialog-error"); + QPixmap pixmap = icon.pixmap(icon.actualSize(QSize(14, 14))); + appVersionIcon->setPixmap(pixmap); + m_updateMutual->importantList.removeOne(appAllMsg.name); + m_updateMutual->failedList.append(appAllMsg.name); + QString message = QString("%1"+tr("Get depends failed!")).arg(dispalyName); + m_updateMutual->onRequestSendDesktopNotify(message); + emit hideUpdateBtnSignal(false); + } +} +//转换包大小的单位 +QString AppUpdateWid::modifySizeUnit(long size) +{ + double tmpSize = size/1024.0; + if(tmpSize >= 1) + { + if((tmpSize/1024.0) >= 1) + { + if((tmpSize/1024.0/1024.0) >= 1) + return QString("%1%2").arg((int)(tmpSize/1024.0/1024.0*100 + 0.5)/100.0).arg("GB");//保留小数点后两位,并四舍五入 + else + return QString("%1%2").arg((int)(tmpSize/1024.0*100 + 0.5)/100.0).arg("MB");//保留小数点后两位,并四舍五入 + } + else + return QString("%1%2").arg((int)(tmpSize*100 + 0.5)/100.0).arg("KB");//保留小数点后两位,并四舍五入 + } + else + return QString("%1%2").arg(size).arg("B"); +} + +//当前下载速度单位换算 +QString AppUpdateWid::modifySpeedUnit(long size, float time) +{ + if(size < 0) + size = 0; + size = size/time; + if((size/1024) >= 1) + { + if((size/1024/1024) >= 1) + { + if((size/1024/1024/1024) >= 1) + return QString("%1%2").arg((int)(size/1024/1024/1024)).arg("GB/S"); + else + return QString("%1%2").arg((int)(size/1024/1024)).arg("MB/S"); + } + else + return QString("%1%2").arg((int)(size/1024)).arg("KB/S"); + } + else + return QString("%1%2").arg(size).arg("B/S"); +} + +void AppUpdateWid::showDownloadStatues(QString downloadSpeed, int progress) +{ +// appVersion->setText(tr("更新中")+"("+downloadSpeed+")"+QString::number(progress)+"%"); + appVersion->setText(tr("In the update")+"("+downloadSpeed+")"+QString::number(progress)+"%"); +// appVersion->setToolTip(tr("更新中")+"("+downloadSpeed+")"+QString::number(progress)+"%"); + appVersion->setToolTip(""); +} + + +//定时器触发计算当前下载速度和下载进度 +void AppUpdateWid::calculateSpeedProgress() +{ + QFile tmpFile(QString("%1%2").arg(downloadPath).arg(currentPackage)); + if(tmpFile.exists()) + { + if(!downloadFinish) + downSize = priorSize + tmpFile.size(); + else + downSize = priorSize; + QString speed = modifySpeedUnit(downSize-preDownSize, 1); + int progress = (int)((downSize*100/appAllMsg.msg.allSize)); + qDebug() << "priorsize:" << priorSize + << "predownsize" << preDownSize + << "tmpsize" << tmpFile.size() + << "downsize" << downSize + << "allsize" << appAllMsg.msg.allSize + << "progress:" << progress + << "speed" << speed + << "name" << currentPackage; + preDownSize = downSize; + showDownloadStatues(speed,progress); + if(downSize == appAllMsg.msg.allSize) //确保完全下载完成后再停止定时器 + { + qDebug() << "dowload over:" << priorSize; + timer->stop(); + m_updateMutual->copyFinsh(downloadPackages, appAllMsg.name); + if(m_updateMutual->fileLock() != false) + { + emit filelockedSignal(); + } +// appVersion->setText(tr("准备安装")); + appVersion->setText(tr("Ready to install")); + appVersion->setToolTip(""); + } + } +} + +void AppUpdateWid::updateAllApp() +{ +// qDebug() << "updateAllApp"; + if(isCancel && m_updateMutual->failedList.indexOf(appAllMsg.name) == -1) + { + qDebug() << "全部更新信号发出,当前: " << appAllMsg.name; + cancelOrUpdate(); + } +} + +void AppUpdateWid::showUpdateBtn() +{ + + updateAPPBtn->show(); +// updateAPPBtn->setText(tr("更新")); + updateAPPBtn->setText(tr("Update")); + +} +void AppUpdateWid::hideOrShowUpdateBtnSlot(int result) +{ + if(result == 0) //0表示备份还原开始 + { + updateAPPBtn->hide(); + } + else if(result == 99 ||result == -20) //99时备份成功 -20时备份还原进程被中断 + { + updateAPPBtn->show(); + } + +} + +QString AppUpdateWid::translationVirtualPackage(QString str) +{ + if(QLocale::system().name()!="zh_CN") + return str; + if(str == "kylin-update-desktop-app") + return "基本应用"; + if(str == "kylin-update-desktop-security") + return "安全更新"; + if(str == "kylin-update-desktop-support") + return "系统基础组件"; + if(str == "kylin-update-desktop-ukui") + return "桌面环境组件"; + if(str == "linux-generic") + return "系统内核组件"; + if(str == "kylin-update-desktop-kernel") + return "系统内核组件"; + if(str == "kylin-update-desktop-kernel-3a4000") + return "系统内核组件"; + if(str == "kylin-update-desktop-kydroid") + return "kydroid补丁包"; + return str; +} +bool AppUpdateWid::eventFilter(QObject *watched, QEvent *event) +{ + if(watched->metaObject()->className() == QStringLiteral("QLabel")) + { + if(event->type() == QEvent :: ToolTip){ + QToolTip::hideText(); + event->ignore(); + return true; + } + else + { + return false; + } + } +} + +QString AppUpdateWid::setDefaultDescription(QString str) +{ + if(str == "") + { +// str = tr("暂无内容"); + str = tr("No content."); + } + return str; +} + +type AppUpdateWid::checkSourcesType() +{ + QFile soucesFile(SOURCESLIST); + soucesFile.open(QIODevice::ReadOnly | QIODevice::Text); + QString result = soucesFile.readAll(); + if(result.contains("http://")){ + qDebug() << "当前源为http源"; + return http; + }else if(result.contains("ftp://")){ + qDebug() << "当前源为ftp源"; + return ftp; + }else if(result.contains("file://")){ + qDebug() << "当前源为本地源"; + return file; + } +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/appupdate.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/appupdate.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/appupdate.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/appupdate.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,126 @@ +#ifndef APPUPDATE_H +#define APPUPDATE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" +#include "updatelog.h" +#include +#include +#include "updatedbus.h" +#include +#include "mylabel.h" +class UpdateLog; +//class UpdateDbus; +class AppUpdateWid : public QWidget +{ + Q_OBJECT +public: + explicit AppUpdateWid(AppAllMsg msg, QWidget *parent = nullptr); + ~AppUpdateWid(); + + QFrame *AppFrame; + UpdateLog *updatelog1; + //缩略界面 + QLabel *appIcon; + QLabel *appIconName; + MyLabel *appNameLab; + QLabel *appVersion; + QLabel *appVersionIcon; + + QLabel *progressLab; //进度 + QLabel *otherBtnLab; + QPushButton *detaileInfo; + QPushButton *updateAPPBtn; + QWidget *appTitleWid; + QHBoxLayout *iconNameLayout; + QHBoxLayout *smallHLayout; + QVBoxLayout *largeVLayout; + QHBoxLayout *otherBtnLayout; + QWidget *largeWidget; + QVBoxLayout *mainVLayout; + //展开界面 + QTextEdit *someInfoEdit; //详情内容 + QPushButton *updatelogBtn; +// AppMsg *thisAppMessage; + QString chlog; //更新日志完整内容 + bool eventFilter(QObject *watched, QEvent *event); //过滤tooltip事件 + QString setDefaultDescription(QString str); //将虚包包名汉化 + void updateOneApp(); //控制更新单个app + QString dispalyName; +private: + bool isCancel = true; + bool firstDownload = true; + long downSize = 0; + long preDownSize = 0; + long priorSize = 0; + int connectTimes = 0; + bool downloadFinish = false; + bool stopTimer = false; + UrlMsg urlmsg; + QString path; + QString currentPackage; + QStringList downloadList; + QStringList downloadPackages; + AppAllMsg appAllMsg; + QProcess *downloadProcess; + QProcess *workProcess; + QTimer *timer; + QString downloadPath; + UpdateDbus *m_updateMutual; + +public slots: + void showDetails(); + void showUpdateLog(); + void cancelOrUpdate(); + + void showInstallStatues(QString status, QString appAptName, float progress, QString errormsg); + void showDownloadStatues(QString downloadSpeed, int progress); + + void slotDownloadPackages(); + void calculateSpeedProgress(); //计算下载速度和进度 + void startInstall(QString appName); + void updateAllApp(); + + void showUpdateBtn(); + void hideOrShowUpdateBtnSlot(int result); //显示或隐藏更新按钮 备份过程中 +private: + void wgetDownload(UrlMsg msg, QString path); //断点续传下载 + bool getDownloadSpeed(QString appName, QString fullName, int fileSize); //获取下载速度 + void initConnect(); //初始化信号槽 + void changeDownloadState(int state); + type checkSourcesType(); + QString modifySizeUnit(long size); + QString modifySpeedUnit(long size, float time); + QStringList analysis_config_file(char *p_file_path); + void remove_last_enter(char *p_src_in_out); + + enum Environment{ + en, + zh_cn + }environment; + +signals: + void startWork(QString appName); + void startMove(QStringList list, QString appName); + void hideUpdateBtnSignal(bool isSucceed); + void changeUpdateAllSignal(); + void downloadFailedSignal(int exitCode); //网络异常或者其他情况下下载失败时 + void filelockedSignal(); + void cancel(); + + +// void aptFinish(); +private: + void updateAppUi(QString name); + QString translationVirtualPackage(QString str); + QString pkgIconPath = ""; +}; + +#endif // APPUPDATE_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/backup.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/backup.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/backup.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/backup.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,227 @@ +#include "backup.h" +#include +#include +#include + +#define TIMESTAMP_PATH "/var/lib/kylin-software-properties/template/kylin-source-status" +#define TIMESTAMP_TAB "UpdateTime=" +#define BACKINFO_STATE "0" + +#define BACKUP_DBUS_SERVICE "com.kylin.backup" +#define BACKUP_DBUS_PATH "/" +#define BACKUP_DBUS_INTERFACE "com.kylin.backup.manager" + +#define BACKUP_PATH "/usr/bin/kybackup" + +const int needBack = int(backuptools::backup_state::BACKUP_STATE_INIT); + +BackUp::BackUp(QObject *parent) : QObject(parent) +{ +// interface = new QDBusInterface(BACKUP_DBUS_SERVICE,BACKUP_DBUS_PATH, BACKUP_DBUS_INTERFACE,QDBusConnection::systemBus()); +// connect(interface,SIGNAL(sendRate(int,int)),this,SLOT(sendRate(int,int))); +// watcher = new QDBusServiceWatcher(BACKUP_DBUS_SERVICE,QDBusConnection::systemBus(),QDBusServiceWatcher::WatchForOwnerChange,this); +// connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged,this, &BackUp::onDBusNameOwnerChanged); +} + +void BackUp::onDBusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner) +{ + Q_UNUSED(oldOwner); + + if (name == BACKUP_DBUS_SERVICE) { + if (newOwner.isEmpty()) { + qWarning() << "麒麟备份还原工具被中断"; + emit bakeupFinish(-20); + } else { + qWarning() << "麒麟备份还原工具被重启"; + } + //Q_EMIT serviceStatusChanged(!newOwner.isEmpty()); + } +} + +void BackUp::creatInterface() +{ + interface->deleteLater(); + interface = new QDBusInterface(BACKUP_DBUS_SERVICE,BACKUP_DBUS_PATH, BACKUP_DBUS_INTERFACE,QDBusConnection::systemBus()); + connect(interface,SIGNAL(sendRate(int,int)),this,SLOT(sendRate(int,int))); +#if 0 + connect(interface, SIGNAL(sendStartBackupResult(int)), this, SIGNAL(bakeupFinish(int))); +#else + connect(interface, SIGNAL(sendStartBackupResult(int)), this, SLOT(receiveStartBackupResult(int))); +#endif + + watcher->deleteLater(); + watcher = new QDBusServiceWatcher(BACKUP_DBUS_SERVICE,QDBusConnection::systemBus(),QDBusServiceWatcher::WatchForOwnerChange,this); + connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged,this, &BackUp::onDBusNameOwnerChanged); +} + +int BackUp::needBacdUp() +{ + //构造dbus对象 + creatInterface(); + //备份工具是否存在 + QFileInfo file(BACKUP_PATH); + if(!file.exists()) + return -9; + //备份工具是否可用 + if(!haveBackTool()) + return -1; + if (m_isActive) { + //正在备份 + if(bakeupState==int(backuptools::backup_state::FULL_BACKUP_SYSUPDATE) || bakeupState==int(backuptools::backup_state::INC_BACKUP_SYSUPDATE)) + return 1; + //备份工具占用 + if(bakeupState!=needBack) + return -2; + } + //获取时间戳 + if(!readSourceManagerInfo()) + return -3; + //比对上次备份时间戳 + if(!readBackToolInfo()) + return -4; + return needBack; +} + +void BackUp::sendRate(int sta,int pro) +{ + if (sta == int(backuptools::backup_state::DU_ING)) { + emit calCapacity(); + return; + } + if(!setProgress) + return; + qDebug()<<"状态码:"< argumentList; + argumentList << QVariant::fromValue(timeStamp) << QVariant::fromValue(create_note) << QVariant::fromValue(inc_note) + << QVariant::fromValue(userName) << QVariant::fromValue(uid); + interface->asyncCallWithArgumentList(QStringLiteral("autoBackUpForSystemUpdate_noreturn"), argumentList); + } +} + +bool BackUp::haveBackTool() +{ + if(interface==nullptr) + { + qDebug()<<"dbus对象未实例化"; + return false; + } +// if(!interface->isValid()) +// { +// qDebug()<<"未创建备份还原分区"; +// return false; +// } + QDBusPendingReply reply = interface->call("getBackupState"); + if(!reply.isValid()) + { + qDebug()<<"备份还原接口异常"; + return false; + } + bakeupState = reply.argumentAt(0).toInt(); + m_isActive = reply.argumentAt(1).toBool(); + return true; +} + +bool BackUp::readSourceManagerInfo() +{ + QFile file(TIMESTAMP_PATH); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + qDebug()<<"读取源管理器配置文件失败"; + return false; + } + while (!file.atEnd()) { + QString line = file.readLine(); + if(line.contains(TIMESTAMP_TAB,Qt::CaseSensitive)) + { + line=line.replace("\n",""); + line=line.replace(TIMESTAMP_TAB,""); + bool ok; + uint time = line.toUInt(&ok); + if(!ok) + { + file.close(); + qDebug()<<"源管理器配置文件不合规"; + return false; + } + QDateTime datetime = QDateTime::fromTime_t(time); + QString filename = "自动备份:"+datetime.toString("yyyy-MM-dd hh:mm:ss")+"("+line+")"; + timeStamp = filename; + break; + } + } + file.close(); + if(timeStamp=="") + { + qDebug()<<"源管理器配置文件不合规"; + return false; + } + + qDebug()<<"读取源管理器配置文件成功"; + return true; +} + +bool BackUp::readBackToolInfo() +{ + QDBusMessage msg = interface->call("getBackupCommentForSystemUpdate"); + QVariantList list = msg.arguments(); + if(list.length()<2) + { + qDebug()<<"备份还原接口异常"; + } + if(list.at(0).toString()!=timeStamp) + { + qDebug()<<"未找到相同版本备份镜像,需要备份"; + return true; + } + qDebug()<<"找到相同版本镜像"; + if(list.at(1).toString() == "0") + { + qDebug()<<"已存在相同版本备份镜像,无需备份"; + return false; + } + return true; +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/backup.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/backup.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/backup.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/backup.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,48 @@ +#ifndef BACKUP_H +#define BACKUP_H + +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include + +class BackUp : public QObject +{ + Q_OBJECT +public: + explicit BackUp(QObject *parent = nullptr); + +signals: + void backupStartRestult(int); + bool calCapacity(); + void bakeupFinish(int); + void backupProgress(int); +public slots: + int needBacdUp(); + void startBackUp(int); + +private slots: + void sendRate(int,int); + void receiveStartBackupResult(int result); + +private: + QString timeStamp =""; + int bakeupState = 0; + bool m_isActive = false; + bool haveBackTool(); + bool readSourceManagerInfo(); + bool readBackToolInfo(); + QDBusInterface *interface = nullptr; + QDBusServiceWatcher *watcher = nullptr; + void onDBusNameOwnerChanged(const QString &name,const QString &oldOwner,const QString &newOwner); + bool setProgress = false; + void creatInterface(); +}; + +#endif // BACKUP_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/checkbutton.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/checkbutton.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/checkbutton.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/checkbutton.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,52 @@ +#include "checkbutton.h" +#include + +m_button::m_button(QWidget *parent) : QPushButton(parent) +{ + m_cTimer = new QTimer(this); + states =true; + m_cTimer->setInterval(140);//设置动画速度 + buttonshow(); + +} + +void m_button::buttonshow() +{ + //通过定时器实现循环插入载入图片 + connect(m_cTimer,&QTimer::timeout, [this] () { + QIcon icon; + QString str = QString(":/img/plugins/upgrade/loading%1.svg").arg(i); + icon.addFile(str); + this->setIcon(icon); + i--; + if(i==9){ + i=17; + } + }); +} + +void m_button::start() +{ + this->setText(""); + m_cTimer->start(); + states = false; +} + +void m_button::stop() +{ + QIcon icon; + this->setIcon(icon); + m_cTimer->stop(); + states = true; +} + +void m_button::buttonswitch() +{ + //两态开关,实现一个按钮开始暂停功能 + qDebug()< +#include +#include + +class m_button : public QPushButton +{ + Q_OBJECT +public: + m_button(QWidget *parent = nullptr); + QTimer *m_cTimer; + int i = 17;//初始化从17图片开始 + bool states; + + void start(); + + void stop(); + + void buttonshow(); + + void buttonswitch(); + + +signals: + +}; +#endif // CHECKBUTTON_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/connection.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/connection.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/connection.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/connection.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,48 @@ +#ifndef CONNECTION_H +#define CONNECTION_H +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static bool CreatConnection() +{ + QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE","A"); + QString dirPath = QString("/var/cache/kylin-update-manager"); + QString dbPath = QString("%1/kylin-update-manager.db").arg(dirPath); + QDir dir(dirPath); + if(!dir.exists()) + { + dir.mkpath(dirPath); + } + QFile file(dbPath); + if(!file.exists()) + { + QFile::copy("/usr/share/kylin-update-manager/kylin-update-manager.db", dbPath); + } + db1.setDatabaseName(dbPath); + if (!db1.open()) { + qDebug()<<"更新管理器数据库打开失败."; + return false; + } + qDebug()<<"更新管理器数据库打开成功."; + + /* 获取软件商店数据库链接 */ + QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE" , "B"); + db2.setDatabaseName(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.cache/uksc/uksc.db"); + if (!db2.open()) { + qDebug() << "Error : open software database fail"; + return false; + } + + qDebug() << "open software center database success!"; + + return true; +} + +#endif // CONNECTION_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/daemonipcdbus.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/daemonipcdbus.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/daemonipcdbus.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/daemonipcdbus.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "daemonipcdbus.h" + +int DaemonIpcDbus::daemonIsNotRunning() +{ + char service_name[SERVICE_NAME_SIZE]; + memset(service_name, 0, SERVICE_NAME_SIZE); + snprintf(service_name, SERVICE_NAME_SIZE, "%s_%d",KYLIN_USER_GUIDE_SERVICE,getuid()); + QDBusConnection conn = QDBusConnection::sessionBus(); + if (!conn.isConnected()) + return -1; + + QDBusReply reply = conn.interface()->call("GetNameOwner", service_name); + return reply.value() == ""; +} + +void DaemonIpcDbus::showGuide(QString appName) +{ + qDebug() << Q_FUNC_INFO << appName; + bool bRet = false; + + char service_name[SERVICE_NAME_SIZE]; + memset(service_name, 0, SERVICE_NAME_SIZE); + snprintf(service_name, SERVICE_NAME_SIZE, "%s_%d",KYLIN_USER_GUIDE_SERVICE,getuid()); + + qDebug() << "service_name " << service_name; + // 用来构造一个在D-Bus上传递的Message + QDBusMessage m = QDBusMessage::createMethodCall(QString(service_name),KYLIN_USER_GUIDE_PATH,KYLIN_USER_GUIDE_INTERFACE,"showGuide"); + // 给QDBusMessage增加一个参数; + // 这是一种比较友好的写法,也可以用setArguments来实现 + m << appName; + + // 发送Message + QDBusMessage response = QDBusConnection::sessionBus().call(m); + // 判断Method是否被正确返回 + if (response.type()== QDBusMessage::ReplyMessage) + { + // QDBusMessage的arguments不仅可以用来存储发送的参数,也用来存储返回值; +// bRet = response.arguments().at(0).toBool(); + } + else { + qDebug()<<"showGuide In fail!\n"; + } + + qDebug()<<"bRet:"<. + */ + +#ifndef DAEMONIPCDBUS_H +#define DAEMONIPCDBUS_H + +#define KYLIN_USER_GUIDE_PATH "/" + +#define KYLIN_USER_GUIDE_SERVICE "com.kylinUserGuide.hotel" + +#define KYLIN_USER_GUIDE_INTERFACE "com.guide.hotel" + +#define SERVICE_NAME_SIZE 30 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class DaemonIpcDbus : public QObject +{ + Q_OBJECT + // 定义Interface名称为com.scorpio.test.value + // Q_CLASSINFO("D-Bus Interface", "com.scorpio.test.value") +public: + + DaemonIpcDbus() {} + +public slots: + + int daemonIsNotRunning(); + void showGuide(QString appName); + +}; + +/* +// 使用方法 +DaemonIpcDbus *mDaemonIpcDbus; +mDaemonIpcDbus = new DaemonIpcDbus(); +if (!mDaemonIpcDbus->daemonIsNotRunning()){ + //增加标题栏帮助菜单、F1快捷键打开用户手册 + mDaemonIpcDbus->showGuide("kylin-ipmsg"); +} +*/ + +#endif // DAEMONIPCDBUS_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/historyupdatelistwig.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/historyupdatelistwig.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/historyupdatelistwig.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/historyupdatelistwig.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,153 @@ +#include "historyupdatelistwig.h" + +const QString FIND_DES_LABLE_TYPE = "FIND_DES_LABLE_TYPE";//历史更新模块标签 +const QString IS_SELECT = "IS_SELECT";//历史更新模块标签 +const int WIDTH = 236 - 2; +const int LINE_SPACING = 2; +const int TOP_MARGIN = 5;//上(下)边距 +const int RIGHT_MARGIN = 3;//右边距 +const int LEFT_MARGIN = 9;//左边距文字和lable本身有边距 + +HistoryUpdateListWig::HistoryUpdateListWig() +{ + initUI(); +} +HistoryUpdateListWig::~HistoryUpdateListWig() +{ + debName->deleteLater(); + debStatue->deleteLater(); + hl1->deleteLater(); + hl2->deleteLater(); + vl1->deleteLater(); +} +void HistoryUpdateListWig::initUI() +{ +// font.setPointSize(14);//字体大小 + font.setBold(true); + + //窗口初始化 + this->setFrameStyle(QFrame::Box); + + //实例化控件 + debName = new QLabel; + debStatue = new QLabel; + + //初始化控件 + debName->setWordWrap(true); + debName->setFixedWidth(WIDTH - LEFT_MARGIN - LEFT_MARGIN); + debName->setFont(font); + debStatue->setWordWrap(true); + debStatue->setFixedWidth(WIDTH - LEFT_MARGIN - LEFT_MARGIN); + + //实例化布局 + hl1 = new QHBoxLayout; + hl2 = new QHBoxLayout; + vl1 = new QVBoxLayout; + + //初始化布局 + hl1->setSpacing(0); + hl1->setMargin(0); + hl2->setSpacing(0); + hl2->setMargin(0); + vl1->setSpacing(0); + vl1->setMargin(0); + + //布局 + hl1->addSpacing(LEFT_MARGIN); + hl1->addWidget(debName); + hl1->addSpacing(RIGHT_MARGIN); + hl2->addSpacing(LEFT_MARGIN); + hl2->addWidget(debStatue); + hl2->addSpacing(RIGHT_MARGIN); + vl1->addSpacing(TOP_MARGIN); + vl1->addLayout(hl1); + vl1->addLayout(hl2); + vl1->addSpacing(TOP_MARGIN); + this->setLayout(vl1); + this->layout()->setSizeConstraint(QLayout::SetFixedSize); +} + +void HistoryUpdateListWig::setAttribute(const QString &mname,const QString &mstatue,const QString &mtime,const QString &mdescription,const int &myid) +{ + debName->setText(mname); + debDescription=mdescription; + QString str = ""; + if(mstatue == "Success") + str=tr("Success"); //更新成功 + else + str=tr("Failed"); //更新失败 + str+=" "+mtime; + debStatue->setText(str); + id = myid; +} + +QSize HistoryUpdateListWig::getTrueSize() +{ + QSize lsize =this->layout()->sizeHint(); + //lsize.setHeight(lsize.rheight()+LINE_SPACING*2); + return lsize; +} + +//鼠标 点击 +void HistoryUpdateListWig::mousePressEvent(QMouseEvent * e) +{ + if(e->button() == Qt::LeftButton) + { + setDescription(); + selectStyle(); + } + if(e->button() == Qt::RightButton) + { + clearStyleSheet(); + } + +} + +void HistoryUpdateListWig::selectStyle() +{ + //如果上次选中的也是自身 + if(this->statusTip()==IS_SELECT) + return; + //清除其他item选中样式及标签 + QList list = this->parent()->findChildren(); + for(HistoryUpdateListWig *tmp : list) + { + if(tmp->statusTip()==IS_SELECT) + { + tmp->clearStyleSheet(); + } + } + //设置选中样式及标签 + debName->setStyleSheet("color:#fff;"); + debStatue->setStyleSheet("color:#fff;"); + this->setStyleSheet("QFrame{background-color:rgba(55, 144, 250, 1);border-radius:4px}"); + this->setStatusTip(IS_SELECT); + //详细内容 + setDescription(); +} + +void HistoryUpdateListWig::clearStyleSheet() +{ + debName->setStyleSheet(""); + debStatue->setStyleSheet(""); + this->setStyleSheet(""); + this->setStatusTip(""); +} + +void HistoryUpdateListWig::setDescription() +{ + QObject *findwig = this->parent(); + while(findwig != nullptr) + { + if(findwig->objectName()==FIND_DES_LABLE_TYPE) + { + break; + } + findwig = findwig->parent(); + } + QTextEdit *dsc = findwig->findChild(FIND_DES_LABLE_TYPE,Qt::FindChildrenRecursively); + if(dsc==nullptr) + qDebug()<<"找不到要赋值的窗口"; + else + dsc->setText(debDescription); +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/historyupdatelistwig.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/historyupdatelistwig.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/historyupdatelistwig.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/historyupdatelistwig.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,38 @@ +#ifndef HISTORYUPDATELISTWIG_H +#define HISTORYUPDATELISTWIG_H + +#include +#include +#include +#include +#include +#include +#include + +class HistoryUpdateListWig : public QFrame +{ + Q_OBJECT +public: + HistoryUpdateListWig(); + ~HistoryUpdateListWig(); + void setAttribute(const QString &mname, const QString &mstatue, const QString &mtime, const QString &mdescription, const int &myid);//赋值 + QSize getTrueSize();//获取真实大小 + void selectStyle();//选中样式 + void clearStyleSheet();//取消选中样式 + int id = 0; +protected: + void mousePressEvent(QMouseEvent * event); +private: + QHBoxLayout *hl1 = nullptr; + QHBoxLayout *hl2 = nullptr; + QVBoxLayout *vl1 = nullptr; + QLabel *debName = nullptr;//app名字&版本号 + QLabel *debStatue = nullptr;//更新状态 + QString debDescription = "";//描述 + //int code = 0 ;//编码 + void initUI();//初始化UI + void setDescription();//赋值事件 + QFont font; +}; + +#endif // HISTORYUPDATELISTWIG_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/metatypes.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/metatypes.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/metatypes.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/metatypes.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,9 @@ +#ifndef METATYPES_H +#define METATYPES_H + +#include + +typedef QMap CustomData; +Q_DECLARE_METATYPE(CustomData); + +#endif // METATYPES_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/m_updatelog.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/m_updatelog.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/m_updatelog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/m_updatelog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,320 @@ +#include "m_updatelog.h" +//#include +//#include + +const QString FIND_DES_LABLE_TYPE = "FIND_DES_LABLE_TYPE";//历史更新模块标签 +const int WIDTH = 680;//窗口宽度 +const int HEIGHT = 604 -40;//窗口高度 注:QFram实际高度比setFixedSize指定的高度高40像素,故减去40 +const int LINE_SPACING = 2;//行间距 +const int TOP_MARGIN = 18;//上边距 +const int BOTTOM_MARGIN = 24;//下边距 +const int LEFT_MARGIN = 32;//左(右)边距 + +const int LIST_LEFT = 8;//列表对于其背景,左侧边距 +const int LIST_TOP = 8;//列表对于其背景,顶(底)部边距 +const int LIST_BACKGROUND_WIDTH = 260 + 6;//列表背景宽度 +const int SLIDER_WIDTH = 6;//滑块宽度 +//const int LIST_WIDTH = LIST_BACKGROUND_WIDTH - LIST_LEFT*2 + SLIDER_WIDTH;//列表宽度 +//const int LIST_HEIGHT = 524 - LIST_TOP*2;//列表高度 + +const int TEXT_TAB_LEFT = 16;//更新详情lable对于其背景,左侧边距 +const int TEXT_TAB_RIGHT = 2;//更新详情lable对于其背景,左侧边距 +const int TEXT_DSC_LEFT_SPACING = 5;//QTextEdit左侧有边距 +const int TEXT_TAB_TOP = 17;//更新详情lable对于其背景,顶部边距 +const int TEXT_TAB_SPACING = 18;//更新详情lable对于内容框的间距 + +const QString OBJECT_NAME = "OBJECT_NAME"; + +m_updatelog * m_updatelog::m_instance(nullptr); + +m_updatelog::m_updatelog(QWidget* parent) : QDialog(parent) +{ + initUI();//初始化UI + initGsettings();//初始化Gsettings + dynamicLoadingInit();//动态加载 + updatesql();//更新列表 + defaultItem();//设置默认选中 + //监听更新完成信号 + UpdateDbus *uddbus = UpdateDbus::getInstance(); + connect(uddbus->interface,SIGNAL(update_sqlite_signal(QString,QString)),this,SLOT(historyUpdateNow(QString,QString))); +} + +QString m_updatelog::setDefaultDescription(QString str) +{ + if(str == "") + str = tr("No content."); //暂无内容 + return str; +} + +m_updatelog * m_updatelog::GetInstance(QWidget *parent) +{ + if(m_instance==nullptr) + { + m_instance = new m_updatelog(parent); + return m_instance; + } + if(m_instance->isHidden()) + { + m_instance->deleteLater(); + m_instance = new m_updatelog(parent); + } + return m_instance; +} + +void m_updatelog::closeUpdateLog() +{ + m_instance->close(); + m_instance->deleteLater(); +} + +void m_updatelog::initUI() +{ + QFont font; +// font.setPointSize(34);//字体大小 + font.setBold(true); + + //初始化窗口属性 + this->setWindowTitle(tr("History Log")); //历史更新 + this->setFixedSize(WIDTH,HEIGHT); + this->setObjectName(FIND_DES_LABLE_TYPE); + //this->setAttribute(Qt::WA_DeleteOnClose); + + //实例化控件 + QFrame *listBackground = new QFrame; + QFrame *desBackground = new QFrame; + mainListwidget = new QListWidget; + QLabel *updateDesTab = new QLabel; + des = new QTextEdit; + + //初始化控件 + updateDesTab->setFont(font); + + QPalette palette = mainListwidget->palette(); + palette.setBrush(QPalette::Base, QColor (0, 0 , 0, 0)); + mainListwidget->setPalette(palette); + mainListwidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); //滑块平滑滚动 + mainListwidget->verticalScrollBar()->setProperty("drawScrollBarGroove" , false); + mainListwidget->setSpacing(2); + + QPalette palette2 = des->palette(); + palette2.setBrush(QPalette::Base, QColor (0, 0 , 0, 0)); + des->verticalScrollBar()->setProperty("drawScrollBarGroove" , false); + des->setPalette(palette2); + des->setReadOnly(true); + des->setObjectName(FIND_DES_LABLE_TYPE); + + listBackground->setFrameStyle(QFrame::Box); + listBackground->setFixedWidth(LIST_BACKGROUND_WIDTH); + + desBackground->setFrameStyle(QFrame::Box); + + updateDesTab->setText(tr("Update Details")); //更新详情 + + //布局 + QHBoxLayout *hl1 = new QHBoxLayout; + hl1->setSpacing(0); + hl1->setMargin(0); + hl1->addSpacing(LEFT_MARGIN); + hl1->addWidget(listBackground); + hl1->addSpacing(LINE_SPACING); + hl1->addWidget(desBackground); + hl1->addSpacing(LEFT_MARGIN); + QVBoxLayout *vl1 = new QVBoxLayout; + vl1->setSpacing(0); + vl1->setMargin(0); + vl1->addSpacing(TOP_MARGIN); + vl1->addLayout(hl1); + vl1->addSpacing(BOTTOM_MARGIN); + this->setLayout(vl1); + + hll = new QHBoxLayout; + hll->setSpacing(0); + hll->setMargin(0); + hll->addSpacing(LIST_LEFT); + hll->addWidget(mainListwidget); + //hll->addWidget(mainListwidget->verticalScrollBar()); + QVBoxLayout *vll = new QVBoxLayout; + vll->setSpacing(0); + vll->setMargin(0); + vll->addSpacing(LIST_TOP); + vll->addLayout(hll); + vll->addSpacing(LIST_TOP); + listBackground->setLayout(vll); + + QHBoxLayout *hlrt = new QHBoxLayout; + hlrt->setSpacing(0); + hlrt->setMargin(0); + hlrt->addSpacing(TEXT_DSC_LEFT_SPACING); + hlrt->addWidget(updateDesTab); + QVBoxLayout *vlr = new QVBoxLayout; + vlr->setSpacing(0); + vlr->setMargin(0); + vlr->addSpacing(TEXT_TAB_TOP); + vlr->addLayout(hlrt); + vlr->addSpacing(TEXT_TAB_SPACING); + vlr->addWidget(des); + vlr->addSpacing(TEXT_TAB_TOP); + QHBoxLayout *hlr = new QHBoxLayout; + hlr->setSpacing(0); + hlr->setMargin(0); + hlr->addSpacing(TEXT_TAB_LEFT - TEXT_DSC_LEFT_SPACING); + hlr->addLayout(vlr); + hlr->addSpacing(TEXT_TAB_RIGHT); + desBackground->setLayout(hlr); +} + +void m_updatelog::initGsettings() +{ + timer = new QTimer; + timer->setSingleShot(true); + connect(timer,&QTimer::timeout,this,&m_updatelog::changeListWidgetItemHeight); + const QByteArray iid(THEME_QT_SCHEMA); + qtSettings = new QGSettings(iid, QByteArray(), this); + + connect(qtSettings,&QGSettings::changed,this,[=] (const QString &key) { + if(key == "systemFontSize") { + timer->start(100); + } + }); +} + +void m_updatelog::changeListWidgetItemHeight() +{ + if(mainListwidget->count()<1) + return; + int row=0; + while(row<(mainListwidget->count())) + { + QListWidgetItem * item = mainListwidget->item(row); + HistoryUpdateListWig * hulw = qobject_cast(mainListwidget->itemWidget(item)); + item->setSizeHint(hulw->getTrueSize()); + row++; + } +} + +void m_updatelog::updatesql( const int &start,const int &num,const QString &intop) +{ + //sql 拼接 + QString sqlCmd = "SELECT * FROM installed"; + if(intop!="") + sqlCmd+=" where `time` = '"+intop+"'"; + else if(start>0) + sqlCmd+=" where `id` < "+QString::number(start); + sqlCmd+=" order by `id` desc limit "; + sqlCmd+=QString::number(num); + //载入数据库数据 + QSqlQuery query(QSqlDatabase::database("A")); + query.exec(sqlCmd); + while(query.next()){ + QString statusType = query.value("keyword").toString(); + if(statusType!=""&&statusType!="1") + continue; + HistoryUpdateListWig *hulw = new HistoryUpdateListWig(); + hulw->setAttribute(translationVirtualPackage(query.value("appname").toString())+" "+query.value("version").toString(), + query.value("statue").toString(), + query.value("time").toString(), + setDefaultDescription(query.value("description").toString()), + query.value("id").toInt()); + QListWidgetItem *item = new QListWidgetItem(); + item->setFlags(Qt::NoItemFlags); + item->setSizeHint(hulw->getTrueSize()); + if(intop!="") + { + if(hulw->id<=firstCode) + { + hulw->deleteLater(); + delete item; + item = nullptr; + return; + } + firstCode=hulw->id; + mainListwidget->insertItem(0,item); + } + else + { + loadingCode = hulw->id;//记录加载到哪个位置 + mainListwidget->addItem(item); + } + mainListwidget->setItemWidget(item,hulw); + if(intop!="") + hulw->selectStyle();//设置选中样式 + } +} + +void m_updatelog::defaultItem() +{ + //默认选中第一个 + HistoryUpdateListWig *first = mainListwidget->findChild(); + if(first!=nullptr) + { + first->selectStyle();//设置选中样式 + firstCode = first->id;//记录id + } +} + +QString m_updatelog::translationVirtualPackage(QString str) +{ + if(QLocale::system().name()!="zh_CN") + return str; + if(str == "kylin-update-desktop-app") + return "基本应用"; + if(str == "kylin-update-desktop-security") + return "安全更新"; + if(str == "kylin-update-desktop-support") + return "系统基础组件"; + if(str == "kylin-update-desktop-ukui") + return "桌面环境组件"; + if(str == "linux-generic") + return "系统内核组件"; + if(str == "kylin-update-desktop-kernel") + return "系统内核组件"; + if(str == "kylin-update-desktop-kernel-3a4000") + return "系统内核组件"; + if(str == "kylin-update-desktop-kydroid") + return "kydroid补丁包"; + + /* 从软件商店数据库根据包名获取应用中文名 */ + QString dst; + dst.clear(); + + QSqlQuery query(QSqlDatabase::database("B")); + bool ret = query.exec(QString("SELECT display_name_cn FROM application WHERE app_name IS '%1'").arg(str)); //执行 + if (ret == false) { + qDebug() << "Error : exec select sql fail , switch chinese pkg name fail"; + return str; + } + + while (query.next()) { + dst = query.value(0).toString(); + qDebug() << "Info : switch chinese pkg name is [" << dst << "]"; + } + + if (dst.isEmpty()) { + return str; + } else { + return dst; + } +} + + +void m_updatelog::dynamicLoadingInit() +{ + //绑定信号和槽 + connect(mainListwidget->verticalScrollBar(),&QScrollBar::valueChanged, this,&m_updatelog::dynamicLoading ); +} + +void m_updatelog::dynamicLoading(int i) +{ + if(mainListwidget->verticalScrollBar()->maximum()==i) + { + qDebug()<<"动态加载"; + updatesql(loadingCode); + } +} + +void m_updatelog::historyUpdateNow(QString str1,QString str2) +{ + qDebug()<<"动态更新:"< +#include +//布局 +#include +//控件 +#include +#include +#include +#include +//数据库 +#include +#include +#include +//GSETTINGS +#include +//其他 +#include +#include +#include "historyupdatelistwig.h" +#include "updatedbus.h" + +#define THEME_QT_SCHEMA "org.ukui.style" + +class m_updatelog : public QDialog +{ + Q_OBJECT +public: + static m_updatelog * GetInstance(QWidget *parent); + static void closeUpdateLog(); + QTextEdit * des = nullptr; + +protected: + +public slots: + void historyUpdateNow(QString str1, QString str2);//实时更新 + +private: + m_updatelog(QWidget *parent); + static m_updatelog * m_instance; + QListWidget *mainListwidget; //列表容器 + int firstCode = 0; + int loadingCode = 0; + QHBoxLayout *hll = nullptr; + QString setDefaultDescription(QString str); + QGSettings *qtSettings=nullptr; + QTimer *timer=nullptr; + +private slots: + void initUI(); //初始化UI + void initGsettings(); //初始化Gsettings + void dynamicLoadingInit(); //动态加载 + void dynamicLoading(int i); //动态加载 + void updatesql(const int &start=0, const int &num=20, const QString &intop="");//更新列表 + void defaultItem();//默认选中 + QString translationVirtualPackage(QString str);//翻译虚包名 + void changeListWidgetItemHeight();//修改列表项高度 +}; + +#endif // M_UPDATELOG_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/mylabel.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/mylabel.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/mylabel.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/mylabel.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,89 @@ +#include "mylabel.h" +#include + +MyLabel::MyLabel(QWidget *parent, Qt::WindowFlags f) + : QLabel(parent, f) +{ + this->setMinimumWidth(minSize); + setTextFormat(Qt::PlainText); +} + +MyLabel::MyLabel(const QString &text, QWidget *parent, Qt::WindowFlags f) + : QLabel(text, parent, f), m_fullText(text) +{ + this->setMinimumWidth(minSize); + setTextFormat(Qt::PlainText); +} + +void MyLabel::setText(const QString &text) +{ + setFullText(text); +} + +void MyLabel::setFullText(const QString &text) +{ + m_fullText = text; + update(); +} + +void MyLabel::setTextLimitShrink(const QString &text, int width) +{ + this->setMinimumWidth(qMin(this->fontMetrics().width(text), width)); +// this->setMinimumSize(200); + setFullText(text); +} + +void MyLabel::setTextLimitExpand(const QString &text) +{ + int textWidth = this->fontMetrics().width(text); + this->setMaximumWidth(textWidth); + setFullText(text); +} + +QString MyLabel::fullText() const +{ + return m_fullText; +} + +void MyLabel::paintEvent(QPaintEvent *event) +{ + QLabel::paintEvent(event); + elideText(); +} + +void MyLabel::elideText() +{ + QFontMetrics fm = this->fontMetrics(); + int dif = fm.width(m_fullText) - this->width(); + if (dif > 0) { + QString showText = fm.elidedText(m_fullText, Qt::ElideRight, this->width()); + QLabel::setText(showText); + if (showText != m_fullText) { + QString str = dealMessage(m_fullText); + this->setToolTip(str); + } else { + this->setToolTip(""); + } + } else { + QLabel::setText(m_fullText); + this->setToolTip(""); + } +} + +QString MyLabel::dealMessage(QString msg) +{ + if(msg.size() > fontSize) + { + QString str; + int time = msg.size()/fontSize; + for(int i = 0; i <= time-1; i++) + { + str = QString(str + msg.mid(i*fontSize,fontSize)+"\r\n"); + } + str = QString(str+msg.mid(time*fontSize,fontSize)); + return str; + } + else + return msg; +} + diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/mylabel.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/mylabel.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/mylabel.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/mylabel.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,28 @@ +#ifndef MYLABEL_H +#define MYLABEL_H +#include + +class MyLabel : public QLabel +{ + Q_OBJECT +public: + explicit MyLabel(QWidget *parent=0, Qt::WindowFlags f=0); + explicit MyLabel(const QString &text, QWidget *parent=0, Qt::WindowFlags f=0); + + void setText(const QString &text); + void setFullText(const QString &text); + void setTextLimitShrink(const QString &text, int width); + void setTextLimitExpand(const QString &text); + QString fullText() const; + QString dealMessage(QString msg); + int fontSize = 24; + int minSize = 120; +protected: + void paintEvent(QPaintEvent *); + +private: + void elideText(); +private: + QString m_fullText; +}; +#endif // MYLABEL_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/shadowwidget.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/shadowwidget.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/shadowwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/shadowwidget.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,19 @@ +#ifndef SHADOWWIDGET_H +#define SHADOWWIDGET_H + +#include +#include +#include + +class SWidget : public QWidget +{ +public: + explicit SWidget(QWidget *parent = nullptr); + + QWidget *widget_bg; + + +}; + + +#endif // SHADOWWIDGET_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/switchbutton.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/switchbutton.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/switchbutton.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/switchbutton.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,204 @@ +/* -*- 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 "switchbutton.h" + +#include + +SwitchButton::SwitchButton(QWidget *parent) : + QWidget(parent) +{ +// this->resize(QSize(52, 24)); + this->setFixedSize(QSize(48, 24)); + + checked = false; + + borderColorOff = QColor("#cccccc"); + + bgColorOff = QColor("#cccccc"); + bgColorOn = QColor("#3790FA"); + + sliderColorOff = QColor("#ffffff"); + sliderColorOn = QColor("#ffffff"); + + space = 4; +// rectRadius = 5; + + step = width() / 40; + startX = 0; + endX= 0; + + timer = new QTimer(this); + timer->setInterval(5); + connect(timer, SIGNAL(timeout()), this, SLOT(updatevalue())); +} + +SwitchButton::~SwitchButton() +{ +} + +void SwitchButton::paintEvent(QPaintEvent *){ + //启用反锯齿 + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing, true); + + drawBg(&painter); + drawSlider(&painter); +} + +void SwitchButton::drawBg(QPainter *painter){ + painter->save(); +// painter->setPen(Qt::NoPen); + + if (!checked){ + painter->setPen(Qt::NoPen); + painter->setBrush(bgColorOff); + } + else{ + painter->setPen(Qt::NoPen); + painter->setBrush(bgColorOn); + } + //circle out +// QRect rect(space, space, width() - space * 2, height() - space * 2); +// painter->drawRoundedRect(rect, rectRadius, rectRadius); + + //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 SwitchButton::drawSlider(QPainter *painter){ + painter->save(); + painter->setPen(Qt::NoPen); + + if (!checked){ + painter->setBrush(sliderColorOff); + } + else + painter->setBrush(sliderColorOn); + //circle out +// QRect rect(0, 0, width() - space, height() - space); +// int sliderwidth = rect.height(); +// QRect sliderRect(startX, space / 2, sliderwidth, sliderwidth); +// painter->drawEllipse(sliderRect); + + //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 SwitchButton::mousePressEvent(QMouseEvent *){ + checked = !checked; + emit checkedChanged(checked); + + step = width() / 40; + + if (checked){ + //circle out +// endX = width() - height() + space; + //circle in + endX = width() - height(); + } + else{ + endX = 0; + } + timer->start(); +} + +void SwitchButton::resizeEvent(QResizeEvent *){ + // + step = width() / 40; + + if (checked){ + //circle out +// startX = width() - height() + space; + //circle in + startX = width() - height(); + } + else + startX = 0; + + update(); +} + +void SwitchButton::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 SwitchButton::setChecked(bool checked){ + if (this->checked != checked){ + this->checked = checked; + emit checkedChanged(checked); + update(); + } + + step = width() / 40; + + if (checked){ + //circle out +// endX = width() - height() + space; + //circle in + endX = width() - height(); + } + else{ + endX = 0; + } + timer->start(); +} + +bool SwitchButton::isChecked(){ + return this->checked; +} + + diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/switchbutton.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/switchbutton.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/switchbutton.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/switchbutton.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,78 @@ +/* -*- 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 SWITCHBUTTON_H +#define SWITCHBUTTON_H + +#include +#include +#include +#include +#include + +class SwitchButton : public QWidget +{ + Q_OBJECT + +public: + SwitchButton(QWidget *parent = 0); + ~SwitchButton(); + + void setChecked(bool checked); + + bool isChecked(); + +protected: + void mousePressEvent(QMouseEvent *); + void resizeEvent(QResizeEvent *); + void paintEvent(QPaintEvent *); + void drawBg(QPainter * painter); + void drawSlider(QPainter * painter); + +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; + + +private slots: + void updatevalue(); + + +Q_SIGNALS: + void checkedChanged(bool checked); + +}; + +#endif // SWITCHBUTTON_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/tabwidget.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/tabwidget.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/tabwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/tabwidget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,769 @@ +#include "tabwidget.h" +#include + +TabWid::TabWid(QWidget *parent):QWidget(parent) +{ + allComponents(); +} + +void TabWid::initDbus() +{ + updateMutual = UpdateDbus::getInstance(); + updateSource = new UpdateSource(); + ukscConnect = new UKSCConn(); +// this->resize(620,580); + + connect(updateMutual,&UpdateDbus::sendAppMessageSignal,this,&TabWid::loadingOneUpdateMsgSlot); + connect(updateMutual,&UpdateDbus::sendFinishGetMsgSignal,this,&TabWid::loadingFinishedSlot); + connect(checkUpdateBtn,&QPushButton::clicked,this,&TabWid::checkUpdateBtnClicked); + connect(historyUpdateLog,&QPushButton::clicked,this,&TabWid::showHistoryWidget); + connect(isAutoCheckSBtn,&SwitchButton::checkedChanged,this,&TabWid::isAutoCheckedChanged); + connect(isAutoBackupSBtn,&SwitchButton::checkedChanged,this,&TabWid::isAutoBackupChanged); + connect(updateSource,&UpdateSource::getReplyFalseSignal,this,&TabWid::getReplyFalseSlot); + bacupInit();//初始化备份 + + checkUpdateBtn->stop(); +// checkUpdateBtn->setText(tr("检查更新")); + checkUpdateBtn->setText(tr("Check Update")); + if(firstCheckedStatus == false) + { + checkUpdateBtnClicked(); + firstCheckedStatus = true; + } +} + +void TabWid::unableToConnectSource() +{ + qDebug() << "源管理器信号是否连接成功:" << isConnectSourceSignal; + if(isConnectSourceSignal == false) + { + disconnectSource(); + } +} +void TabWid::disconnectSource() +{ + disconnect(updateSource->serviceInterface,SIGNAL(updateTemplateStatus(QString)),this,SLOT(slotUpdateTemplate(QString))); + disconnect(updateSource->serviceInterface,SIGNAL(updateCacheStatus(QVariantList)),this,SLOT(slotUpdateCache(QVariantList))); + disconnect(updateSource->serviceInterface,SIGNAL(updateSourceProgress(QVariantList)),this,SLOT(slotUpdateCacheProgress(QVariantList))); + checkUpdateBtn->setEnabled(true); + checkUpdateBtn->stop(); +// checkUpdateBtn->setText(tr("检查更新")); + checkUpdateBtn->setText(tr("Check Update")); +// versionInformationLab->setText(tr("服务连接异常,请重新检测!") ); + versionInformationLab->setText(tr("Service connection abnormal,please retest!") ); +} +TabWid::~TabWid() +{ + qDebug() << "~TabWid" ; + delete updateMutual; + updateMutual = nullptr; + backupDelete();//回收资源 +// updateMutual->cleanUpdateList(); +} + +void TabWid::backupMessageBox(QString str) +{ + QMessageBox msgBox; + msgBox.setText(str); + msgBox.setWindowTitle(tr("Prompt information")); +// msgBox.setWindowTitle("提示信息"); + msgBox.setStandardButtons(QMessageBox::Save + | QMessageBox::Discard|QMessageBox::Abort); +// msgBox.setButtonText(QMessageBox::Save,"立即更新"); +// msgBox.setButtonText(QMessageBox::Discard,"取消更新"); +// msgBox.setButtonText(QMessageBox::Abort,"否,我不备份"); + msgBox.setButtonText(QMessageBox::Save,tr("Update now")); + msgBox.setButtonText(QMessageBox::Discard,tr("Cancel update")); + msgBox.setButtonText(QMessageBox::Abort,tr("No,I Don't Backup")); + msgBox.button(QMessageBox::Abort)->hide(); + int ret = msgBox.exec(); + if(ret == QMessageBox::Save) + { + qDebug() << "立即更新!"; + checkUpdateBtn->start(); + checkUpdateBtn->setEnabled(false); + versionInformationLab->setText(tr("Being updated...")); +// versionInformationLab->setText("正在更新..."); + updateMutual->isPointOutNotBackup = false; //全部更新时不再弹出单个更新未备份提示 + emit updateAllSignal(); + } + else if(ret == QMessageBox::Discard) + { + qDebug() << "不进行全部更新。"; + checkUpdateBtn->stop(); + checkUpdateBtn->setEnabled(true); +// checkUpdateBtn->setText(tr("全部更新")); + versionInformationLab->setText(tr("Updatable app detected on your system!")); + checkUpdateBtn->setText(tr("UpdateAll")); + } + else if(ret == QMessageBox::Abort) + { + qDebug() << "不进行全部更新。"; + checkUpdateBtn->stop(); + checkUpdateBtn->setEnabled(true); +// checkUpdateBtn->setText(tr("全部更新")); + checkUpdateBtn->setText(tr("UpdateAll")); + + } +} + +void TabWid::backupCore() +{ + int initresult = emit needBackUp(); + switch (initresult) { + case -1: + backupMessageBox(tr("The backup restore partition could not be found. The system will not be backed up in this update!")); +// backupMessageBox(tr("未能找到备份还原分区,本次更新不会备份系统!")); + //如果是则立即更新,否的话取消全部更新 + return; + case -2: + versionInformationLab->setText(tr("Kylin backup restore tool is doing other operations, please update later.")); +// versionInformationLab->setText("麒麟备份还原工具正在进行其他操作,请稍后更新"); + return; + case -3: + versionInformationLab->setText(tr("The source manager configuration file is abnormal, the system temporarily unable to update!")); +// versionInformationLab->setText("源管理器配置文件异常,暂时无法更新!"); + return; + case -4: +// versionInformationLab->setText("已备份,无需再次备份"); + versionInformationLab->setText(tr("Backup already, no need to backup again.")); + checkUpdateBtn->start(); + checkUpdateBtn->setEnabled(false); + updateMutual->isPointOutNotBackup = false; //全部更新时不再弹出单个更新未备份提示 + emit updateAllSignal(); + return; + case 1://正在备份 + emit startBackUp(0); + versionInformationLab->setText(tr("Start backup,getting progress")+"..."); + break; + case needBack://需要备份 + emit startBackUp(1); + break; + case -9://备份还原工具不存在 +// backupMessageBox("麒麟备份还原工具不存在,本次更新不会备份系统!"); + backupMessageBox(tr("Kylin backup restore tool does not exist, this update will not backup the system!")); + return; + default: + qDebug()<<"备份还原工具状态码"<setText("备份完成"); + versionInformationLab->setText(tr("Backup complete.")); + return; + } +// versionInformationLab->setText("备份中:"+QString::number(progress)+"%"); + versionInformationLab->setText(tr("In backup:")+QString::number(progress)+"%"); + +} + +void TabWid::bakeupFinish(int result) +{ + switch (result) { + case -20: +// versionInformationLab->setText(tr("备份过程被中断,停止更新!")); + versionInformationLab->setText(tr("Backup interrupted, stop updating!")); + break; + case 99: +// versionInformationLab->setText(tr("备份完成!")); + versionInformationLab->setText(tr("Backup finished!")); + break; + default: +// backupMessageBox(tr("麒麟备份还原工具异常:")+QString::number(result)+","+tr("本次更新不会备份系统!")); + backupMessageBox(tr("Kylin backup restore tool exception:")+QString::number(result)+","+tr("There will be no backup in this update!")); + break; + } +} + +void TabWid::backupHideUpdateBtn(int result) +{ + if(result == 99) + { + checkUpdateBtn->start(); +// versionInformationLab->setText("正在更新..."); + versionInformationLab->setText(tr("Being updated...")); + updateMutual->isPointOutNotBackup = false; //全部更新时不再弹出单个更新未备份提示 + emit updateAllSignal(); + } + else if(result == -20) + { + checkUpdateBtn->stop(); + checkUpdateBtn->setEnabled(true); +// checkUpdateBtn->setText(tr("全部更新")); + checkUpdateBtn->setText(tr("UpdateAll")); + + } +} + +void TabWid::bacupInit() +{ + backup = new BackUp; + backupThread = new QThread; + qDebug() << "======>tabwid info: " <moveToThread(backupThread); + connect(this,&TabWid::needBackUp,backup,&BackUp::needBacdUp,Qt::BlockingQueuedConnection);//同步信号,阻塞,取返回值 + connect(this,&TabWid::startBackUp,backup,&BackUp::startBackUp); + connect(backup, &BackUp::calCapacity, this, &TabWid::whenStateIsDuing); + connect(backup, &BackUp::backupStartRestult, this, &TabWid::receiveBackupStartResult); + connect(backup,&BackUp::bakeupFinish,this,&TabWid::bakeupFinish); + connect(backup,&BackUp::backupProgress,this,&TabWid::backupProgress); + connect(backup,&BackUp::bakeupFinish,this,&TabWid::backupHideUpdateBtn); + backupThread->start(); +} + +void TabWid::backupDelete() +{ + backup->deleteLater(); + backupThread->deleteLater(); +} + +void TabWid::slotUpdateTemplate(QString status) +{ + qDebug() << "源管理器:" <<"update template status :" << status; + +} +void TabWid::slotUpdateCache(QVariantList sta) +{ + QString status = sta.at(1).toString(); + QString nowsymbol = sta.at(0).toString(); + qDebug() << "源管理器:" <<"slotUpdateCache" << "nowsymbol" <setText(tr("正在获取更新列表...")); + versionInformationLab->setText(tr("Getting update list")+"..."); + QFile file(IMPORTANT_FIEL_PATH); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug() <<"file open failed!" << IMPORTANT_FIEL_PATH; + versionInformationLab->setText(tr("Software source update failed: ")); //软件源更新失败 + checkUpdateBtn->setEnabled(true); + checkUpdateBtn->stop(); + checkUpdateBtn->setText(tr("Check Update")); + return ; + } + QString str = file.readAll(); + QStringList list; + str = str.simplified(); + if (!str.isEmpty()) { + list = str.split(" "); + } + qDebug() << "slotUpdateCache函数:获取到的包列表:" << list; + updateMutual->getAppMessage(list); + retryTimes = 0; + } + else + { + int statuscode = status.toInt(); + if(statuscode == 400 && retryTimes < netErrorRetry) + { + updateSource->callDBusUpdateTemplate(); + qDebug() << "源管理器:" <<"statuscode = :" << statuscode; + QString failedInfo = updateSource->getFailInfo(statuscode); + qDebug() << "源管理器:" <<"failedInfo:" << failedInfo; + retryTimes++; + } + else + { + QString failedInfo = updateSource->getFailInfo(statuscode); + checkUpdateBtn->setEnabled(true); + checkUpdateBtn->stop(); +// checkUpdateBtn->setText(tr("检查更新")); + checkUpdateBtn->setText(tr("Check Update")); +// versionInformationLab->setText(tr("软件源更新失败:")+failedInfo ); + versionInformationLab->setText(tr("Software source update failed: ")+failedInfo ); + disconnect(updateSource->serviceInterface,SIGNAL(updateTemplateStatus(QString)),this,SLOT(slotUpdateTemplate(QString))); + disconnect(updateSource->serviceInterface,SIGNAL(updateCacheStatus(QVariantList)),this,SLOT(slotUpdateCache(QVariantList))); + disconnect(updateSource->serviceInterface,SIGNAL(updateSourceProgress(QVariantList)),this,SLOT(slotUpdateCacheProgress(QVariantList))); + retryTimes = 0; + } + } + } +} +void TabWid::slotUpdateCacheProgress(QVariantList pro) +{ + int progress = pro.at(1).toInt(); + QString nowsymbol = pro.at(0).toString(); + // qDebug() << "update cache progress :" << progress; + if(nowsymbol == Symbol) + { + if(retryTimes == 0) + { + versionInformationLab->setText(tr("Update software source :") + QString::number(progress)+"%"); +// versionInformationLab->setText(tr("更新软件源进度:") + QString::number(progress)+"%"); + } + else + { + versionInformationLab->setText(tr("Update software source :") + QString::number(progress)+"%(" + tr("Reconnect times:")+ QString::number(retryTimes)+")"); +// versionInformationLab->setText(tr("更新软件源进度:") + QString::number(progress)+"%" + "(第" + QString::number(retryTimes) +"次重试)"); + } + } +} + +void TabWid::allComponents() +{ + mainTabLayout = new QVBoxLayout(); //整个页面的主布局 + scrollArea = new QScrollArea(this); + updateTab = new QWidget(this); //更新页面 + + AppMessage = new QVBoxLayout(); + AppMessage->setAlignment(Qt::AlignTop); + updateTab->setLayout(AppMessage); + systemWidget = new QFrame(updateTab); + systemWidget->setFrameShape(QFrame::Box); + systemPortraitLab = new QLabel(systemWidget); + + allUpdateWid = new QWidget(this); + allUpdateLayout = new QVBoxLayout(); + allUpdateLayout->setAlignment(Qt::AlignTop); + allUpdateWid->setLayout(allUpdateLayout); + allUpdateLayout->setSpacing(2); + allUpdateLayout->setMargin(0); + + labUpdate = new QLabel(this); +// labUpdate->setText(tr("更新")); + labUpdate->setText(tr("Update")); + labUpdate->adjustSize(); + labUpdate->setStyleSheet("font-size:18px;font-weight: 500;line-height: 25px;"); + + scrollArea->setWidget(updateTab); + scrollArea->setFrameStyle(0); +// scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + scrollArea->setWidgetResizable(true); + + systemWidget->resize(560,140); + systemWidget->setFixedHeight(140); + + systemPortraitLab = new QLabel(); + tab1HLayout = new QHBoxLayout(); + systemWidget->setLayout(tab1HLayout); + systemPortraitLab->setFixedSize(96,96); + systemPortraitLab->setPixmap(QPixmap(":/img/plugins/upgrade/normal.png").scaled(QSize(96,96))); + + QWidget *historyUpdateLogWid = new QWidget(this); + QHBoxLayout *historyUpdateLogLayout = new QHBoxLayout(); + historyUpdateLog = new QPushButton(this); // 历史日志弹出窗口控制按钮 +// historyUpdateLog->setText(tr("查看更新历史")); + historyUpdateLog->setText(tr("View history")); + historyUpdateLogWid->setLayout(historyUpdateLogLayout); + historyUpdateLogLayout->setAlignment(Qt::AlignLeft); + historyUpdateLogLayout->addWidget(historyUpdateLog); + historyUpdateLogLayout->setSpacing(0); + historyUpdateLogLayout->setMargin(0); + + + inforLayout = new QVBoxLayout(); + lastRefreshTime = new QLabel(systemWidget); + versionInformationLab = new QLabel(systemWidget); + versionInformationLab->setStyleSheet("font-size:16px;font-weight:500;line-height: 22px;"); + + inforLayout->setAlignment(Qt::AlignTop); + inforLayout->addWidget(versionInformationLab); + inforLayout->addWidget(lastRefreshTime); + inforLayout->setSpacing(8); + inforLayout->setContentsMargins(8,20,0,0); + QWidget *inforWidget = new QWidget(systemWidget); + inforWidget->setLayout(inforLayout); + + checkUpdateBtn = new m_button(systemWidget); + checkUpdateBtn->setDefault(true); + checkUpdateBtn->start(); + checkUpdateBtn->setFixedSize(120,36); + + + tab1HLayout->addWidget(systemPortraitLab,0,Qt::AlignLeft); + tab1HLayout->addWidget(inforWidget,Qt::AlignLeft|Qt::AlignTop); + tab1HLayout->addWidget(checkUpdateBtn); + tab1HLayout->setContentsMargins(8,25,20,20); + tab1HLayout->setSpacing(0); + + updateSettingLab = new QLabel(); +// updateSettingLab->setText(tr("更新设置")); + updateSettingLab->setText(tr("Update Settings")); + updateSettingLab->setStyleSheet("font-size:18px;font-weight: 500;line-height: 25px;"); + updateSettingWidget = new QWidget(this); + updatesettingLayout = new QVBoxLayout(); + updateSettingWidget->setLayout(updatesettingLayout); + + isAutoCheckWidget = new QFrame(); + isAutoCheckWidget->setFrameShape(QFrame::Box); + isAutoCheckLayout = new QHBoxLayout(); + isAutoCheckedLab = new QLabel(); +// isAutoCheckedLab->setText(tr("允许通知可更新的应用")); + isAutoCheckedLab->setText(tr("Allowed to renewable notice")); + isAutoCheckSBtn = new SwitchButton(); + isAutoCheckWidget->setLayout(isAutoCheckLayout); + isAutoCheckLayout->addWidget(isAutoCheckedLab); + isAutoCheckLayout->addWidget(isAutoCheckSBtn); + + isAutoBackupWidget = new QFrame(); + isAutoBackupWidget->setFrameShape(QFrame::Box); + isAutoBackupLayout = new QHBoxLayout(); + isAutoBackupLab = new QLabel(); + isAutoBackupLab->setText(tr("Backup current system before updates all")); +// isAutoBackupLab->setText(tr("全部更新前备份系统")); + isAutoBackupSBtn = new SwitchButton(); + isAutoBackupLayout->addWidget(isAutoBackupLab); + isAutoBackupLayout->addWidget(isAutoBackupSBtn); + isAutoBackupWidget->setLayout(isAutoBackupLayout); + + updatesettingLayout->setAlignment(Qt::AlignTop); + updatesettingLayout->addWidget(updateSettingLab); + updatesettingLayout->addSpacing(10); + updatesettingLayout->addWidget(isAutoCheckWidget); + updatesettingLayout->addWidget(isAutoBackupWidget); + updatesettingLayout->setSpacing(2); + updatesettingLayout->setMargin(0); + + + AppMessage->addWidget(labUpdate); + AppMessage->addWidget(systemWidget); + AppMessage->addWidget(allUpdateWid); + AppMessage->addWidget(historyUpdateLogWid); + AppMessage->addSpacing(30); + AppMessage->addWidget(updateSettingWidget); + AppMessage->addStretch(); + AppMessage->setContentsMargins(0,0,28,10); + + mainTabLayout->setAlignment(Qt::AlignTop); + mainTabLayout->addWidget(scrollArea); +// mainTabLayout->setSpacing(0); + mainTabLayout->setMargin(0); + this->setLayout(mainTabLayout); + getAllDisplayInformation(); + +} + + + +void TabWid::loadingOneUpdateMsgSlot(AppAllMsg msg) +{ +// checkUpdateBtn->setText(); + if(updateMutual->importantList.indexOf(msg.name) == -1) + { + updateMutual->importantList.append(msg.name); //重要更新列表中添加appname + AppUpdateWid *appWidget = new AppUpdateWid(msg, this); + appWidget->updateAPPBtn->hide(); + connect(appWidget, &AppUpdateWid::cancel, this, &TabWid::slotCancelDownload); + connect(this, &TabWid::updateAllSignal, appWidget, &AppUpdateWid::updateAllApp); + connect(appWidget,&AppUpdateWid::hideUpdateBtnSignal,this,&TabWid::hideUpdateBtnSlot); + connect(appWidget,&AppUpdateWid::changeUpdateAllSignal,this,&TabWid::changeUpdateAllSlot); + connect(updateMutual,&UpdateDbus::sendFinishGetMsgSignal,appWidget,&AppUpdateWid::showUpdateBtn); + connect(appWidget,&AppUpdateWid::filelockedSignal,this,&TabWid::waitCrucialInstalled); + connect(backup,&BackUp::bakeupFinish,appWidget,&AppUpdateWid::hideOrShowUpdateBtnSlot); + if(ukscConnect->isConnectUskc == true) + { + QStringList list = ukscConnect->getInfoByName(msg.name); + if(list[2] != "") + { + appWidget->appNameLab->setText(list[2]); + + } + if(list[1] != "" && QLocale::system().name()=="zh_CN") + { + appWidget->appNameLab->setText(list[1]); + } + if(list[0] != "") + { + appWidget->appIcon->setPixmap(QPixmap(list[0]).scaled(32, 32)); + } + } + allUpdateLayout->addWidget(appWidget); + qDebug() << "更新管理器:" << "loadingOneUpdateMsgSlot:" << appWidget->dispalyName; + + } + +} + +void TabWid::loadingFinishedSlot(int size) +{ + disconnect(updateSource->serviceInterface,SIGNAL(updateTemplateStatus(QString)),this,SLOT(slotUpdateTemplate(QString))); + disconnect(updateSource->serviceInterface,SIGNAL(updateCacheStatus(QVariantList)),this,SLOT(slotUpdateCache(QVariantList))); + disconnect(updateSource->serviceInterface,SIGNAL(updateSourceProgress(QVariantList)),this,SLOT(slotUpdateCacheProgress(QVariantList))); + qDebug()<< "更新管理器:" <<"加载完毕信号 " << "size = " <importantList.size() == 0) + { + checkUpdateBtn->setEnabled(true); + checkUpdateBtn->stop(); +// checkUpdateBtn->setText(tr("检查更新")); + checkUpdateBtn->setText(tr("Check Update")); +// versionInformationLab->setText(tr("您的系统已是最新!")); + versionInformationLab->setText(tr("Your system is the latest!")); + } + else + { + updateMutual->importantSize = updateMutual->importantList.size(); //此次检测结果的更新数量 + checkUpdateBtn->stop(); + checkUpdateBtn->setEnabled(true); +// checkUpdateBtn->setText(tr("全部更新")); + checkUpdateBtn->setText(tr("UpdateAll")); +// versionInformationLab->setText(tr("检测到你的系统有可更新的应用!")); + versionInformationLab->setText(tr("Updatable app detected on your system!")); + systemPortraitLab->setPixmap(QPixmap(":/img/plugins/upgrade/update.png").scaled(96,96)); + + } +} + +void TabWid::getAllDisplayInformation() +{ + QSqlQuery query(QSqlDatabase::database("A")); + QString updatetime; + QString checkedtime; + QString checkedstatues; + QString backupStatus; + query.exec("select * from display"); + while(query.next()) + { + updatetime = query.value("update_time").toString(); + checkedtime = query.value("check_time").toString(); + checkedstatues = query.value("auto_check").toString(); + backupStatus = query.value("auto_backup").toString(); + } + if(QLocale::system().name()!="zh_CN" && updatetime.contains("暂无信息")) + { + updatetime = "No Information!"; + } +// lastRefreshTime->setText(tr("上次更新:")+updatetime); + lastRefreshTime->setText(tr("Last refresh:")+updatetime); +// versionInformationLab->setText(tr("上次检测:")+checkedtime); + versionInformationLab->setText(tr("Last Checked:")+checkedtime); + if(checkedstatues == "false") + { + isAutoCheckSBtn->setChecked(false); + } + else + { + isAutoCheckSBtn->setChecked(true); + } + isAutoCheckSBtn->setEnabled(true); + + if(backupStatus == "false") + { + isAutoBackupSBtn->setChecked(false); + } + else + { + isAutoBackupSBtn->setChecked(true); + } +} +void TabWid::showHistoryWidget() +{ + + historyLog = m_updatelog::GetInstance(this); + //在屏幕中央显示 + QRect availableGeometry = qApp->primaryScreen()->availableGeometry(); + historyLog->move((availableGeometry.width()-historyLog->width())/2,(availableGeometry.height()- historyLog->height())/2); + historyLog->show(); +} + +void TabWid::checkUpdateBtnClicked() +{ + if(checkUpdateBtn->text() == tr("Check Update")) + { + connect(updateSource->serviceInterface,SIGNAL(updateTemplateStatus(QString)),this,SLOT(slotUpdateTemplate(QString))); + connect(updateSource->serviceInterface,SIGNAL(updateCacheStatus(QVariantList)),this,SLOT(slotUpdateCache(QVariantList))); + connect(updateSource->serviceInterface,SIGNAL(updateSourceProgress(QVariantList)),this,SLOT(slotUpdateCacheProgress(QVariantList))); + updateMutual->failedList.clear(); + QList list = this->findChildren(); + for(AppUpdateWid* tmp:list) + { + tmp->deleteLater(); + } + updateSource->callDBusUpdateTemplate(); +// versionInformationLab->setText(tr("正在更新软件源...")); + versionInformationLab->setText(tr("Updating the software source")+"..."); + //判断信号连接超时 + QTimer *timer = new QTimer; + timer->setSingleShot(true); + connect(timer,&QTimer::timeout,this,&TabWid::unableToConnectSource); + timer->start(60000); + QDateTime current_date_time = QDateTime::currentDateTime(); + QString current_date = current_date_time.toString("yyyy.MM.dd hh:mm:ss"); + updateMutual->insertInstallStates("check_time",current_date); + checkUpdateBtn->start(); + checkUpdateBtn->setEnabled(false); + } + else if(checkUpdateBtn->text() == tr("UpdateAll")) + { + if(isAutoBackupSBtn->isChecked() == true) + { + backupCore();//备份模块主函数 + } + else + { + QMessageBox msgBox; + msgBox.setText(tr("This update will not backup the current system, do you want to continue the update?")); +// msgBox.setText(tr("本次更新不会备份当前系统,是否继续更新?")); + msgBox.setWindowTitle(tr("Prompt information")); +// msgBox.setWindowTitle("提示信息"); + msgBox.setStandardButtons(QMessageBox::Yes + | QMessageBox::No + | QMessageBox::Cancel); + msgBox.setButtonText(QMessageBox::Yes,tr("Yes, keep updating")); + msgBox.setButtonText(QMessageBox::No,tr("No, backup now")); + msgBox.setButtonText(QMessageBox::Cancel,tr("Not updated")); +// msgBox.setButtonText(QMessageBox::Yes,"是,继续更新"); +// msgBox.setButtonText(QMessageBox::No,"否,立即备份"); +// msgBox.setButtonText(QMessageBox::Cancel,"暂不更新"); + int ret = msgBox.exec(); + switch (ret) { + case QMessageBox::Yes: + qDebug() << "是,继续更新"; +// checkUpdateBtn->setText("正在更新..."); + checkUpdateBtn->setEnabled(false); + checkUpdateBtn->start(); + updateMutual->isPointOutNotBackup = false; //全部更新时不再弹出单个更新未备份提示 + emit updateAllSignal(); + break; + case QMessageBox::No: + backupCore(); + qDebug() << "否,立即备份"; + break; + case QMessageBox::Cancel: + qDebug() << "Close 暂不更新!"; + break; + } + } + } +} + +void TabWid::isAutoCheckedChanged() //自动检测按钮绑定的槽函数 +{ + if(isAutoCheckSBtn->isChecked() == false) + { + updateMutual->insertInstallStates("auto_check","false"); + + } + else if(isAutoCheckSBtn->isChecked() == true) + { + updateMutual->insertInstallStates("auto_check","true"); + } +} + +void TabWid::isAutoBackupChanged() +{ + if(isAutoBackupSBtn->isChecked() == false) + { + updateMutual->insertInstallStates("auto_backup","false"); + + } + else if(isAutoBackupSBtn->isChecked() == true) + { + updateMutual->insertInstallStates("auto_backup","true"); + } +} + +void TabWid::slotCancelDownload() +{ + checkUpdateBtn->stop(); +// checkUpdateBtn->setText("全部更新"); + checkUpdateBtn->setText(tr("UpdateAll")); + checkUpdateBtn->setCheckable(true); +} + +void TabWid::hideUpdateBtnSlot(bool isSucceed) +{ + if(isSucceed == true) + { + qDebug() << "当前更新列表" << updateMutual->importantList; + QDateTime nowtime = QDateTime::currentDateTime(); + QString current_date = nowtime.toString("yyyy.MM.dd hh:mm:ss"); +// lastRefreshTime->setText(tr("上次更新:")+current_date); + lastRefreshTime->setText(tr("Last refresh:")+current_date); +// updateMutual->insertInstallStates("update_time",current_date); + + } + if(updateMutual->importantList.size() == 0) + { + checkUpdateBtn->setEnabled(true); + checkUpdateBtn->stop(); +// checkUpdateBtn->setText(tr("检查更新")); + checkUpdateBtn->setText(tr("Check Update")); + if(updateMutual->failedList.size() == 0) + { +// versionInformationLab->setText(tr("您的系统已是最新!")); + versionInformationLab->setText(tr("Your system is the latest!")); + systemPortraitLab->setPixmap(QPixmap(":/img/plugins/upgrade/normal.png").scaled(96,96)); + } + else + { +// versionInformationLab->setText(tr("部分更新失败!")); + versionInformationLab->setText(tr("Part of the update failed!")); + } + } +} + +void TabWid::changeUpdateAllSlot() +{ + + if(checkUpdateBtn->isEnabled() == false) + { +// checkUpdateBtn->setText("全部更新"); + checkUpdateBtn->setText(tr("UpdateAll")); + checkUpdateBtn->setEnabled(true); + } +} + + +void TabWid::waitCrucialInstalled() +{ + if(fileLockedStatus == false) + { + QString msg = tr("An important update is in progress, please wait."); +// QString msg = tr("正在进行一项重要更新,请等待。"); + updateMutual->onRequestSendDesktopNotify(msg); + versionInformationLab->setText(msg); + fileLockedStatus = true; + } +} + +void TabWid::getReplyFalseSlot() +{ + isConnectSourceSignal = true; + disconnectSource(); +} + +void TabWid::receiveBackupStartResult(int result) +{ + switch (result) { + case int(backuptools::backup_result::BACKUP_START_SUCCESS): +// versionInformationLab->setText(tr("开始备份,正在获取进度")+"..."); + versionInformationLab->setText(tr("Start backup,getting progress")+"..."); + checkUpdateBtn->start(); + checkUpdateBtn->setEnabled(false); + return; + case int(backuptools::backup_result::WRITE_STORAGEINFO_ADD_ITEM_FAIL): + case int(backuptools::backup_result::WRITE_STORAGEINFO_UPDATE_ITEM_FAIL): +// backupMessageBox(tr("写入配置文件失败,本次更新不会备份系统!")); + backupMessageBox(tr("Failed to write configuration file, this update will not back up the system!")); + break; + case int(backuptools::backup_result::BACKUP_CAPACITY_IS_NOT_ENOUGH): +// backupMessageBox(tr("备份空间不足,本次更新不会备份系统!")); + backupMessageBox(tr("Insufficient backup space, this update will not backup your system!")); + break; + case int(backuptools::backup_result::INC_NOT_FOUND_UUID): +// backupMessageBox(tr("麒麟备份还原工具无法找到UUID,本次更新不会备份系统!")); + backupMessageBox(tr("Kylin backup restore tool could not find the UUID, this update will not backup the system!")); + break; + default: + backupMessageBox(tr("The backup restore partition is abnormal. You may not have a backup restore partition.For more details,see /var/log/backup.log")); + break; + } +} + +void TabWid::whenStateIsDuing() +{ + versionInformationLab->setText(tr("Calculating Capacity...")); + checkUpdateBtn->start(); + checkUpdateBtn->setEnabled(false); +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/tabwidget.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/tabwidget.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/tabwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/tabwidget.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,157 @@ +#ifndef TABWIDGET_H +#define TABWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "appupdate.h" +//#include "switchbutton.h" +#include "m_updatelog.h" +#include "updatesource.h" +#include "ukscconn.h" +#include "backup.h" +#include "checkbutton.h" +#include "SwitchButton/switchbutton.h" +#define CRUCIAL_FILE_PATH "/var/lib/kylin-software-properties/template/crucial.list" +#define IMPORTANT_FIEL_PATH "/var/lib/kylin-software-properties/template/important.list" + +const int needBack = 99; + +const int netErrorRetry = 3; + +class TabWid : public QWidget +{ + Q_OBJECT +public: + explicit TabWid(QWidget *parent = nullptr); + ~TabWid(); + void allComponents(); //更新页面里所有组件 + + void getAllDisplayInformation(); +// void allBinding(); //更新页面里所有组件绑定 + void checkUpdateBtnClicked(); //检测更新、全部更新按钮 + + +// void updateSettings(); //更新设置页面 + + //选项卡页面,具有更新和更新设置两个选项卡及对应界面 + QTabWidget *updateWidget; + QLabel *labUpdate; + QWidget *updateTab; + QWidget *updateSettingTab; + QVBoxLayout *mainTabLayout; + QFont ft; + QCheckBox *isAutoCheckBox; + + //更新页面布局 + QHBoxLayout *tab1HLayout; + QFrame *systemWidget; + QVBoxLayout *AppMessage; + QScrollArea *scrollArea; + //更新设置页面布局 +// QHBoxLayout *tab2HLayout; + QVBoxLayout *tab2VLayout; + + //系统头像 + QLabel *systemPortraitLab; + m_button *checkUpdateBtn; //检测更新 + //三种状态下的版本信息 显示当前版本、可更新版本、或最新版本 + QLabel *versionInformationLab; + QLabel *lastRefreshTime; + QPushButton *historyUpdateLog; //历史更新日志界面 + QVBoxLayout *inforLayout; + + //更新设置页面组件 + QWidget *updateSettingWidget; + QLabel *updateSettingLab; + QVBoxLayout *updatesettingLayout; + QFrame *isAutoCheckWidget; + QHBoxLayout *isAutoCheckLayout; + QLabel *isAutoCheckedLab; + SwitchButton *isAutoCheckSBtn; + QFrame *isAutoBackupWidget; + QHBoxLayout *isAutoBackupLayout; + QLabel *isAutoBackupLab; + SwitchButton *isAutoBackupSBtn; + + + QWidget *allUpdateWid; + QVBoxLayout *allUpdateLayout; + + int inumber = 0; + int retryTimes = 0; + m_updatelog *historyLog; +// QDialog *historyLog; + bool fileLockedStatus = false; //等待静默安装提示是否弹出 + UpdateDbus *updateMutual; + bool downloadFailedStatus = false; //下载失败时的弹窗是否弹出 + //源管理器Dbus对象 + UpdateSource *updateSource; + + + void disconnectSource(); +signals: +// void send_Signal(); +// void parameterSignal(int i); + void updateAllSignal(); +public slots: + void showHistoryWidget(); + void isAutoCheckedChanged(); + void slotCancelDownload(); + void loadingOneUpdateMsgSlot(AppAllMsg msg); //逐个加载更新 + void loadingFinishedSlot(int size); //加载完毕信号 + void waitCrucialInstalled(); //等待静默更新安装完的消息提示 + + void hideUpdateBtnSlot(bool isSucceed); + void changeUpdateAllSlot(); + + //调用源管理器相关 + void slotUpdateTemplate(QString status); + void slotUpdateCache(QVariantList sta); + void slotUpdateCacheProgress(QVariantList pro); + + //解决首次运行卡顿问题 + //DBus单独初始化 + void initDbus(); + + +private: + UKSCConn *ukscConnect; + bool firstCheckedStatus = false; + bool isConnectSourceSignal = false; + void unableToConnectSource(); +//备份还原相关 + void bacupInit(); + void backupDelete(); + void backupCore(); + BackUp *backup = nullptr; + QThread *backupThread = nullptr; + + void backupMessageBox(QString str); + void backupHideUpdateBtn(int result); +signals: + int needBackUp(); + void startBackUp(int); + +public slots: + void bakeupFinish(int); + void backupProgress(int); + void isAutoBackupChanged(); + + void getReplyFalseSlot(); + +private slots: + void receiveBackupStartResult(int result); + void whenStateIsDuing(); +}; + +#endif // TABWIDGET_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/traybusthread.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/traybusthread.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/traybusthread.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/traybusthread.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,39 @@ +#include "traybusthread.h" +#include +#include + +void traybusthread::run() +{ + +// QTime dieTime = QTime::currentTime().addMSecs(2000); +// while( QTime::currentTime() < dieTime ) +// QCoreApplication::processEvents(QEventLoop::AllEvents, 100); + m_pServiceInterface = new QDBusInterface("com.scorpio.test", + "/test/objectsd", + "com.scorpio.test.value", + QDBusConnection::sessionBus()); + + QDBusConnection::sessionBus().connect(QString("com.scorpio.test"), QString("/test/objectsd"), + QString("com.scorpio.test.value"), + QString("ready"), this, SLOT(getInameAndCnameList(QString))); + QDBusReply reply1 = m_pServiceInterface->call("connectSuccessslots"); +} + +void traybusthread::getInameAndCnameList(QString arg) +{ + qDebug()<<"getsignal"; + qDebug()< reply = m_pServiceInterface->call("getImportant"); + if (reply.isValid()) { + inameList = reply.value(); + qDebug() << inameList; + + } else { + qDebug() << "value method called failed!"; + } + emit result(inameList); + QDBusReply rep = m_pServiceInterface->call("quitslots"); + +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/traybusthread.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/traybusthread.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/traybusthread.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/traybusthread.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,26 @@ +#ifndef TRAYBUSTHREAD_H +#define TRAYBUSTHREAD_H + +#include +#include + +class traybusthread : public QThread +{ + Q_OBJECT +signals: + void result(QStringList updateList); + +private: + void run(); + QStringList inameList; //重要更新列表 + QDBusInterface *m_pServiceInterface; + + + +public slots: + void getInameAndCnameList(QString arg); + +}; + + +#endif // TRAYBUSTHREAD_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/ukscconn.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/ukscconn.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/ukscconn.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/ukscconn.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,74 @@ +#include "ukscconn.h" +UKSCConn::UKSCConn() +{ + ukscDb = QSqlDatabase::addDatabase("QSQLITE"); + + QString UKSC_CACHE_DIR = QString(getenv("HOME")) + "/.cache/uksc/"; + QString UKSC_DATA_DIR = "/usr/share/kylin-software-center/data/"; + QString KUM_DIR = "/usr/share/kylin-update-manager/"; + QString dbFileName = ""; + dbFileName = UKSC_CACHE_DIR + "uksc.db"; + QFile file(dbFileName); + if (!file.exists()) { + dbFileName = UKSC_DATA_DIR + "uksc.db"; + file.setFileName(dbFileName); + + if (!file.exists()) { + dbFileName = KUM_DIR + "uksc.db"; + file.setFileName(dbFileName); + if (file.exists()) { + ukscDb.setDatabaseName(dbFileName); + } + } + } + ukscDb.setDatabaseName(dbFileName); + if (!ukscDb.open()) + { + qWarning() << "软件商店数据库打开错误!"; + isConnectUskc = false; + } + else + { + query = QSqlQuery(ukscDb);//连接数据库 + } +} + +// 根据应用名获取应用信息 +QStringList UKSCConn::getInfoByName(QString appName) +{ + QStringList appInfo; + if(isConnectUskc == true) + { + QString str = QString("select * from application where app_name = '%1'").arg(appName); + query.exec(str); + QString iconPath; // 应用图标 + QString displayNameCN; // 应用中文名 + QString displayName; // 应用英文名 + QString description; // 应用描述 + + while (query.next()) + { + iconPath = query.value(15).toString(); + displayNameCN = query.value(4).toString(); + displayName = query.value(3).toString(); + description = query.value(7).toString(); + } + + iconPath = QString(getenv("HOME")) + "/.cache/uksc/icons/" + appName + ".png"; + QFile file(iconPath); + if (!file.exists()) + { + appInfo.append(""); + } + else + { + appInfo.append(iconPath); + + } + appInfo.append(displayNameCN); + appInfo.append(displayName); + appInfo.append(description); + } + return appInfo; + +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/ukscconn.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/ukscconn.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/ukscconn.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/ukscconn.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,26 @@ +#ifndef UKSCCONN_H +#define UKSCCONN_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class UKSCConn : public QObject +{ +public: + explicit UKSCConn(); + QSqlDatabase ukscDb; + QSqlQuery query; + bool isConnectUskc = true; + + // 根据应用名获取图标、中文名、描述 + QStringList getInfoByName(QString appName); + +}; + +#endif // UKSCCONN_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatedbus.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatedbus.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatedbus.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatedbus.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,347 @@ +#include "updatedbus.h" +#include "connection.h" +#include +#define PROGRAM_NAME "control-upgrade" +#define PATH_MAX_LEN 1024 +#define PID_STRING_LEN 64 + +UpdateDbus* UpdateDbus::updateMutual = nullptr; +using namespace std; + +UpdateDbus* UpdateDbus::getInstance(QObject *parent) +{ + static QMutex mutex; + if(nullptr == updateMutual) + { + QMutexLocker locker(&mutex); + updateMutual = new UpdateDbus(parent); + } + return updateMutual; +} + +UpdateDbus::UpdateDbus(QObject *parent) + :QObject(parent) +{ + qRegisterMetaType("AppMsg"); //注册信号槽类型 + qRegisterMetaType("AppAllMsg"); //注册信号槽类型 + interface = new QDBusInterface(KYLIN_UPDATE_MANAGER_SERVICE, + KYLIN_UPDATE_MANAGER_PATH, + KYLIN_UPDATE_MANAGER_INTERFACE, + QDBusConnection::systemBus()); + QDBusConnection::systemBus().connect(QString("cn.kylinos.KylinUpdateManager"), QString("/cn/kylinos/KylinUpdateManager"), + QString("cn.kylinos.KylinUpdateManager"), + QString("kum_apt_signal"), this, SLOT(getAptSignal(QString, QMap))); + + QDBusConnection::systemBus().connect(QString("cn.kylinos.KylinUpdateManager"), QString("/cn/kylinos/KylinUpdateManager"), + QString("cn.kylinos.KylinUpdateManager"), + QString("important_app_message_signal"), this, SLOT(getAppMessageSignal(QMap, QStringList, QStringList, QStringList, QStringList, QString, bool))); + + QDBusConnection::systemBus().connect(QString("cn.kylinos.KylinUpdateManager"), QString("/cn/kylinos/KylinUpdateManager"), + QString("cn.kylinos.KylinUpdateManager"), + QString("get_message_finished_signal"), this, SLOT(slotFinishGetMessage(QString))); + + QDBusConnection::systemBus().connect(QString("cn.kylinos.KylinUpdateManager"), QString("/cn/kylinos/KylinUpdateManager"), + QString("cn.kylinos.KylinUpdateManager"), + QString("copy_finish"), this, SLOT(slotCopyFinished(QString))); + +// cleanUpdateList(); + setImportantStatus(true); + +} + +void UpdateDbus::onRequestSendDesktopNotify(QString message) +{ + QDBusInterface iface("org.freedesktop.Notifications", + "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", + QDBusConnection::sessionBus()); + QList args; + args<<(tr("ukui-control-center")) + <<((unsigned int) 0) + <<("ukui-control-center") + <call("copy_file_to_install",srcPath,appName); + qDebug() << "拷贝软件包到安装目录,调用接口copy_file_to_install"; +} + +bool UpdateDbus::makeDirs(QString path) +{ + // 有参数的情况下 传参调用dbus接口并保存返回值 + replyBool = interface->call("makedirs", path); + + // 将reply.value()作为返回值 + if (replyBool.isValid()) { + qDebug() << "makeDirs" << replyBool.value(); + return replyBool.value(); + } + else{ + qDebug() << QString("调用失败: makeDirs"); + return false; + } +} + +// setImportantStatus +void UpdateDbus::setImportantStatus(bool status) +{ + interface->asyncCall("set_important_status", status); + qDebug() <<"更新管理器-设置状态值" <<"setImportantStatus:"<asyncCall("install_and_upgrade",pkgName); + + // 将reply.value()作为返回值 + return true; +} + + + +void UpdateDbus::modifyConf(QString path, QString group, QString key, QString value) +{ + replyStr = interface->call("modify_conf",path,group,key,value); + qDebug() << QString("调用 modify_conf接口"); + +} + +void UpdateDbus::cleanUpdateList() +{ + qDebug() << "更新管理器清除列表:cleanUpdateList"; + interface->asyncCall("clear_install_list"); +} + +//初始化cache +void UpdateDbus::init_cache() +{ + + interface->call("init_cache"); + qDebug() << " call init_cache"; +} + +void UpdateDbus::getInameAndCnameList(QString arg) +{ + + qDebug()<<"getsignal"; + qDebug()< reply = interface1->call("getImportant"); + if (reply.isValid()) { + inameList = reply.value(); + qDebug() << inameList; +// qDebug() << value; + } else { + qDebug() << "value method 调用失败!"; + } +// emit sendImportant(); + +} + +void UpdateDbus::getAppMessageSignal(QMap map, QStringList urlList, QStringList nameList,QStringList fullnameList,QStringList sizeList, QString allSize, bool dependState) +{ + QVariant dateQVariant; + AppAllMsg appAllMsg; + QVariantMap::Iterator it; + for (it = map.begin(); it != map.end(); ++it) { + if (it.key() == "appname") + { + dateQVariant = it.value(); + appAllMsg.name = dateQVariant.toString(); + } + if(it.key() == "current_version") + { + dateQVariant = it.value(); + appAllMsg.version = dateQVariant.toString(); + } + if(it.key() == "source_version") + { + dateQVariant = it.value(); + appAllMsg.availableVersion = dateQVariant.toString(); + } + if(it.key() == "size") + { + dateQVariant = it.value(); + appAllMsg.packageSize = dateQVariant.toInt(); + } + if(it.key() == "description") + { + dateQVariant = it.value(); + appAllMsg.longDescription = dateQVariant.toString(); + } + } + if(urlList.length() != 0) + { + for(int i = 0; i < urlList.length(); i++) + { + UrlMsg msg; + msg.url = urlList.at(i); + msg.name = nameList.at(i); + msg.fullname = fullnameList.at(i); + QString size = sizeList.at(i); + msg.size = size.toInt(); + appAllMsg.msg.depList.append(msg); + } + } + appAllMsg.msg.allSize = allSize.toLong(); + appAllMsg.msg.getDepends = dependState; +// qDebug() << "获取信息" << appAllMsg.name << appAllMsg.longDescription; + emit sendAppMessageSignal(appAllMsg); +} + +void UpdateDbus::insertInstallStates(QString item,QString info) +{ + interface->asyncCall("insert_install_state",item,info); +} + +QStringList UpdateDbus::checkInstallOrUpgrade(QStringList list) +{ + replyStrList = interface->call("check_installed_or_upgrade",list); + if (replyStrList.isValid()) { + return replyStrList.value(); + } + else{ + QStringList error; + qDebug() << QString("check_installed_or_upgrade接口调用失败!"); + return error; + } +} + +void UpdateDbus::getAppMessage(QStringList list) +{ + interface->asyncCall("get_app_message",list); + qDebug() << "调用 get_app_message"; +} + + +void UpdateDbus::getAptSignal(QString arg, QMap map) +{ + + QString aptStatus; + QString aptAppName; + QString errorMessage; + float aptPercent = 0; + + QVariant dateQVariant; + aptStatus = arg; + + qDebug() << "安装状态" << arg; + + + QVariantMap::Iterator it; + for (it = map.begin(); it != map.end(); ++it) { + if (it.key() == "apt_appname") + { + dateQVariant = it.value(); + aptAppName = dateQVariant.toString(); + } + if(it.key() == "apt_percent") + { + dateQVariant = it.value(); + aptPercent = dateQVariant.toFloat(); + } + if(it.key() == "error_message") + { + dateQVariant = it.value(); + errorMessage = dateQVariant.toString(); + } + } + + qDebug() << "aptAppName:" << aptAppName; + qDebug() << "aptPercent:" << aptPercent; + + emit transferAptProgress(aptStatus,aptAppName,aptPercent,errorMessage); + +} + +void UpdateDbus::slotCopyFinished(QString appName) +{ + emit copyFinish(appName); +} + + +UpdateDbus::~UpdateDbus() +{ +// qDebug() << "update quit------>"; + cleanUpdateList(); + setImportantStatus(false); + fileUnLock(); +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatedbus.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatedbus.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatedbus.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatedbus.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,118 @@ +#ifndef UPDATEDBUS_H +#define UPDATEDBUS_H + +#define KYLIN_UPDATE_MANAGER_PATH "/cn/kylinos/KylinUpdateManager" + +#define KYLIN_UPDATE_MANAGER_SERVICE "cn.kylinos.KylinUpdateManager" + +#define KYLIN_UPDATE_MANAGER_INTERFACE "cn.kylinos.KylinUpdateManager" + +//#define SERVICE_NAME_SIZE 30 + +#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 "traybusthread.h" + +//#include +//#include "appupdate.h" +#include "metatypes.h" +#include "utils.h" +#include +#include + + +//Q_DECLARE_METATYPE(AppAllMsg) //注册AppMsg结构用于信号槽传输 + +class UpdateDbus : public QObject +{ + Q_OBJECT +public: + static UpdateDbus *getInstance(QObject *parenet = nullptr); + ~UpdateDbus(); + QDBusInterface *interface; //dbus接口 + QDBusReply replyStr; //string类型的返回值 + QDBusReply replyBool; //bool类型的返回值 + QDBusReply replyStrList; + QDBusReply replyInt; //int类型的返回值 + QDBusInterface *interface1; + + //拷贝软件包到安装目录 + void copyFinsh(QStringList srcPath,QString appName); + //创建root目录 + bool makeDirs(QString path); + // setImportantStatus + void setImportantStatus(bool status); + //检查列表中的包是否可升级 + QStringList checkInstallOrUpgrade(QStringList list); + + void getAppMessage(QStringList list); + //安装和升级 + bool installAndUpgrade(QString pkgName); + //修改配置文件 + void modifyConf(QString path,QString group,QString key,QString value); + //kill pid + void cleanUpdateList(); + //初始化cache + void init_cache(); +// bool makeDirs(QString path); +//dbus接口函数定义完毕 + // + void onRequestSendDesktopNotify(QString message); + QStringList inameList; //重要更新列表 + QStringList importantList; + QStringList failedList; + int importantSize = 0; + bool isPointOutNotBackup = true; //是否在单包更新时弹出提示未备份 + + + bool fileLock(); + void fileUnLock(); + //调用接口插入数据库 + void insertInstallStates(QString item, QString info); +signals: + void copyFinish(QString appName); + void transferAptProgress(QString status,QString appName,float aptPercent,QString errormsg); + void sendImportant(); + void sendAppMessageSignal(AppAllMsg msg); +// void emitInameList(QStringList list); + void sendFinishGetMsgSignal(int size); + +public slots: + void getAptSignal(QString arg, QMap map); + void slotCopyFinished(QString appName); + void getInameAndCnameList(QString arg); //获取重要更新列表和紧急更新列表 +// void initD_bus(bool status); + void getAppMessageSignal(QMap map, QStringList urlList, QStringList nameList,QStringList fullnameList,QStringList sizeList, QString allSize, bool dependState); + void slotFinishGetMessage(QString num); + +private: + explicit UpdateDbus(QObject *parent = nullptr); + static UpdateDbus *updateMutual; //UpdateDbus类静态对象 + QString lockPath = "/tmp/lock/kylin-update.lock"; +}; + + +#endif // UPDATEDBUS_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatelog.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatelog.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatelog.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatelog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,86 @@ +#include "updatelog.h" + + +UpdateLog::UpdateLog(QDialog *parent) : QDialog(parent) +{ + logUi(); + +} +void UpdateLog::logUi() +{ +// this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); +// this->setAttribute(Qt::WA_TranslucentBackground, true); + + this->setFixedSize(460,560); + if(QLocale::system().name()!="zh_CN") + { + this->setWindowTitle(tr("Update log")); + } + else + { + this->setWindowTitle("更新日志"); + } +// this->setWindowTitle("更新日志"); + + logVLayout = new QVBoxLayout(); + logMainLayout = new QVBoxLayout(); + + logAppHLayout = new QHBoxLayout(); + logAppVLayout = new QVBoxLayout(); + + logAppIcon = new QLabel(this); + logAppIcon->setFixedSize(48,48); + + logAppName = new QLabel(this); + logAppVerson = new QLabel(this); + + logWidget = new QWidget(this); + logAppWidget = new QWidget(this); + + + logContent = new QTextEdit(this); + QPalette pl = logContent->palette(); + pl.setBrush(QPalette::Base,QBrush(QColor(255,0,0,0))); + logContent->setPalette(pl); + contentFrame = new QFrame(this); + contentFrame->setFrameShape(QFrame::Box); + QVBoxLayout *contentLayout = new QVBoxLayout(); + contentFrame->setLayout(contentLayout); + contentLayout->addWidget(logContent); + contentLayout->setMargin(0); + contentLayout->setSpacing(0); + logContent->setReadOnly(true); + + logAppVLayout->addWidget(logAppName); + logAppVLayout->addWidget(logAppVerson); + logAppVLayout->setMargin(0); + logAppVLayout->setSpacing(0); + logAppHLayout->addWidget(logAppIcon); + logAppHLayout->addLayout(logAppVLayout); + logAppHLayout->setMargin(0); + logAppHLayout->setSpacing(8); + logAppWidget->setLayout(logAppHLayout); + + logVLayout->addWidget(logAppWidget); + logVLayout->addSpacing(12); + logVLayout->addWidget(contentFrame); + logVLayout->setContentsMargins(24,0,24,24); + logVLayout->setSpacing(0); + logWidget->setLayout(logVLayout); + + + logMainLayout->addWidget(logWidget); + logMainLayout->setMargin(5); + logMainLayout->setSpacing(0); + + + this->setLayout(logMainLayout); +} + +// 实现圆角阴影效果 +void UpdateLog::paintEvent(QPaintEvent *event) +{ +// WidgetStyle::paintEvent(event, this); +} + + diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatelog.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatelog.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatelog.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatelog.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,49 @@ +#ifndef UPDATELOG_H +#define UPDATELOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "widgetstyle.h" + + +class UpdateLog : public QDialog +{ + Q_OBJECT +public: + explicit UpdateLog(QDialog *parent = nullptr); + + void logUi(); + + QLabel *logAppIcon; + QLabel *logAppName; + QLabel *logAppVerson; + + QWidget *logWidget; + QWidget *logAppWidget; + + QHBoxLayout *logAppHLayout; + QVBoxLayout *logAppVLayout; + + QVBoxLayout *logVLayout; + + QVBoxLayout *logMainLayout; + + QTextEdit *logContent; + QFrame *contentFrame; + + + void paintEvent(QPaintEvent *); + + +}; + + + +#endif // UPDATELOG_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatesource.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatesource.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatesource.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatesource.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,70 @@ +#include "updatesource.h" +#include "updatesource.h" + +UpdateSource::UpdateSource(QObject *parent) : QObject(parent) +{ + serviceInterface = new QDBusInterface("com.kylin.software.properties", + "/com/kylin/software/properties", + "com.kylin.software.properties.interface", + QDBusConnection::systemBus()); + if(!serviceInterface->isValid()) + { + qDebug() << "源管理器:" <<"Service Interface: " << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } +} +/* + * 调用源管理器更新源模版接口 +*/ +void UpdateSource::callDBusUpdateTemplate() +{ + QDBusPendingCall call = serviceInterface->asyncCall("updateSourceTemplate"); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call,this); + connect(watcher,&QDBusPendingCallWatcher::finished,this,&UpdateSource::getReply); + qDebug() <<"源管理器:" << "callDBusUpdateTemplate: " << "updateSourceTemplate"; +} +/* + * 调用源管理器更新源缓存接口 +*/ +void UpdateSource::callDBusUpdateSource(QString symbol) +{ + QDBusPendingCall call = serviceInterface->asyncCall("updateSourcePackages",symbol); + qDebug() << "源管理器:" <<"Call updateSourcePackages" ; + +} + +QString UpdateSource::getFailInfo(int statusCode) +{ + qDebug()<< "UpdateSource::getFailInfo::::"<< statusCode; + QDBusReply replyStr; //string类型的返回值 + replyStr = serviceInterface->call("getFailInfo",statusCode); + if (replyStr.isValid()) { + qDebug() <<"源管理器:" << "getFailInfo:"< reply = *call; + if (!reply.isValid()) { + qDebug() <<"源管理器:" << "getReply:" << "iserror"; + } else { + bool status = reply.value(); + qDebug() <<"源管理器:" << "getReply:" << status; + if (status) { + callDBusUpdateSource(Symbol); + } + else + { + emit getReplyFalseSignal(); + } + + } +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatesource.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatesource.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/updatesource.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/updatesource.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,30 @@ +#ifndef UPDATESOURCE_H +#define UPDATESOURCE_H + +#include +#include +#include +#include +#include +#include +#include +const QString Symbol = "control"; +class UpdateSource : public QObject +{ + Q_OBJECT +public: + explicit UpdateSource(QObject *parent = nullptr); + + void callDBusUpdateTemplate(); + void callDBusUpdateSource(QString symbol); +// QDBusReply replyStr; //string类型的返回值 + QDBusInterface *serviceInterface; + void getReply(QDBusPendingCallWatcher *call); + QString getFailInfo(int statusCode); +signals: + void getReplyFalseSignal(); +public slots: + +}; + +#endif // UPDATESOURCE_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/upgrademain.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/upgrademain.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/upgrademain.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/upgrademain.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "upgrademain.h" +#include "metatypes.h" +//#include "connection.h" + +UpgradeMain::UpgradeMain(QString arg,QWidget *parent) + : QMainWindow(parent) +{ + qDBusRegisterMetaType(); + // 界面获取焦点 +// setFocus(); + +// CreatConnection(); + if(!CreatConnection()) + { + qDebug() << "datebase can not open."; + } + + // 用户手册功能 + mDaemonIpcDbus = new DaemonIpcDbus(); + + // 初始化组件 + setWidgetUi(); + + // 初始化样式 + setWidgetStyle(); + + + //初始化DBus + QTimer *timer = new QTimer; + timer->setSingleShot(true); + connect(timer,&QTimer::timeout,myTabwidget,&TabWid::initDbus); + timer->start(1); +} + +UpgradeMain::~UpgradeMain() +{ +// qDebug() << "quit mainwindow"; +} + +// 初始化组件 +void UpgradeMain::setWidgetUi() +{ + // 整体界面widget + mainWid = new QWidget(this); + + // 整体界面布局 + mainLayout = new QVBoxLayout(); + + // 设置整体界面布局 + mainLayout->setMargin(0); + mainLayout->setSpacing(0); + myTabwidget = new TabWid(this); + mainLayout->addWidget(myTabwidget); + + this->mainWid->setLayout(mainLayout); + // 将mainWid作为整体界面 + this->setCentralWidget(mainWid); +} + +// 初始化样式 +void UpgradeMain::setWidgetStyle() +{ + // 读取主题颜色配置文件 监听主题颜色改变 + if(QGSettings::isSchemaInstalled(FITTHEMEWINDOW)) + { + gSettings = new QGSettings(FITTHEMEWINDOW); + if(gSettings->get("style-name").toString() == "ukui-dark" || gSettings->get("style-name").toString() == "ukui-black"){ + WidgetStyle::themeColor = 1; + } + else + { + WidgetStyle::themeColor = 0; + } + + connect(gSettings,&QGSettings::changed,this,[=]() + { + qDebug() << "主题颜色" << gSettings->get("style-name").toString(); + if(gSettings->get("style-name").toString() == "ukui-dark" || gSettings->get("style-name").toString() == "ukui-black"){ + WidgetStyle::themeColor = 1; + changeDarkTheme(); + } + else + { + WidgetStyle::themeColor = 0; + changeLightTheme(); + } + + }); + } + + this->mainWid->setObjectName("mainWid"); +} + +// 切换深色模式 +void UpgradeMain::changeDarkTheme() +{ +} + +// 切换浅色模式 +void UpgradeMain::changeLightTheme() +{ +} + +// 实现键盘响应 +void UpgradeMain::keyPressEvent(QKeyEvent *event) +{ + // F1快捷键打开用户手册 + if (event->key() == Qt::Key_F1) { + if (!mDaemonIpcDbus->daemonIsNotRunning()){ + // F1快捷键打开用户手册,如kylin-update-manager + mDaemonIpcDbus->showGuide("kylin-update-manager"); + } + } +} + + + diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/upgrademain.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/upgrademain.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/upgrademain.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/upgrademain.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "connection.h" +#include "daemonipcdbus.h" +#include "widgetstyle.h" +#include "tabwidget.h" +#include "updatedbus.h" + + +class UpgradeMain : public QMainWindow +{ + Q_OBJECT + +public: + UpgradeMain(QString arg, QWidget *parent = nullptr); + ~UpgradeMain(); + + // 初始化组件 + void setWidgetUi(); + + // 初始化样式 + void setWidgetStyle(); + + // 切换深色模式 + void changeDarkTheme(); + + // 切换浅色模式 + void changeLightTheme(); + +public slots: + + // 键盘响应事件 + void keyPressEvent(QKeyEvent *event); + + + +private: + + + // 更新管理器Dbus + UpdateDbus *updateDbus; + // 整体界面widget + QWidget *mainWid; + // QGSettings + QGSettings *gSettings = nullptr; + // 用户手册功能 + DaemonIpcDbus *mDaemonIpcDbus; + // 整体界面布局 + QVBoxLayout *mainLayout; + TabWid *myTabwidget; + QTimer *my_time; + + +}; + +#endif // MAINWINDOW_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/utils.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/utils.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/utils.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/utils.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,53 @@ +#ifndef UTILS_H +#define UTILS_H +#include +#include + +#define DOWN_CACHE_PATH QString("%1/.kylin-update-manager/").arg(QDir::homePath()) +#define DOWN_TEMP_PATH QString("%1/.kylin-update-manager/kylin-update-manager-deb/deb/").arg(QDir::homePath()) +#define SOURCESLIST "/etc/apt/sources.list" + +enum type {http, ftp, file}; +struct UrlMsg //记录单包信息:包名、全名、链接、大小 +{ + QString name = ""; + QString fullname = ""; + QString url = ""; + int size; +}; + +struct AppMsg //记录当前包信息:包名、依赖列表、总大小、获取依赖状态 +{ + QVector depList; + long allSize = 0; + bool getDepends = false; +}; + +struct AppAllMsg +{ + QString name; + QString section; + QString origin; + int installedSize; + QString maintainer; + QString source; + QString version; + int packageSize; + QString shortDescription; + QString longDescription; + + QString changedPackages; + QString packageCount; + + QString changelogUrl; + QString screenshotUrl; + QString availableVersion; + + bool isInstalled; + bool upgradeable; + AppMsg msg; + +}; +Q_DECLARE_METATYPE(AppMsg) //注册AppMsg结构用于信号槽传输 +Q_DECLARE_METATYPE(AppAllMsg) //注册AppMsg结构用于信号槽传输 +#endif // UTILS_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/widgetstyle.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/widgetstyle.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/widgetstyle.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/widgetstyle.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "widgetstyle.h" + +int WidgetStyle::themeColor = 0; +int WidgetStyle::systemStatus = 0; + +//在屏幕中央显示 +WidgetStyle::WidgetStyle(QWidget *parent) +{ + // 初始化组件 + this->setWidgetUi(); + + // 初始化样式 + this->setWidgetStyle(); +} + +//在屏幕中央显示 +void WidgetStyle::handleIconClickedSub() +{ + QRect availableGeometry = qApp->primaryScreen()->availableGeometry(); + this->move((availableGeometry.width() - this->width())/2, (availableGeometry.height() - this->height())/2); +} + +// 初始化组件 +void WidgetStyle::setWidgetUi() +{ + +} + +// 初始化样式 +void WidgetStyle::setWidgetStyle() +{ + +} + +// 实现圆角阴影效果 +void WidgetStyle::paintEvent(QPaintEvent *event, QWidget *widget) +{ + QPainterPath path; + path.setFillRule(Qt::WindingFill); + QRectF rect(10, 10, widget->width()-20, widget->height()-20); + path.addRoundRect(rect, 6, 6); + + QPainter painter(widget); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.fillPath(path, QBrush(Qt::white)); + + QColor color(0, 0, 0, 50); + for(int i = 0; i < 10; i++) { + QPainterPath path; + path.setFillRule(Qt::WindingFill); + path.addRoundRect(10-i, 10-i, widget->width()-(10-i)*2, widget->height()-(10-i)*2,6); + color.setAlpha(150 - qSqrt(i)*50); + painter.setPen(color); + painter.drawPath(path); + } +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/widgetstyle.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/widgetstyle.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/src/widgetstyle.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/src/widgetstyle.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef WIDGETSTYLE_H +#define WIDGETSTYLE_H + +#define WINDOWW 620 //窗口宽度 +#define WINDOWH 580 //窗口高度 +#define TITLEH 38 //标题栏高度 + +#include +//窗口显示在屏幕中心 +#include +#include +//控件 +#include +#include +#include +#include +#include +//布局 +#include +//读取本地字体 +#include +//窗体阴影 +#include +#include +#include +#include + +#include "updatedbus.h" + +#define KYLINRECORDER "org.kylin-update-manager-data.settings" +#define FITTHEMEWINDOW "org.ukui.style" + + +class WidgetStyle : public QWidget +{ + Q_OBJECT +public: + explicit WidgetStyle(QWidget *parent = 0); + ~WidgetStyle() {} + + //主题颜色适配--浅色 + static int themeColor; + + //当前系统更新模式 是否为最新系统、是否开启自动更新 + static int systemStatus; + + //在屏幕中央显示 + void handleIconClickedSub(); + + // !!!组件和样式分离,每一个QWidget类都要有setWidgetUi()和setWidgetStyle()函数 + + // 初始化组件 + void setWidgetUi(); + + // 初始化样式 + void setWidgetStyle(); + + // 添加圆角阴影 + static void paintEvent(QPaintEvent *event, QWidget *widget); +}; + +#endif // WIDGETSTYLE_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/upgrade.cpp ukui-control-center-3.0.3/plugins/security-updates/upgrade/upgrade.cpp --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/upgrade.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/upgrade.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,40 @@ +#include "upgrade.h" + +#include +#include + +Upgrade::Upgrade() :mFirstLoad(true) { + //~ contents_path /upgrade/Upgrade + pluginName = tr("Upgrade"); + pluginType = UPDATE; +} + +Upgrade::~Upgrade() { + +} + +QString Upgrade::get_plugin_name() { + return pluginName; +} + +int Upgrade::get_plugin_type() { + return pluginType; +} + +QWidget *Upgrade::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + // will delete by takewidget + pluginWidget = new UpgradeMain(""); + } + + return pluginWidget; +} + +void Upgrade::plugin_delay_control() { + +} + +const QString Upgrade::name() const { + return QStringLiteral("upgrade"); +} diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/upgrade.h ukui-control-center-3.0.3/plugins/security-updates/upgrade/upgrade.h --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/upgrade.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/upgrade.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,31 @@ +#ifndef UPGRADE_H +#define UPGRADE_H + +#include + +#include "shell/interface.h" +#include "src/upgrademain.h" + +class Upgrade : public QObject, CommonInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") + Q_INTERFACES(CommonInterface) +public: + Upgrade(); + ~Upgrade(); + + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + +private: + QString pluginName; + int pluginType; + UpgradeMain *pluginWidget; + bool mFirstLoad; +}; + +#endif // UPGRADE_H diff -Nru ukui-control-center-2.0.3/plugins/security-updates/upgrade/upgrade.pro ukui-control-center-3.0.3/plugins/security-updates/upgrade/upgrade.pro --- ukui-control-center-2.0.3/plugins/security-updates/upgrade/upgrade.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/security-updates/upgrade/upgrade.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,95 @@ +include(../../../env.pri) +include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) + + +QT += core gui widgets network dbus sql + +TEMPLATE = lib +CONFIG += plugin link_pkgconfig c++11 +PKGCONFIG += gsettings-qt + +TARGET = $$qtLibraryTarget(upgrade) +DESTDIR = ../.. +target.path = $${PLUGIN_INSTALL_DIRS} + + +# 应用图标装载 +#icon.path = /usr/share/pixmaps +#icon.files = img/kylin-update-manager.png + +# desktop文件装载 +#desktop.path = /usr/share/applications/ +#desktop.files = kylin-update-manager.desktop + +# gsetting文件装载 +#schemes.files = data/org.kylin-update-manager-data.gschema.xml +#schemes.path = /usr/share/glib-2.0/schemas/ + +config.files = ./config_file/* +config.path = /usr/share/ukui-control-center/upgrade/ + + +INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE \ + $$PROJECT_ROOTDIR \ +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked 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 it uses 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 += \ + src/appupdate.cpp \ + src/backup.cpp \ + src/checkbutton.cpp \ + src/daemonipcdbus.cpp \ + src/historyupdatelistwig.cpp \ + src/m_updatelog.cpp \ + src/mylabel.cpp \ +# src/switchbutton.cpp \ + src/tabwidget.cpp \ + src/traybusthread.cpp \ + src/ukscconn.cpp \ + src/updatedbus.cpp \ + src/updatelog.cpp \ + src/updatesource.cpp \ + src/upgrademain.cpp \ + src/widgetstyle.cpp \ + upgrade.cpp + +HEADERS += \ + src/appupdate.h \ + src/backup.h \ + src/checkbutton.h \ + src/connection.h \ + src/daemonipcdbus.h \ + src/historyupdatelistwig.h \ + src/m_updatelog.h \ + src/metatypes.h \ + src/mylabel.h \ + src/shadowwidget.h \ +# src/switchbutton.h \ + src/tabwidget.h \ + src/traybusthread.h \ + src/ukscconn.h \ + src/updatedbus.h \ + src/updatelog.h \ + src/updatesource.h \ + src/upgrademain.h \ + src/utils.h \ + src/widgetstyle.h \ + upgrade.h + +# Default rules for deployment. +INSTALLS += target \ + icon \ + desktop \ + schemes \ + config + + diff -Nru ukui-control-center-2.0.3/plugins/system/autoboot/addautoboot.cpp ukui-control-center-3.0.3/plugins/system/autoboot/addautoboot.cpp --- ukui-control-center-2.0.3/plugins/system/autoboot/addautoboot.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/autoboot/addautoboot.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -19,10 +19,12 @@ */ #include "addautoboot.h" #include "ui_addautoboot.h" +#include "CloseButton/closebutton.h" #include +#include -//#define DESKTOPPATH "/etc/xdg/autostart/" +// #define DESKTOPPATH "/etc/xdg/autostart/" #define DESKTOPPATH "/usr/share/applications/" extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); @@ -35,61 +37,27 @@ setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - selectFile = ""; - -// ui->frame->setStyleSheet("QFrame{background: #ffffff; border: none; border-radius: 6px;}"); - -// //关闭按钮在右上角,窗体radius 6px,所以按钮只得6px -// ui->closeBtn->setStyleSheet("QPushButton#closeBtn{background: #ffffff; border: none; border-radius: 6px;}" -// "QPushButton:hover:!pressed#closeBtn{background: #FA6056; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}" -// "QPushButton:hover:pressed#closeBtn{background: #E54A50; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}"); - -// QString lineEditQss = QString("QLineEdit{background: #E9E9E9; border: none; border-radius: 4px;}"); -// ui->nameLineEdit->setStyleSheet(lineEditQss); -// ui->execLineEdit->setStyleSheet(lineEditQss); -// ui->commentLineEdit->setStyleSheet(lineEditQss); - -// QString btnQss = QString("QPushButton{background: #E9E9E9; border-radius: 4px;}" -// "QPushButton:checked{background: #3d6be5; border-radius: 4px;}" -// "QPushButton:hover:!pressed{background: #3d6be5; border-radius: 4px;}" -// "QPushButton:hover:pressed{background: #415FC4; border-radius: 4px;}"); - -// ui->cancelBtn->setStyleSheet(btnQss); -// ui->certainBtn->setStyleSheet(btnQss); - - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); - - - connect(ui->openBtn, SIGNAL(clicked(bool)), this, SLOT(open_desktop_dir_slots())); - connect(ui->cancelBtn, SIGNAL(clicked(bool)), this, SLOT(close())); - connect(ui->cancelBtn, &QPushButton::clicked, [=]{ - resetBeforeClose(); - }); - connect(ui->certainBtn, &QPushButton::clicked, this, [=]{ - emit autoboot_adding_signals(selectFile, ui->nameLineEdit->text(), ui->execLineEdit->text(), ui->commentLineEdit->text()); - resetBeforeClose(); - }); - connect(ui->closeBtn, &QPushButton::clicked, [=]{ - resetBeforeClose(); - }); + initStyle(); + initConnection(); } -void AddAutoBoot::resetBeforeClose(){ +void AddAutoBoot::resetBeforeClose() +{ + userEditNameFlag = false; + userEditCommentFlag = false; + ui->certainBtn->setEnabled(false); + ui->hintLabel->clear(); + ui->nameLineEdit->setToolTip(""); + ui->commentLineEdit->setToolTip(""); + ui->execLineEdit->setToolTip(""); ui->nameLineEdit->setText(QString()); ui->commentLineEdit->setText(QString()); ui->execLineEdit->setText(QString()); close(); } -void AddAutoBoot::paintEvent(QPaintEvent *event) { +void AddAutoBoot::paintEvent(QPaintEvent *event) +{ Q_UNUSED(event); QPainter p(this); p.setRenderHint(QPainter::Antialiasing); @@ -103,6 +71,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); @@ -124,19 +93,75 @@ // 绘制一个背景 p.save(); - p.fillPath(rectPath,palette().color(QPalette::Base)); + p.fillPath(rectPath, palette().color(QPalette::Base)); p.restore(); +} + +void AddAutoBoot::initStyle() +{ + ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); + + selectFile = ""; + + ui->nameLineEdit->setPlaceholderText(tr("Program name")); + ui->execLineEdit->setPlaceholderText(tr("Program exec")); + ui->commentLineEdit->setPlaceholderText(tr("Program comment")); + + ui->hintLabel->setAlignment(Qt::AlignCenter); + ui->hintLabel->setStyleSheet("color:red;"); + ui->certainBtn->setEnabled(false); +} +void AddAutoBoot::initConnection() +{ + connect(ui->openBtn, SIGNAL(clicked(bool)), this, SLOT(open_desktop_dir_slots())); + connect(ui->cancelBtn, SIGNAL(clicked(bool)), this, SLOT(close())); + connect(ui->execLineEdit, SIGNAL(textEdited(QString)), this, SLOT(execLinEditSlot(QString))); + connect(ui->cancelBtn, &QPushButton::clicked, [=] { + resetBeforeClose(); + }); + connect(ui->certainBtn, &QPushButton::clicked, this, [=] { + emit autoboot_adding_signals(selectFile, ui->nameLineEdit->text(), mDesktopExec, + ui->commentLineEdit->text(), mDesktopIcon); + resetBeforeClose(); + }); + + connect(ui->nameLineEdit, &QLineEdit::editingFinished, this, [=](){ + if (ui->nameLineEdit->text().isEmpty()) { + userEditNameFlag = false; + } else { // 用户输入了程序名 + userEditNameFlag = true; + } + }); + connect(ui->commentLineEdit, &QLineEdit::editingFinished, this, [=](){ + if (ui->commentLineEdit->text().isEmpty()) { + userEditCommentFlag = false; + } else { // 用户输入了描述 + userEditCommentFlag = true; + } + }); + + connect(ui->nameLineEdit, &QLineEdit::textChanged, this, [=](){ + ui->nameLineEdit->setToolTip(ui->nameLineEdit->text()); + }); + connect(ui->commentLineEdit, &QLineEdit::textChanged, this, [=](){ + ui->commentLineEdit->setToolTip(ui->commentLineEdit->text()); + }); + connect(ui->execLineEdit, &QLineEdit::textChanged, this, [=](){ + ui->execLineEdit->setToolTip(ui->execLineEdit->text()); + }); } AddAutoBoot::~AddAutoBoot() { delete ui; + ui = nullptr; } -void AddAutoBoot::open_desktop_dir_slots(){ - QString filters = "Desktop files(*.desktop)"; +void AddAutoBoot::open_desktop_dir_slots() +{ + QString filters = tr("Desktop files(*.desktop)"); QFileDialog fd; fd.setDirectory(DESKTOPPATH); fd.setAcceptMode(QFileDialog::AcceptOpen); @@ -144,7 +169,8 @@ fd.setNameFilter(filters); fd.setFileMode(QFileDialog::ExistingFile); fd.setWindowTitle(tr("select autoboot desktop")); - fd.setLabelText(QFileDialog::Accept, "Select"); + fd.setLabelText(QFileDialog::Accept, tr("Select")); + fd.setLabelText(QFileDialog::Reject, tr("Cancel")); if (fd.exec() != QDialog::Accepted) return; @@ -156,26 +182,90 @@ QByteArray ba; ba = selectedfile.toUtf8(); - //解析desktop文件 - GKeyFile * keyfile; - char *name, * comment, * exec; + // 解析desktop文件 + GKeyFile *keyfile; + char *name, *comment; + bool no_display; keyfile = g_key_file_new(); - if (!g_key_file_load_from_file(keyfile, ba.data(), G_KEY_FILE_NONE, NULL)){ - g_key_file_free (keyfile); + if (!g_key_file_load_from_file(keyfile, ba.data(), G_KEY_FILE_NONE, NULL)) { + g_key_file_free(keyfile); return; } + no_display = g_key_file_get_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, FALSE); + name = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL); + comment = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL); + mDesktopExec = g_key_file_get_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, NULL); + mDesktopIcon = g_key_file_get_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_ICON, NULL); - name = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL); - comment = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL); - exec = g_key_file_get_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL); - -// if (ui->nameLineEdit->text().isEmpty()) + if (userEditNameFlag == false) { // 用户输入了程序名,以用户输入为准,否则以自带的为准 ui->nameLineEdit->setText(QString(name)); -// if (ui->execLineEdit->text().isEmpty()) - ui->execLineEdit->setText(QString(exec)); -// if (ui->commentLineEdit->text().isEmpty()) + } + + ui->execLineEdit->setText(QString(selectedfile)); + if (userEditCommentFlag == false) { // 用户输入了程序描述,以用户输入为准,否则以自带的为准 ui->commentLineEdit->setText(QString(comment)); + } + emit ui->execLineEdit->textEdited(QString(selectedfile)); + if (no_display) { + ui->hintLabel->setText(tr("desktop file not allowed add")); + ui->hintLabel->setAlignment(Qt::AlignCenter); + ui->hintLabel->setStyleSheet("color:red;"); + ui->certainBtn->setEnabled(false); + } g_key_file_free(keyfile); } + +void AddAutoBoot::execLinEditSlot(const QString &fileName) +{ + selectFile = fileName; + QFileInfo fileInfo(fileName); + if (fileInfo.isFile() && fileName.endsWith("desktop")) { + ui->hintLabel->clear(); + ui->certainBtn->setEnabled(true); + + QByteArray ba; + ba = fileName.toUtf8(); + + // 解析desktop文件 + GKeyFile *keyfile; + char *name, *comment; + + keyfile = g_key_file_new(); + if (!g_key_file_load_from_file(keyfile, ba.data(), G_KEY_FILE_NONE, NULL)) { + g_key_file_free(keyfile); + return; + } + + name = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL); + mDesktopExec = g_key_file_get_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, NULL); + mDesktopIcon = g_key_file_get_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_ICON, NULL); + comment = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL); + + if (userEditNameFlag == false) { // 用户输入了程序名,以用户输入为准,否则以自带的为准 + ui->nameLineEdit->setText(QString(name)); + } + + ui->execLineEdit->setText(fileName); + if (userEditCommentFlag == false) { // 用户输入了程序描述,以用户输入为准,否则以自带的为准 + ui->commentLineEdit->setText(QString(comment)); + } + + g_key_file_free(keyfile); + } else { + ui->hintLabel->setText(tr("desktop file not exist")); + ui->hintLabel->setAlignment(Qt::AlignCenter); + ui->hintLabel->setStyleSheet("color:red;"); + ui->certainBtn->setEnabled(false); + } +} diff -Nru ukui-control-center-2.0.3/plugins/system/autoboot/addautoboot.h ukui-control-center-3.0.3/plugins/system/autoboot/addautoboot.h --- ukui-control-center-2.0.3/plugins/system/autoboot/addautoboot.h 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/autoboot/addautoboot.h 2021-05-20 13:08:14.000000000 +0000 @@ -24,7 +24,7 @@ #include #include #include - +#include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ @@ -58,15 +58,22 @@ private: Ui::AddAutoBoot *ui; + QString selectFile; + QString mDesktopExec; + QString mDesktopIcon; + bool userEditNameFlag = false; + bool userEditCommentFlag = false; private: - QString selectFile; + void initStyle(); + void initConnection(); private slots: void open_desktop_dir_slots(); + void execLinEditSlot(const QString &fileName); Q_SIGNALS: - void autoboot_adding_signals(QString path, QString name, QString exec, QString comment); + void autoboot_adding_signals(QString path, QString name, QString exec, QString comment, QString icon); }; #endif // ADDAUTOBOOT_H diff -Nru ukui-control-center-2.0.3/plugins/system/autoboot/addautoboot.ui ukui-control-center-3.0.3/plugins/system/autoboot/addautoboot.ui --- ukui-control-center-2.0.3/plugins/system/autoboot/addautoboot.ui 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/autoboot/addautoboot.ui 2021-04-14 01:27:20.000000000 +0000 @@ -6,20 +6,26 @@ 0 0 - 482 - 360 + 418 + 320 + + + 0 + 0 + + - 430 - 360 + 418 + 320 - 482 - 360 + 418 + 320 @@ -30,19 +36,25 @@ 0 - 9 + 42 - 9 + 32 - 9 + 4 - 9 + 42 + + + 0 + 0 + + 0 @@ -81,77 +93,67 @@ + + 0 + + + 0 + - 8 + 0 - 8 + 0 + + + + 0 + 0 + + + + Add autoboot program + + + + Qt::Horizontal + + QSizePolicy::Fixed + - 40 + 50 20 - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - 8 + 0 - 32 + 0 - 16 + 0 - 32 + 0 - 32 + 0 - - - - 0 - 0 - - - - Add autoboot program - - - - Qt::Vertical @@ -168,203 +170,249 @@ - - - 0 - - - - - - 0 - 0 - - - - - 110 - 0 - - - - - 110 - 16777215 - - - - Program name - - - true - - - - - - - - 258 - 28 - - - - - 258 - 28 - - - - - - - - + - 0 + 8 - - - - - 0 - 0 - - - - - 110 - 0 - - - - - 110 - 16777215 - - - - Program exec - - - true - - - - - - - - 182 - 28 - - - - - 182 - 28 - - - - - - - - - 60 - 28 - - - - - 60 - 28 - - - - Open - - - - - - - - + 0 - - - - 0 - 0 - - - - - 110 - 0 - - - - - 110 - 16777215 - - - - Program comment - - - true - - + + + 8 + + + + + + 0 + 0 + + + + + 110 + 0 + + + + + 140 + 16777215 + + + + Program name + + + true + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + + 140 + 16777215 + + + + Program exec + + + true + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + + 140 + 16777215 + + + + Program comment + + + true + + + + - - - - 258 - 28 - - - - - 258 - 28 - - - + + + 8 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 33 + + + + + 258 + 33 + + + + + + + + 6 + + + + + + 0 + 0 + + + + + 19 + 33 + + + + + 190 + 33 + + + + + + + + + 0 + 0 + + + + + 60 + 33 + + + + + 60 + 33 + + + + Open + + + + + + + + + + 0 + 0 + + + + + 0 + 33 + + + + + 258 + 33 + + + + + - - - Qt::Vertical - - - QSizePolicy::Fixed + + + + 0 + 0 + - + - 20 - 48 + 0 + 32 - + + + + + + 12 + Qt::Horizontal + + QSizePolicy::Fixed + - 40 + 80 20 @@ -416,19 +464,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - diff -Nru ukui-control-center-2.0.3/plugins/system/autoboot/autoboot.cpp ukui-control-center-3.0.3/plugins/system/autoboot/autoboot.cpp --- ukui-control-center-2.0.3/plugins/system/autoboot/autoboot.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/autoboot/autoboot.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -30,6 +30,7 @@ #include #include #include +#include /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 @@ -49,139 +50,158 @@ #define ITEMHEIGHT 62 #define HEADHEIGHT 38 +#define THEME_QT_SCHEMA "org.ukui.style" +#define THEME_GTK_SCHEMA "org.mate.interface" -//struct SaveData : QObjectUserData { -// QString bname; -//}; - -AutoBoot::AutoBoot(){ - ui = new Ui::AutoBoot; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); +#define ICON_QT_KEY "icon-theme-name" +#define ICON_GTK_KEY "icon-theme" - pluginName = tr("Autoboot"); +AutoBoot::AutoBoot() : mFirstLoad(true) +{ + pluginName = tr("Auto Boot"); pluginType = SYSTEM; - -// ui->addFrame->installEventFilter(this); - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - - -// pluginWidget->setStyleSheet("background: #ffffff;"); -// ui->addWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - -// ui->listWidget->setStyleSheet("QListWidget#listWidget{background: #ffffff; border: none;}" -// ""); - -// ui->addBtn->setIcon(QIcon("://img/plugins/autoboot/add.png")); -// ui->addBtn->setIconSize(QSize(48, 48)); -// ui->addBtn->setStyleSheet("QPushButton{background-color:transparent;}"); - - - -// ui->listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -// ui->listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - -// ui->listWidget->setSpacing(0); - - localconfigdir = g_build_filename(g_get_user_config_dir(), "autostart", NULL); - //初始化添加界面 - dialog = new AddAutoBoot(); - - initAddBtn(); - initUI(); - - connect(dialog, SIGNAL(autoboot_adding_signals(QString, QString,QString,QString)), this, SLOT(add_autoboot_realize_slot(QString ,QString,QString,QString))); } AutoBoot::~AutoBoot() { - delete ui; -// delete dialog; - g_free(localconfigdir); + if (!mFirstLoad) { + delete ui; + ui = nullptr; + g_free(localconfigdir); + } } -QString AutoBoot::get_plugin_name(){ +QString AutoBoot::get_plugin_name() +{ return pluginName; } -int AutoBoot::get_plugin_type(){ +int AutoBoot::get_plugin_type() +{ return pluginType; } -QWidget *AutoBoot::get_plugin_ui(){ +QWidget *AutoBoot::get_plugin_ui() +{ + if (mFirstLoad) { + mFirstLoad = false; + + ui = new Ui::AutoBoot; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + connectToServer(); + initTitleLabel(); + initStyle(); + localconfigdir = g_build_filename(g_get_user_config_dir(), "autostart", NULL); + + // 初始化添加界面 + dialog = new AddAutoBoot(); + + initConfig(); + initAddBtn(); + initUI(); + setupGSettings(); + initConnection(); + } return pluginWidget; } -void AutoBoot::plugin_delay_control(){ +void AutoBoot::plugin_delay_control() +{ +} +const QString AutoBoot::name() const +{ + return QStringLiteral("autoboot"); +} + +void AutoBoot::setupGSettings() +{ + const QByteArray id(THEME_QT_SCHEMA); + mQtSettings = new QGSettings(id, QByteArray(), this); } -void AutoBoot::initAddBtn() { - addWgt = new HoverWidget(""); +void AutoBoot::initAddBtn() +{ + addWgt = new HoverWidget("", pluginWidget); addWgt->setObjectName("addwgt"); addWgt->setMinimumSize(QSize(580, 50)); addWgt->setMaximumSize(QSize(960, 50)); - addWgt->setStyleSheet("HoverWidget#addwgt{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); + addWgt->setStyleSheet( + "HoverWidget#addwgt{background: palette(button); border-radius: 4px;}HoverWidget:hover:!pressed#addwgt{background: #3D6BE5; border-radius: 4px;}"); QHBoxLayout *addLyt = new QHBoxLayout; - QLabel * iconLabel = new QLabel(); - QLabel * textLabel = new QLabel(tr("Add autoboot app ")); + QLabel *iconLabel = new QLabel(pluginWidget); + QLabel *textLabel = new QLabel(tr("Add autoboot app "), pluginWidget); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); + iconLabel->setProperty("useIconHighlightEffect", true); + iconLabel->setProperty("iconHighlightEffectMode", 1); addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); addWgt->setLayout(addLyt); // 悬浮改变Widget状态 - connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname){ + connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname) { + Q_UNUSED(mname); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: palette(base);"); - }); // 还原状态 - connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname){ + connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname) { + Q_UNUSED(mname); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); textLabel->setStyleSheet("color: palette(windowText);"); }); connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname){ + Q_UNUSED(mname); dialog->exec(); }); ui->addLyt->addWidget(addWgt); +} + +void AutoBoot::initTitleLabel() +{ + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); +} +void AutoBoot::initStyle() +{ + //~ contents_path /autoboot/Autoboot Settings + ui->titleLabel->setText(tr("Autoboot Settings")); } -void AutoBoot::initUI(){ +void AutoBoot::initUI() +{ _walk_config_dirs(); appgroupMultiMaps.clear(); int num = statusMaps.count(); - //显示全部ITEM,设置高 -// ui->listWidget->setFixedHeight(num * ITEMHEIGHT + HEADHEIGHT); - - //构建行头基础Widget - QFrame * headbaseFrame = new QFrame; + // 构建行头基础Widget + QFrame *headbaseFrame = new QFrame(pluginWidget); headbaseFrame->setMinimumWidth(550); headbaseFrame->setMaximumWidth(960); headbaseFrame->setFrameShape(QFrame::Shape::Box); headbaseFrame->setAttribute(Qt::WA_DeleteOnClose); - QVBoxLayout * headbaseVerLayout = new QVBoxLayout(headbaseFrame); + QVBoxLayout *headbaseVerLayout = new QVBoxLayout(headbaseFrame); headbaseVerLayout->setSpacing(0); headbaseVerLayout->setContentsMargins(0, 0, 0, 2); - //构建行头 - QWidget * headWidget = new QWidget; + // 构建行头 + QWidget *headWidget = new QWidget(pluginWidget); headWidget->setMinimumWidth(550); headWidget->setMaximumWidth(960); @@ -189,28 +209,18 @@ headWidget->setMaximumHeight(36); headWidget->setAttribute(Qt::WA_DeleteOnClose); headWidget->setObjectName("headWidget"); -// headWidget->setFixedHeight(36); -// headWidget->setStyleSheet("QWidget#headWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); - QHBoxLayout * headHorLayout = new QHBoxLayout(headWidget); + QHBoxLayout *headHorLayout = new QHBoxLayout(headWidget); headHorLayout->setSpacing(16); headHorLayout->setContentsMargins(64, 0, 32, 0); - QLabel * nameLabel = new QLabel(headWidget); -// QSizePolicy nameSizePolicy = nameLabel->sizePolicy(); -// nameSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); -// nameLabel->setSizePolicy(nameSizePolicy); + QLabel *nameLabel = new QLabel(headWidget); nameLabel->setFixedWidth(220); nameLabel->setText(tr("Name")); -// nameLabel->setStyleSheet("background: #F4F4F4;"); - QLabel * statusLabel = new QLabel(headWidget); -// QSizePolicy statusSizePolicy = statusLabel->sizePolicy(); -// statusSizePolicy.setHorizontalPolicy(QSizePolicy::Fixed); -// statusLabel->setSizePolicy(statusSizePolicy); - statusLabel->setFixedWidth(68); + QLabel *statusLabel = new QLabel(headWidget); + statusLabel->setFixedWidth(150); statusLabel->setText(tr("Status")); -// statusLabel->setStyleSheet("background: #F4F4F4;"); headHorLayout->addWidget(nameLabel); headHorLayout->addStretch(); @@ -222,32 +232,26 @@ headbaseVerLayout->addWidget(headWidget); headbaseVerLayout->addStretch(); -// headbaseFrame->setLayout(headbaseVerLayout); - -// QListWidgetItem * hItem = new QListWidgetItem(ui->listWidget); -// hItem->setSizeHint(QSize(ITEMWIDTH, HEADHEIGHT)); -// ui->listWidget->setItemWidget(hItem, headbaseFrame); ui->autoLayout->addWidget(headbaseFrame); - //构建每个启动项 - QSignalMapper * checkSignalMapper = new QSignalMapper(this); + // 构建每个启动项 + QSignalMapper *checkSignalMapper = new QSignalMapper(this); QMap::iterator it = statusMaps.begin(); - for (int index = 0; it != statusMaps.end(); it++, index++){ + for (int index = 0; it != statusMaps.end(); it++, index++) { QString bname = it.value().bname; QString appName = it.value().name; - QFrame * baseWidget = new QFrame; + QFrame *baseWidget = new QFrame(pluginWidget); baseWidget->setMinimumWidth(550); baseWidget->setMaximumWidth(960); baseWidget->setFrameShape(QFrame::Shape::Box); baseWidget->setAttribute(Qt::WA_DeleteOnClose); - QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget); + QVBoxLayout *baseVerLayout = new QVBoxLayout(baseWidget); baseVerLayout->setSpacing(0); baseVerLayout->setContentsMargins(0, 0, 0, 2); - HoverWidget * widget = new HoverWidget(bname); -// widget->setFixedHeight(60); // + HoverWidget *widget = new HoverWidget(bname); widget->setMinimumWidth(550); widget->setMaximumWidth(960); @@ -255,43 +259,35 @@ widget->setMaximumHeight(60); widget->setAttribute(Qt::WA_DeleteOnClose); -// widget->setStyleSheet("background: #F4F4F4;"); - QHBoxLayout * mainHLayout = new QHBoxLayout(widget); + QHBoxLayout *mainHLayout = new QHBoxLayout(widget); mainHLayout->setContentsMargins(16, 0, 32, 0); mainHLayout->setSpacing(16); - QLabel * iconLabel = new QLabel(widget); + QLabel *iconLabel = new QLabel(widget); iconLabel->setFixedSize(32, 32); iconLabel->setPixmap(it.value().pixmap); -// iconLabel->setStyleSheet("background: #F4F4F4"); - QLabel * textLabel = new QLabel(widget); -// textLabel->setStyleSheet("background: #F4F4F4"); + QLabel *textLabel = new QLabel(widget); textLabel->setFixedWidth(250); textLabel->setText(appName); - SwitchButton * button = new SwitchButton(); + SwitchButton *button = new SwitchButton(widget); button->setAttribute(Qt::WA_DeleteOnClose); -// button->setChecked(it.value().enable); button->setChecked(!it.value().hidden); connect(button, SIGNAL(checkedChanged(bool)), checkSignalMapper, SLOT(map())); checkSignalMapper->setMapping(button, it.key()); appgroupMultiMaps.insert(it.key(), button); - QPushButton * dBtn = new QPushButton(widget); - dBtn->setFixedSize(QSize(32, 32)); - dBtn->setText("Del"); + QPushButton *dBtn = new QPushButton(widget); + dBtn->setFixedSize(QSize(64, 32)); + dBtn->setText(tr("Delete")); dBtn->setHidden(true); - connect(dBtn, &QPushButton::clicked, this, [=]{ + connect(dBtn, &QPushButton::clicked, this, [=] { del_autoboot_realize(bname); }); -// dBtn->setStyleSheet("" -// "QPushButton{background: #FA6056; border-radius: 2px;}" -// "QPushButton:hover:pressed{background: #E54A50; border-radius: 2px;}"); - - QLabel * pLabel = new QLabel(widget); - pLabel->setFixedSize(QSize(32, 32)); + QLabel *pLabel = new QLabel(widget); + pLabel->setFixedSize(QSize(64, 32)); pLabel->setHidden(false); mainHLayout->addWidget(iconLabel); @@ -303,19 +299,16 @@ mainHLayout->addWidget(dBtn); widget->setLayout(mainHLayout); - if (it.value().xdg_position == LOCALPOS){ + if (it.value().xdg_position == LOCALPOS) { connect(widget, &HoverWidget::enterWidget, this, [=](QString name){ Q_UNUSED(name) dBtn->setHidden(false); pLabel->setHidden(true); - // widget->setStyleSheet("background: #EEF2FD;"); - }); connect(widget, &HoverWidget::leaveWidget, this, [=](QString name){ Q_UNUSED(name) dBtn->setHidden(true); pLabel->setHidden(false); - // widget->setStyleSheet("background: #F4F4F4;"); }); } @@ -324,54 +317,40 @@ baseWidget->setLayout(baseVerLayout); -// QListWidgetItem * item = new QListWidgetItem(ui->listWidget); -// item->setSizeHint(QSize(ITEMWIDTH, ITEMHEIGHT)); -// ui->listWidget->setItemWidget(item, baseWidget); -// ui->listWidget->setSpacing(1); ui->autoLayout->addWidget(baseWidget); } connect(checkSignalMapper, SIGNAL(mapped(QString)), this, SLOT(checkbox_changed_cb(QString))); } +void AutoBoot::initConnection() +{ + connect(mQtSettings, &QGSettings::changed, this, [=] { + QLayoutItem *child; + while ((child = ui->autoLayout->takeAt(0)) != nullptr) + { + child->widget()->setParent(nullptr); + delete child; + } + initUI(); + }); + connect(dialog, SIGNAL(autoboot_adding_signals(QString,QString,QString,QString,QString)), + this, SLOT(add_autoboot_realize_slot(QString,QString,QString,QString,QString))); +} -bool AutoBoot::_copy_desktop_file_to_local(QString bname){ -// GFile * srcfile; -// GFile * dstfile; -// GError * error; -// char * dstpath, * srcpath; - +bool AutoBoot::_copy_desktop_file_to_local(QString bname) +{ QString srcPath; QString dstPath; - //不存在则创建~/.config/autostart/ - if (!g_file_test(localconfigdir, G_FILE_TEST_EXISTS)){ - GFile * dstdirfile; - dstdirfile = g_file_new_for_path(localconfigdir); - g_file_make_directory(dstdirfile, NULL, NULL); - } - QMap::iterator it = appMaps.find(bname); -// dstpath = g_build_filename(localconfigdir, bname.toLatin1().data(), NULL); -// srcpath = it.value().path.toLatin1().data(); dstPath = QString(localconfigdir) + "/" + bname; srcPath = it.value().path; -// srcfile = g_file_new_for_path(srcpath); -// dstfile = g_file_new_for_path(dstpath); - -// if (!g_file_copy(srcfile, dstfile, G_FILE_COPY_NONE, NULL, NULL, NULL, &error)){ -// qDebug() << "Could not copy desktop file for autoboot"; -// g_object_unref(srcfile); -// g_object_unref(dstfile); -// g_free(dstpath); -// return false; -// } - if (!QFile::copy(srcPath, dstPath)) return false; - //更新数据 + // 更新数据 AutoApp addapp; addapp = _app_new(dstPath.toLatin1().data()); addapp.xdg_position = ALLPOS; @@ -382,50 +361,48 @@ updateit.value().xdg_position = ALLPOS; updateit.value().path = dstPath; -// g_object_unref(srcfile); -// g_object_unref(dstfile); -// g_free(dstpath); return true; } void AutoBoot::clearAutoItem() { if (ui->autoLayout->layout() != NULL) { - QLayoutItem* item; - while ((item = ui->autoLayout->layout()->takeAt(0)) != NULL ) + QLayoutItem *item; + while ((item = ui->autoLayout->layout()->takeAt(0)) != NULL) { delete item->widget(); delete item; + item = nullptr; } -// delete ui->availableLayout->layout(); } } -bool AutoBoot::_delete_local_autoapp(QString bname){ - char * dstpath; +bool AutoBoot::_delete_local_autoapp(QString bname) +{ + char *dstpath; + QByteArray ba = bname.toUtf8(); - dstpath = g_build_filename(localconfigdir, bname.toUtf8().data(), NULL); + dstpath = g_build_filename(localconfigdir, ba.data(), NULL); - if (g_remove(dstpath) == -1){ + if (g_remove(dstpath) == -1) { g_free(dstpath); return false; } - //更新数据 + // 更新数据 localappMaps.remove(bname); QMap::iterator updateit = statusMaps.find(bname); if (updateit == statusMaps.end()) qDebug() << "statusMaps Data Error when delete local file"; - else{ - - if (updateit.value().xdg_position == LOCALPOS){ + else { + if (updateit.value().xdg_position == LOCALPOS) { statusMaps.remove(bname); - } else if (updateit.value().xdg_position == ALLPOS){ + } else if (updateit.value().xdg_position == ALLPOS) { QMap::iterator appit = appMaps.find(bname); if (appit == appMaps.end()) qDebug() << "appMaps Data Error when delete local file"; - else{ + else { updateit.value().hidden = appit.value().hidden; updateit.value().path = appit.value().path; } @@ -437,29 +414,30 @@ return true; } -bool AutoBoot::_enable_autoapp(QString bname, bool status){ - char * dstpath; +bool AutoBoot::_enable_autoapp(QString bname, bool status) +{ + char *dstpath; dstpath = g_build_filename(localconfigdir, bname.toUtf8().data(), NULL); - //获取并修改值 - GKeyFile * keyfile; - GError * error; + // 获取并修改值 + GKeyFile *keyfile; + GError *error; keyfile = g_key_file_new(); error = NULL; g_key_file_load_from_file(keyfile, dstpath, G_KEY_FILE_KEEP_COMMENTS, &error); - - if (error){ + if (error) { g_error_free(error); qDebug() << "Start autoboot failed because keyfile load from file error"; g_free(dstpath); return false; } - g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, !status); + g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, + !status); - if (!_key_file_to_file(keyfile, dstpath)){ + if (!_key_file_to_file(keyfile, dstpath)) { qDebug() << "Start autoboot failed because could not save desktop file"; g_free(dstpath); return false; @@ -467,33 +445,32 @@ g_key_file_free(keyfile); - //更新数据 + // 更新数据 QMap::iterator updateit = statusMaps.find(bname); if (updateit == statusMaps.end()) qDebug() << "Start autoboot failed because autoBoot Data Error"; - else{ + else { updateit.value().hidden = !status; } g_free(dstpath); return true; - } -bool AutoBoot::_delete_autoapp(QString bname){ - char * dstpath; +bool AutoBoot::_delete_autoapp(QString bname) +{ + char *dstpath; dstpath = g_build_filename(localconfigdir, bname.toUtf8().data(), NULL); - //获取并修改值 - GKeyFile * keyfile; - GError * error; + // 获取并修改值 + GKeyFile *keyfile; + GError *error; keyfile = g_key_file_new(); error = NULL; g_key_file_load_from_file(keyfile, dstpath, G_KEY_FILE_KEEP_COMMENTS, &error); - - if (error){ + if (error) { g_error_free(error); qDebug() << "Delete autoboot failed because keyfile load from file error"; g_free(dstpath); @@ -502,36 +479,36 @@ g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, true); - if (!_key_file_to_file(keyfile, dstpath)){ + if (!_key_file_to_file(keyfile, dstpath)) { qDebug() << "Delete autoboot failed because could not save desktop file"; g_free(dstpath); return false; } - //刷新界面 -// ui->listWidget->clear(); + // 刷新界面 +// ui->listWidget->clear(); clearAutoItem(); initUI(); g_free(dstpath); + g_free(keyfile); return true; } -bool AutoBoot::_stop_autoapp(QString bname){ - - char * dstpath; +bool AutoBoot::_stop_autoapp(QString bname) +{ + char *dstpath; dstpath = g_build_filename(localconfigdir, bname.toUtf8().data(), NULL); - //获取并修改值 - GKeyFile * keyfile; - GError * error; + // 获取并修改值 + GKeyFile *keyfile; + GError *error; keyfile = g_key_file_new(); error = NULL; g_key_file_load_from_file(keyfile, dstpath, G_KEY_FILE_KEEP_COMMENTS, &error); - - if (error){ + if (error) { g_error_free(error); qDebug() << "Stop autoboot failed because keyfile load from file error"; g_free(dstpath); @@ -540,7 +517,7 @@ g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, true); - if (!_key_file_to_file(keyfile, dstpath)){ + if (!_key_file_to_file(keyfile, dstpath)) { qDebug() << "Stop autoboot failed because could not save desktop file"; g_free(dstpath); return false; @@ -548,11 +525,11 @@ g_key_file_free(keyfile); - //更新数据 + // 更新数据 QMap::iterator updateit = statusMaps.find(bname); if (updateit == statusMaps.end()) qDebug() << "Stop autoboot failed because AutoBoot Data Error"; - else{ + else { updateit.value().hidden = true; } @@ -560,9 +537,10 @@ return true; } -gboolean AutoBoot::_key_file_to_file(GKeyFile *keyfile, const gchar *path){ - GError * werror; - gchar * data; +gboolean AutoBoot::_key_file_to_file(GKeyFile *keyfile, const gchar *path) +{ + GError *werror; + gchar *data; gsize length; gboolean res; @@ -579,11 +557,11 @@ return FALSE; return res; - } -gboolean AutoBoot::_key_file_get_shown(GKeyFile *keyfile, const char *currentdesktop){ - char ** only_show_in, ** not_show_in; +gboolean AutoBoot::_key_file_get_shown(GKeyFile *keyfile, const char *currentdesktop) +{ + char **only_show_in, **not_show_in; gboolean found; if (!currentdesktop) @@ -591,10 +569,10 @@ only_show_in = g_key_file_get_string_list(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, NULL, NULL); - if (only_show_in){ + if (only_show_in) { found = FALSE; - for (int i = 0; only_show_in[i] != NULL; i++){ - if (g_strcmp0(currentdesktop, only_show_in[i]) == 0){ + for (int i = 0; only_show_in[i] != NULL; i++) { + if (g_strcmp0(currentdesktop, only_show_in[i]) == 0) { found = TRUE; break; } @@ -606,10 +584,10 @@ not_show_in = g_key_file_get_string_list(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, NULL, NULL); - if (not_show_in){ + if (not_show_in) { found = FALSE; - for (int i = 0; not_show_in[i] != NULL; i++){ - if (g_strcmp0(currentdesktop, not_show_in[i]) == 0){ + for (int i = 0; not_show_in[i] != NULL; i++) { + if (g_strcmp0(currentdesktop, not_show_in[i]) == 0) { found = TRUE; break; } @@ -622,30 +600,32 @@ return TRUE; } -gboolean AutoBoot::_key_file_get_boolean(GKeyFile *keyfile, const gchar *key, gboolean defaultvalue){ - GError * error; +gboolean AutoBoot::_key_file_get_boolean(GKeyFile *keyfile, const gchar *key, gboolean defaultvalue) +{ + GError *error; gboolean retval; error = NULL; retval = g_key_file_get_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, key, &error); - if (error != NULL){ + if (error != NULL) { retval = defaultvalue; g_error_free(error); } return retval; } -AutoApp AutoBoot::_app_new(const char *path){ +AutoApp AutoBoot::_app_new(const char *path) +{ AutoApp app; - GKeyFile * keyfile; - char * bname, * obpath, *name, * comment, * exec, * icon; - bool hidden, no_display, enable, shown; + GKeyFile *keyfile; + char *bname, *obpath, *name, *comment, *exec, *icon; + bool hidden, no_display, enable, shown; app.bname = ""; keyfile = g_key_file_new(); - if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, NULL)){ - g_key_file_free (keyfile); + if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, NULL)) { + g_key_file_free(keyfile); return app; } @@ -653,12 +633,16 @@ obpath = g_strdup(path); hidden = _key_file_get_boolean(keyfile, G_KEY_FILE_DESKTOP_KEY_HIDDEN, FALSE); no_display = _key_file_get_boolean(keyfile, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, FALSE); -// enable = _key_file_get_boolean(keyfile, APP_KEY_FILE_DESKTOP_KEY_AUTOSTART_ENABLE, TRUE); +// enable = _key_file_get_boolean(keyfile, APP_KEY_FILE_DESKTOP_KEY_AUTOSTART_ENABLE, TRUE); shown = _key_file_get_shown(keyfile, g_getenv("XDG_CURRENT_DESKTOP")); - name = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL); - comment = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL); - exec = g_key_file_get_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, NULL); - icon = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL, NULL); + name = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL); + comment = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL); + exec = g_key_file_get_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, + NULL); + icon = g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_ICON, NULL, NULL); app.bname = QString::fromUtf8(bname); app.path = QString::fromUtf8(obpath); @@ -666,16 +650,23 @@ app.hidden = hidden; app.no_display = no_display; app.shown = shown; -// app.enable = enable; +// app.enable = enable; app.name = QString::fromUtf8(name); app.comment = QString::fromUtf8(comment); app.exec = QString::fromUtf8(exec); - if (!QString(icon).isEmpty() && QIcon::hasThemeIcon(QString(icon))){ - QIcon currenticon = QIcon::fromTheme(QString(icon)); + + QFileInfo iconfile(static_cast(icon)); + + if (!QString(icon).isEmpty() /*&& QIcon::hasThemeIcon(QString(icon))*/) { + QIcon currenticon + = QIcon::fromTheme(QString(icon), + QIcon(QString("/usr/share/pixmaps/"+QString(QLatin1String(icon)) + +".png"))); app.pixmap = currenticon.pixmap(QSize(32, 32)); - } - else{ + } else if (iconfile.exists()) { + app.pixmap = QPixmap(iconfile.filePath()).scaled(32, 32); + } else { app.pixmap = QPixmap(QString(":/img/plugins/autoboot/desktop.png")); } @@ -686,49 +677,50 @@ return app; } -void AutoBoot::_walk_config_dirs(){ - const char * const * systemconfigdirs; - GDir * dir; - const char * name; +void AutoBoot::_walk_config_dirs() +{ + const char * const *systemconfigdirs; + GDir *dir; + const char *name; appMaps.clear(); - systemconfigdirs = g_get_system_config_dirs(); //获取系统配置目录 - for (int i = 0; systemconfigdirs[i]; i++){ - char * path; + systemconfigdirs = g_get_system_config_dirs(); // 获取系统配置目录 + for (int i = 0; systemconfigdirs[i]; i++) { + char *path; path = g_build_filename(systemconfigdirs[i], "autostart", NULL); dir = g_dir_open(path, 0, NULL); if (!dir) continue; while ((name = g_dir_read_name(dir))) { AutoApp app; - char * desktopfilepath; + char *desktopfilepath; if (!g_str_has_suffix(name, ".desktop")) continue; desktopfilepath = g_build_filename(path, name, NULL); app = _app_new(desktopfilepath); -// if (app.bname == "" || app.hidden || app.no_display || !app.shown || -// app.exec == "/usr/bin/ukui-settings-daemon") //gtk控制面板屏蔽ukui-settings-daemon,猜测禁止用户关闭 -// continue; +// if (app.bname == "" || app.hidden || app.no_display || !app.shown || +// app.exec == "/usr/bin/ukui-settings-daemon") //gtk控制面板屏蔽ukui-settings-daemon,猜测禁止用户关闭 +// continue; app.xdg_position = SYSTEMPOS; appMaps.insert(app.bname, app); - g_free (desktopfilepath); + g_free(desktopfilepath); } g_dir_close(dir); } localappMaps.clear(); dir = g_dir_open(localconfigdir, 0, NULL); - if (dir){ + if (dir) { while ((name = g_dir_read_name(dir))) { AutoApp localapp; - char * localdesktopfilepath; + char *localdesktopfilepath; if (!g_str_has_suffix(name, ".desktop")) continue; localdesktopfilepath = g_build_filename(localconfigdir, name, NULL); localapp = _app_new(localdesktopfilepath); localapp.xdg_position = LOCALPOS; - localappMaps.insert(localapp.bname, localapp); + localappMaps.insert(localapp.bname, localapp); g_free(localdesktopfilepath); } g_dir_close(dir); @@ -736,82 +728,87 @@ update_app_status(); } -void AutoBoot::update_app_status(){ +void AutoBoot::update_app_status() +{ statusMaps.clear(); QMap::iterator it = appMaps.begin(); - for (; it != appMaps.end(); it++){ - if (/*it.value().hidden || */it.value().no_display || !it.value().shown || - it.value().exec == "/usr/bin/ukui-settings-daemon") //gtk控制面板屏蔽ukui-settings-daemon,猜测禁止用户关闭 + for (; it != appMaps.end(); it++) { + if (/*it.value().hidden || */ it.value().no_display || !it.value().shown + || it.value().bname == "browser360-cn_preheat.desktop" + || it.value().bname == "vmware-user.desktop" + || it.value().exec == "/usr/bin/ukui-settings-daemon") // gtk控制面板屏蔽ukui-settings-daemon,猜测禁止用户关闭 continue; statusMaps.insert(it.key(), it.value()); } QMap::iterator localit = localappMaps.begin(); - for (; localit != localappMaps.end(); localit++){ - if (/*localit.value().hidden || */localit.value().no_display || !localit.value().shown){ + for (; localit != localappMaps.end(); localit++) { + if (/*localit.value().hidden || */ localit.value().no_display || !localit.value().shown) { statusMaps.remove(localit.key()); continue; } - if (statusMaps.contains(localit.key())){ - //整合状态 + if (statusMaps.contains(localit.key())) { + // 整合状态 QMap::iterator updateit = statusMaps.find(localit.key()); -// if (localit.value().enable != updateit.value().enable){ -// updateit.value().enable = localit.value().enable; -// updateit.value().path = localit.value().path; -// if (appMaps.contains(localit.key())) -// updateit.value().xdg_position = ALLPOS; -// } - if (localit.value().hidden != updateit.value().hidden){ + if (localit.value().hidden != updateit.value().hidden) { updateit.value().hidden = localit.value().hidden; updateit.value().path = localit.value().path; - if (appMaps.contains(localit.key())){ + if (appMaps.contains(localit.key())) { updateit.value().xdg_position = ALLPOS; } } - } - else{ + } else { statusMaps.insert(localit.key(), localit.value()); } - } } - -void AutoBoot::add_autoboot_realize_slot(QString path, QString name, QString exec, QString comment){ +void AutoBoot::add_autoboot_realize_slot(QString path, QString name, QString exec, QString comment, + QString icon) +{ + if (exec.contains("kylin-screenshot")) { + QStringList screenshotExec = exec.split(" "); + exec = screenshotExec.at(0); + } if (path.isEmpty()) return; - char * filename, * filepath; + char *filename, *filepath; + QByteArray ba = path.section("/", -1, -1).toUtf8(); - filename = path.section("/", -1, -1).toUtf8().data(); - - - if (!g_file_test(localconfigdir, G_FILE_TEST_EXISTS)){ - GFile * dstdirfile; - dstdirfile = g_file_new_for_path(localconfigdir); - g_file_make_directory(dstdirfile, NULL, NULL); - } + // filename = path.section("/", -1, -1).toUtf8().data(); + // 需要定位desktop解析失败原因,bug#37606 + // Fix: toUtf8 -> data 数据类型不可连转 + filename = ba.data(); + qDebug() << "desktop: "<< path.section("/", -1, -1).toUtf8().data(); filepath = g_build_filename(localconfigdir, filename, NULL); - GKeyFile * keyfile; + GKeyFile *keyfile; keyfile = g_key_file_new(); - const char * locale = const_cast(QLocale::system().name().toUtf8().data()); - char * type = QString("Application").toUtf8().data(); + const char *locale = const_cast(QLocale::system().name().toUtf8().data()); + char *type = QString("Application").toUtf8().data(); g_key_file_set_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TYPE, type); -// g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, APP_KEY_FILE_DESKTOP_KEY_AUTOSTART_ENABLE, true); - g_key_file_set_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, exec.toUtf8().data()); +// g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, APP_KEY_FILE_DESKTOP_KEY_AUTOSTART_ENABLE, true); + g_key_file_set_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, + exec.toUtf8().data()); g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, false); - g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, false); - g_key_file_set_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, name.toUtf8().data()); - g_key_file_set_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, locale, name.toUtf8().data()); - g_key_file_set_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, comment.toUtf8().data()); -// g_key_file_set_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, locale, comment.toUtf8().data()); + g_key_file_set_boolean(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, + false); + g_key_file_set_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, + name.toUtf8().data()); + g_key_file_set_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, + locale, name.toUtf8().data()); + g_key_file_set_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, + comment.toUtf8().data()); + g_key_file_set_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, + icon.toUtf8().data()); +// g_key_file_set_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, locale, comment.toUtf8().data()); if (!_key_file_to_file(keyfile, filepath)) qDebug() << "Could not save desktop file"; @@ -819,112 +816,114 @@ g_key_file_free(keyfile); g_free(filepath); - //refresh -// ui->listWidget->clear(); + // refresh clearAutoItem(); initUI(); - } -void AutoBoot::del_autoboot_realize(QString bname){ - +void AutoBoot::del_autoboot_realize(QString bname) +{ QMap::iterator it = statusMaps.find(bname); - if (it == statusMaps.end()){ + if (it == statusMaps.end()) { qDebug() << "AutoBoot Data Error"; return; } -// if (it.value().xdg_position == SYSTEMPOS){ //复制改值 -// if (_copy_desktop_file_to_local(bname)){ -// _delete_autoapp(bname); -// } -// } -// else if (it.value().xdg_position == ALLPOS){ //改值 -// _delete_autoapp(bname); - -// } -// else if (it.value().xdg_position == LOCALPOS){ //删除 - _delete_local_autoapp(bname); -// ui->listWidget->clear(); - clearAutoItem(); - initUI(); - // } + _delete_local_autoapp(bname); + clearAutoItem(); + initUI(); } - - -//bool AutoBoot::eventFilter(QObject *watched, QEvent *event) -//{ -// if (watched == ui->addFrame){ -// if (event->type() == QEvent::MouseButtonPress){ -// QMouseEvent * mouseEvent = static_cast(event); -// if (mouseEvent->button() == Qt::LeftButton){ -// AddAutoBoot * mdialog = new AddAutoBoot(); -// mdialog->exec(); -// dialog->exec(); -// return true; -// } else -// return false; -// } -// } -// return QObject::eventFilter(watched, event); -//} - -void AutoBoot::checkbox_changed_cb(QString bname){ +void AutoBoot::checkbox_changed_cb(QString bname) +{ foreach (QString key, appgroupMultiMaps.keys()) { - if (key == bname){ - + if (key == bname) { QMap::iterator it = statusMaps.find(bname); - if (it == statusMaps.end()){ + if (it == statusMaps.end()) { qDebug() << "AutoBoot Data Error"; return; } - if (((SwitchButton *)appgroupMultiMaps.value(key))->isChecked()){ //开启开机启动 - if (it.value().xdg_position == SYSTEMPOS){ // - - } else if (it.value().xdg_position == ALLPOS){ //删除 + if (((SwitchButton *)appgroupMultiMaps.value(key))->isChecked()) { // 开启开机启动 + if (it.value().xdg_position == SYSTEMPOS) { // + } else if (it.value().xdg_position == ALLPOS) { // 删除 QMap::iterator appit = appMaps.find(bname); - if (!appit.value().hidden){ //直接删除 + if (!appit.value().hidden) { // 直接删除 _delete_local_autoapp(bname); - //更新状态 + // 更新状态 QMap::iterator updateit = statusMaps.find(bname); - if (updateit != statusMaps.end()){ + if (updateit != statusMaps.end()) { updateit.value().hidden = false; updateit.value().xdg_position = SYSTEMPOS; updateit.value().path = appit.value().path; - } - else + } else qDebug() << "Update status failed when start autoboot"; } -// QMap::iterator statusit = statusMaps.begin(); -// for (; statusit != statusMaps.end(); statusit++){ -// qDebug() << statusit.value().xdg_position << statusit.value().path; -// } - } - else if (it.value().xdg_position == LOCALPOS){//改值 + } else if (it.value().xdg_position == LOCALPOS) {// 改值 _enable_autoapp(bname, true); } - - } - else{ //关闭 - if (it.value().xdg_position == SYSTEMPOS){ //复制后改值 - if (_copy_desktop_file_to_local(bname)){ + } else { // 关闭 + if (it.value().xdg_position == SYSTEMPOS) { // 复制后改值 + if (_copy_desktop_file_to_local(bname)) { _stop_autoapp(bname); } - } - else if (it.value().xdg_position == ALLPOS){//正常逻辑不应存在该情况,预防处理 + } else if (it.value().xdg_position == ALLPOS) {// 正常逻辑不应存在该情况,预防处理 QMap::iterator appit = appMaps.find(bname); if (appit.value().hidden) _delete_local_autoapp(bname); - } - else if (it.value().xdg_position == LOCALPOS){//改值 -// _enable_autoapp(bname, false); + } else if (it.value().xdg_position == LOCALPOS) {// 改值 +// _enable_autoapp(bname, false); _stop_autoapp(bname); } - } } } } +void AutoBoot::connectToServer() +{ + m_cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", + "/org/kylinssoclient/path", + "org.freedesktop.kylinssoclient.interface", + QDBusConnection::sessionBus()); + if (!m_cloudInterface->isValid()) { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), + QString( + "org.freedesktop.kylinssoclient.interface"), "keyChanged", this, + SLOT(keyChangedSlot(QString))); + // 将以后所有DBus调用的超时设置为 milliseconds + m_cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} + +void AutoBoot::initConfig() +{ + // 不存在则创建~/.config/autostart/ + if (!g_file_test(localconfigdir, G_FILE_TEST_EXISTS)) { + GFile *dstdirfile; + dstdirfile = g_file_new_for_path(localconfigdir); + gboolean status = g_file_make_directory(dstdirfile, NULL, NULL); + if (!status) { + qWarning() << "create autostart dir failed"; + } + } +} + +void AutoBoot::keyChangedSlot(const QString &key) +{ + if (key == "boot") { + QLayoutItem *child; + while ((child = ui->autoLayout->takeAt(0)) != 0) { + // setParent为NULL,防止删除之后界面不消失 + if (child->widget()) { + child->widget()->setParent(NULL); + } + delete child; + child = nullptr; + } + initUI(); + } +} diff -Nru ukui-control-center-2.0.3/plugins/system/autoboot/autoboot.h ukui-control-center-3.0.3/plugins/system/autoboot/autoboot.h --- ukui-control-center-2.0.3/plugins/system/autoboot/autoboot.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/autoboot/autoboot.h 2021-05-20 13:08:14.000000000 +0000 @@ -27,30 +27,13 @@ #include "datadefined.h" #include "addautoboot.h" #include "HoverWidget/hoverwidget.h" +#include +#include namespace Ui { class AutoBoot; } -//typedef struct _AutoApp{ - -// QString bname; -// QString path; - -// bool enable; -// bool no_display; -// bool shown; -// bool hidden; - -// QString name; -// QString comment; -// QPixmap pixmap; -// QString exec; -// QString description; - -// int xdg_position; -//}AutoApp; - class AutoBoot : public QObject, CommonInterface { Q_OBJECT @@ -63,52 +46,63 @@ QString get_plugin_name() Q_DECL_OVERRIDE; int get_plugin_type() Q_DECL_OVERRIDE; - QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; +private: void initAddBtn(); + void initTitleLabel(); + void initStyle(); void initUI(); + void initConnection(); void update_app_status(); void del_autoboot_realize(QString bname); + void connectToServer(); + void initConfig(); + void setupGSettings(); -protected: -// bool eventFilter(QObject *watched, QEvent *event); + void _walk_config_dirs(); + AutoApp _app_new(const char *path); + gboolean _key_file_get_boolean(GKeyFile *keyfile, const gchar *key, gboolean defaultvalue); + gboolean _key_file_get_shown(GKeyFile *keyfile, const char *currentdesktop); + bool _stop_autoapp(QString bname); + bool _delete_autoapp(QString bname); + bool _enable_autoapp(QString bname, bool status); + bool _delete_local_autoapp(QString bname); + gboolean _key_file_to_file(GKeyFile *keyfile, const gchar *path); + bool _copy_desktop_file_to_local(QString bname); + void clearAutoItem(); private: Ui::AutoBoot *ui; QString pluginName; int pluginType; - QWidget * pluginWidget; + QWidget *pluginWidget; - AddAutoBoot * dialog; + AddAutoBoot *dialog; + QDBusInterface *m_cloudInterface; QMap appMaps; QMap localappMaps; QMap statusMaps; QMultiMap appgroupMultiMaps; - char * localconfigdir; + char *localconfigdir; HoverWidget *addWgt; - void _walk_config_dirs(); - AutoApp _app_new(const char * path); - gboolean _key_file_get_boolean(GKeyFile * keyfile, const gchar * key, gboolean defaultvalue); - gboolean _key_file_get_shown(GKeyFile * keyfile, const char * currentdesktop); - bool _stop_autoapp(QString bname); - bool _delete_autoapp(QString bname); - bool _enable_autoapp(QString bname, bool status); - bool _delete_local_autoapp(QString bname); - gboolean _key_file_to_file(GKeyFile * keyfile, const gchar * path); - bool _copy_desktop_file_to_local(QString bname); + bool mFirstLoad; - void clearAutoItem(); + QGSettings *mQtSettings; public slots: void checkbox_changed_cb(QString bname); - void add_autoboot_realize_slot(QString path, QString name, QString exec, QString comment); + void keyChangedSlot(const QString &key); + void add_autoboot_realize_slot(QString path, QString name, QString exec, QString comment, + QString icon); }; #endif // AUTOBOOT_H diff -Nru ukui-control-center-2.0.3/plugins/system/autoboot/autoboot.pro ukui-control-center-3.0.3/plugins/system/autoboot/autoboot.pro --- ukui-control-center-2.0.3/plugins/system/autoboot/autoboot.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/autoboot/autoboot.pro 2021-04-14 01:27:20.000000000 +0000 @@ -7,8 +7,9 @@ include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) -QT += widgets svg +QT += widgets svg dbus TEMPLATE = lib CONFIG += plugin @@ -25,7 +26,8 @@ CONFIG += link_pkgconfig \ C++11 PKGCONFIG += gio-2.0 \ - gio-unix-2.0 + gio-unix-2.0 \ + gsettings-qt #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 diff -Nru ukui-control-center-2.0.3/plugins/system/defaultapp/addappdialog.cpp ukui-control-center-3.0.3/plugins/system/defaultapp/addappdialog.cpp --- ukui-control-center-2.0.3/plugins/system/defaultapp/addappdialog.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/defaultapp/addappdialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -54,4 +54,5 @@ AddAppDialog::~AddAppDialog() { delete ui; + ui = nullptr; } diff -Nru ukui-control-center-2.0.3/plugins/system/defaultapp/defaultapp.cpp ukui-control-center-3.0.3/plugins/system/defaultapp/defaultapp.cpp --- ukui-control-center-2.0.3/plugins/system/defaultapp/defaultapp.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/defaultapp/defaultapp.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -25,363 +25,458 @@ #include "addappdialog.h" #define BROWSERTYPE "x-scheme-handler/http" -#define MAILTYPE "x-scheme-handler/mailto" -#define IMAGETYPE "image/png" -#define AUDIOTYPE "audio/x-vorbis+ogg" -#define VIDEOTYPE "video/x-ogm+ogg" -#define TEXTTYPE "text/plain" +#define MAILTYPE "x-scheme-handler/mailto" +#define IMAGETYPE "image/png" +#define AUDIOTYPE "audio/x-vorbis+ogg" +#define VIDEOTYPE "video/x-ogm+ogg" +#define TEXTTYPE "text/plain" #define DESKTOPPATH "/usr/share/applications/" -DefaultApp::DefaultApp(){ - ui = new Ui::DefaultAppWindow; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - - pluginName = tr("Defaultapp"); +DefaultApp::DefaultApp() : mFirstLoad(true) +{ + pluginName = tr("Default App"); pluginType = SYSTEM; - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - initUI(); - -// ui->resetPushBtn->hide(); } -DefaultApp::~DefaultApp(){ - delete ui; +DefaultApp::~DefaultApp() { + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } } -QString DefaultApp::get_plugin_name(){ +QString DefaultApp::get_plugin_name() { return pluginName; } -int DefaultApp::get_plugin_type(){ +int DefaultApp::get_plugin_type() { return pluginType; } -QWidget *DefaultApp::get_plugin_ui(){ +QWidget *DefaultApp::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + ui = new Ui::DefaultAppWindow; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + isCloudEmitted = false; + + ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); + + initUI(); + connectToServer(); +#ifdef __sw_64__ + ui->ResetBtn->show(); +#else + ui->ResetBtn->hide(); +#endif + connect(ui->ResetBtn, SIGNAL(clicked(bool)), this, SLOT(resetDefaultApp())); + } return pluginWidget; } -void DefaultApp::plugin_delay_control(){ +void DefaultApp::plugin_delay_control() { } -void DefaultApp::initUI(){ -// ui->browserComBoBox->setView(new QListView()); +const QString DefaultApp::name() const { + + return QStringLiteral("defaultapp"); +} + +void DefaultApp::initUI() { + + connect(this,&DefaultApp::appInitDone,this,[=](int index, const QString &type) { + if (type == BROWSERTYPE) { + ui->browserComBoBox->setCurrentIndex(index); + browserComBoBox_changed_cb(index); + connect(ui->browserComBoBox, static_cast (&QComboBox::currentIndexChanged), this, &DefaultApp::browserComBoBox_changed_cb); + + } else if(type == MAILTYPE) { + ui->mailComBoBox->setCurrentIndex(index); + mailComBoBox_changed_cb(index); + connect(ui->mailComBoBox, static_cast (&QComboBox::currentIndexChanged), this, &DefaultApp::mailComBoBox_changed_cb); + + } else if(type == IMAGETYPE) { + ui->imageComBoBox->setCurrentIndex(index); + imageComBoBox_changed_cb(index); + connect(ui->imageComBoBox, static_cast (&QComboBox::currentIndexChanged), this, &DefaultApp::imageComBoBox_changed_cb); - // BROWSER - int browserindex = -1; - QString currentbrowser(getDefaultAppId(BROWSERTYPE)); //获取当前 - AppList * list = getAppIdList(BROWSERTYPE); //获取可选列表 - if (list){ - for (int i = 0; list[i].appid != NULL; i++){ - QString single(list[i].appid); - QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); - GDesktopAppInfo * browserinfo = g_desktop_app_info_new_from_filename(ba.constData()); - QString appname = g_app_info_get_name(G_APP_INFO(browserinfo)); - // qDebug() << appname ; - const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(browserinfo))); - QIcon appicon; - if (QIcon::hasThemeIcon(QString(iconname))) + } else if(type == AUDIOTYPE) { + ui->audioComBoBox->setCurrentIndex(index); + audioComBoBox_changed_cb(index); + connect(ui->audioComBoBox, static_cast (&QComboBox::currentIndexChanged), this, &DefaultApp::audioComBoBox_changed_cb); + + } else if(type == VIDEOTYPE) { + ui->videoComBoBox->setCurrentIndex(index); + videoComBoBox_changed_cb(index); + connect(ui->videoComBoBox, static_cast (&QComboBox::currentIndexChanged), this, &DefaultApp::videoComBoBox_changed_cb); + + } else if(type == TEXTTYPE) { + ui->textComBoBox->setCurrentIndex(index); + textComBoBox_changed_cb(index); + connect(ui->textComBoBox, static_cast (&QComboBox::currentIndexChanged), this, &DefaultApp::textComBoBox_changed_cb); + + } + }); + + QtConcurrent::run([this] { + // BROWSER + int browserindex = -1; + QString currentbrowser(getDefaultAppId(BROWSERTYPE)); //获取当前 + QVector list = getAppIdList(BROWSERTYPE); //获取可选列表 + if (!list.isEmpty()) { + for (int i = 0; i < list.size(); i++) { + QString single(list[i].strAppid); + QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); + GDesktopAppInfo * browserinfo = g_desktop_app_info_new_from_filename(ba.constData()); + QString appname = g_app_info_get_name(G_APP_INFO(browserinfo)); + const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(browserinfo))); + QIcon appicon; appicon = QIcon::fromTheme(QString(iconname)); - ui->browserComBoBox->addItem(appicon, appname, single); - if (currentbrowser == single) - browserindex = i; - free(list[i].appid); - } - free(list); - } - ui->browserComBoBox->setCurrentIndex(browserindex); - browserComBoBox_changed_cb(browserindex); - connect(ui->browserComBoBox, SIGNAL(currentIndexChanged(int)), this, SLOT(browserComBoBox_changed_cb(int))); - - // MAIL - int mailindex = -1; - QString currentmail(getDefaultAppId(MAILTYPE)); - - AppList * maillist = getAppIdList(MAILTYPE); - if (maillist){ - for (int i = 0; maillist[i].appid != NULL; i++){ - QString single(maillist[i].appid); - QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); - GDesktopAppInfo * mailinfo = g_desktop_app_info_new_from_filename(ba.constData()); - QString appname = g_app_info_get_name(G_APP_INFO(mailinfo)); - const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(mailinfo))); - QIcon appicon; - if (QIcon::hasThemeIcon(QString(iconname))) + ui->browserComBoBox->addItem(appicon, appname, single); + if (currentbrowser == single) { + browserindex = i; + emit appInitDone(browserindex, BROWSERTYPE); + } + if("qaxbrowser-safe.desktop" == single) { + mDefaultBrowser = appname; + } + } + } + + // MAIL + int mailindex = -1; + QString currentmail(getDefaultAppId(MAILTYPE)); + QVector maillist = getAppIdList(MAILTYPE); + if (!maillist.isEmpty()) { + for (int i = 0; i < maillist.size(); i++) { + QString single(maillist[i].strAppid); + QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); + GDesktopAppInfo * mailinfo = g_desktop_app_info_new_from_filename(ba.constData()); + QString appname = g_app_info_get_name(G_APP_INFO(mailinfo)); + const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(mailinfo))); + QIcon appicon; appicon = QIcon::fromTheme(QString(iconname)); - ui->mailComBoBox->addItem(appicon, appname, single); - if (currentmail == single) - mailindex = i; - free(maillist[i].appid); - } - free(maillist); - } - ui->mailComBoBox->setCurrentIndex(mailindex); - mailComBoBox_changed_cb(mailindex); - connect(ui->mailComBoBox, SIGNAL(currentIndexChanged(int)), this, SLOT(mailComBoBox_changed_cb(int))); - - // IMAGE - int imageindex = -1; - QString currentimage(getDefaultAppId(IMAGETYPE)); - - AppList * imagelist = getAppIdList(IMAGETYPE); - if (imagelist){ - for (int i = 0; imagelist[i].appid != NULL; i++){ - QString single(imagelist[i].appid); - QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); - GDesktopAppInfo * imageinfo = g_desktop_app_info_new_from_filename(ba.constData()); - QString appname = g_app_info_get_name(G_APP_INFO(imageinfo)); - const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(imageinfo))); - QIcon appicon; - if (QIcon::hasThemeIcon(QString(iconname))) + ui->mailComBoBox->addItem(appicon, appname, single); + if (currentmail == single) { + mailindex = i; + emit appInitDone(mailindex, MAILTYPE); + } + if ("claws-mail.desktop" == single) { + mDefaultMail = appname; + } + } + } + + // IMAGE + int imageindex = -1; + QStringList browserList; + QString currentimage(getDefaultAppId(IMAGETYPE)); + QVector imagelist = getAppIdList(IMAGETYPE); + + for(int i = 0; i < ui->browserComBoBox->count(); i++){ + browserList << ui->browserComBoBox->itemText(i); + } + if (!imagelist.isEmpty()) { + for (int i = 0; i < imagelist.size(); i++) { + QString single(imagelist[i].strAppid); + QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); + GDesktopAppInfo * imageinfo = g_desktop_app_info_new_from_filename(ba.constData()); + QString appname = g_app_info_get_name(G_APP_INFO(imageinfo)); + const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(imageinfo))); + QIcon appicon; appicon = QIcon::fromTheme(QString(iconname)); - ui->imageComBoBox->addItem(appicon, appname, single); - if (currentimage == single) + if(!browserList.contains(appname)){ + ui->imageComBoBox->addItem(appicon, appname, single); + } + + if ("eom.desktop" == single) { + mDefaultPic = appname; + } + + } + } + for(int i = 0; i < ui->imageComBoBox->count(); i++){ + if(currentimage == ui->imageComBoBox->itemData(i)){ imageindex = i; - free(imagelist[i].appid); + emit appInitDone(imageindex, IMAGETYPE); + } } - free(imagelist); - } - ui->imageComBoBox->setCurrentIndex(imageindex); - imageComBoBox_changed_cb(imageindex); - connect(ui->imageComBoBox, SIGNAL(currentIndexChanged(int)), this, SLOT(imageComBoBox_changed_cb(int))); - - // AUDIO - int audioindex = -1; - QString currentaudio(getDefaultAppId(AUDIOTYPE)); - - AppList * audiolist = getAppIdList(AUDIOTYPE); - if (audiolist){ - for (int i = 0; audiolist[i].appid != NULL; i++){ - QString single(audiolist[i].appid); - QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); - GDesktopAppInfo * audioinfo = g_desktop_app_info_new_from_filename(ba.constData()); - QString appname = g_app_info_get_name(G_APP_INFO(audioinfo)); - const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(audioinfo))); - QIcon appicon; - if (QIcon::hasThemeIcon(QString(iconname))) + + // AUDIO + int audioindex = -1; + QString currentaudio(getDefaultAppId(AUDIOTYPE)); + QVector audiolist = getAppIdList(AUDIOTYPE); + if (!audiolist.isEmpty()) { + for (int i = 0; i < audiolist.size(); i++) { + QString single(audiolist[i].strAppid); + QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); + GDesktopAppInfo * audioinfo = g_desktop_app_info_new_from_filename(ba.constData()); + QString appname = g_app_info_get_name(G_APP_INFO(audioinfo)); + const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(audioinfo))); + QIcon appicon; appicon = QIcon::fromTheme(QString(iconname)); - ui->audioComBoBox->addItem(appicon, appname, single); - if (currentaudio == single) - audioindex = i; - free(audiolist[i].appid); - } - free(audiolist); - } - ui->audioComBoBox->setCurrentIndex(audioindex); - audioComBoBox_changed_cb(audioindex); - connect(ui->audioComBoBox, SIGNAL(currentIndexChanged(int)), this, SLOT(audioComBoBox_changed_cb(int))); - - // VIDEO - int videoindex =-1; - QString currentvideo(getDefaultAppId(VIDEOTYPE)); - - AppList * videolist = getAppIdList(VIDEOTYPE); - if (videolist){ - for (int i = 0; videolist[i].appid != NULL; i++){ - QString single(videolist[i].appid); - QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); - GDesktopAppInfo * videoinfo = g_desktop_app_info_new_from_filename(ba.constData()); - QString appname = g_app_info_get_name(G_APP_INFO(videoinfo)); - const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(videoinfo))); - QIcon appicon; - if (QIcon::hasThemeIcon(QString(iconname))) + ui->audioComBoBox->addItem(appicon, appname, single); + if (currentaudio == single) { + audioindex = i; + emit appInitDone(audioindex, AUDIOTYPE); + } + if ("kylin-music.desktop" == single) { + mDefaultAdudio = appname; + } + } + } + + // VIDEO + int videoindex =-1; + QString currentvideo(getDefaultAppId(VIDEOTYPE)); + QVector videolist = getAppIdList(VIDEOTYPE); + if (!videolist.isEmpty()) { + for (int i = 0; i< videolist.size(); i++) { + QString single(videolist[i].strAppid); + QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); + GDesktopAppInfo * videoinfo = g_desktop_app_info_new_from_filename(ba.constData()); + QString appname = g_app_info_get_name(G_APP_INFO(videoinfo)); + const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(videoinfo))); + QIcon appicon; appicon = QIcon::fromTheme(QString(iconname)); - ui->videoComBoBox->addItem(appicon, appname, single); - if (currentvideo == single) - videoindex = i; - free(videolist[i].appid); - } - free(videolist); - } - ui->videoComBoBox->setCurrentIndex(videoindex); - videoComBoBox_changed_cb(videoindex); - connect(ui->videoComBoBox, SIGNAL(currentIndexChanged(int)), this, SLOT(videoComBoBox_changed_cb(int))); - - // TEXT - int textindex = -1; - QString currenttext(getDefaultAppId(TEXTTYPE)); - - AppList * textlist = getAppIdList(TEXTTYPE); - if (textlist){ - for (int i = 0; textlist[i].appid != NULL; i++){ - QString single(textlist[i].appid); - QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); - GDesktopAppInfo * textinfo = g_desktop_app_info_new_from_filename(ba.constData()); - QString appname = g_app_info_get_name(G_APP_INFO(textinfo)); - const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(textinfo))); - QIcon appicon; - if (QIcon::hasThemeIcon(QString(iconname))) + ui->videoComBoBox->addItem(appicon, appname, single); + if (currentvideo == single) { + videoindex = i; + emit appInitDone(videoindex, VIDEOTYPE); + } + if ("kylin-video.desktop" == single) { + mDefaultVideo = appname; + } + } + } + + // TEXT + int textindex = -1; + QString currenttext(getDefaultAppId(TEXTTYPE)); + QVector textlist = getAppIdList(TEXTTYPE); + if (!textlist.isEmpty()){ + for (int i = 0; i < textlist.size(); i++) { + QString single(textlist[i].strAppid); + QByteArray ba = QString(DESKTOPPATH + single).toUtf8(); + GDesktopAppInfo * textinfo = g_desktop_app_info_new_from_filename(ba.constData()); + QString appname = g_app_info_get_name(G_APP_INFO(textinfo)); + const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(textinfo))); + QIcon appicon; appicon = QIcon::fromTheme(QString(iconname)); - ui->textComBoBox->addItem(appicon, appname, single); - if (currenttext == single) - textindex = i; - free(textlist[i].appid); + ui->textComBoBox->addItem(appicon, appname, single); + if (currenttext == single) { + textindex = i; + emit appInitDone(textindex, TEXTTYPE); + } + if ("pluma.desktop" == single) { + mDefaultText = appname; + } + } } - free(textlist); - } - ui->textComBoBox->setCurrentIndex(textindex); - textComBoBox_changed_cb(textindex); - connect(ui->textComBoBox, SIGNAL(currentIndexChanged(int)), this, SLOT(textComBoBox_changed_cb(int))); + isCloudEmitted = false; + }); } -void DefaultApp::browserComBoBox_changed_cb(int index){ -// QString appid = ui->browserComBoBox->currentData().toString(); +void DefaultApp::initSearchText() { + //~ contents_path /defaultapp/Browser + ui->browserLabel->setText(tr("Browser")); + //~ contents_path /defaultapp/Mail + ui->mailLabel->setText(tr("Mail")); + //~ contents_path /defaultapp/Image Viewer + ui->imageLabel->setText(tr("Image Viewer")); + //~ contents_path /defaultapp/Audio Player + ui->audioLabel->setText(tr("Audio Player")); + //~ contents_path /defaultapp/Video Player + ui->videoLabel->setText(tr("Video Player")); + //~ contents_path /defaultapp/Text Editor + ui->textLabel->setText(tr("Text Editor")); +} + +void DefaultApp::browserComBoBox_changed_cb(int index) { QString appid = ui->browserComBoBox->itemData(index).toString(); - if (appid == "add"){ -// AddAppDialog * dialog = new AddAppDialog(); -// dialog->show(); - qDebug() << "add clicked"; - } - else{ - QByteArray ba = appid.toUtf8(); // QString to char * - setWebBrowsersDefaultProgram(ba.data()); + QByteArray ba = appid.toUtf8(); // QString to char * + + bool bRunSync = false; + + isCloudEmitted == false ? setWebBrowsersDefaultProgram(ba.data()):bRunSync = true; + + if(bRunSync == true) { + QtConcurrent::run([=] { + QString appid = ui->browserComBoBox->itemData(index).toString(); + QByteArray ba = appid.toUtf8(); // QString to char * + setWebBrowsersDefaultProgram(ba.data()); + }); } } -void DefaultApp::mailComBoBox_changed_cb(int index){ +void DefaultApp::mailComBoBox_changed_cb(int index) { QString appid = ui->mailComBoBox->itemData(index).toString(); - if (appid == "add"){ - qDebug() << "add clicked"; - } - else{ - QByteArray ba = appid.toUtf8(); // QString to char * - setMailReadersDefaultProgram(ba.data()); + QByteArray ba = appid.toUtf8(); // QString to char * + bool bRunSync = false; + + isCloudEmitted == false ? setMailReadersDefaultProgram(ba.data()):bRunSync = true; + + if(bRunSync == true) { + QtConcurrent::run([=] { + QString appid = ui->mailComBoBox->itemData(index).toString(); + QByteArray ba = appid.toUtf8(); // QString to char * + setMailReadersDefaultProgram(ba.data()); + }); } } -void DefaultApp::imageComBoBox_changed_cb(int index){ +void DefaultApp::imageComBoBox_changed_cb(int index) { QString appid = ui->imageComBoBox->itemData(index).toString(); - if (appid == "add"){ - qDebug() << "add clicked"; - } - else{ - QByteArray ba = appid.toUtf8(); // QString to char * - setImageViewersDefaultProgram(ba.data()); + QByteArray ba = appid.toUtf8(); // QString to char * + + bool bRunSync = false; + + isCloudEmitted == false ? setImageViewersDefaultProgram(ba.data()):bRunSync = true; + + if(bRunSync == true) { + QtConcurrent::run([=] { + QString appid = ui->imageComBoBox->itemData(index).toString(); + QByteArray ba = appid.toUtf8(); // QString to char * + setImageViewersDefaultProgram(ba.data()); + }); } } -void DefaultApp::audioComBoBox_changed_cb(int index){ - qDebug() << "this is audio:" << endl; - +void DefaultApp::audioComBoBox_changed_cb(int index) { QString appid = ui->audioComBoBox->itemData(index).toString(); - if (appid == "add"){ - qDebug() << "add clicked"; - } - else{ - QByteArray ba = appid.toUtf8(); // QString to char * - setAudioPlayersDefaultProgram(ba.data()); + QByteArray ba = appid.toUtf8(); // QString to char * + + bool bRunSync = false; + + isCloudEmitted == false ? setAudioPlayersDefaultProgram(ba.data()):bRunSync = true; + + if(bRunSync == true) { + QtConcurrent::run([=] { + QString appid = ui->audioComBoBox->itemData(index).toString(); + QByteArray ba = appid.toUtf8(); // QString to char * + setAudioPlayersDefaultProgram(ba.data()); + }); } } -void DefaultApp::videoComBoBox_changed_cb(int index){ +void DefaultApp::videoComBoBox_changed_cb(int index) { QString appid = ui->videoComBoBox->itemData(index).toString(); - if (appid == "add"){ - qDebug() << "add clicked"; - } - else{ - QByteArray ba = appid.toUtf8(); // QString to char * - setVideoPlayersDefaultProgram(ba.data()); + QByteArray ba = appid.toUtf8(); // QString to char * + + bool bRunSync = false; + + isCloudEmitted == false ? setVideoPlayersDefaultProgram(ba.data()):bRunSync = true; + + if(bRunSync == true) { + QtConcurrent::run([=] { + QString appid = ui->videoComBoBox->itemData(index).toString(); + QByteArray ba = appid.toUtf8(); // QString to char * + setVideoPlayersDefaultProgram(ba.data()); + }); } } -void DefaultApp::textComBoBox_changed_cb(int index){ +void DefaultApp::textComBoBox_changed_cb(int index) { QString appid = ui->textComBoBox->itemData(index).toString(); - if (appid == "add"){ - qDebug() << "add clicked"; + QByteArray ba = appid.toUtf8(); // QString to char * + + bool bRunSync = false; + + isCloudEmitted == false ? setTextEditorsDefautlProgram(ba.data()):bRunSync = true; + + if(bRunSync == true) { + QtConcurrent::run([=] { + QString appid = ui->textComBoBox->itemData(index).toString(); + QByteArray ba = appid.toUtf8(); // QString to char * + setTextEditorsDefautlProgram(ba.data()); + }); } - else{ - QByteArray ba = appid.toUtf8(); // QString to char * - setTextEditorsDefautlProgram(ba.data()); +} + +void DefaultApp::resetDefaultApp() { + + ui->browserComBoBox->setCurrentText(mDefaultBrowser); + ui->imageComBoBox->setCurrentText(mDefaultPic); + ui->audioComBoBox->setCurrentText(mDefaultAdudio); + ui->videoComBoBox->setCurrentText(mDefaultVideo); + ui->textComBoBox->setCurrentText(mDefaultText); + + if (mDefaultMail.isEmpty()) { + ui->mailComBoBox->setCurrentIndex(0); + } else { + ui->mailComBoBox->setCurrentText(mDefaultMail); } } -char * DefaultApp::getDefaultAppId(const char * contentType){ +QString DefaultApp::getDefaultAppId(const char * contentType) { GAppInfo * app = g_app_info_get_default_for_type(contentType, false); if(app != NULL){ const char * id = g_app_info_get_id(app); - if(id != NULL){ - gint len = strlen(id); - char * appid = (char *)malloc(sizeof(char)*(len+1)); - strcpy(appid,id); - return appid; - } else { - return NULL; - } + QString strId(id); + return strId; } else { - return NULL; + return QString(""); } } -AppList * DefaultApp::getAppIdList(const char *contentType){ - Appinfo *appinfo = _getAppList(contentType); - if(appinfo != NULL){ - int i = 0; - while(appinfo[i].item != NULL) - i++; - AppList *list = (AppList *)malloc(sizeof(AppList)*(i+1)); - int count = i; - int index = 0; - for(gint j = 0;appinfo[j].item != NULL;j++){ +QVector DefaultApp::getAppIdList(const char *contentType) { + QVector appList; + appList.clear(); + QVector appinfo = _getAppList(contentType); + if (!appinfo.isEmpty()) { + for(int j = 0; j < appinfo.size(); j++) { const char *id = g_app_info_get_id(appinfo[j].item); - if(id != NULL){ - int len = strlen(id); - list[index].appid = (char *)malloc(sizeof(char)*(len+1)); - strcpy(list[index].appid,id); - index++; - } else { - free(list+count); - count--; + if (id != NULL) { + AppList al; + al.strAppid = QString(id); + appList.append(al); } } - list[count].appid=NULL; - free(appinfo); - return list; - } else { - return NULL; } + return appList; } -Appinfo * DefaultApp::_getAppList(const char *contentType){ +QVector DefaultApp::_getAppList(const char *contentType) { GList *applist; applist = g_app_info_get_all_for_type(contentType); GAppInfo * item; + QVector appinfo; + appinfo.clear(); - if(applist != NULL){ + if (applist != NULL) { int len = g_list_length(applist); - Appinfo * appinfo=(Appinfo *)malloc(sizeof(Appinfo)*(len+1)); //获取应用列表 - for (int index=0; index < len; index++){ + for (int index=0; index < len; index++) { item = (GAppInfo*) g_list_nth_data(applist, index); - appinfo[index].item=item; + Appinfo ai; + ai.item = item; + appinfo.append(ai); } - appinfo[len].item=NULL; - return appinfo; - - } else { - return NULL; - } + } + return appinfo; } -bool DefaultApp::setWebBrowsersDefaultProgram(char * appid){ +bool DefaultApp::setWebBrowsersDefaultProgram(char * appid) { const char * content_type = "x-scheme-handler/http"; - Appinfo * appinfo = _getAppList(content_type); + QVector appinfo = _getAppList(content_type); bool judge = false; - if(appinfo != NULL){ - for(int i = 0; appinfo[i].item != NULL; i++){ + if (!appinfo.isEmpty()) { + for(int i = 0; i < appinfo.size(); i++) { const char *id = g_app_info_get_id(appinfo[i].item); int result = strcmp(id,appid); - if(0 == result){ + if (0 == result) { GAppInfo *appitem=appinfo[i].item; gboolean ret1=g_app_info_set_as_default_for_type(appitem, "x-scheme-handler/http", NULL); gboolean ret2=g_app_info_set_as_default_for_type(appitem, "x-scheme-handler/https", NULL); @@ -392,21 +487,20 @@ break; } } - free(appinfo); } return judge; } -bool DefaultApp::setMailReadersDefaultProgram(char *appid){ +bool DefaultApp::setMailReadersDefaultProgram(char *appid) { const char *content_type="x-scheme-handler/mailto"; - Appinfo *appinfo=_getAppList(content_type); + QVector appinfo = _getAppList(content_type); bool judge = false; - if(appinfo != NULL){ - for(int i = 0; appinfo[i].item != NULL; i++){ + if (!appinfo.isEmpty()) { + for (int i = 0; i < appinfo.size(); i++) { const char * id = g_app_info_get_id(appinfo[i].item); int result=strcmp(id,appid); - if(0 == result){ + if (0 == result) { GAppInfo *appitem=appinfo[i].item; gboolean ret1=g_app_info_set_as_default_for_type(appitem, "x-scheme-handler/mailto", NULL); gboolean ret2=g_app_info_set_as_default_for_type(appitem, "application/x-extension-eml", NULL); @@ -416,21 +510,20 @@ break; } } - free(appinfo); } return judge; } -bool DefaultApp::setImageViewersDefaultProgram(char *appid){ +bool DefaultApp::setImageViewersDefaultProgram(char *appid) { const char *content_type="image/png"; - Appinfo *appinfo = _getAppList(content_type); + QVector appinfo = _getAppList(content_type); bool judge = false; - if(appinfo != NULL){ - for(int i=0;appinfo[i].item!=NULL;i++){ + if (!appinfo.isEmpty()) { + for (int i=0; i < appinfo.size();i++){ const char *id = g_app_info_get_id(appinfo[i].item); int result = strcmp(id, appid); - if(0 == result){ + if (0 == result) { GAppInfo *appitem=appinfo[i].item; gboolean ret1 = g_app_info_set_as_default_for_type(appitem, "image/bmp", NULL); gboolean ret2 = g_app_info_set_as_default_for_type(appitem, "image/gif", NULL); @@ -442,22 +535,21 @@ break; } } - free(appinfo); } return judge; } -bool DefaultApp::setVideoPlayersDefaultProgram(char *appid){ +bool DefaultApp::setVideoPlayersDefaultProgram(char *appid) { const char *content_type = "video/x-ogm+ogg"; - Appinfo * appinfo = _getAppList(content_type); + QVector appinfo = _getAppList(content_type); bool judge = false; - if(appinfo != NULL){ - for(int i = 0; appinfo[i].item != NULL; i++){ + if (!appinfo.isEmpty()) { + for(int i = 0; i < appinfo.size(); i++) { const char *id = g_app_info_get_id(appinfo[i].item); int result = strcmp(id,appid); - if(0 == result){ + if (0 == result) { GAppInfo *appitem = appinfo[i].item; gboolean ret1 = g_app_info_set_as_default_for_type(appitem, "video/mp4", NULL); gboolean ret2 = g_app_info_set_as_default_for_type(appitem, "video/mpeg", NULL); @@ -470,27 +562,62 @@ gboolean ret9 = g_app_info_set_as_default_for_type(appitem, "video/x-matroska", NULL); gboolean ret10 = g_app_info_set_as_default_for_type(appitem, "video/x-mpeg", NULL); gboolean ret11 = g_app_info_set_as_default_for_type(appitem, "video/x-ogm+ogg", NULL); - if(ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7 && ret8 && ret9 && ret10 && ret11) + gboolean ret12 = g_app_info_set_as_default_for_type(appitem, "video/rm", NULL); + gboolean ret13 = g_app_info_set_as_default_for_type(appitem, "video/3pg", NULL); + gboolean ret14 = g_app_info_set_as_default_for_type(appitem, "video/asf", NULL); + gboolean ret15 = g_app_info_set_as_default_for_type(appitem, "video/3gp", NULL); + gboolean ret16 = g_app_info_set_as_default_for_type(appitem, "video/3gpp", NULL); + gboolean ret17 = g_app_info_set_as_default_for_type(appitem, "video/3gpp2", NULL); + gboolean ret18 = g_app_info_set_as_default_for_type(appitem, "video/x-ms-afs", NULL); + gboolean ret19 = g_app_info_set_as_default_for_type(appitem, "video/x-ms-asf", NULL); + gboolean ret20 = g_app_info_set_as_default_for_type(appitem, "video/x-mpeg2", NULL); + gboolean ret21 = g_app_info_set_as_default_for_type(appitem, "video/x-mpeg3", NULL); + gboolean ret22 = g_app_info_set_as_default_for_type(appitem, "video/mp4v-es", NULL); + gboolean ret23 = g_app_info_set_as_default_for_type(appitem, "video/x-m4v", NULL); + gboolean ret24 = g_app_info_set_as_default_for_type(appitem, "video/divx", NULL); + gboolean ret25 = g_app_info_set_as_default_for_type(appitem, "video/vnd.divx", NULL); + gboolean ret26 = g_app_info_set_as_default_for_type(appitem, "video/x-msvideo", NULL); + gboolean ret27 = g_app_info_set_as_default_for_type(appitem, "video/ogg", NULL); + gboolean ret28 = g_app_info_set_as_default_for_type(appitem, "video/vnd.rn-realvideo", NULL); + gboolean ret29 = g_app_info_set_as_default_for_type(appitem, "video/x-ms-wmv", NULL); + gboolean ret30 = g_app_info_set_as_default_for_type(appitem, "video/x-ms-wmx", NULL); + gboolean ret31 = g_app_info_set_as_default_for_type(appitem, "video/x-ms-wvxvideo", NULL); + gboolean ret32 = g_app_info_set_as_default_for_type(appitem, "video/avi", NULL); + gboolean ret33 = g_app_info_set_as_default_for_type(appitem, "video/x-flic", NULL); + gboolean ret34 = g_app_info_set_as_default_for_type(appitem, "video/fli", NULL); + gboolean ret35 = g_app_info_set_as_default_for_type(appitem, "video/x-flc", NULL); + gboolean ret36 = g_app_info_set_as_default_for_type(appitem, "video/flv", NULL); + gboolean ret37 = g_app_info_set_as_default_for_type(appitem, "video/x-theora", NULL); + gboolean ret38 = g_app_info_set_as_default_for_type(appitem, "video/x-theora+ogg", NULL); + gboolean ret39 = g_app_info_set_as_default_for_type(appitem, "video/mkv", NULL); + gboolean ret40 = g_app_info_set_as_default_for_type(appitem, "video/x-ogm", NULL); + gboolean ret41 = g_app_info_set_as_default_for_type(appitem, "video/vnd.mpegurl", NULL); + gboolean ret42 = g_app_info_set_as_default_for_type(appitem, "video/dv", NULL); + gboolean ret43 = g_app_info_set_as_default_for_type(appitem, "application/vnd.rn-realmedia", NULL); + gboolean ret44 = g_app_info_set_as_default_for_type(appitem, "application/vnd.rn-realmedia-vbr", NULL); + if (ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7 && ret8 && ret9 && ret10 && ret11 && \ + ret12 && ret13 && ret14 && ret15 && ret16 && ret17 && ret18 && ret19 && ret20 && ret21 && \ + ret22 && ret23 && ret24 && ret25 && ret26 && ret27 && ret28 && ret29 && ret30 && \ + ret31 && ret32 && ret33 && ret34 && ret35 && ret36 && ret37 && ret38 && ret39 && \ + ret40 && ret41 && ret42 && ret43 && ret44) judge=true; break; } } - free(appinfo); } return judge; } -bool DefaultApp::setAudioPlayersDefaultProgram(char *appid){ +bool DefaultApp::setAudioPlayersDefaultProgram(char *appid) { const char *content_type = "audio/x-vorbis+ogg"; - Appinfo * appinfo = _getAppList(content_type); + QVector appinfo = _getAppList(content_type); bool judge = false; - if(appinfo != NULL){ - for(int i = 0; appinfo[i].item != NULL ;i++){ + if (!appinfo.isEmpty()) { + for(int i = 0; i < appinfo.size() ;i++) { const char *id = g_app_info_get_id(appinfo[i].item); int result = strcmp(id,appid); - if(0 == result) - { + if (0 == result) { GAppInfo *appitem=appinfo[i].item; gboolean ret1 = g_app_info_set_as_default_for_type(appitem, "audio/mpeg", NULL); gboolean ret2 = g_app_info_set_as_default_for_type(appitem, "audio/x-mpegurl", NULL); @@ -503,28 +630,36 @@ gboolean ret9 = g_app_info_set_as_default_for_type(appitem, "audio/acc", NULL); gboolean ret10 = g_app_info_set_as_default_for_type(appitem, "audio/aac", NULL); gboolean ret11 = g_app_info_set_as_default_for_type(appitem, "audio/mp4", NULL); - if(ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7 && ret8 && ret9 && ret10 && ret11) { - qDebug()<<"set succes in default app----->"< appinfo = _getAppList(content_type); bool judge = false; - if(appinfo != NULL){ - for(int i = 0; appinfo[i].item != NULL; i++){ + if (!appinfo.isEmpty()) { + for (int i = 0;i < appinfo.size(); i++) { const char * id = g_app_info_get_id(appinfo[i].item); int result = strcmp(id,appid); - if(0 == result){ + if (0 == result) { GAppInfo *appitem = appinfo[i].item; gboolean ret1 = g_app_info_set_as_default_for_type(appitem, "text/plain", NULL); if(ret1) @@ -532,8 +667,36 @@ break; } } - free(appinfo); } return judge; } + +void DefaultApp::connectToServer(){ + m_cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", + "/org/kylinssoclient/path", + "org.freedesktop.kylinssoclient.interface", + QDBusConnection::sessionBus()); + if (!m_cloudInterface->isValid()) + { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), QString("org.freedesktop.kylinssoclient.interface"), "keyChanged", this, SLOT(keyChangedSlot(QString))); + // 将以后所有DBus调用的超时设置为 milliseconds + m_cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} + +void DefaultApp::keyChangedSlot(const QString &key) { + if(key == "default-open") { + isCloudEmitted = true; + ui->browserComBoBox->clear(); + ui->audioComBoBox->clear(); + ui->imageComBoBox->clear(); + ui->textComBoBox->clear(); + ui->mailComBoBox->clear(); + ui->videoComBoBox->clear(); + initUI(); + } +} diff -Nru ukui-control-center-2.0.3/plugins/system/defaultapp/defaultapp.h ukui-control-center-3.0.3/plugins/system/defaultapp/defaultapp.h --- ukui-control-center-2.0.3/plugins/system/defaultapp/defaultapp.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/defaultapp/defaultapp.h 2021-04-14 01:27:20.000000000 +0000 @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "shell/interface.h" @@ -43,7 +45,7 @@ typedef struct _Applist { - char *appid; + QString strAppid; }AppList;// 用于存放应用列表 typedef struct _AppInfo @@ -69,8 +71,10 @@ int get_plugin_type() Q_DECL_OVERRIDE; QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; void initUI(); + void initSearchText(); bool setWebBrowsersDefaultProgram(char * appid); bool setMailReadersDefaultProgram(char * appid); @@ -79,11 +83,12 @@ bool setVideoPlayersDefaultProgram(char * appid); bool setTextEditorsDefautlProgram(char * appid); + void connectToServer(); private: - char * getDefaultAppId(const char * contentType); - AppList * getAppIdList(const char * contentType); - static Appinfo * _getAppList(const char *contentType); + QString getDefaultAppId(const char * contentType); + QVector getAppIdList(const char * contentType); + static QVector _getAppList(const char *contentType); private: Ui::DefaultAppWindow * ui; @@ -91,8 +96,18 @@ QWidget * pluginWidget; QString pluginName; - int pluginType; + QDBusInterface *m_cloudInterface; + + QString mDefaultBrowser; + QString mDefaultMail; + QString mDefaultPic; + QString mDefaultAdudio; + QString mDefaultVideo; + QString mDefaultText; + + bool isCloudEmitted; + bool mFirstLoad; public slots: void browserComBoBox_changed_cb(int index); @@ -101,6 +116,10 @@ void audioComBoBox_changed_cb(int index); void videoComBoBox_changed_cb(int index); void textComBoBox_changed_cb(int index); + void keyChangedSlot(const QString &key); + void resetDefaultApp(); +Q_SIGNALS: + void appInitDone(int index,const QString &type); }; #endif // DEFAULTAPP_H diff -Nru ukui-control-center-2.0.3/plugins/system/defaultapp/defaultapp.pro ukui-control-center-3.0.3/plugins/system/defaultapp/defaultapp.pro --- ukui-control-center-2.0.3/plugins/system/defaultapp/defaultapp.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/defaultapp/defaultapp.pro 2021-04-14 01:27:20.000000000 +0000 @@ -5,7 +5,7 @@ #------------------------------------------------- include(../../../env.pri) -QT += widgets +QT += widgets dbus concurrent TEMPLATE = lib CONFIG += plugin diff -Nru ukui-control-center-2.0.3/plugins/system/defaultapp/defaultapp.ui ukui-control-center-3.0.3/plugins/system/defaultapp/defaultapp.ui --- ukui-control-center-2.0.3/plugins/system/defaultapp/defaultapp.ui 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/defaultapp/defaultapp.ui 2021-04-14 01:27:20.000000000 +0000 @@ -116,13 +116,13 @@ - 120 + 130 0 - 120 + 130 16777215 @@ -138,7 +138,7 @@ - 400 + 350 0 @@ -202,13 +202,13 @@ - 120 + 130 0 - 120 + 130 16777215 @@ -224,7 +224,7 @@ - 400 + 350 0 @@ -285,13 +285,13 @@ - 120 + 130 0 - 120 + 130 16777215 @@ -307,7 +307,7 @@ - 400 + 350 0 @@ -368,13 +368,13 @@ - 120 + 130 0 - 120 + 130 16777215 @@ -390,7 +390,7 @@ - 400 + 350 0 @@ -451,13 +451,13 @@ - 120 + 130 0 - 120 + 130 16777215 @@ -473,7 +473,7 @@ - 400 + 350 0 @@ -534,13 +534,13 @@ - 120 + 130 0 - 120 + 130 16777215 @@ -556,7 +556,7 @@ - 400 + 350 0 @@ -575,6 +575,42 @@ + + + + + + 120 + 36 + + + + + 16777215 + 36 + + + + Reset to default + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + Qt::Vertical diff -Nru ukui-control-center-2.0.3/plugins/system/display/colorinfo.h ukui-control-center-3.0.3/plugins/system/display/colorinfo.h --- ukui-control-center-2.0.3/plugins/system/display/colorinfo.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/colorinfo.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,32 @@ +#ifndef COLORINFO_H +#define COLORINFO_H + +#include +#include +#include +#include + +struct ColorInfo { + QString arg; + QDBusVariant out; +}; + +QDBusArgument &operator<<(QDBusArgument &argument, const ColorInfo &mystruct) +{ + argument.beginStructure(); + argument << mystruct.arg << mystruct.out; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, ColorInfo &mystruct) +{ + argument.beginStructure(); + argument >> mystruct.arg >> mystruct.out; + argument.endStructure(); + return argument; +} + +Q_DECLARE_METATYPE(ColorInfo) + +#endif // COLORINFO_H diff -Nru ukui-control-center-2.0.3/plugins/system/display/controlpanel.cpp ukui-control-center-3.0.3/plugins/system/display/controlpanel.cpp --- ukui-control-center-2.0.3/plugins/system/display/controlpanel.cpp 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/controlpanel.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -1,26 +1,22 @@ #include "controlpanel.h" #include "outputconfig.h" #include "unifiedoutputconfig.h" -//#include "kcm_screen_debug.h" #include #include #include +#include #include -ControlPanel::ControlPanel(QWidget *parent) - : QFrame(parent) - , mUnifiedOutputCfg(nullptr) +ControlPanel::ControlPanel(QWidget *parent) : + QFrame(parent), + mUnifiedOutputCfg(nullptr) { -// setMinimumSize(553,150); -// setMaximumSize(16777215,150); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); -// setFrameStyle(QFrame::NoFrame | QFrame::Sunken); -// this->setStyleSheet("border: 1px solid #ff0000"); mLayout = new QVBoxLayout(this); - mLayout->setContentsMargins(0,0,0,0); - + mLayout->setContentsMargins(0, 0, 0, 0); + isWayland(); } ControlPanel::~ControlPanel() @@ -29,7 +25,6 @@ void ControlPanel::setConfig(const KScreen::ConfigPtr &config) { - qDeleteAll(mOutputConfigs); mOutputConfigs.clear(); delete mUnifiedOutputCfg; @@ -46,7 +41,6 @@ this, &ControlPanel::removeOutput); for (const KScreen::OutputPtr &output : mConfig->outputs()) { - //qDebug()<<"output is----->"<setVisible(false); -#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) outputCfg->setShowScaleOption(mConfig->supportedFeatures().testFlag(KScreen::Config::Feature::PerOutputScaling)); -#else - -#endif outputCfg->setOutput(output); connect(outputCfg, &OutputConfig::changed, @@ -68,71 +58,78 @@ connect(outputCfg, &OutputConfig::scaleChanged, this, &ControlPanel::scaleChanged); - - mLayout->addWidget(outputCfg); mOutputConfigs << outputCfg; + + if (mIsWayland) { + activateOutput(mCurrentOutput); + } } void ControlPanel::removeOutput(int outputId) { + if (mUnifiedOutputCfg) { + mUnifiedOutputCfg->setVisible(false); + } + for (OutputConfig *outputCfg : mOutputConfigs) { if (outputCfg->output()->id() == outputId) { mOutputConfigs.removeOne(outputCfg); delete outputCfg; - return; + outputCfg = nullptr; + } else { + outputCfg->setVisible(true); } } } void ControlPanel::activateOutput(const KScreen::OutputPtr &output) { - // Ignore activateOutput when in unified mode if (mUnifiedOutputCfg) { return; } + mCurrentOutput = output; - //qCDebug(KSCREEN_KCM) << "Activate output" << output->id(); - //qDebug()<<"activateOutput---->"<output()->id()<<" "<id(); cfg->setVisible(cfg->output()->id() == output->id()); - - //cfg->setVisible(cfg->output()->id() == 66) } } - void ControlPanel::activateOutputNoParam() { - // Ignore activateOutput when in unified mode if (mUnifiedOutputCfg) { return; } - qDebug()<<"activateOutputNoParam ------>"<id(); Q_FOREACH (OutputConfig *cfg, mOutputConfigs) { qDebug()<output()->id()<<" id"; - //cfg->setVisible(cfg->output()->id() == output->id()); cfg->setVisible(cfg->output()->id() == 66); } } +void ControlPanel::isWayland() +{ + QString sessionType = getenv("XDG_SESSION_TYPE"); + + if (!sessionType.compare(kSession, Qt::CaseSensitive)) { + mIsWayland = true; + } else { + mIsWayland = false; + } +} + void ControlPanel::setUnifiedOutput(const KScreen::OutputPtr &output) { Q_FOREACH (OutputConfig *config, mOutputConfigs) { if (!config->output()->isConnected()) { continue; } - //qDebug()<<"config is---->"<output()<<"--------"<setVisible(output == nullptr); } @@ -140,7 +137,6 @@ mUnifiedOutputCfg->deleteLater(); mUnifiedOutputCfg = nullptr; } else { - //qDebug()<<"config is---->"<setOutput(output); mUnifiedOutputCfg->setVisible(true); diff -Nru ukui-control-center-2.0.3/plugins/system/display/controlpanel.h ukui-control-center-3.0.3/plugins/system/display/controlpanel.h --- ukui-control-center-2.0.3/plugins/system/display/controlpanel.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/controlpanel.h 2021-05-20 13:08:14.000000000 +0000 @@ -14,38 +14,46 @@ class QSlider; class QComboBox; +const QString kSession = "wayland"; + class ControlPanel : public QFrame { Q_OBJECT - public: +public: explicit ControlPanel(QWidget *parent = nullptr); ~ControlPanel() override; void setConfig(const KScreen::ConfigPtr &config); - void setUnifiedOutput(const KScreen::OutputPtr &output); + void activateOutputNoParam(); - public Q_SLOTS: - void activateOutput(const KScreen::OutputPtr &output); +private: + void isWayland(); -public: - void activateOutputNoParam(); +public Q_SLOTS: + void activateOutput(const KScreen::OutputPtr &output); - Q_SIGNALS: +Q_SIGNALS: void changed(); - void scaleChanged(int index); + void scaleChanged(double scale); private Q_SLOTS: void addOutput(const KScreen::OutputPtr &output); void removeOutput(int outputId); - private: +public: + QVBoxLayout *mLayout; + +private: KScreen::ConfigPtr mConfig; - QList mOutputConfigs; + QList mOutputConfigs; - QVBoxLayout *mLayout; UnifiedOutputConfig *mUnifiedOutputCfg; + + KScreen::OutputPtr mCurrentOutput; + + bool mIsWayland; }; #endif // CONTROLPANEL_H diff -Nru ukui-control-center-2.0.3/plugins/system/display/declarative/qmloutputcomponent.cpp ukui-control-center-3.0.3/plugins/system/display/declarative/qmloutputcomponent.cpp --- ukui-control-center-2.0.3/plugins/system/display/declarative/qmloutputcomponent.cpp 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/declarative/qmloutputcomponent.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -28,7 +28,6 @@ #include #include -//这里注册的类型为什么不起作用 Q_DECLARE_METATYPE(KScreen::OutputPtr) Q_DECLARE_METATYPE(QMLScreen*) @@ -36,11 +35,7 @@ QQmlComponent(engine, parent), m_engine(engine) { - //const QString qmlPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kcm_kscreen/qml/Output.qml")); -// const QString qmlpath = QStringLiteral("qrc:/qml/Output.qml"); -// qDebug()<<"qmlPath is ------>"<setProperty("outputPtr", QVariant::fromValue(qobject_cast(output))); -// qDebug()<<"qmloutcomponent.cpp---->instance类型---->"<"<"<(output))<<" "<setProperty("screen", QVariant::fromValue(qobject_cast(parent()))); diff -Nru ukui-control-center-2.0.3/plugins/system/display/declarative/qmloutputcomponent.h ukui-control-center-3.0.3/plugins/system/display/declarative/qmloutputcomponent.h --- ukui-control-center-2.0.3/plugins/system/display/declarative/qmloutputcomponent.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/declarative/qmloutputcomponent.h 2021-04-14 01:27:20.000000000 +0000 @@ -23,7 +23,6 @@ #include - class QMLScreen; class QMLOutput; @@ -31,15 +30,14 @@ { Q_OBJECT - public: +public: explicit QMLOutputComponent(QQmlEngine *engine, QMLScreen *parent); ~QMLOutputComponent() override; - QMLOutput* createForOutput(const KScreen::OutputPtr &output); + QMLOutput *createForOutput(const KScreen::OutputPtr &output); - private: +private: QQmlEngine *m_engine; - }; #endif // QMLOUTPUTCOMPONENT_H diff -Nru ukui-control-center-2.0.3/plugins/system/display/declarative/qmloutput.cpp ukui-control-center-3.0.3/plugins/system/display/declarative/qmloutput.cpp --- ukui-control-center-2.0.3/plugins/system/display/declarative/qmloutput.cpp 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/declarative/qmloutput.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -65,7 +65,6 @@ void QMLOutput::setOutputPtr(const KScreen::OutputPtr &output) { - //qDebug()<<"setOutputPtr------> qmloutput"<size().height()---->"<size()<size().height() ;/// m_output->scale(); + return mode->size().height() / m_output->scale(); } -//返回上面小屏幕宽度 int QMLOutput::currentOutputWidth() const { if (!m_output) { @@ -230,12 +223,7 @@ return 1000; } } -#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - return mode->size().width();// / m_output->scale(); -#else return mode->size().width() / m_output->scale(); -#endif - } void QMLOutput::currentModeIdChanged() @@ -278,7 +266,7 @@ void QMLOutput::setOutputX(int x) { - //qDebug()<<"setOutputX--->"<"<pos().rx() == x) { return; } @@ -297,7 +285,7 @@ void QMLOutput::setOutputY(int y) { - //qDebug()<<"setOutputY--->"<"<pos().ry() == y) { return; } @@ -385,7 +373,6 @@ bool QMLOutput::maybeSnapTo(QMLOutput *other) { - //qDebug()<<"maybeSnapTo---->"<"< siblings = screen()->childItems(); // First, if we have moved, then unset the "cloneOf" flag diff -Nru ukui-control-center-2.0.3/plugins/system/display/declarative/qmloutput.h ukui-control-center-3.0.3/plugins/system/display/declarative/qmloutput.h --- ukui-control-center-2.0.3/plugins/system/display/declarative/qmloutput.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/declarative/qmloutput.h 2021-04-14 01:27:20.000000000 +0000 @@ -28,12 +28,11 @@ class ModesProxyModel; class QMLScreen; - class QMLOutput : public QQuickItem { Q_OBJECT - Q_PROPERTY(KScreen::Output* output + Q_PROPERTY(KScreen::Output *output READ output NOTIFY outputChanged) @@ -101,37 +100,37 @@ WRITE setOutputY NOTIFY outputYChanged) - public: - enum { - ModeRole = Qt::UserRole, - ModeIdRole, - SizeRole, - RefreshRateRole +public: + enum { + ModeRole = Qt::UserRole, + ModeIdRole, + SizeRole, + RefreshRateRole }; explicit QMLOutput(QQuickItem *parent = nullptr); - KScreen::Output* output() const; // For QML + KScreen::Output *output() const; // For QML KScreen::OutputPtr outputPtr() const; void setOutputPtr(const KScreen::OutputPtr &output); - QMLScreen* screen() const; + QMLScreen *screen() const; void setScreen(QMLScreen *screen); - QMLOutput* leftDockedTo() const; + QMLOutput *leftDockedTo() const; void setLeftDockedTo(QMLOutput *output); void undockLeft(); - QMLOutput* topDockedTo() const; + QMLOutput *topDockedTo() const; void setTopDockedTo(QMLOutput *output); void undockTop(); - QMLOutput* rightDockedTo() const; + QMLOutput *rightDockedTo() const; void setRightDockedTo(QMLOutput *output); void undockRight(); - QMLOutput* bottomDockedTo() const; + QMLOutput *bottomDockedTo() const; void setBottomDockedTo(QMLOutput *output); void undockBottom(); @@ -139,7 +138,7 @@ Q_INVOKABLE bool maybeSnapTo(QMLOutput *other); void setCloneOf(QMLOutput *other); - QMLOutput* cloneOf() const; + QMLOutput *cloneOf() const; int currentOutputHeight() const; int currentOutputWidth() const; @@ -155,10 +154,10 @@ void dockToNeighbours(); - public Q_SLOTS: +public Q_SLOTS: void updateRootProperties(); - Q_SIGNALS: +Q_SIGNALS: void changed(); void moved(const QString &self); @@ -179,11 +178,11 @@ void isCloneModeChanged(); - private Q_SLOTS: +private Q_SLOTS: void moved(); void currentModeIdChanged(); - private: +private: /** * Returns the biggest resolution available assuming it's the preferred one */ @@ -202,4 +201,3 @@ }; #endif // QMLOUTPUT_H - diff -Nru ukui-control-center-2.0.3/plugins/system/display/declarative/qmlscreen.cpp ukui-control-center-3.0.3/plugins/system/display/declarative/qmlscreen.cpp --- ukui-control-center-2.0.3/plugins/system/display/declarative/qmlscreen.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/declarative/qmlscreen.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -28,8 +28,8 @@ Q_DECLARE_METATYPE(KScreen::OutputPtr) -QMLScreen::QMLScreen(QQuickItem *parent) - : QQuickItem(parent) +QMLScreen::QMLScreen(QQuickItem *parent) : + QQuickItem(parent) { connect(this, &QMLScreen::widthChanged, this, &QMLScreen::viewSizeChanged); connect(this, &QMLScreen::heightChanged, this, &QMLScreen::viewSizeChanged); @@ -62,15 +62,15 @@ m_config = config; connect(m_config.data(), &KScreen::Config::outputAdded, this, [this](const KScreen::OutputPtr &output) { - addOutput(output); - updateOutputsPlacement(); - }); + QTimer::singleShot(1000, this, [=]{ + addOutput(output); + updateOutputsPlacement(); + }); + }); connect(m_config.data(), &KScreen::Config::outputRemoved, this, &QMLScreen::removeOutput); - //qDebug()<<"所要拿取的配置为------>"<outputs()) { -// qDebug()<<"\noutput类型----debug------>"<"<(output))<<" "<output()->isConnected() && qmlOutput->output()->isEnabled()) { - //qDebug()<<"qmlOutput---->"<dockToNeighbours(); } } } - void QMLScreen::addOutput(const KScreen::OutputPtr &output) { - //qDebug()<<"qmlscreen.cpp-------> output类型------->"<updateRootProperties(); } @@ -129,13 +138,13 @@ QMLOutput *qmlOutput = m_outputMap.take(output); qmlOutput->setParentItem(nullptr); qmlOutput->setParent(nullptr); - qmlOutput->deleteLater(); + // TODO:bug51346 + // qmlOutput->deleteLater(); return; } } } - int QMLScreen::connectedOutputsCount() const { return m_connectedOutputsCount; @@ -157,12 +166,11 @@ return nullptr; } -QList QMLScreen::outputs() const +QList QMLScreen::outputs() const { return m_outputMap.values(); } - void QMLScreen::setActiveOutput(QMLOutput *output) { Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { @@ -172,14 +180,144 @@ } output->setZ(m_outputMap.count()); - //选中屏幕 + // 中屏幕 output->setFocus(true); Q_EMIT focusedOutputChanged(output); } +void QMLScreen::setScreenCenterPos() +{ + // 组成最大矩形四个边的位置,分别对应左上(1),右下(2)的xy坐标值 + qreal localX1 = -1, localX2 = -1, localY1 = -1, localY2 = -1; + qreal mX1 = 0, mY1 = 0, mX2 = 0, mY2 = 0; // 矩形中点坐标 + qreal moveX = 0, moveY = 0;// 移动的值 + bool firstFlag = true; + Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { + if (qmlOutput->output()->isConnected()) { + if (firstFlag == true || localX1 > qmlOutput->x()) { + localX1 = qmlOutput->x(); + } + if (firstFlag == true || localX2 < qmlOutput->x() + qmlOutput->width()) { + localX2 = qmlOutput->x() + qmlOutput->width(); + } + if (firstFlag == true || localY1 > qmlOutput->y()) { + localY1 = qmlOutput->y(); + } + if (firstFlag == true || localY2 < qmlOutput->y() + qmlOutput->height()) { + localY2 = qmlOutput->y() + qmlOutput->height(); + } + firstFlag = false; + } + } + + mX1 = localX1 + (localX2-localX1)/2; + mY1 = localY1 + (localY2-localY1)/2; + + mX2 = (width() - (localX2 - localX1))/2 + (localX2-localX1)/2; + mY2 = (height() - (localY2 - localY1))/2 + (localY2-localY1)/2; + + moveX = mX2 - mX1; + moveY = mY2 - mY1; + + Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { + qmlOutput->blockSignals(true); + qmlOutput->setX(qmlOutput->x() + moveX); + qmlOutput->setY(qmlOutput->y() + moveY); + qmlOutput->blockSignals(false); + } +} + +void QMLScreen::setScreenPos(QMLOutput *output) +{ + // 镜像模式下跳过屏幕旋转处理 + if (this->primaryOutput() && this->primaryOutput()->isCloneMode()) { + return; + } + + int x1 = 0, y1 = 0; + int width1 = 0, height1 = 0; + int x2 = 0, y2 = 0; + int width2 = 0, height2 = 0; + + x1 = output->x(); + y1 = output->y(); + width1 = output->width(); + height1 = output->height(); + + int connectedScreen = 0; + + QMLOutput *other = NULL; + Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { + if (qmlOutput->output()->isConnected()) { + connectedScreen++; + } + if (qmlOutput != output && qmlOutput->output()->isConnected()) { + other = qmlOutput; + x2 = other->x(); + y2 = other->y(); + width2 = other->width(); + height2 = other->height(); + } + } + + if (connectedScreen < 2) { + setScreenCenterPos(); + return; + } + output->blockSignals(true); + if (!((x1 + width1 == x2) + || (y1 == y2 + height2) + || (x1 == x2 + width2) + || (y1 + height1 == y2))) { + if (x1 + width1 < x2) { + output->setX(x2 - width1); + output->setY(y2); + } else if (y1 > y2 + height2) { + output->setX(x2); + output->setY(y2 + height2); + } else if (x1 > x2 + width2) { + output->setX(x2 + width2); + output->setY(y2); + } else if (y1 + height1 < y2) { + output->setX(x2); + output->setY(y2 - height1); + } + + // 矩形是否相交 + if (!(x1 + width1 <= x2 || x2 + width2 <= x1 + || y1 >= y2 +height2 || y2 >= y1 + height1) + && (x1 != x2 || y1 != y2) && other != NULL + && other->output()->isConnected()) { + if ((x1 + width1 > x2) && (x1 < x2)) { + output->setX(x2 - width1); + } else if ((x1 < x2 + width2) && (x1 + width1 > x2 + width2)) { + output->setX(x2 + width2); + } else if ((y1 + height() > y2) && (y1 < y2 + height2)) { + output->setY(y2 - height1); + } else if ((y1 < y2 + height2) && (y1 + height1 > y2 + height2)) { + output->setY(y2 + height2); + } + } + } + output->blockSignals(false); + + setScreenCenterPos(); +} + +void QMLScreen::setActiveOutputByCombox(int screenId) +{ + QHash::const_iterator it = m_outputMap.constBegin(); + while (it != m_outputMap.constEnd()) { + if (screenId == it.key()->id()) { + setActiveOutput(it.value()); + return; + } + it++; + } +} + QSize QMLScreen::maxScreenSize() const { - //qDebug()<<"m_config->screen()->maxSize()--->"<screen()->maxSize()<screen()->maxSize(); } @@ -207,7 +345,8 @@ void QMLScreen::outputEnabledChanged() { - const KScreen::OutputPtr output(qobject_cast(sender()), [](void *){}); + const KScreen::OutputPtr output(qobject_cast(sender()), [](void *){ + }); if (output->isEnabled()) { updateOutputsPlacement(); } @@ -232,10 +371,10 @@ void QMLScreen::qmlOutputMoved(QMLOutput *qmlOutput) { - //qDebug()<<"qmlOutputMoved------>"<isCloneMode()) { return; } + if (!m_manuallyMovedOutputs.contains(qmlOutput)) m_manuallyMovedOutputs.append(qmlOutput); @@ -284,6 +423,7 @@ void QMLScreen::viewSizeChanged() { updateOutputsPlacement(); + setScreenCenterPos(); } void QMLScreen::updateCornerOutputs() @@ -325,33 +465,34 @@ emit outputScaleChanged(); } -//应该是画坐标的地方? +// 画坐标 void QMLScreen::updateOutputsPlacement() { - //qDebug()<<"updateOutputsPlacement---->"<(item); + QMLOutput *qmlOutput = qobject_cast(item); if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled()) { continue; } - if (qmlOutput->outputX() + qmlOutput->currentOutputWidth() > initialActiveScreenSize.width()) { - // qDebug()<outputX()<currentOutputWidth()<outputX() + qmlOutput->currentOutputWidth()); - } - if (qmlOutput->outputY() + qmlOutput->currentOutputHeight() > initialActiveScreenSize.height()) { - initialActiveScreenSize.setHeight(qmlOutput->outputY() + qmlOutput->currentOutputHeight()); + if (qmlOutput->outputX() + qmlOutput->currentOutputWidth() + > initialActiveScreenSize.width()) { + initialActiveScreenSize.setWidth(qmlOutput->outputX() + + qmlOutput->currentOutputWidth()); + } + if (qmlOutput->outputY() + qmlOutput->currentOutputHeight() + > initialActiveScreenSize.height()) { + initialActiveScreenSize.setHeight( + qmlOutput->outputY() + qmlOutput->currentOutputHeight()); } } auto initialScale = outputScale(); - //qDebug() << " -----debug0--->outputScale" << initialScale; auto scale = initialScale; qreal lastX = -1.0; do { @@ -360,30 +501,28 @@ const QPointF offset((width() - activeScreenSize.width()) / 2.0, (height() - activeScreenSize.height()) / 2.0); - // qDebug() << " ----------debug1--->offset-->" << offset; - lastX = -1.0; qreal lastY = -1.0; Q_FOREACH (QQuickItem *item, childItems()) { - QMLOutput *qmlOutput = qobject_cast(item); - if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled() || - m_manuallyMovedOutputs.contains(qmlOutput)) { + QMLOutput *qmlOutput = qobject_cast(item); + if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled() + || m_manuallyMovedOutputs.contains(qmlOutput)) { continue; } qmlOutput->blockSignals(true); qmlOutput->setPosition(QPointF(offset.x() + (qmlOutput->outputX() * scale), - offset.y() + (qmlOutput->outputY() * scale))); - lastX = qMax(lastX, qmlOutput->position().x() + qmlOutput->width() / initialScale * scale); + offset.y() + (qmlOutput->outputY() * scale))); + lastX = qMax(lastX, + qmlOutput->position().x() + qmlOutput->width() / initialScale * scale); lastY = qMax(lastY, qmlOutput->position().y()); - // qDebug()<<"坐标---->"<blockSignals(false); } Q_FOREACH (QQuickItem *item, childItems()) { - QMLOutput *qmlOutput = qobject_cast(item); - if (qmlOutput->output()->isConnected() && !qmlOutput->output()->isEnabled() && - !m_manuallyMovedOutputs.contains(qmlOutput)) { + QMLOutput *qmlOutput = qobject_cast(item); + if (qmlOutput->output()->isConnected() && !qmlOutput->output()->isEnabled() + && !m_manuallyMovedOutputs.contains(qmlOutput)) { qmlOutput->blockSignals(true); qmlOutput->setPosition(QPointF(lastX, lastY)); lastX += qmlOutput->width() / initialScale * scale; @@ -395,6 +534,7 @@ scale *= 0.8; } } while (lastX > width()); + // Use a timer to avoid binding loop on width() QTimer::singleShot(0, this, [scale, this] { setOutputScale(scale); diff -Nru ukui-control-center-2.0.3/plugins/system/display/declarative/qmlscreen.h ukui-control-center-3.0.3/plugins/system/display/declarative/qmlscreen.h --- ukui-control-center-2.0.3/plugins/system/display/declarative/qmlscreen.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/declarative/qmlscreen.h 2021-05-20 13:08:14.000000000 +0000 @@ -51,14 +51,14 @@ READ outputScale NOTIFY outputScaleChanged) - public: +public: explicit QMLScreen(QQuickItem *parent = nullptr); ~QMLScreen() override; int connectedOutputsCount() const; int enabledOutputsCount() const; - QMLOutput* primaryOutput() const; + QMLOutput *primaryOutput() const; QList outputs() const; QSize maxScreenSize() const; @@ -72,13 +72,22 @@ void setActiveOutput(QMLOutput *output); - public Q_SLOTS: - void setActiveOutput() { - setActiveOutput(qobject_cast(sender())); + void setScreenPos(QMLOutput *output); + + void setScreenCenterPos(); +public Q_SLOTS: + void setActiveOutput() + { + setActiveOutput(qobject_cast(sender())); } + void setActiveOutputByCombox(int screenId); + void setScreenPos() + { + setScreenPos(qobject_cast(sender())); + } - Q_SIGNALS: +Q_SIGNALS: void connectedOutputsCountChanged(); void enabledOutputsCountChanged(); @@ -86,7 +95,7 @@ void focusedOutputChanged(QMLOutput *output); - private Q_SLOTS: +private Q_SLOTS: void addOutput(const KScreen::OutputPtr &output); void removeOutput(int outputId); @@ -96,24 +105,23 @@ void viewSizeChanged(); - private: +private: void qmlOutputMoved(QMLOutput *qmlOutput); void updateCornerOutputs(); void setOutputScale(float scale); KScreen::ConfigPtr m_config; - QHash m_outputMap; + QHash m_outputMap; QVector m_manuallyMovedOutputs; int m_connectedOutputsCount = 0; int m_enabledOutputsCount = 0; - float m_outputScale = 1.0 / 11.0;//缩放比例 + float m_outputScale = 1.0 / 14.0;// 缩放比例 QMLOutput *m_leftmost = nullptr; QMLOutput *m_topmost = nullptr; QMLOutput *m_rightmost = nullptr; QMLOutput *m_bottommost = nullptr; - }; #endif // QMLSCREEN_H diff -Nru ukui-control-center-2.0.3/plugins/system/display/display.cpp ukui-control-center-3.0.3/plugins/system/display/display.cpp --- ukui-control-center-2.0.3/plugins/system/display/display.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/display.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -25,37 +25,67 @@ #include #include #include +#include +#include -DisplaySet::DisplaySet(){ - pluginWidget = new Widget; -// pluginWidget->setStyleSheet("background: #ffffff;"); +DisplaySet::DisplaySet() : mFirstLoad(true) +{ pluginName = tr("Display"); - QObject::connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, - [&](KScreen::ConfigOperation *op) { - pluginWidget->setConfig(qobject_cast(op)->config()); - }); - pluginType = SYSTEM; - } -DisplaySet::~DisplaySet(){ - +DisplaySet::~DisplaySet() +{ } -QWidget *DisplaySet::get_plugin_ui(){ +QWidget *DisplaySet::get_plugin_ui() +{ + if (mFirstLoad) { + requestBackend(); + mFirstLoad = false; + pluginWidget = new Widget; + QObject::connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, + [&](KScreen::ConfigOperation *op) { + pluginWidget->setConfig(qobject_cast(op)->config()); + }); + } return pluginWidget; } -QString DisplaySet::get_plugin_name(){ +QString DisplaySet::get_plugin_name() +{ return pluginName; } -int DisplaySet::get_plugin_type(){ +int DisplaySet::get_plugin_type() +{ return pluginType; } -void DisplaySet::plugin_delay_control(){ - +void DisplaySet::plugin_delay_control() +{ } +const QString DisplaySet::name() const +{ + return QStringLiteral("display"); +} + +void DisplaySet::requestBackend() +{ + QDBusInterface screenIft("org.kde.KScreen", + "/", + "org.kde.KScreen", + QDBusConnection::sessionBus()); + if (!screenIft.isValid()) { + QProcess process; + process.start("uname -m"); + process.waitForFinished(); + QString output = process.readAll(); + output = output.simplified(); + + QString command = "/usr/lib/" + output + "-linux-gnu" + +"/libexec/kf5/kscreen_backend_launcher"; + QProcess::startDetached(command); + } +} diff -Nru ukui-control-center-2.0.3/plugins/system/display/display.h ukui-control-center-3.0.3/plugins/system/display/display.h --- ukui-control-center-2.0.3/plugins/system/display/display.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/display.h 2021-05-20 13:08:14.000000000 +0000 @@ -32,7 +32,8 @@ class DisplayWindow; } -class DisplaySet : public QObject, CommonInterface{ +class DisplaySet : public QObject, CommonInterface +{ Q_OBJECT Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") Q_INTERFACES(CommonInterface) @@ -41,18 +42,21 @@ DisplaySet(); ~DisplaySet(); - QString get_plugin_name() Q_DECL_OVERRIDE; - int get_plugin_type() Q_DECL_OVERRIDE; - QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; - private: - Ui::DisplayWindow * ui; + void requestBackend(); +private: + Ui::DisplayWindow *ui; QString pluginName; int pluginType; - Widget * pluginWidget; + Widget *pluginWidget; + bool mFirstLoad; }; #endif // DISPLAYSET_H diff -Nru ukui-control-center-2.0.3/plugins/system/display/displayperformancedialog.cpp ukui-control-center-3.0.3/plugins/system/display/displayperformancedialog.cpp --- ukui-control-center-2.0.3/plugins/system/display/displayperformancedialog.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/displayperformancedialog.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -19,13 +19,14 @@ */ #include "displayperformancedialog.h" #include "ui_displayperformancedialog.h" +#include "CloseButton/closebutton.h" #include #include #include #include #include - +#include #include #define ADVANCED_SCHEMAS "org.ukui.session.required-components" @@ -47,12 +48,13 @@ setAttribute(Qt::WA_DeleteOnClose); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); + ui->label->setAlignment(Qt::AlignTop); + ui->label_2->setAlignment(Qt::AlignTop); + ui->label_3->setAlignment(Qt::AlignTop); + ui->label_4->setAlignment(Qt::AlignTop); + ui->label_5->setAlignment(Qt::AlignTop); + ui->label_6->setAlignment(Qt::AlignTop); ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); @@ -71,8 +73,11 @@ DisplayPerformanceDialog::~DisplayPerformanceDialog() { delete ui; + ui = nullptr; delete settings; + settings = nullptr; delete confSettings; + confSettings = nullptr; } void DisplayPerformanceDialog::setupComponent(){ @@ -82,7 +87,7 @@ } void DisplayPerformanceDialog::setupConnect(){ - connect(ui->closeBtn, &QPushButton::clicked, [=]{ + connect(ui->closeBtn, &CloseButton::clicked, [=]{ close(); }); @@ -148,6 +153,7 @@ tempSettings->endGroup(); delete tempSettings; + tempSettings = nullptr; //替换kylin-wm-chooser QDBusInterface * sysinterface = new QDBusInterface("com.control.center.qt.systemdbus", @@ -162,9 +168,9 @@ QString cmd = QString("mv %1 %2").arg(WM_CHOOSER_CONF_TMP).arg(WM_CHOOSER_CONF); - QDBusReply reply = sysinterface->call("systemRun", QVariant(cmd)); - + QProcess::execute(cmd); delete sysinterface; + sysinterface = nullptr; } void DisplayPerformanceDialog::paintEvent(QPaintEvent *event){ @@ -181,6 +187,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); diff -Nru ukui-control-center-2.0.3/plugins/system/display/displayperformancedialog.h ukui-control-center-3.0.3/plugins/system/display/displayperformancedialog.h --- ukui-control-center-2.0.3/plugins/system/display/displayperformancedialog.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/displayperformancedialog.h 2021-04-14 01:27:20.000000000 +0000 @@ -45,14 +45,14 @@ void changeConfValue(); private: - void paintEvent(QPaintEvent * event); + void paintEvent(QPaintEvent *event); private: Ui::DisplayPerformanceDialog *ui; private: - QGSettings * settings; - QSettings * confSettings; + QGSettings *settings; + QSettings *confSettings; }; #endif // DISPLAYPERFORMANCEDIALOG_H diff -Nru ukui-control-center-2.0.3/plugins/system/display/displayperformancedialog.ui ukui-control-center-3.0.3/plugins/system/display/displayperformancedialog.ui --- ukui-control-center-2.0.3/plugins/system/display/displayperformancedialog.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/displayperformancedialog.ui 2021-04-14 01:27:20.000000000 +0000 @@ -39,10 +39,16 @@ 9 - 0 + 9 + + + 0 + 0 + + QFrame::NoFrame @@ -70,6 +76,9 @@ 0 + + QLayout::SetDefaultConstraint + 0 @@ -131,7 +140,7 @@ - + 32 @@ -155,560 +164,632 @@ - - - 8 - - - 32 + + + + 0 + 0 + - - 16 - - - 32 + + + 0 + 0 + - - 32 + + + 16777215 + 16777215 + - - - - - 0 - 0 - - - - Display Advanced Settings - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 16 - - - - - - - - 2 - - - - - - 0 - 50 - - - - - 16777215 - 50 - - - - QFrame::Box - - - QFrame::Plain + + + 8 + + + QLayout::SetDefaultConstraint + + + 32 + + + 16 + + + 32 + + + 32 + + + + + + 0 + 0 + + + + Display Advanced Settings + + + + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + true + + + + + 0 + 0 + 501 + 538 + - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - + - + - 0 - - - 16 + 2 - - - Performance - - - buttonGroup - + + + + 0 + 50 + + + + + 16777215 + 50 + + + + QFrame::Box + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 16 + + + + + + 0 + 0 + + + + Performance + + + buttonGroup + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + - - - Qt::Horizontal + + + + 0 + 0 + - + - 40 - 20 + 0 + 0 - + + + 16777215 + 16777215 + + + + QFrame::Box + + + QFrame::Plain + + + + 8 + + + 16 + + + 0 + + + 16 + + + 0 + + + + + + 0 + 0 + + + + false + + + Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. + + + true + + + + + + + + 0 + 0 + + + + (Note: not support connect graphical with xmanager on windows.) + + + true + + + + + - - - - - - - - 0 - 90 - - - - - 16777215 - 90 - - - - QFrame::Box - - - QFrame::Plain - - - - 8 - - - 16 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. - - - - - - - - 0 - 0 - - - - (Note: not support connect graphical with xmanager on windows.) - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - 2 - - - - - - 0 - 50 - - - - - 16777215 - 50 - - - - QFrame::Box - - - QFrame::Plain - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - + - 0 - - - 16 + 2 - - - Compatible - - - buttonGroup - + + + + 0 + 50 + + + + + 16777215 + 50 + + + + QFrame::Box + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 16 + + + + + + 0 + 0 + + + + Compatible + + + buttonGroup + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + - - - Qt::Horizontal + + + + 0 + 0 + - + - 40 - 20 + 0 + 0 - + + + 16777215 + 16777215 + + + + QFrame::Box + + + QFrame::Plain + + + + 8 + + + 16 + + + 0 + + + 16 + + + 0 + + + + + + 0 + 0 + + + + Applicable to machine with integrated graphics, there is no 3D graphics acceleration. + + + true + + + + + + + + 0 + 0 + + + + (Note: need connect graphical with xmanager on windows, use this option.) + + + true + + + + + - - - - - - - - 0 - 90 - - - - - 16777215 - 90 - - - - QFrame::Box - - - QFrame::Plain - - - - 8 - - - 16 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Applicable to machine with integrated graphics, there is no 3D graphics acceleration. - - - - - - - 0 - 0 - - - - (Note: need connect graphical with xmanager on windows, use this option.) - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - 2 - - - - - - 0 - 50 - - - - - 16777215 - 50 - - - - QFrame::Box - - - QFrame::Plain - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - + - 0 - - - 16 + 2 - - - Automatic - - - buttonGroup - - - - - - - Qt::Horizontal + + + + 0 + 50 + - + - 40 - 20 + 16777215 + 50 - + + QFrame::Box + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + 16 + + + + + + 0 + 0 + + + + Automatic + + + buttonGroup + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + - - - - - - - - - - 0 - 140 - - - - - 16777215 - 140 - - - - QFrame::Box - - - QFrame::Plain - - - - 8 - - - 16 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Auto select according to environment, delay the login time (about 0.5 sec). - - - - - - - 16 - - + - + 0 0 - - Threshold: + + + 0 + 0 + - - - - - - - - - Apply + + + 16777215 + 16777215 + - - - - - - Reset + + QFrame::Box + + QFrame::Plain + + + + 8 + + + 16 + + + 0 + + + 16 + + + 0 + + + + + + 0 + 0 + + + + Auto select according to environment, delay the login time (about 0.5 sec). + + + true + + + + + + + 16 + + + + + + 0 + 0 + + + + Threshold: + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Apply + + + + + + + + 0 + 0 + + + + Reset + + + + + + + + + + 0 + 0 + + + + (Note: select this option to use 3D graphics acceleration and xmanager.) + + + true + + + + - - - - - 0 - 0 - - - - (Note: select this option to use 3D graphics acceleration and xmanager.) - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - + + + - - - - + + + + @@ -717,6 +798,13 @@ + + + CloseButton + QPushButton +
CloseButton/closebutton.h
+
+
diff -Nru ukui-control-center-2.0.3/plugins/system/display/display.pro ukui-control-center-3.0.3/plugins/system/display/display.pro --- ukui-control-center-2.0.3/plugins/system/display/display.pro 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/display.pro 2021-05-20 13:08:14.000000000 +0000 @@ -5,8 +5,9 @@ #------------------------------------------------- include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) -QT += widgets core gui quickwidgets quick xml KScreen KI18n KConfigCore KConfigWidgets KWidgetsAddons dbus +QT += widgets core gui quickwidgets quick xml KScreen KI18n KConfigCore KConfigWidgets KWidgetsAddons dbus concurrent TEMPLATE = lib CONFIG += c++11 link_pkgconfig plugin @@ -41,6 +42,7 @@ displayperformancedialog.cpp HEADERS += \ + colorinfo.h \ display.h \ declarative/qmloutput.h \ declarative/qmloutputcomponent.h \ diff -Nru ukui-control-center-2.0.3/plugins/system/display/display.ui ukui-control-center-3.0.3/plugins/system/display/display.ui --- ukui-control-center-2.0.3/plugins/system/display/display.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/display.ui 2021-05-20 13:08:14.000000000 +0000 @@ -7,7 +7,7 @@ 0 0 945 - 919 + 1133 @@ -17,6 +17,9 @@ 0 + + 0 + 32 @@ -24,35 +27,70 @@ 48 + + + Display + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 12 + 12 + + + + + 550 - 200 + 0 960 - 200 + 16777215 QFrame::Box + + 0 + + + 0 + + + 0 + + + 0 + 550 - 200 + 300 - 550 - 200 + 960 + 300 @@ -131,7 +169,7 @@ - 120 + 150 30 @@ -140,6 +178,9 @@ 11 + + Qt::NoFocus + set as home screen @@ -296,7 +337,7 @@ - + unify output @@ -341,7 +382,7 @@ - + @@ -362,7 +403,7 @@ - + dark @@ -385,12 +426,19 @@ - + bright + + + + + + + @@ -421,6 +469,25 @@ + + + + 550 + 50 + + + + + 960 + 50 + + + + QFrame::Box + + + + @@ -781,33 +848,7 @@ - QSlider{ - width: 178px; - height: 20px; -} -QSlider::groove:horizontal { - border: 0px solid #bbb; - -} -QSlider::sub-page:horizontal { - background: #3D6BE5; - border-radius: 2px; - margin-top:8px; - margin-bottom:9px; -} -QSlider::add-page:horizontal { - background: rgba(52,70,80,90%); - border: 0px solid #777; - border-radius: 2px; - margin-top:8px; - margin-bottom:9px; -} -QSlider::handle:horizontal { - width: 20px; - height: 20px; - background: #3D6BE5; - border-radius:10px; -} + Qt::Horizontal @@ -830,20 +871,29 @@ + + 6 + + + 0 + 120 - 30 + 36 16777215 - 30 + 36 + + Qt::LeftToRight + apply diff -Nru ukui-control-center-2.0.3/plugins/system/display/outputconfig.cpp ukui-control-center-3.0.3/plugins/system/display/outputconfig.cpp --- ukui-control-center-2.0.3/plugins/system/display/outputconfig.cpp 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/outputconfig.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -1,7 +1,6 @@ #include "outputconfig.h" #include "resolutionslider.h" #include "utils.h" -//#include "kcm_screen_debug.h" #include #include @@ -12,31 +11,43 @@ #include #include -//#include #include #include +#include #include #include #include "ComboBox/combobox.h" -#define FONT_RENDERING_DPI "org.ukui.font-rendering" -#define DPI_KEY "dpi" +#define SCALE_SCHEMAS "org.ukui.SettingsDaemon.plugins.xsettings" +#define SCALE_KEY "scaling-factor" -//#define SCRENN_SCALE_SCHMES "org.ukui.session" -//#define GDK_SCALE_KEY "gdk-scale" +const QSize KRsolution(1920, 1080); +const QVector k150Scale{QSize(1280, 1024), QSize(1440, 900), QSize(1600, 900), + QSize(1680, 1050), QSize(1920, 1080), QSize(1920, 1200), + QSize(2048, 1080), QSize(2048, 1280), QSize(2160, 1440), + QSize(2560, 1440),QSize(3840, 2160)}; -OutputConfig::OutputConfig(QWidget *parent) - : QWidget(parent) - , mOutput(nullptr) +const QVector k175Scale{QSize(1680, 1050), QSize(1920, 1080), QSize(1920, 1200), + QSize(2048, 1080), QSize(2048, 1280), QSize(2160, 1440), + QSize(2560, 1440), QSize(3840, 2160)}; + +const QVector k200Scale{QSize(1920, 1200), QSize(2048, 1280), QSize(2160, 1440), + QSize(2560, 1440), QSize(3840, 2160)}; + +OutputConfig::OutputConfig(QWidget *parent) : + QWidget(parent), + mOutput(nullptr) { + initDpiConnection(); } -OutputConfig::OutputConfig(const KScreen::OutputPtr &output, QWidget *parent) - : QWidget(parent) +OutputConfig::OutputConfig(const KScreen::OutputPtr &output, QWidget *parent) : + QWidget(parent) { + initDpiConnection(); setOutput(output); } @@ -44,292 +55,200 @@ { } -void OutputConfig::setTitle(const QString& title) +void OutputConfig::setTitle(const QString &title) { mTitle->setText(title); } - void OutputConfig::initUi() { connect(mOutput.data(), &KScreen::Output::isConnectedChanged, this, [=]() { - if (!mOutput->isConnected()) { - setVisible(false); - } - }); - -// connect(mOutput.data(), &KScreen::Output::isEnabledChanged, -// this, [=]() { -// mEnabled->setChecked(mOutput->isEnabled()); -// }); + if (!mOutput->isConnected()) { + setVisible(false); + } + }); connect(mOutput.data(), &KScreen::Output::rotationChanged, this, [=]() { - const int index = mRotation->findData(mOutput->rotation()); - mRotation->setCurrentIndex(index); - }); - -// connect(mOutput.data(), &KScreen::Output::scaleChanged, -// this, [=]() { -// const int index = mScale->findData(mOutput->scale()); -// mScale->setCurrentIndex(index); -// }); - + const int index = mRotation->findData(mOutput->rotation()); + mRotation->setCurrentIndex(index); + }); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); QVBoxLayout *vbox = new QVBoxLayout(this); - vbox->setContentsMargins(0,0,0,0); + vbox->setContentsMargins(0, 0, 0, 0); vbox->setSpacing(2); - //注释显示器上方标签 - -// mTitle = new QLabel(this); -// mTitle->setAlignment(Qt::AlignHCenter); -// vbox->addWidget(mTitle); - // setTitle(Utils::outputName(mOutput)); - - //QFormLayout *formLayout = new QFormLayout(); - - - -// mEnabled = new QCheckBox(i18n("已启用"), this); -// //mEnabled->setVisible(false); -// mEnabled->setChecked(mOutput->isEnabled()); -// qDebug()<<"是否开启---->mEnable"<mEnable"<setEnabled(checked); -// qDebug() << "上层勾选---->"<name() << mOutput->isEnabled(); -// Q_EMIT changed(); -// }); -// formLayout->addRow(i18n("显示:"), mEnabled); - -// mMonitor = new QComboBox(this); -// formLayout->addRow(i18n("主显示器"),mMonitor); - - //分辨率下拉框 + // 分辨率下拉框 mResolution = new ResolutionSlider(mOutput, this); -// mResolution->setFont(ft); - mResolution->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - mResolution->setMinimumSize(402,30); - mResolution->setMaximumSize(16777215,30); - + mResolution->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); QLabel *resLabel = new QLabel(this); + //~ contents_path /display/resolution resLabel->setText(tr("resolution")); -// resLabel->setFont(ft); - resLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - resLabel->setMinimumSize(118,30); - resLabel->setMaximumSize(118,30); + resLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + resLabel->setFixedSize(118, 30); QHBoxLayout *resLayout = new QHBoxLayout(); - //resLayout->setContentsMargins(0,5,0,5); resLayout->addWidget(resLabel); resLayout->addWidget(mResolution); -// resLayout->addStretch(); - QFrame *resFrame = new QFrame(this); resFrame->setFrameShape(QFrame::Shape::Box); resFrame->setLayout(resLayout); -// resWidget->setStyleSheet("background-color:#F4F4F4;border-radius:6px"); -// mResolution->setStyleSheet("background-color:#F8F9F9"); - resFrame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - resFrame->setMinimumSize(552,50); - resFrame->setMaximumSize(960,50); + resFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + resFrame->setMinimumSize(552, 50); + resFrame->setMaximumSize(960, 50); vbox->addWidget(resFrame); connect(mResolution, &ResolutionSlider::resolutionChanged, this, &OutputConfig::slotResolutionChanged); - //方向下拉框 - mRotation = new QComboBox(); - -// mRotation->setFont(ft); - mRotation->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - mRotation->setMinimumSize(402,30); - mRotation->setMaximumSize(16777215,30); -// mRotation->setStyleSheet(qss); -// mRotation->setItemDelegate(itemDelege); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + connect(mResolution, &ResolutionSlider::resolutionChanged, + this, &OutputConfig::slotScaleIndex); +#endif + // 方向下拉框 + mRotation = new QComboBox(this); + mRotation->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - QLabel *rotateLabel = new QLabel(); + QLabel *rotateLabel = new QLabel(this); + // ~contents_path /display/orientation rotateLabel->setText(tr("orientation")); -// rotateLabel->setFont(ft); - rotateLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - rotateLabel->setMinimumSize(118,30); - rotateLabel->setMaximumSize(118,30); + rotateLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + rotateLabel->setFixedSize(118, 30); QHBoxLayout *rotateLayout = new QHBoxLayout(); rotateLayout->addWidget(rotateLabel); - rotateLayout->addWidget(mRotation); -// rotateLayout->addStretch(); QFrame *rotateFrame = new QFrame(this); rotateFrame->setFrameShape(QFrame::Shape::Box); rotateFrame->setLayout(rotateLayout); -// rotateWidget->setStyleSheet("background-color:#F4F4F4;border-radius:6px"); -// mRotation->setStyleSheet("background-color:#F8F9F9"); - rotateFrame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - rotateFrame->setMinimumSize(550,50); - rotateFrame->setMaximumSize(960,50); - - mRotation->addItem( tr("arrow-up"), KScreen::Output::None); - mRotation->addItem( tr("90° arrow-right"), KScreen::Output::Right); - mRotation->addItem( tr("arrow-down"), KScreen::Output::Inverted); + rotateFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + rotateFrame->setMinimumSize(550, 50); + rotateFrame->setMaximumSize(960, 50); + + mRotation->addItem(tr("arrow-up"), KScreen::Output::None); + mRotation->addItem(tr("90° arrow-right"), KScreen::Output::Right); mRotation->addItem(tr("90° arrow-left"), KScreen::Output::Left); - connect(mRotation, static_cast(&QComboBox::activated), + mRotation->addItem(tr("arrow-down"), KScreen::Output::Inverted); + connect(mRotation, static_cast(&QComboBox::activated), this, &OutputConfig::slotRotationChanged); mRotation->setCurrentIndex(mRotation->findData(mOutput->rotation())); - //formLayout->addRow(rotateLabel, mRotation); vbox->addWidget(rotateFrame); - //缩放暂时用不到 -// if (!mShowScaleOption) { -// mScale = new QComboBox(this); -// mScale->addItem(i18nc("Scale multiplier, show everything at 1 times normal scale", "1x"), 1); -// mScale->addItem(i18nc("Scale multiplier, show everything at 2 times normal scale", "2x"), 2); -// connect(mScale, static_cast(&QComboBox::activated), -// this, &OutputConfig::slotScaleChanged); -// mScale->setCurrentIndex(mScale->findData(mOutput->scale())); -// formLayout->addRow(i18n("缩放:"), mScale); -// formLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); -// } - - - //刷新率下拉框 - mRefreshRate = new QComboBox(); -// mRefreshRate->setFont(ft); -// mRefreshRate->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - mRefreshRate->setMinimumSize(402,30); - mRefreshRate->setMaximumSize(16777215,30); -// mRefreshRate->setStyleSheet(qss); -// mRefreshRate->setItemDelegate(itemDelege); -// mRefreshRate->setMaxVisibleItems(5); - - QLabel *freshLabel = new QLabel(); - freshLabel->setText(tr("refresh rate")); -// freshLabel->setFont(ft); - freshLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - freshLabel->setMinimumSize(118,30); - freshLabel->setMaximumSize(118,30); + // 刷新率下拉框 + mRefreshRate = new QComboBox(this); + + QLabel *freshLabel = new QLabel(this); + // ~contents_path /display/frequency + freshLabel->setText(tr("frequency")); + freshLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + freshLabel->setFixedSize(118, 30); QHBoxLayout *freshLayout = new QHBoxLayout(); freshLayout->addWidget(freshLabel); freshLayout->addWidget(mRefreshRate); -// freshLayout->addStretch(); QFrame *freshFrame = new QFrame(this); freshFrame->setFrameShape(QFrame::Shape::Box); freshFrame->setLayout(freshLayout); -// freshWidget->setStyleSheet("background-color:#F4F4F4;border-radius:6px"); - freshFrame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - freshFrame->setMinimumSize(550,50); - freshFrame->setMaximumSize(960,50); + freshFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + freshFrame->setMinimumSize(550, 50); + freshFrame->setMaximumSize(960, 50); mRefreshRate->addItem(tr("auto"), -1); vbox->addWidget(freshFrame); slotResolutionChanged(mResolution->currentResolution()); - connect(mRefreshRate, static_cast(&QComboBox::activated), + connect(mRefreshRate, static_cast(&QComboBox::activated), this, &OutputConfig::slotRefreshRateChanged); + mScaleCombox = new QComboBox(this); + mScaleCombox->setObjectName("scaleCombox"); + double scale = getScreenScale(); - scaleCombox = new QComboBox(); -// mRefreshRate->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - scaleCombox->setMinimumSize(402,30); - scaleCombox->setMaximumSize(16777215,30); - - - +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + slotScaleIndex(mResolution->currentResolution()); +#else int maxReslu = mResolution->getMaxResolution().width(); -#if QT_VERSION < QT_VERSION_CHECK(5,7,0) + mScaleCombox->addItem("100%", 1.0); if (maxReslu >= 2000) { - scaleCombox->addItem(tr("200%")); - } else { - scaleCombox->addItem(tr("100%")); + mScaleCombox->addItem("200%", 2.0); } -#else - scaleCombox->addItem(tr("100%")); - if (maxReslu >= 2000 && maxReslu <= 3800) { - scaleCombox->addItem(tr("200%")); - } else if (maxReslu >= 3800 || maxReslu >= 4000) { - scaleCombox->addItem(tr("200%")); - scaleCombox->addItem(tr("300%")); + + mScaleCombox->setCurrentIndex(0); + if (mScaleCombox->findData(scale) == -1) { + mScaleCombox->addItem("200%", 2.0); } #endif + mScaleCombox->setCurrentText(scaleToString(scale)); + + if (mScaleCombox->findData(scale) == -1) { + mScaleCombox->addItem(scaleToString(scale), scale); + mScaleCombox->setCurrentText(scaleToString(scale)); + } + + connect(mScaleCombox, static_cast(&QComboBox::currentIndexChanged), + this, &OutputConfig::slotScaleChanged); - QLabel *scaleLabel = new QLabel(); + QLabel *scaleLabel = new QLabel(this); + //~ contents_path /display/screen zoom scaleLabel->setText(tr("screen zoom")); - scaleLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - scaleLabel->setMinimumSize(118,30); - scaleLabel->setMaximumSize(118,30); + scaleLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + scaleLabel->setFixedSize(118, 30); QHBoxLayout *scaleLayout = new QHBoxLayout(); scaleLayout->addWidget(scaleLabel); - scaleLayout->addWidget(scaleCombox); -// freshLayout->addStretch(); + scaleLayout->addWidget(mScaleCombox); QFrame *scaleFrame = new QFrame(this); scaleFrame->setFrameShape(QFrame::Shape::Box); scaleFrame->setLayout(scaleLayout); -// scaleWidget->setStyleSheet("background-color:#F4F4F4;border-radius:6px"); - scaleFrame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - scaleFrame->setMinimumSize(550,50); - scaleFrame->setMaximumSize(960,50); + scaleFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + scaleFrame->setMinimumSize(550, 50); + scaleFrame->setMaximumSize(960, 50); vbox->addWidget(scaleFrame); +} - int scale = getScreenScale(); -#if QT_VERSION < QT_VERSION_CHECK(5,7,0) - -#else - scaleCombox->setCurrentIndex(0); - if (scale <= scaleCombox->count() && scale > 0) { -// qDebug()<<"scale is----->"<setCurrentIndex(scale - 1); +double OutputConfig::getScreenScale() +{ + double scale = 1.0; + if (QGSettings::isSchemaInstalled(SCALE_SCHEMAS)) { + if (mDpiSettings->keys().contains("scalingFactor")) { + scale = mDpiSettings->get(SCALE_KEY).toDouble(); + } } - slotScaleChanged(scale - 1); -#endif - - connect(scaleCombox, static_cast(&QComboBox::activated), - this, &OutputConfig::slotScaleChanged); + return scale; } -int OutputConfig::getMaxReslotion() { - +void OutputConfig::initDpiConnection() +{ + QByteArray id(SCALE_SCHEMAS); + if (QGSettings::isSchemaInstalled(SCALE_SCHEMAS)) { + mDpiSettings = new QGSettings(id, QByteArray(), this); + connect(mDpiSettings, &QGSettings::changed, this, [=](QString key) { + slotDPIChanged(key); + }); + } } -int OutputConfig::getScreenScale() { - QGSettings * dpiSettings; - QByteArray id(FONT_RENDERING_DPI); - int scale = 0; - if (QGSettings::isSchemaInstalled(FONT_RENDERING_DPI)) { - dpiSettings = new QGSettings(id); - scale = dpiSettings->get(DPI_KEY).toInt(); - if (96 == scale) { - scale = 1; - } else if (192 == scale) { - scale = 2; - } else if (288 == scale) { - scale = 3; - } else { - scale = 1; - } - } - return scale; +QString OutputConfig::scaleToString(double scale) +{ + return QString::number(scale * 100) + "%"; } void OutputConfig::setOutput(const KScreen::OutputPtr &output) @@ -343,7 +262,6 @@ return mOutput; } - void OutputConfig::slotResolutionChanged(const QSize &size) { // Ignore disconnected outputs @@ -351,45 +269,62 @@ return; } + QString modeID; KScreen::ModePtr selectedMode; + KScreen::ModePtr currentMode = mOutput->currentMode(); QList modes; Q_FOREACH (const KScreen::ModePtr &mode, mOutput->modes()) { if (mode->size() == size) { + selectedMode = mode; modes << mode; - if (!selectedMode || selectedMode->refreshRate() < mode->refreshRate()) { - selectedMode = mode; - } } } Q_ASSERT(selectedMode); - mOutput->setCurrentModeId(selectedMode->id()); + modeID = selectedMode->id(); // Don't remove the first "Auto" item - prevents ugly flicker of the combobox // when changing resolution - for (int i = 1; i < mRefreshRate->count(); ++i) { - mRefreshRate->removeItem(i); + for (int i = mRefreshRate->count(); i >= 2; --i) { + mRefreshRate->removeItem(i - 1); } for (int i = 0, total = modes.count(); i < total; ++i) { const KScreen::ModePtr mode = modes.at(i); - mRefreshRate->addItem(tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())), mode->id()); + + bool alreadyExisted = false; + for (int j = 0; j < mRefreshRate->count(); ++j) { + if (tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())) == mRefreshRate->itemText(j)) { + alreadyExisted = true; + break; + } + } + if (alreadyExisted == false) { //不添加已经存在的项 + mRefreshRate->addItem(tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())), mode->id()); + } + // If selected refresh rate is other then what we consider the "Auto" value // - that is it's not the highest resolution - then select it, otherwise // we stick with "Auto" - if (mode == selectedMode && i > 1) { + if (mode == currentMode && mRefreshRate->count() > 1) { // i + 1 since 0 is auto mRefreshRate->setCurrentIndex(i + 1); } } + if (-1 == mRefreshRate->currentIndex() || 0 == mRefreshRate->currentIndex()) { + modeID = mRefreshRate->itemData(1).toString(); + } + + mOutput->setCurrentModeId(modeID); + Q_EMIT changed(); } void OutputConfig::slotRotationChanged(int index) { - KScreen::Output::Rotation rotation = - static_cast(mRotation->itemData(index).toInt()); + KScreen::Output::Rotation rotation + = static_cast(mRotation->itemData(index).toInt()); mOutput->setRotation(rotation); Q_EMIT changed(); @@ -406,6 +341,7 @@ } else { modeId = mRefreshRate->itemData(index).toString(); } + qDebug() << "modeId is:" << modeId << endl; mOutput->setCurrentModeId(modeId); Q_EMIT changed(); @@ -413,9 +349,37 @@ void OutputConfig::slotScaleChanged(int index) { -// auto scale = mScale->itemData(index).toInt(); -// mOutput->setScale(scale); - Q_EMIT scaleChanged(index); + Q_EMIT scaleChanged(mScaleCombox->itemData(index).toDouble()); +} + +void OutputConfig::slotDPIChanged(QString key) +{ + if (!key.compare("scalingFactor", Qt::CaseSensitive)) { + double scale = mDpiSettings->get(key).toDouble(); + if (mScaleCombox->findData(scale) == -1) { + mScaleCombox->addItem(scaleToString(scale), scale); + } + mScaleCombox->blockSignals(true); + mScaleCombox->setCurrentText(scaleToString(scale)); + mScaleCombox->blockSignals(false); + } +} + +void OutputConfig::slotScaleIndex(const QSize &size) +{ + mScaleCombox->clear(); + mScaleCombox->addItem("100%", 1.0); + + if (k150Scale.contains(size)) { + mScaleCombox->addItem("125%", 1.25); + mScaleCombox->addItem("150%", 1.5); + } + if (k175Scale.contains(size)) { + mScaleCombox->addItem("175%", 1.75); + } + if (k200Scale.contains(size)) { + mScaleCombox->addItem("200%", 2.0); + } } void OutputConfig::setShowScaleOption(bool showScaleOption) @@ -431,48 +395,8 @@ return mShowScaleOption; } -//拿取配置 -void OutputConfig::initConfig(const KScreen::ConfigPtr &config){ +// 拿取配置 +void OutputConfig::initConfig(const KScreen::ConfigPtr &config) +{ mConfig = config; } - -QStringList OutputConfig::readFile(const QString& filepath) { - QFile file(filepath); - if(file.exists()) { - if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - qWarning() << "ReadFile() failed to open" << filepath; - return QStringList(); - } - QTextStream textStream(&file); - while(!textStream.atEnd()) { - QString line= textStream.readLine(); - line.remove('\n'); - this->proRes<proRes; - } else { - qWarning() << filepath << " not found"<get(DPI_KEY).toInt(); - if (96 == scale) { - scale = 1; - } else if (192 == scale) { - scale = 2; - } else if (288 == scale) { - scale = 3; - } else { - scale = 1; - } - } - return scale; -} diff -Nru ukui-control-center-2.0.3/plugins/system/display/outputconfig.h ukui-control-center-3.0.3/plugins/system/display/outputconfig.h --- ukui-control-center-2.0.3/plugins/system/display/outputconfig.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/outputconfig.h 2021-05-20 13:08:14.000000000 +0000 @@ -14,7 +14,6 @@ class QLabel; class QStyledItemDelegate; - namespace Ui { class KScreenWidget; } @@ -23,7 +22,7 @@ { Q_OBJECT - public: +public: explicit OutputConfig(QWidget *parent); explicit OutputConfig(const KScreen::OutputPtr &output, QWidget *parent = nullptr); ~OutputConfig() override; @@ -35,50 +34,53 @@ void setShowScaleOption(bool showScaleOption); bool showScaleOption() const; - //拿取配置 void initConfig(const KScreen::ConfigPtr &config); - QStringList readFile(const QString& filepath); - int scaleRet(); - protected Q_SLOTS: +protected Q_SLOTS: void slotResolutionChanged(const QSize &size); void slotRotationChanged(int index); void slotRefreshRateChanged(int index); void slotScaleChanged(int index); + void slotDPIChanged(QString key); + +private Q_SLOTS: + void slotScaleIndex(const QSize &size); - Q_SIGNALS: +Q_SIGNALS: void changed(); - void scaleChanged(int index); + void scaleChanged(double scale); - protected: +protected: virtual void initUi(); - int getMaxReslotion(); - int getScreenScale(); + double getScreenScale(); - protected: - QLabel *mTitle = nullptr; +private: + void initDpiConnection(); + QString scaleToString(double scale); + +protected: KScreen::OutputPtr mOutput; + QLabel *mTitle = nullptr; QCheckBox *mEnabled = nullptr; ResolutionSlider *mResolution = nullptr; + QComboBox *mRotation = nullptr; QComboBox *mScale = nullptr; QComboBox *mRefreshRate = nullptr; QComboBox *mMonitor = nullptr; - QComboBox *tmpResolution = nullptr; - QComboBox *scaleCombox = nullptr; - bool mShowScaleOption = false; + QComboBox *mScaleCombox = nullptr; + + bool mShowScaleOption = false; + bool mIsWayland = false; + bool mIsFirstLoad = true; #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - KScreen::ConfigPtr mConfig ; + KScreen::ConfigPtr mConfig; #else KScreen::ConfigPtr mConfig = nullptr; #endif - QString qss; - QStringList proRes; //profile文件内容 - - QGSettings *m_gsettings = nullptr; - + QGSettings *mDpiSettings = nullptr; }; #endif // OUTPUTCONFIG_H diff -Nru ukui-control-center-2.0.3/plugins/system/display/qml/main.qml ukui-control-center-3.0.3/plugins/system/display/qml/main.qml --- ukui-control-center-2.0.3/plugins/system/display/qml/main.qml 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/qml/main.qml 2021-05-20 13:08:14.000000000 +0000 @@ -14,16 +14,14 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ import QtQuick 2.1 import QtQuick.Controls 1.1 as Controls -//import org.kde.plasma.core 2.0 as PlasmaCore -//import org.kde.kquickcontrols 2.0 import org.kde.kscreen 1.0 Item { - id: root; property variant virtualScreen: null; @@ -35,72 +33,43 @@ id: palette; } - Rectangle { - id: background; - + MouseArea { anchors.fill: parent; focus: true; -// color: "#000000"; - color: "transparent"; -// color: palette.button; -// opacity: 0.6; -// radius: 6 //设置矩形圆角弧度 - - - FocusScope { - - id: outputViewFocusScope; + Rectangle { + id: background; anchors.fill: parent; focus: true; - QMLScreen { + color: "transparent"; + + FocusScope { - id: outputView; + id: outputViewFocusScope; anchors.fill: parent; - clip: true; + focus: true; - objectName: "outputView"; + QMLScreen { + id: outputView; + anchors.fill: parent; + clip: true; + objectName: "outputView"; + } } - } - Column { - - anchors { - left: parent.left; - //right: identifyButton.left; - bottom: parent.bottom; - margins: 5; + Column { + anchors { + left: parent.left; + bottom: parent.bottom; + margins: 5; + } + spacing: 5; } - - spacing: 5; - - - - - - } -//对识别按钮注释 -// Controls.ToolButton { - -// id: identifyButton -// objectName: "identifyButton"; - -// anchors { -// right: parent.right -// bottom: parent.bottom -// margins: 5 -// } - -// height: width -// width: theme.largeIconSize; -// iconName: "kdocumentinfo" - -// tooltip: i18nd("kcm_displayconfiguration", "Identify outputs"); -// } } + } diff -Nru ukui-control-center-2.0.3/plugins/system/display/qml/Output.qml ukui-control-center-3.0.3/plugins/system/display/qml/Output.qml --- ukui-control-center-2.0.3/plugins/system/display/qml/Output.qml 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/qml/Output.qml 2021-05-20 13:08:14.000000000 +0000 @@ -29,38 +29,53 @@ signal enabledToggled(string self); signal mousePressed(); signal mouseReleased(); + signal positionChanged(); + signal rotationChanged(); + signal widthChanged(); + signal heightChanged(); property bool isDragged: monitorMouseArea.drag.active; property bool isDragEnabled: true; property bool isToggleButtonVisible: false; property bool hasMoved: false; + property var screenName:[ + "Unknown", + "VGA", + "DVI", + "DVII", + "DVIA", + "DVID", + "HDMI", + "eDP-1", + "TV", + "TVComposite", + "TVSVideo", + "TVComponent", + "TVSCART", + "TVC4", + "DP-1" + ]; + width: monitorMouseArea.width; height: monitorMouseArea.height; - visible: (opacity > 0); opacity: output.connected ? 1.0 : 0.0; - Component.onCompleted: { root.updateRootProperties(); } SystemPalette { - id: palette; } MouseArea { - id: monitorMouseArea; - width: root.currentOutputWidth * screen.outputScale; height: root.currentOutputHeight * screen.outputScale - anchors.centerIn: parent; - //是否激活时的透明度 opacity: root.output.enabled ? 1.0 : 0.3; transformOrigin: Item.Center; @@ -93,8 +108,6 @@ drag.onActiveChanged: { /* If the drag is shorter then the animation then make sure * we won't end up in an inconsistent state */ -// console.log("宽度------>"+width) -// console.log("高度------>"+height) if (dragActiveChangedAnimation.running) { dragActiveChangedAnimation.complete(); } @@ -103,6 +116,10 @@ } onPressed: root.clicked(); + onReleased: root.mouseReleased() + onRotationChanged: root.rotationChanged(); + onWidthChanged: root.widthChanged(); + onHeightChanged: root.heightChanged(); /* FIXME: This could be in 'Behavior', but MouseArea had * some complaints...to tired to investigate */ @@ -150,11 +167,8 @@ } Rectangle { - id: monitor; - anchors.fill: parent; - //圆角 radius: 8; //是否点击到屏幕 @@ -174,17 +188,12 @@ } Rectangle { - id: posLabel; - y: 4; x: 4; - width: childrenRect.width + 5; height: childrenRect.height + 2; - radius: 8; - opacity: root.output.enabled && monitorMouseArea.drag.active ? 1.0 : 0.0; visible: opacity != 0.0; @@ -192,11 +201,8 @@ Text { id: posLabelText; - text: root.outputX + "," + root.outputY; - color: "white"; - y: 2; x: 2; } @@ -214,37 +220,11 @@ } Text { - id: nameLabel - text: if (root.isCloneMode === true) { - return ""; - } else if (root.output.type !== KScreenOutput.Panel && root.output.edid && root.output.edid.name) { - return root.output.edid.name; - } else { - return ""; - } - - //上面文字颜色 - color: "#FFFFFF"; - font.pixelSize: 12; - - anchors { - horizontalCenter: parent.horizontalCenter; - bottom: labelVendor.top; - topMargin: 5; - } - } - - Text { id: labelVendor; text: if (root.isCloneMode) { return ("Unified Outputs"); - } else if (root.output.type === KScreenOutput.Panel) { - return ("Laptop Screen"); - } else if (root.output.edid && root.output.edid.vendor) { - - return root.output.edid.vendor; } else { - return root.output.name; + return screenName[root.output.type]; } anchors { @@ -253,26 +233,10 @@ right: parent.right; } horizontalAlignment: Text.AlignHCenter; - //下面文字颜色 - //color: palette.text; color: "#FFFFFF"; - font.pixelSize: 10; + font.pixelSize: 12; elide: Text.ElideRight; } - - Text { - id: label - text: (labelVendor.text === root.output.name) ? "" : root.output.name - - color: palette.text; - font.pixelSize: 10; - - anchors { - horizontalCenter: parent.horizontalCenter; - top: labelVendor.bottom; - topMargin: 5; - } - } } } Item { @@ -284,16 +248,7 @@ Rectangle { id: orientationPanel; - - //注释底部不会变色拖动时候 -// anchors { -// left: parent.left; -// right: parent.right; -// bottom: parent.bottom; -// } - height: 10; - //color: root.focus ? palette.highlight : palette.shadow; //底部颜色 color: palette.highlight ; smooth: true; diff -Nru ukui-control-center-2.0.3/plugins/system/display/resolutionslider.cpp ukui-control-center-3.0.3/plugins/system/display/resolutionslider.cpp --- ukui-control-center-2.0.3/plugins/system/display/resolutionslider.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/resolutionslider.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -8,29 +8,28 @@ #include #include -//#include +#include #include static bool sizeLessThan(const QSize &sizeA, const QSize &sizeB) { - return sizeA.width() * sizeA.height() < sizeB.width() * sizeB.height(); } -ResolutionSlider::ResolutionSlider(const KScreen::OutputPtr &output, QWidget *parent) - : QWidget(parent) - , mOutput(output) -{ +ResolutionSlider::ResolutionSlider(const KScreen::OutputPtr &output, QWidget *parent) : + QWidget(parent), + mOutput(output) +{ + QString sessionType = getenv("XDG_SESSION_TYPE"); + if (sessionType.compare("wayland", Qt::CaseSensitive)) { + mExcludeModes.push_back(QSize(1152, 864)); + } + connect(output.data(), &KScreen::Output::currentModeIdChanged, this, &ResolutionSlider::slotOutputModeChanged); -#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - -#else connect(output.data(), &KScreen::Output::modesChanged, this, &ResolutionSlider::init); -#endif - init(); } @@ -40,11 +39,14 @@ void ResolutionSlider::init() { - this->setMinimumSize(402,30); + this->setMinimumSize(402, 30); this->setMaximumSize(1677215, 30); mModes.clear(); Q_FOREACH (const KScreen::ModePtr &mode, mOutput->modes()) { - if (mModes.contains(mode->size())) { + if (mModes.contains(mode->size()) + || mode->size().width() * mode->size().height() < 1024 * 768 + || mExcludeModes.contains(mode->size()) + || mode->size().width() < 1024) { continue; } mModes << mode->size(); @@ -69,26 +71,19 @@ layout->setContentsMargins(0, 0, 0, 0); if (!mModes.empty()) { std::reverse(mModes.begin(), mModes.end()); - mComboBox = new QComboBox(); - mComboBox->setMinimumSize(402,30); + mComboBox = new QComboBox(this); + mComboBox->setMinimumSize(402, 30); mComboBox->setMaximumSize(1677215, 30); -// mComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); -// mComboBox->setEditable(false); -// mComboBox->setStyleSheet(qss); -// mComboBox->setItemDelegate(itemDelege); -// mComboBox->setMaxVisibleItems(5); int currentModeIndex = -1; int preferredModeIndex = -1; Q_FOREACH (const QSize &size, mModes) { - if (size.width() < 1024) { +#ifdef __sw_64__ + if (size.width() < int(1920)) { continue; } - if (size == mModes[0]) { - mComboBox->addItem(Utils::sizeToString(size)); - } else { - mComboBox->addItem(Utils::sizeToString(size)); - } +#endif + mComboBox->addItem(Utils::sizeToString(size)); if (mOutput->currentMode() && (mOutput->currentMode()->size() == size)) { currentModeIndex = mComboBox->count() - 1; @@ -103,7 +98,7 @@ } layout->addWidget(mComboBox, 0, 0, 1, 1); - connect(mComboBox, static_cast(&QComboBox::currentIndexChanged), + connect(mComboBox, static_cast(&QComboBox::currentIndexChanged), this, &ResolutionSlider::slotValueChanged, Qt::UniqueConnection); Q_EMIT resolutionChanged(mModes.at(mComboBox->currentIndex())); } else { @@ -169,13 +164,21 @@ } } -QSize ResolutionSlider::getMaxResolution() const { +QSize ResolutionSlider::getMaxResolution() const +{ if (mModes.isEmpty()) { return QSize(); } return mModes.first(); } +void ResolutionSlider::setResolution(const QSize &size) +{ + mComboBox->blockSignals(true); + mComboBox->setCurrentIndex(mModes.indexOf(size)); + mComboBox->blockSignals(false); +} + void ResolutionSlider::slotOutputModeChanged() { if (!mOutput->currentMode()) { @@ -199,6 +202,5 @@ if (mCurrentLabel) { mCurrentLabel->setText(Utils::sizeToString(size)); } - Q_EMIT resolutionChanged(size); } diff -Nru ukui-control-center-2.0.3/plugins/system/display/resolutionslider.h ukui-control-center-3.0.3/plugins/system/display/resolutionslider.h --- ukui-control-center-2.0.3/plugins/system/display/resolutionslider.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/resolutionslider.h 2021-04-14 01:27:20.000000000 +0000 @@ -15,27 +15,30 @@ { Q_OBJECT - public: +public: explicit ResolutionSlider(const KScreen::OutputPtr &output, QWidget *parent = nullptr); ~ResolutionSlider() override; QSize currentResolution() const; QSize getMaxResolution() const; + void setResolution(const QSize &size); - Q_SIGNALS: +Q_SIGNALS: void resolutionChanged(const QSize &size); - private Q_SLOTS: +public Q_SLOTS: void slotValueChanged(int); void slotOutputModeChanged(); - private: +private: void init(); +private: KScreen::OutputPtr mOutput; QList mModes; + QList mExcludeModes; QLabel *mSmallestLabel = nullptr; QLabel *mBiggestLabel = nullptr; @@ -43,7 +46,7 @@ QSlider *mSlider = nullptr; QComboBox *mComboBox = nullptr; - QString qss; + bool mIsWayland = false; }; #endif // RESOLUTIONSLIDER_H diff -Nru ukui-control-center-2.0.3/plugins/system/display/slider.cpp ukui-control-center-3.0.3/plugins/system/display/slider.cpp --- ukui-control-center-2.0.3/plugins/system/display/slider.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/slider.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -5,15 +5,14 @@ #include #include - Slider::Slider() : QSlider(Qt::Horizontal) { scaleList << "1.0" << "1.25" << "1.5" << "1.75" << "2.0"; this->setMinimumHeight(50); } + void Slider::paintEvent(QPaintEvent *e) { - QSlider::paintEvent(e); auto painter = new QPainter(this); @@ -28,17 +27,16 @@ if (this->orientation() == Qt::Horizontal) { int fontHeight = fontMetrics.height(); - for (int i=0; i<=numTicks; i++) { + for (int i = 0; i <= numTicks; i++) { int tickNum = minimum() + (tickInterval() * i); int tickX = (((rect.width()/numTicks) * i) - (fontMetrics.width(QString::number(tickNum))/2)); int tickY = rect.height()/2 + fontHeight + 2; painter->drawText(QPoint(tickX + 0.1, tickY), - this->scaleList.at(i)); - } - } + this->scaleList.at(i)); + } + } painter->end(); } - diff -Nru ukui-control-center-2.0.3/plugins/system/display/unifiedoutputconfig.cpp ukui-control-center-3.0.3/plugins/system/display/unifiedoutputconfig.cpp --- ukui-control-center-2.0.3/plugins/system/display/unifiedoutputconfig.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/unifiedoutputconfig.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -1,12 +1,9 @@ #include "unifiedoutputconfig.h" #include "resolutionslider.h" #include "utils.h" -//#include "kcm_screen_debug.h" #include #include -//#include - #include #include #include @@ -16,10 +13,11 @@ #include #include #include +#include #include #include - +#include bool operator<(const QSize &s1, const QSize &s2) { @@ -32,12 +30,10 @@ return s1 < s2; } - -UnifiedOutputConfig::UnifiedOutputConfig(const KScreen::ConfigPtr &config, QWidget *parent) - : OutputConfig(parent) - , mConfig(config) -{ - +UnifiedOutputConfig::UnifiedOutputConfig(const KScreen::ConfigPtr &config, QWidget *parent) : + OutputConfig(parent), + mConfig(config) +{ } UnifiedOutputConfig::~UnifiedOutputConfig() @@ -60,122 +56,95 @@ void UnifiedOutputConfig::initUi() { - - QVBoxLayout *vbox = new QVBoxLayout(this); - vbox->setContentsMargins(0,0,0,0); - //mTitle = new QLabel(this); - // mTitle->setAlignment(Qt::AlignHCenter); -// vbox->addWidget(mTitle); - - // setTitle(i18n("统一输出")); + vbox->setContentsMargins(0, 0, 0, 0); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - //vbox->addStretch(0); - KScreen::OutputPtr fakeOutput = createFakeOutput(); mResolution = new ResolutionSlider(fakeOutput, this); + mResolution->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + mResolution->setMinimumSize(402, 30); + connect(mOutput.data(), &KScreen::Output::currentModeIdChanged, + this, &UnifiedOutputConfig::slotRestoreResoltion); - //统一输出分辨率下拉框 - - mResolution->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - mResolution->setMinimumSize(402,30); -// mResolution->setMaximumSize(402,30); + connect(mOutput.data(), &KScreen::Output::rotationChanged, + this, &UnifiedOutputConfig::slotRestoreRatation); QLabel *resLabel = new QLabel(this); resLabel->setText(tr("resolution")); - resLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - resLabel->setMinimumSize(118,30); - resLabel->setMaximumSize(118,30); + resLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + resLabel->setMinimumSize(118, 30); + resLabel->setMaximumSize(118, 30); QHBoxLayout *resLayout = new QHBoxLayout(); resLayout->addWidget(resLabel); resLayout->addWidget(mResolution); -// resLayout->addStretch(); QFrame *resFrame = new QFrame(this); resFrame->setFrameShape(QFrame::Shape::Box); resFrame->setLayout(resLayout); -// resWidget->setStyleSheet("background-color:#F4F4F4;border-radius:6px"); -// mResolution->setStyleSheet("background-color:#F8F9F9"); - - resFrame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - resFrame->setMinimumSize(552,50); - resFrame->setMaximumSize(960,50); + resFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + resFrame->setMinimumSize(552, 50); + resFrame->setMaximumSize(960, 50); vbox->addWidget(resFrame); connect(mResolution, &ResolutionSlider::resolutionChanged, this, &UnifiedOutputConfig::slotResolutionChanged); + // 方向下拉框 + mRotation = new QComboBox(this); - slotResolutionChanged(mResolution->currentResolution()); - - //方向下拉框 - mRotation = new QComboBox(); - connect(mRotation, static_cast(&QComboBox::currentIndexChanged), - this, &UnifiedOutputConfig::slotRotationChanged); - - mRotation->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - mRotation->setMinimumSize(402,30); - mRotation->setMaximumSize(16777215,30); -// mRotation->setStyleSheet(qss); -// mRotation->setItemDelegate(itemDelege); -// mRotation->setMaxVisibleItems(5); - + mRotation->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + mRotation->setMinimumSize(402, 30); + mRotation->setMaximumSize(16777215, 30); QLabel *rotateLabel = new QLabel(this); rotateLabel->setText(tr("orientation")); - rotateLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - rotateLabel->setMinimumSize(118,30); - rotateLabel->setMaximumSize(118,30); - - connect(mRotation, static_cast(&QComboBox::currentIndexChanged), - this, &UnifiedOutputConfig::slotRotationChangedDerived); + rotateLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + rotateLabel->setMinimumSize(118, 30); + rotateLabel->setMaximumSize(118, 30); mRotation->addItem(tr("arrow-up"), KScreen::Output::None); mRotation->addItem(tr("90° arrow-right"), KScreen::Output::Right); mRotation->addItem(tr("arrow-down"), KScreen::Output::Inverted); mRotation->addItem(tr("90° arrow-left"), KScreen::Output::Left); + int index = mRotation->findData(mOutput->rotation()); + mRotation->setCurrentIndex(index); + + connect(mRotation, static_cast(&QComboBox::currentIndexChanged), + this, &UnifiedOutputConfig::slotRotationChangedDerived); QHBoxLayout *roatateLayout = new QHBoxLayout(); roatateLayout->addWidget(rotateLabel); roatateLayout->addWidget(mRotation); - QFrame *rotateFrame = new QFrame(this); rotateFrame->setFrameShape(QFrame::Shape::Box); rotateFrame->setLayout(roatateLayout); -// rotateWidget->setStyleSheet("background-color:#F4F4F4;border-radius:6px"); -// mRotation->setStyleSheet("background-color:#F8F9F9"); - - rotateFrame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - rotateFrame->setMinimumSize(552,50); - rotateFrame->setMaximumSize(960,50); + rotateFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + rotateFrame->setMinimumSize(552, 50); + rotateFrame->setMaximumSize(960, 50); vbox->addWidget(rotateFrame); - - //统一输出刷新率下拉框 + // 统一输出刷新率下拉框 mRefreshRate = new QComboBox(this); - mRefreshRate->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - mRefreshRate->setMinimumSize(402,30); - mRefreshRate->setMaximumSize(16777215,30); + mRefreshRate->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + mRefreshRate->setMinimumSize(402, 30); + mRefreshRate->setMaximumSize(16777215, 30); QLabel *freshLabel = new QLabel(this); - freshLabel->setText(tr("refresh rate")); - freshLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - freshLabel->setMinimumSize(118,30); - freshLabel->setMaximumSize(118,30); + freshLabel->setText(tr("frequency")); + freshLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + freshLabel->setMinimumSize(118, 30); + freshLabel->setMaximumSize(118, 30); mRefreshRate->addItem(tr("auto"), -1); - mRefreshRate->addItem(tr("aa"), -1); - QHBoxLayout *freshLayout = new QHBoxLayout(); freshLayout->addWidget(freshLabel); @@ -184,15 +153,28 @@ QFrame *freshFrame = new QFrame(this); freshFrame->setFrameShape(QFrame::Shape::Box); freshFrame->setLayout(freshLayout); -// freshFrame->setStyleSheet("background-color:#F4F4F4;border-radius:6px"); vbox->addWidget(freshFrame); - freshFrame->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); - freshFrame->setMinimumSize(552,50); - freshFrame->setMaximumSize(960,50); + freshFrame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + freshFrame->setMinimumSize(552, 50); + freshFrame->setMaximumSize(960, 50); - mRefreshRate->setEnabled(false); + slotResolutionChanged(mResolution->currentResolution()); + connect(mRefreshRate, static_cast(&QComboBox::activated), + this, &UnifiedOutputConfig::slotRefreshRateChanged); + + QObject::connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, + [&](KScreen::ConfigOperation *op) { + KScreen::ConfigPtr sConfig = qobject_cast(op)->config(); + KScreen::OutputPtr sOutput = sConfig -> primaryOutput(); + + for (int i = 0; i < mRefreshRate->count(); ++i) { + if (mRefreshRate->itemText(i) == tr("%1 Hz").arg(QLocale().toString(sOutput->currentMode()->refreshRate()))) { + mRefreshRate->setCurrentIndex(i); + } + } + }); } KScreen::OutputPtr UnifiedOutputConfig::createFakeOutput() @@ -226,7 +208,6 @@ if (commonResults.isEmpty()) { QSize smallestMode; Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { - //qCDebug(KSCREEN_KCM) << smallestMode << clone->preferredMode()->size(); if (!smallestMode.isValid() || clone->preferredMode()->size() < smallestMode) { smallestMode = clone->preferredMode()->size(); } @@ -244,17 +225,25 @@ modes.insert(mode->id(), mode); } fakeOutput->setModes(modes); - fakeOutput->setCurrentModeId(Utils::sizeToString(commonResults.last())); + if (!mOutput->currentModeId().isEmpty()) { + fakeOutput->setCurrentModeId(Utils::sizeToString(mOutput->currentMode()->size())); + } else { + fakeOutput->setCurrentModeId(Utils::sizeToString(commonResults.last())); + } + return fakeOutput; } void UnifiedOutputConfig::slotResolutionChanged(const QSize &size) { - // Ignore disconnected outputs + // Ignore disconnected outputs if (!size.isValid()) { return; } - + QVectorVrefresh; + for (int i = mRefreshRate->count(); i >= 0; --i) { + mRefreshRate->removeItem(i); + } Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { const QString &id = findBestMode(clone, size); if (id.isEmpty()) { @@ -263,8 +252,69 @@ } clone->setCurrentModeId(id); + clone->setPos(QPoint(0, 0)); + + QList modes; + Q_FOREACH (const KScreen::ModePtr &mode, clone->modes()) { + if (mode->size() == size) { + modes << mode; + } + } + + QVectorVrefreshTemp; + for (int i = 0, total = modes.count(); i < total; ++i) { + const KScreen::ModePtr mode = modes.at(i); + + bool alreadyExisted = false; //判断该显示器的刷新率是否有重复的,确保同一刷新率在一个屏幕上只出现一次 + for (int j = 0; j < VrefreshTemp.size(); ++j) { + if (tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())) == VrefreshTemp[j]) { + alreadyExisted = true; + break; + } + } + if (alreadyExisted == false) { //不添加重复的项 + VrefreshTemp.append(tr("%1 Hz").arg(QLocale().toString(mode->refreshRate()))); + } + } + + for (int i = 0; i < VrefreshTemp.size(); ++i) { + Vrefresh.append(VrefreshTemp[i]); + } } + for (int i = 0; i < Vrefresh.size(); ++i) { + if (Vrefresh.count(Vrefresh[i]) == mClones.size()) { //该刷新率出现次数等于屏幕数,即每个屏幕都有该刷新率 + bool existFlag = false; + for (int j = 0; j < mRefreshRate->count(); ++j) { //已经存在就不再添加 + if (Vrefresh[i] == mRefreshRate->itemText(j)) { + existFlag = true; + break; + } + } + if (existFlag == false) { //不存在添加到容器中 + mRefreshRate->addItem(Vrefresh[i]); + } + } + } + if (mRefreshRate->count() == 0) { + mRefreshRate->addItem(tr("auto"), -1); + } + Q_EMIT changed(); +} + +void UnifiedOutputConfig::slotRefreshRateChanged(int index) +{ + if (index == 0) { + index = 1; + } + Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { + Q_FOREACH (const KScreen::ModePtr &mode, clone->modes()) { + if (mode->size() == mResolution->currentResolution() && \ + tr("%1 Hz").arg(QLocale().toString(mode->refreshRate())) == mRefreshRate->itemText(index)) { + clone->setCurrentModeId(mode->id()); + } + } + } Q_EMIT changed(); } @@ -281,29 +331,27 @@ return id; } -//统一输出方向信号改变 -void UnifiedOutputConfig::slotRotationChangedDerived(int index){ - KScreen::Output::Rotation rotation = - static_cast(mRotation->itemData(index).toInt()); - auto mainOutput = mConfig->primaryOutput(); - //qDebug()<<"首屏幕输出--->"<(mRotation->itemData(index).toInt()); Q_FOREACH (const KScreen::OutputPtr &clone, mClones) { - if(clone->isConnected()&&clone->isEnabled()){ - //mOutput = clone; - - mainOutput->setRotation(rotation); - // clone->setRotation(rotation); - //qDebug()<<"是不是首屏------->"<isPrimary()<isPrimary()){ - // qDebug()<<"非首屏------>"<setRotation(rotation); - //output->apply(mainOutput); - //clone->apply(mainOutput); - } + if (clone->isConnected() && clone->isEnabled()) { + clone->setRotation(rotation); + clone->setPos(QPoint(0, 0)); } } Q_EMIT changed(); } +void UnifiedOutputConfig::slotRestoreResoltion() +{ + if (!(mResolution->currentResolution() == mOutput->currentMode()->size())) { + mResolution->setResolution(mOutput->currentMode()->size()); + } +} +void UnifiedOutputConfig::slotRestoreRatation() +{ + mRotation->setCurrentIndex(mRotation->findData(mOutput->rotation())); +} diff -Nru ukui-control-center-2.0.3/plugins/system/display/unifiedoutputconfig.h ukui-control-center-3.0.3/plugins/system/display/unifiedoutputconfig.h --- ukui-control-center-2.0.3/plugins/system/display/unifiedoutputconfig.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/unifiedoutputconfig.h 2021-05-20 13:08:14.000000000 +0000 @@ -3,8 +3,7 @@ #include "outputconfig.h" -namespace KScreen -{ +namespace KScreen { class Output; class Config; } @@ -12,24 +11,28 @@ class UnifiedOutputConfig : public OutputConfig { Q_OBJECT - public: +public: explicit UnifiedOutputConfig(const KScreen::ConfigPtr &config, QWidget *parent); ~UnifiedOutputConfig() override; void setOutput(const KScreen::OutputPtr &output) override; - private Q_SLOTS: +private Q_SLOTS: void slotResolutionChanged(const QSize &size); - //统一输出后调整屏幕方向统一代码 + // 统一输出后调整屏幕方向统一代码 void slotRotationChangedDerived(int index); - private: + void slotRestoreResoltion(); + void slotRestoreRatation(); + void slotRefreshRateChanged(int index); + +private: void initUi() override; KScreen::OutputPtr createFakeOutput(); QString findBestMode(const KScreen::OutputPtr &output, const QSize &size); - private: +private: KScreen::ConfigPtr mConfig; QList mClones; }; diff -Nru ukui-control-center-2.0.3/plugins/system/display/utils.cpp ukui-control-center-3.0.3/plugins/system/display/utils.cpp --- ukui-control-center-2.0.3/plugins/system/display/utils.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/utils.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -3,36 +3,16 @@ #include #include -//#include +#include "../../../shell/utils/utils.h" -QString Utils::outputName(const KScreen::OutputPtr& output) +QString Utils::outputName(const KScreen::OutputPtr &output) { - //qDebug()<<"显示器名称-------->"<type() == KScreen::Output::Panel) { -// return i18n("Laptop Screen"); -// } - - if (output->edid()) { - // The name will be "VendorName ModelName (ConnectorName)", - // but some components may be empty. - QString name; - if (!(output->edid()->vendor().isEmpty())) { - name = output->edid()->vendor() + QLatin1Char(' '); - } - if (!output->edid()->name().isEmpty()) { - name += output->edid()->name() + QLatin1Char(' '); - } - if (!name.trimmed().isEmpty()) { - return name + QLatin1Char('(') + output->name() + QLatin1Char(')'); - } - } - //qDebug()<<"显示器名称-------->"<name(); - return output->name(); + return kOutput.at(output->type()); } QString Utils::sizeToString(const QSize &size) diff -Nru ukui-control-center-2.0.3/plugins/system/display/utils.h ukui-control-center-3.0.3/plugins/system/display/utils.h --- ukui-control-center-2.0.3/plugins/system/display/utils.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/utils.h 2021-05-20 13:08:14.000000000 +0000 @@ -3,17 +3,34 @@ #include #include +#include #include #include -//获取显示器名字和ID类 -namespace Utils -{ - QString outputName(const KScreen::Output *output); - QString outputName(const KScreen::OutputPtr &output); +const QStringList kOutput { + "Unknown", + "VGA", + "DVI", + "DVII", + "DVIA", + "DVID", + "HDMI", + "eDP-1", + "TV", + "TVComposite", + "TVSVideo", + "TVComponent", + "TVSCART", + "TVC4", + "DP-1" +}; - QString sizeToString(const QSize &size); +namespace Utils { +QString outputName(const KScreen::Output *output); +QString outputName(const KScreen::OutputPtr &output); + +QString sizeToString(const QSize &size); } #endif diff -Nru ukui-control-center-2.0.3/plugins/system/display/widget.cpp ukui-control-center-3.0.3/plugins/system/display/widget.cpp --- ukui-control-center-2.0.3/plugins/system/display/widget.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/widget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -5,6 +5,8 @@ #include "utils.h" #include "ui_display.h" #include "displayperformancedialog.h" +#include "colorinfo.h" +#include "../../../shell/utils/utils.h" #include #include @@ -24,9 +26,11 @@ #include #include #include +#include +#include +#include +#include -#include -#include #include #include #include @@ -35,6 +39,7 @@ #include #include #include +#include #ifdef signals #undef signals @@ -51,73 +56,59 @@ #define QML_PATH "kcm_kscreen/qml/" #define UKUI_CONTORLCENTER_PANEL_SCHEMAS "org.ukui.control-center.panel.plugins" -#define NIGHT_MODE_KEY "nightmodestatus" +#define THEME_NIGHT_KEY "themebynight" -#define FONT_RENDERING_DPI "org.ukui.SettingsDaemon.plugins.xsettings" -#define SCALE_KEY "scaling-factor" +#define FONT_RENDERING_DPI "org.ukui.SettingsDaemon.plugins.xsettings" +#define SCALE_KEY "scaling-factor" -#define DPI_SCHEMAS "org.ukui.font-rendering" -#define DPI_KEY "dpi" +#define MOUSE_SIZE_SCHEMAS "org.ukui.peripherals-mouse" +#define CURSOR_SIZE_KEY "cursor-size" -#define MOUSE_SIZE_SCHEMAS "org.ukui.peripherals-mouse" -#define CURSOR_SIZE_KEY "cursor-size" +#define POWER_SCHMES "org.ukui.power-manager" +#define POWER_KEY "brightness-ac" -#define POWER_SCHMES "org.ukui.power-manager" -#define POWER_KEY "brightness-ac" +#define ADVANCED_SCHEMAS "org.ukui.session.required-components" +#define ADVANCED_KEY "windowmanager" -#define ADVANCED_SCHEMAS "org.ukui.session.required-components" -#define ADVANCED_KEY "windowmanager" +const QString kCpu = "ZHAOXIN"; +const QString kLoong = "Loongson"; +const QString tempDayBrig = "6500"; Q_DECLARE_METATYPE(KScreen::OutputPtr) -Widget::Widget(QWidget *parent) - : QWidget(parent) - , ui(new Ui::DisplayWindow()), slider(new Slider()) +Widget::Widget(QWidget *parent) : + QWidget(parent), + ui(new Ui::DisplayWindow()) { - qRegisterMetaType(); + qRegisterMetaType(); gdk_init(NULL, NULL); ui->setupUi(this); ui->quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); + ui->quickWidget->setContentsMargins(0, 0, 0, 9); -#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - oriApply = true; -#else - oriApply = false; - ui->quickWidget->setAttribute(Qt::WA_AlwaysStackOnTop); - ui->quickWidget->setClearColor(Qt::transparent); -#endif - - ui->quickWidget->setContentsMargins(0,0,0,9); - - closeScreenButton = new SwitchButton; - ui->showScreenLayout->addWidget(closeScreenButton); - - m_unifybutton = new SwitchButton; -// m_unifybutton->setEnabled(false); - ui->unionLayout->addWidget(m_unifybutton); - + mCloseScreenButton = new SwitchButton(this); + ui->showScreenLayout->addWidget(mCloseScreenButton); - QHBoxLayout *nightLayout = new QHBoxLayout(ui->nightframe); - nightLabel = new QLabel(tr("night mode")); - nightButton = new SwitchButton; - nightLayout->addWidget(nightLabel); - nightLayout->addStretch(); - nightLayout->addWidget(nightButton); + mUnifyButton = new SwitchButton(this); + ui->unionLayout->addWidget(mUnifyButton); + setHideModuleInfo(); + initNightUI(); + isWayland(); - QProcess * process = new QProcess; + QProcess *process = new QProcess; process->start("lsb_release -r"); process->waitForFinished(); QByteArray ba = process->readAllStandardOutput(); QString osReleaseCrude = QString(ba.data()); QStringList res = osReleaseCrude.split(":"); - QString osRelease = res.length() >= 2 ? res.at(1) : ""; + QString osRelease = res.length() >= 2 ? res.at(1) : ""; osRelease = osRelease.simplified(); const QByteArray idd(ADVANCED_SCHEMAS); - if (QGSettings::isSchemaInstalled(idd) && osRelease == "V10"){ + if (QGSettings::isSchemaInstalled(idd) && osRelease == "V10") { ui->advancedBtn->show(); ui->advancedHorLayout->setContentsMargins(9, 8, 9, 32); } else { @@ -125,114 +116,50 @@ ui->advancedHorLayout->setContentsMargins(9, 0, 9, 0); } + setTitleLabel(); + initGSettings(); initTemptSlider(); - initConfigFile(); initUiComponent(); initNightStatus(); initBrightnessUI(); -// nightButton->setVisible(this->m_redshiftIsValid); - -#if QT_VERSION <= QT_VERSION_CHECK(5,12,0) +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) ui->nightframe->setVisible(false); #else - ui->nightframe->setVisible(this->m_redshiftIsValid); + ui->nightframe->setVisible(this->mRedshiftIsValid); #endif + mNightButton->setChecked(this->mIsNightMode); + showNightWidget(mNightButton->isChecked()); -// qDebug()<<"set night mode here ---->"<m_isNightMode<setChecked(this->m_isNightMode); - showNightWidget(nightButton->isChecked()); - -// connect(this,&Widget::nightModeChanged,nightButton,&SwitchButton::setChecked); -// connect(this,&Widget::redShiftValidChanged,nightButton,&SwitchButton::setVisible); - connect(nightButton,SIGNAL(checkedChanged(bool)),this,SLOT(showNightWidget(bool))); - connect(singleButton, SIGNAL(buttonClicked(int)), this, SLOT(showCustomWiget(int))); - - //是否禁用主显示器确认按钮 - connect(ui->primaryCombo, static_cast(&QComboBox::currentIndexChanged), - this, &Widget::mainScreenButtonSelect); - - //主屏确认按钮 - connect(ui->mainScreenButton, SIGNAL(clicked()), - this, SLOT(primaryButtonEnable())); - - mControlPanel = new ControlPanel(this); - connect(mControlPanel, &ControlPanel::changed, - this, &Widget::changed); - - connect(mControlPanel, &ControlPanel::scaleChanged, - this, &Widget::scaleChangedSlot); - - //ui->formLayout_2->addWidget(mControlPanel); - ui->controlPanelLayout->addWidget(mControlPanel); - - -// connect(ui->applyButton,SIGNAL(clicked()),this,SLOT(save())); - // TODO: Find out why adjusting the screen orientation does not take effect - connect(ui->applyButton, &QPushButton::clicked, this, [=](){ - save(); - if (oriApply) { - QTimer::singleShot(1000, this, - [this] () { - save(); - } - ); - } - }); -// connect(ui->applyButton,SIGNAL(clicked()),this,SLOT(saveBrigthnessConfig())); - - connect(ui->advancedBtn, &QPushButton::clicked, this, [=]{ - DisplayPerformanceDialog * dialog = new DisplayPerformanceDialog; - dialog->exec(); - }); - - connect(m_unifybutton,&SwitchButton::checkedChanged, - [this]{ -// if(checked) - slotUnifyOutputs(); - }); - - //TODO----->bug -// ui->showMonitorwidget->setVisible(false); - connect(closeScreenButton,&SwitchButton::checkedChanged, - this,[=](bool checked){ - checkOutputScreen(checked); - }); - - mOutputTimer = new QTimer(this); - connect(mOutputTimer, &QTimer::timeout, - this, &Widget::clearOutputIdentifiers); - - initGSettings(); + initConnection(); loadQml(); - setBrigthnessFile(); - //亮度调节UI -// initBrightnessUI(); + + mScreenScale = scaleGSettings->get(SCALE_KEY).toDouble(); } Widget::~Widget() { clearOutputIdentifiers(); delete ui; + ui = nullptr; } -bool Widget::eventFilter(QObject* object, QEvent* event) +bool Widget::eventFilter(QObject *object, QEvent *event) { if (event->type() == QEvent::Resize) { - if (mOutputIdentifiers.contains(qobject_cast(object))) { - QResizeEvent *e = static_cast(event); + if (mOutputIdentifiers.contains(qobject_cast(object))) { + QResizeEvent *e = static_cast(event); const QRect screenSize = object->property("screenSize").toRect(); QRect geometry(QPoint(0, 0), e->size()); geometry.moveCenter(screenSize.center()); - static_cast(object)->setGeometry(geometry); + static_cast(object)->setGeometry(geometry); // Pass the event further } } return QObject::eventFilter(object, event); } - void Widget::setConfig(const KScreen::ConfigPtr &config) { if (mConfig) { @@ -242,8 +169,8 @@ } mConfig->disconnect(this); } - mConfig = config; + mPrevConfig = config->clone(); KScreen::ConfigMonitor::instance()->addConfig(mConfig); resetPrimaryCombo(); @@ -251,33 +178,49 @@ this, &Widget::outputAdded); connect(mConfig.data(), &KScreen::Config::outputRemoved, this, &Widget::outputRemoved); - connect(mConfig.data(), &KScreen::Config::primaryOutputChanged, - this, &Widget::primaryOutputChanged); + if (!mIsWayland) { + connect(mConfig.data(), &KScreen::Config::primaryOutputChanged, + this, &Widget::primaryOutputChanged); + } // 上面屏幕拿取配置 mScreen->setConfig(mConfig); mControlPanel->setConfig(mConfig); -// ui->unifyButton->setEnabled(mConfig->outputs().count() > 1); - m_unifybutton->setEnabled(mConfig->outputs().count() > 1); - - //ui->scaleAllOutputsButton->setVisible(!mConfig->supportedFeatures().testFlag(KScreen::Config::Feature::PerOutputScaling)); + mUnifyButton->setEnabled(mConfig->connectedOutputs().count() > 1); + ui->unionframe->setVisible(mConfig->outputs().count() > 1); for (const KScreen::OutputPtr &output : mConfig->outputs()) { outputAdded(output); } - // 选择主屏幕输出 + ui->brightnessframe->setVisible(isVisibleBrightness()); + + // 择主屏幕输出 QMLOutput *qmlOutput = mScreen->primaryOutput(); + if (qmlOutput) { mScreen->setActiveOutput(qmlOutput); } else { if (!mScreen->outputs().isEmpty()) { mScreen->setActiveOutput(mScreen->outputs().at(0)); - //选择一个主屏幕,避免闪退现象 - primaryButtonEnable(); + // 择一个主屏幕,避免闪退现象 + primaryButtonEnable(true); } } slotOutputEnabledChanged(); + + if (mFirstLoad && isCloneMode()) { + mUnifyButton->blockSignals(true); + mUnifyButton->setChecked(true); + mUnifyButton->blockSignals(false); + slotUnifyOutputs(); + } + mFirstLoad = false; + QtConcurrent::run(std::mem_fn(&Widget::setBrightnesSldierValue), this); + + if (mIsWayland) { + mScreenId = getPrimaryScreenID(); + } } KScreen::ConfigPtr Widget::currentConfig() const @@ -296,8 +239,8 @@ ui->quickWidget->setSource(QUrl("qrc:/qml/main.qml")); - QQuickItem* rootObject = ui->quickWidget->rootObject(); - mScreen = rootObject->findChild(QStringLiteral("outputView")); + QQuickItem *rootObject = ui->quickWidget->rootObject(); + mScreen = rootObject->findChild(QStringLiteral("outputView")); if (!mScreen) { return; } @@ -307,19 +250,9 @@ void Widget::resetPrimaryCombo() { - //qDebug()<<"resetPrimaryCombo----->"<supportedFeatures().testFlag(KScreen::Config::Feature::PrimaryDisplay); - ui->primaryLabel->setVisible(isPrimaryDisplaySupported); - ui->primaryCombo->setVisible(isPrimaryDisplaySupported); -#endif - // Don't emit currentIndexChanged when resetting bool blocked = ui->primaryCombo->blockSignals(true); ui->primaryCombo->clear(); - //ui->primaryCombo->addItem(i18n("无主显示输出")); ui->primaryCombo->blockSignals(blocked); if (!mConfig) { @@ -339,38 +272,35 @@ } ui->primaryCombo->addItem(Utils::outputName(output), output->id()); - if (output->isPrimary()) { + if (output->isPrimary() && !mIsWayland) { Q_ASSERT(mConfig); int lastIndex = ui->primaryCombo->count() - 1; ui->primaryCombo->setCurrentIndex(lastIndex); } } -//这里从屏幕点击来读取输出 +// 这里从屏幕点击来读取输出 void Widget::slotFocusedOutputChanged(QMLOutput *output) { mControlPanel->activateOutput(output->outputPtr()); - //读取屏幕点击选择下拉框 + // 读取屏幕点击选择下拉框 Q_ASSERT(mConfig); int index = output->outputPtr().isNull() ? 0 : ui->primaryCombo->findData(output->outputPtr()->id()); if (index == -1 || index == ui->primaryCombo->currentIndex()) { return; } - //qDebug()<<"下拉框id----->"<primaryCombo->setCurrentIndex(index); } void Widget::slotFocusedOutputChangedNoParam() { - //qDebug()<<"slotFocusedOutputChangedNoParam-------->"<activateOutput(res); } - void Widget::slotOutputEnabledChanged() { - // 这里为点击禁用屏幕输出后的改变 + // 点击禁用屏幕输出后的改变 resetPrimaryCombo(); int enabledOutputsCount = 0; Q_FOREACH (const KScreen::OutputPtr &output, mConfig->outputs()) { @@ -381,8 +311,8 @@ break; } } -// ui->unifyButton->setEnabled(enabledOutputsCount > 1); - m_unifybutton->setEnabled(enabledOutputsCount > 1); + mUnifyButton->setEnabled(enabledOutputsCount > 1); + ui->unionframe->setVisible(enabledOutputsCount > 1); } void Widget::slotOutputConnectedChanged() @@ -393,7 +323,7 @@ void Widget::slotUnifyOutputs() { QMLOutput *base = mScreen->primaryOutput(); - //qDebug()<<"primaryOutput---->"< clones; if (!base) { @@ -409,58 +339,50 @@ } } - if (base->isCloneMode() && !m_unifybutton->isChecked()) { - qDebug()<<"取消clone------------>"<connectedOutputs(); - - QMap::iterator it = screens.begin(); - while (it != screens.end()) { - - KScreen::OutputPtr screen= it.value(); -// qDebug()<<"screens is-------->"<isPrimary()) { - - secPoint = QPoint(screen->size().width(),0); - } - it++; - } - - QMap::iterator secIt = screens.begin(); - while (secIt != screens.end()) { - KScreen::OutputPtr screen= secIt.value(); - qDebug()<<"screens is-------->"<isPrimary()) { - screen->setPos(secPoint); + // 取消统一输出 + if (base->isCloneMode() && !mUnifyButton->isChecked()) { + KScreen::OutputList screens = mPrevConfig->connectedOutputs(); + + QMap::iterator preIt = screens.begin(); + QMap::iterator nowIt = screens.begin(); + nowIt++; + while (nowIt != screens.end()) { + nowIt.value()->setPos(QPoint(preIt.value()->pos().x() + preIt.value()->size().width(), 0)); + KScreen::ModeList modes = preIt.value()->modes(); + Q_FOREACH (const KScreen::ModePtr &mode, modes) { + if (preIt.value()->currentModeId() == mode->id()) { + if (preIt.value()->rotation() != KScreen::Output::Rotation::Left && preIt.value()->rotation() != KScreen::Output::Rotation::Right) { + nowIt.value()->setPos(QPoint(preIt.value()->pos().x() + mode->size().width(), 0)); + } else { + nowIt.value()->setPos(QPoint(preIt.value()->pos().x() + mode->size().height(), 0)); + } + } } - secIt++; + preIt = nowIt; + nowIt++; } - setConfig(mPrevConfig); - mPrevConfig.clear(); ui->primaryCombo->setEnabled(true); - //开启开关 -// ui->checkBox->setEnabled(true); - closeScreenButton->setEnabled(true); + mCloseScreenButton->setEnabled(true); + ui->showMonitorframe->setVisible(true); + ui->brightnessframe->setVisible(isVisibleBrightness()); ui->primaryCombo->setEnabled(true); -// ui->unifyButton->setText(tr("统一输出")); - } else if (!base->isCloneMode() && m_unifybutton->isChecked()){ + } else if (!base->isCloneMode() && mUnifyButton->isChecked()) { // Clone the current config, so that we can restore it in case user // breaks the cloning - qDebug()<<"点击统一输出---->"<clone(); for (QMLOutput *output: mScreen->outputs()) { + if (output != mScreen->primaryOutput()) { + output->output()->setRotation(mScreen->primaryOutput()->output()->rotation()); + } if (!output->output()->isConnected()) { continue; } if (!output->output()->isEnabled()) { - output->setVisible(false); continue; } @@ -482,21 +404,18 @@ } base->output()->setClones(clones); + base->setIsCloneMode(true); mScreen->updateOutputsPlacement(); - - //关闭开关 -// ui->checkBox->setEnabled(false); - closeScreenButton->setEnabled(false); + // 关闭开关 + mCloseScreenButton->setEnabled(false); + ui->showMonitorframe->setVisible(false); + ui->brightnessframe->setVisible(false); ui->primaryCombo->setEnabled(false); ui->mainScreenButton->setEnabled(false); - - //qDebug()<<"输出---->"<outputPtr()<setUnifiedOutput(base->outputPtr()); - -// ui->unifyButton->setText(tr("取消统一输出")); } Q_EMIT changed(); } @@ -505,12 +424,14 @@ KScreen::OutputPtr Widget::findOutput(const KScreen::ConfigPtr &config, const QVariantMap &info) { KScreen::OutputList outputs = config->outputs(); - Q_FOREACH(const KScreen::OutputPtr &output, outputs) { + Q_FOREACH (const KScreen::OutputPtr &output, outputs) { if (!output->isConnected()) { continue; } - const QString outputId = (output->edid() && output->edid()->isValid()) ? output->edid()->hash() : output->name(); + const QString outputId + = (output->edid() + && output->edid()->isValid()) ? output->edid()->hash() : output->name(); if (outputId != info[QStringLiteral("id")].toString()) { continue; } @@ -520,18 +441,21 @@ output->setPos(point); output->setPrimary(info[QStringLiteral("primary")].toBool()); output->setEnabled(info[QStringLiteral("enabled")].toBool()); - output->setRotation(static_cast(info[QStringLiteral("rotation")].toInt())); + output->setRotation(static_cast(info[QStringLiteral("rotation")]. + toInt())); QVariantMap modeInfo = info[QStringLiteral("mode")].toMap(); QVariantMap modeSize = modeInfo[QStringLiteral("size")].toMap(); - QSize size(modeSize[QStringLiteral("width")].toInt(), modeSize[QStringLiteral("height")].toInt()); + QSize size(modeSize[QStringLiteral("width")].toInt(), + modeSize[QStringLiteral("height")].toInt()); const KScreen::ModeList modes = output->modes(); - Q_FOREACH(const KScreen::ModePtr &mode, modes) { + Q_FOREACH (const KScreen::ModePtr &mode, modes) { if (mode->size() != size) { continue; } - if (QString::number(mode->refreshRate()) != modeInfo[QStringLiteral("refresh")].toString()) { + if (QString::number(mode->refreshRate()) + != modeInfo[QStringLiteral("refresh")].toString()) { continue; } @@ -544,191 +468,334 @@ return KScreen::OutputPtr(); } -//float Widget::scaleRet() { -// QString filepath = getenv("HOME"); -// QString scale; -// filepath += "/.profile"; -// QStringList res = this->readFile(filepath); -// QRegExp re("export( GDK_SCALE)?=(.*)$"); -// for(int i = 0; i < res.length(); i++) { -// int pos = 0; -//// qDebug()<quickWidget->setAttribute(Qt::WA_AlwaysStackOnTop); + ui->quickWidget->setClearColor(Qt::transparent); } - isScaleChanged = false; +} + +void Widget::setTitleLabel() +{ + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + + //~ contents_path /display/monitor + ui->primaryLabel->setText(tr("monitor")); +} + +void Widget::writeScale(double scale) +{ + if (scale != scaleGSettings->get(SCALE_KEY).toDouble()) { + mIsScaleChanged = true; + } + + if (mIsScaleChanged) { + QMessageBox::information(this, tr("Information"), + tr("Some applications need to be logouted to take effect")); + } else { + return; + } + + mIsScaleChanged = false; int cursize; - QGSettings * dpiSettings; - QGSettings * cursorSettings; - QGSettings * fontSettings; - QByteArray id(FONT_RENDERING_DPI); QByteArray iid(MOUSE_SIZE_SCHEMAS); - QByteArray iiid(DPI_SCHEMAS); - if (QGSettings::isSchemaInstalled(FONT_RENDERING_DPI) && QGSettings::isSchemaInstalled(MOUSE_SIZE_SCHEMAS) - && QGSettings::isSchemaInstalled(DPI_SCHEMAS)) { - dpiSettings = new QGSettings(id); - cursorSettings = new QGSettings(iid); - fontSettings = new QGSettings(iiid); + if (QGSettings::isSchemaInstalled(MOUSE_SIZE_SCHEMAS)) { + QGSettings cursorSettings(iid); - if (1 == scale) { + if (1.0 == scale) { cursize = 24; - } else if (2 == scale) { + } else if (2.0 == scale) { cursize = 48; - } else if (3 == scale) { + } else if (3.0 == scale) { cursize = 96; } else { - scale = 1; cursize = 24; } - QStringList keys = dpiSettings->keys(); + QStringList keys = scaleGSettings->keys(); if (keys.contains("scalingFactor")) { - fontSettings->set(DPI_KEY, 96); - dpiSettings->set(SCALE_KEY, scale); - } - cursorSettings->set(CURSOR_SIZE_KEY, cursize); - delete dpiSettings; - delete cursorSettings; + scaleGSettings->set(SCALE_KEY, scale); + } + cursorSettings.set(CURSOR_SIZE_KEY, cursize); + Utils::setKwinMouseSize(cursize); } } - -void Widget::initGSettings() { +void Widget::initGSettings() +{ QByteArray id(UKUI_CONTORLCENTER_PANEL_SCHEMAS); - if(QGSettings::isSchemaInstalled(id)) { -// qDebug()<<"initGSettings-------------------->"<keys().contains(THEME_NIGHT_KEY)) { + mThemeButton->setChecked(mGsettings->get(THEME_NIGHT_KEY).toBool()); + } } else { - return ; + qDebug() << Q_FUNC_INFO << "org.ukui.control-center.panel.plugins not install"; + return; + } + + QByteArray powerId(POWER_SCHMES); + if (QGSettings::isSchemaInstalled(powerId)) { + mPowerGSettings = new QGSettings(powerId, QByteArray(), this); + mPowerKeys = mPowerGSettings->keys(); + connect(mPowerGSettings, &QGSettings::changed, this, [=](QString key) { + if ("brightnessAc" == key || "brightnessBat" == key) { + int value = mPowerGSettings->get(key).toInt(); + if (mIsWayland && !mIsBattery) { + value = (value == 0 ? 0 : value / 10); + } + ui->brightnessSlider->blockSignals(true); + ui->brightValueLabel->setText(QString::number(value)); + ui->brightnessSlider->setValue(value); + ui->brightnessSlider->blockSignals(false); + } + }); } -// QByteArray scaleId(SCRENN_SCALE_SCHMES); -// if(QGSettings::isSchemaInstalled(scaleId)) { -//// qDebug()<<"initGSettings-------------------->"<(QString("scaleCombox")); + if (scaleCombox) { + scale = ("100%" == scaleCombox->currentText() ? 1 : 2); + } + writeScale(scale); } -bool Widget::getNightModeGSetting(const QString &key) { - if (!m_gsettings) { - return ""; +void Widget::initNightUI() +{ + //~ contents_path /display/unify output + ui->unifyLabel->setText(tr("unify output")); + + QHBoxLayout *nightLayout = new QHBoxLayout(ui->nightframe); + //~ contents_path /display/night mode + nightLabel = new QLabel(tr("night mode"), this); + mNightButton = new SwitchButton(this); + nightLayout->addWidget(nightLabel); + nightLayout->addStretch(); + nightLayout->addWidget(mNightButton); + + QHBoxLayout *themeLayout = new QHBoxLayout(ui->themeFrame); + mThemeButton = new SwitchButton(this); + themeLayout->addWidget(new QLabel(tr("Theme follow night mode"))); + themeLayout->addStretch(); + themeLayout->addWidget(mThemeButton); +} + +bool Widget::isRestoreConfig() +{ + int cnt = 15; + int ret; + QRect rect = this->topLevelWidget()->geometry(); + QMessageBox msg; + int msgX = 0, msgY = 0; + if (mConfigChanged) { + msg.setWindowTitle(tr("Hint")); + msg.setText(tr("After modifying the resolution or refresh rate, " + "due to compatibility issues between the display device and the graphics card, " + "the display may be abnormal or unable to display\n" + "the settings will be saved after 14 seconds")); + msg.addButton(tr("Save Config"), QMessageBox::RejectRole); + msg.addButton(tr("Restore Config"), QMessageBox::AcceptRole); + + QTimer cntDown; + QObject::connect(&cntDown, &QTimer::timeout, [&msg, &cnt, &cntDown, &ret]()->void { + if (--cnt < 0) { + cntDown.stop(); + msg.close(); + } else { + msg.setText(QString(tr("After modifying the resolution or refresh rate, " + "due to compatibility issues between the display device and the graphics card, " + "the display may be abnormal or unable to display \n" + "the settings will be saved after %1 seconds")).arg(cnt)); + } + }); + cntDown.start(1000); + msgX = rect.x() + rect.width()/2 - 500/2 - 2; + msgY = rect.y() + rect.height()/2 - 145/2 + 35; + msg.move(msgX, msgY); + ret = msg.exec(); } - const QStringList list = m_gsettings->keys(); - if (!list.contains(key)) { - return ""; + + bool res = false; + switch (ret) { + case QMessageBox::AcceptRole: + res = false; + break; + case QMessageBox::RejectRole: + res = true; + break; } - bool res = m_gsettings->get(key).toBool(); return res; } -void Widget::setNightModebyPanel(bool judge) { -// QProcess *process = new QProcess; -// if(judge == true) { -// process->startDetached("redshift -t 5700:3600 -g 0.8 -m randr -v"); -// } else { -// QProcess::execute("killall redshift"); -// } +QString Widget::getCpuInfo() +{ + QDBusInterface youkerInterface("com.kylin.assistant.systemdaemon", + "/com/kylin/assistant/systemdaemon", + "com.kylin.assistant.systemdaemon", + QDBusConnection::systemBus()); + if (!youkerInterface.isValid()) { + qCritical() << "Create youker Interface Failed When Get Computer info: " << + QDBusConnection::systemBus().lastError(); + return QString(); + } + + QDBusReply > cpuinfo; + QString cpuType; + cpuinfo = youkerInterface.call("get_cpu_info"); + if (!cpuinfo.isValid()) { + qDebug() << "cpuinfo is invalid" << endl; + } else { + QMap res = cpuinfo.value(); + cpuType = res["CpuVersion"].toString(); + } + return cpuType; } -void Widget::setSessionScale(int scale) { +bool Widget::isCloneMode() +{ + KScreen::OutputPtr output = mConfig->primaryOutput(); + if (mConfig->connectedOutputs().count() >= 2) { + foreach (KScreen::OutputPtr secOutput, mConfig->connectedOutputs()) { + if (secOutput->geometry() != output->geometry() || !secOutput->isEnabled()) { + return false; + } + } + } else { + return false; + } + return true; +} -// if (!scaleGSettings) { -// return; -// } -// QStringList keys = scaleGSettings->keys(); -// if (keys.contains("hidpi")){ -// scaleGSettings->set(USER_SACLE_KEY, true); -// } -// if (keys.contains("gdkScale")){ +bool Widget::isBacklight() +{ + QString cmd = "ukui-power-backlight-helper --get-max-brightness"; + QProcess process; + process.start(cmd); + process.waitForFinished(); + QString result = process.readAllStandardOutput().trimmed(); -// scaleGSettings->set(GDK_SCALE_KEY, scale); -// } -// if (keys.contains("qtScaleFactor")) { -// scaleGSettings->set(QT_SCALE_KEY, scale); -// } -} + QString pattern("^[0-9]*$"); + QRegExp reg(pattern); -void Widget::writeConfigFile() { + return reg.exactMatch(result); +} - if (m_gsettings) { - m_gsettings->set(NIGHT_MODE_KEY, nightButton->isChecked()); +QString Widget::getMonitorType() +{ + QString monitor = ui->primaryCombo->currentText(); + QString type; + if (monitor.contains("VGA", Qt::CaseInsensitive)) { + type = "4"; + } else { + type = "8"; } + return type; +} - m_qsettings->beginGroup("redshift"); - QString optime = ui->opHourCom->currentText() + ":" + ui->opMinCom->currentText(); - QString cltime = ui->clHourCom->currentText() + ":" + ui->clMinCom->currentText(); - QString value = QString::number(ui->temptSlider->value()); - +bool Widget::isLaptopScreen() +{ + const QString &monitor = ui->primaryCombo->currentText(); + if (monitor == "eDP-1") { + return true; + } + return false; +} - if ( !ui->customradioBtn->isChecked()) { - optime = "17:55"; - cltime = "05:04"; +bool Widget::isVisibleBrightness() +{ + if ((mIsBattery && isLaptopScreen()) + || (mIsWayland && !mIsBattery) + || (!mIsWayland && mIsBattery)) { + return true; } + return false; +} - m_qsettings->setValue("dawn-time", cltime); - m_qsettings->setValue("dusk-time", optime); - m_qsettings->setValue("temp-day", tempDayBrig); - m_qsettings->setValue("temp-night", value); +int Widget::getDDCBrighthess() +{ + QString type = getMonitorType(); + QDBusInterface ukccIfc("com.control.center.qt.systemdbus", + "/", + "com.control.center.interface", + QDBusConnection::systemBus()); - m_qsettings->endGroup(); + QDBusReply reply = ukccIfc.call("getDDCBrightness", type); - m_qsettings->beginGroup("switch"); - m_qsettings->setValue("unionswitch", m_unifybutton->isChecked()); - m_qsettings->setValue("nightjudge", nightButton->isChecked()); - m_qsettings->setValue("sunjudge", ui->sunradioBtn->isChecked()); - m_qsettings->setValue("manualjudge", ui->customradioBtn->isChecked()); - m_qsettings->setValue("nightStatus", nightButton->isChecked()); + if (reply.isValid()) { + return reply.value(); + } + return 0; +} - m_qsettings->endGroup(); - m_qsettings->sync(); +int Widget::getLaptopBrightness() const +{ + return mPowerGSettings->get(POWER_KEY).toInt(); +} +int Widget::getPrimaryScreenID() +{ + QString primaryScreen = getPrimaryWaylandScreen(); + int screenId; + for (const KScreen::OutputPtr &output : mConfig->outputs()) { + if (!output->name().compare(primaryScreen, Qt::CaseInsensitive)) { + screenId = output->id(); + } + } + return screenId; } -void Widget::showNightWidget(bool judge) { +void Widget::showNightWidget(bool judge) +{ if (judge) { ui->sunframe->setVisible(true); ui->customframe->setVisible(true); -// ui->temptwidget->setVisible(true); ui->temptframe->setVisible(true); + ui->themeFrame->setVisible(false); } else { ui->sunframe->setVisible(false); ui->customframe->setVisible(false); - -// ui->temptwidget->setVisible(false); ui->temptframe->setVisible(false); + ui->themeFrame->setVisible(false); } - if (judge && ui->customradioBtn->isChecked()) { - showCustomWiget(CUSTOM); - } else { - showCustomWiget(SUN); - } + if (judge && ui->customradioBtn->isChecked()) { + showCustomWiget(CUSTOM); + } else { + showCustomWiget(SUN); + } } -void Widget::showCustomWiget(int index) { +void Widget::showCustomWiget(int index) +{ if (SUN == index) { ui->opframe->setVisible(false); ui->clsframe->setVisible(false); } else if (CUSTOM == index) { - ui->opframe->setVisible(true);; + ui->opframe->setVisible(true); ui->clsframe->setVisible(true); } } +void Widget::slotThemeChanged(bool judge) +{ + if (mGsettings->keys().contains(THEME_NIGHT_KEY)) { + mGsettings->set(THEME_NIGHT_KEY, judge); + } +} + void Widget::clearOutputIdentifiers() { mOutputTimer->stop(); @@ -746,6 +813,29 @@ this, &Widget::changed); addOutputToPrimaryCombo(output); + + // 检查统一输出-防止多显示屏幕 + if (mUnifyButton->isChecked()) { + for (QMLOutput *qmlOutput: mScreen->outputs()) { + if (!qmlOutput->output()->isConnected()) { + continue; + } + if (!qmlOutput->isCloneMode()) { + qmlOutput->blockSignals(true); + qmlOutput->setVisible(false); + qmlOutput->blockSignals(false); + } + } + } + + ui->unionframe->setVisible(mConfig->connectedOutputs().count() > 1); + mUnifyButton->setEnabled(mConfig->connectedOutputs().count() > 1); + + if (!mFirstLoad) { + QTimer::singleShot(2000, this, [=] { + mainScreenButtonSelect(ui->primaryCombo->currentIndex()); + }); + } } void Widget::outputRemoved(int outputId) @@ -768,11 +858,28 @@ ui->primaryCombo->blockSignals(blocked); } ui->primaryCombo->removeItem(index); + + // 检查统一输出-防止移除后没有屏幕可显示 + if (mUnifyButton->isChecked()) { + for (QMLOutput *qmlOutput: mScreen->outputs()) { + if (!qmlOutput->output()->isConnected()) { + continue; + } + qmlOutput->setIsCloneMode(false); + qmlOutput->blockSignals(true); + qmlOutput->setVisible(true); + qmlOutput->blockSignals(false); + } + } + ui->unionframe->setVisible(mConfig->connectedOutputs().count() > 1); + mUnifyButton->blockSignals(true); + mUnifyButton->setChecked(mConfig->connectedOutputs().count() > 1); + mUnifyButton->blockSignals(false); + mainScreenButtonSelect(ui->primaryCombo->currentIndex()); } void Widget::primaryOutputSelected(int index) { - //qDebug()<<"选中主显示器--->"<(op)->config(); + const KScreen::ConfigPtr config = qobject_cast(op)->config(); const QString qmlPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(QML_PATH "OutputIdentifier.qml")); @@ -874,6 +981,86 @@ mOutputTimer->start(2500); } +void Widget::callMethod(QRect geometry, QString name) +{ + auto scale = 1; + QDBusInterface waylandIfc("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/wayland", + "org.ukui.SettingsDaemon.wayland", + QDBusConnection::sessionBus()); + + QDBusReply reply = waylandIfc.call("scale"); + if (reply.isValid()) { + scale = reply.value(); + } + + QDBusMessage message = QDBusMessage::createMethodCall("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/wayland", + "org.ukui.SettingsDaemon.wayland", + "priScreenChanged"); + message << geometry.x() / scale << geometry.y() / scale << geometry.width() / scale << + geometry.height() / scale << name; + QDBusConnection::sessionBus().send(message); +} + +QString Widget::getPrimaryWaylandScreen() +{ + QDBusInterface screenIfc("org.ukui.SettingsDaemon", + "/org/ukui/SettingsDaemon/wayland", + "org.ukui.SettingsDaemon.wayland", + QDBusConnection::sessionBus()); + QDBusReply screenReply = screenIfc.call("priScreenName"); + if (screenReply.isValid()) { + return screenReply.value(); + } + return QString(); +} + +void Widget::isWayland() +{ + QString sessionType = getenv("XDG_SESSION_TYPE"); + + if (!sessionType.compare(kSession, Qt::CaseSensitive)) { + mIsWayland = true; + } else { + mIsWayland = false; + } +} + +void Widget::setDDCBrighthessSlot(int brightnessValue) +{ + QString type = getMonitorType(); + QDBusInterface ukccIfc("com.control.center.qt.systemdbus", + "/", + "com.control.center.interface", + QDBusConnection::systemBus()); + + + if (mLock.tryLock()) { + ukccIfc.call("setDDCBrightness", QString::number(brightnessValue), type); + mLock.unlock(); + } +} + +void Widget::kdsScreenchangeSlot() +{ + connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, + [&](KScreen::ConfigOperation *op) { + bool cloneMode = true; + KScreen::ConfigPtr config = qobject_cast(op)->config(); + KScreen::OutputPtr output = config->primaryOutput(); + if (config->connectedOutputs().count() >= 2) { + foreach (KScreen::OutputPtr secOutput, config->connectedOutputs()) { + if (secOutput->geometry() != output->geometry() || !secOutput->isEnabled()) { + cloneMode = false; + } + } + } else { + cloneMode = false; + } + mUnifyButton->setChecked(cloneMode); + }); +} void Widget::save() { @@ -882,26 +1069,17 @@ } const KScreen::ConfigPtr &config = this->currentConfig(); - const int countOutput = config->connectedOutputs().count(); bool atLeastOneEnabledOutput = false; - int i = 0; - int connectedScreen = 0; - Q_FOREACH(const KScreen::OutputPtr &output, config->outputs()) { - KScreen::ModePtr mode = output->currentMode(); + Q_FOREACH (const KScreen::OutputPtr &output, config->outputs()) { if (output->isEnabled()) { -// qDebug()<<"atLeastOneEnabledOutput------------>"<isConnected()) continue; QMLOutput *base = mScreen->primaryOutput(); -// qDebug()<<"primaryOutput---->"<outputs()) { if (output->output()->isConnected() && output->output()->isEnabled()) { base = output; @@ -914,75 +1092,32 @@ return; } } - inputXml[i].isClone = base->isCloneMode() == true? "yes" : "no"; - inputXml[i].outputName = output->name(); + } - inputXml[i].widthValue = QString::number(mode->size().width()); - inputXml[i].heightValue = QString::number(mode->size().height()); - inputXml[i].rateValue = QString::number(mode->refreshRate()); - inputXml[i].posxValue = QString::number(output->pos().x()); - inputXml[i].posyValue = QString::number(output->pos().y()); - inputXml[i].vendorName = output->edid()->pnpId(); - - auto rotation = [&] ()->QString { - if(1 == output->rotation()) - return "normal"; - else if(2 == output->rotation()) - return "left"; - else if(4 == output->rotation()) - return "upside_down"; - else if(8 == output->rotation()) - return "right"; - }; - - inputXml[i].rotationValue = rotation(); - inputXml[i].isPrimary = (output->isPrimary() == true?"yes":"no"); - inputXml[i].isEnable = output->isEnabled(); - - getEdidInfo(output->name(),&inputXml[i]); - i++; - } - - if (!atLeastOneEnabledOutput ) { - qDebug()<<"atLeastOneEnabledOutput---->"<setChecked(true); - return ; - } else if( ((ui->opHourCom->currentIndex() < ui->clHourCom->currentIndex()) || - (ui->opHourCom->currentIndex() == ui->clHourCom->currentIndex() && - ui->opMinCom->currentIndex() <= ui->clMinCom->currentIndex())) && - CUSTOM == singleButton->checkedId() && nightButton->isChecked()) { - KMessageBox::error(this,tr("Morning time should be earlier than evening time!"), - tr("Warning"),KMessageBox::Notify); - closeScreenButton->setChecked(true); - return ; - } - -// int scale = static_cast(this->scaleRet()); - initScreenXml(countOutput); - writeScreenXml(countOutput); -#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0) -#else - writeScale(static_cast(this->screenScale)); -#endif - writeConfigFile(); - setNightMode(nightButton->isChecked()); + if (!atLeastOneEnabledOutput) { + QMessageBox::warning(this, tr("Warning"), tr("please insure at least one output!")); + mCloseScreenButton->setChecked(true); + return; + } else if (((ui->opHourCom->currentIndex() < ui->clHourCom->currentIndex()) + || (ui->opHourCom->currentIndex() == ui->clHourCom->currentIndex() + && ui->opMinCom->currentIndex() <= ui->clMinCom->currentIndex())) + && CUSTOM == singleButton->checkedId() && mNightButton->isChecked()) { + QMessageBox::warning(this, tr("Warning"), + tr("Open time should be earlier than close time!")); + mCloseScreenButton->setChecked(true); + return; + } + writeScale(this->mScreenScale); + setNightMode(mNightButton->isChecked()); if (!KScreen::Config::canBeApplied(config)) { - KMessageBox::information(this, - tr("Sorry, your configuration could not be applied.\nCommon reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU."), - tr("@title:window", "Unsupported Configuration")); + QMessageBox::information(this, + tr("Warnning"), + tr("Sorry, your configuration could not be applied.\nCommon reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU.")); return; } -// qDebug()<<"scale ann screenScale is -------->"<scaleRet()<<" "<screenScale<screenScale) { -// KMessageBox::information(this,tr("Some applications need to be restarted to take effect")); -// } - - m_blockChanges = true; + mBlockChanges = true; /* Store the current config, apply settings */ auto *op = new KScreen::SetConfigOperation(config); @@ -993,819 +1128,659 @@ // The 1000ms is a bit "random" here, it's what works on the systems I've tested, but ultimately, this is a hack // due to the fact that we just can't be sure when xrandr is done changing things, 1000 doesn't seem to get in the way QTimer::singleShot(1000, this, - [this] () { - m_blockChanges = false; + [=]() { + if (mIsWayland) { + QtConcurrent::run(std::mem_fn(&Widget::setBrightSliderVisible), this); + QString hash = config->connectedOutputsHash(); + writeFile(mDir % hash); } - ); -} + mBlockChanges = false; + }); -void Widget::scaleChangedSlot(int index) { - qDebug()<<"scale changed----------->"<screenScale = 1; - break; - case 1: - this->screenScale = 2; - break; - case 2: - this->screenScale = 3; - break; - default: - this->screenScale = 1; - break; + int enableScreenCount = 0; + KScreen::OutputPtr enableOutput; + for (const KScreen::OutputPtr &output : mConfig->outputs()) { + if (output->isEnabled()) { + enableOutput = output; + enableScreenCount++; + } } - isScaleChanged = true; -} + if (mIsWayland && -1 != mScreenId) { + if (enableScreenCount >= 2 && !config.isNull()) { + config->output(mScreenId)->setPrimary(true); + callMethod(config->primaryOutput()->geometry(), config->primaryOutput()->name()); + if (mScreen->primaryOutput()) { + mScreen->primaryOutput()->setIsCloneMode(mUnifyButton->isChecked()); + } + } else if (!enableOutput.isNull()) { + enableOutput->setPrimary(true); + callMethod(enableOutput->geometry(), enableOutput->name()); + } + } -//是否禁用主屏按钮 -void Widget::mainScreenButtonSelect(int index){ - //qDebug()<<"index is----->"<primaryOutput()<updateOutputsPlacement(); + + QTimer::singleShot(500, this, [=]() { + if (isRestoreConfig()) { + if (mIsWayland && -1 != mScreenId) { + mPrevConfig->output(mScreenId)->setPrimary(true); + callMethod(mPrevConfig->output(mScreenId)->geometry(), mPrevConfig->output(mScreenId)->name()); + } + auto *op = new KScreen::SetConfigOperation(mPrevConfig); + op->exec(); + + // 无法知道什么时候执行完操作 + QTimer::singleShot(1000, this, [=]() { + writeFile(mDir % mPrevConfig->connectedOutputsHash()); + }); + } else { + writeScreenXml(); + } + }); + +} + +QVariantMap metadata(const KScreen::OutputPtr &output) +{ + QVariantMap metadata; + metadata[QStringLiteral("name")] = output->name(); + if (!output->edid() || !output->edid()->isValid()) { + return metadata; } - const KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); - //qDebug()<<"newPrimary----->"<primaryOutput()) { - ui->mainScreenButton->setEnabled(false); - }else{ - ui->mainScreenButton->setEnabled(true); + metadata[QStringLiteral("fullname")] = output->edid()->deviceId(); + return metadata; +} + +QString Widget::globalFileName(const QString &hash) +{ + QString s_dirPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + %QStringLiteral("/kscreen/"); + QString dir = s_dirPath % QStringLiteral("outputs/"); + if (!QDir().mkpath(dir)) { + return QString(); } -// if(index == 0){ -// ui->mainScreenButton->setEnabled(false); -// ui->checkBox->setEnabled(false); -// return ; -// } - // 设置是否勾选 -// ui->checkBox->setEnabled(true); - closeScreenButton->setEnabled(true); -// ui->checkBox->setChecked(newPrimary->isEnabled()); - closeScreenButton->setChecked(newPrimary->isEnabled()); - mControlPanel->activateOutput(newPrimary); + return QString(); } +QVariantMap Widget::getGlobalData(KScreen::OutputPtr output) +{ + QFile file(globalFileName(output->hashMd5())); + if (!file.open(QIODevice::ReadOnly)) { + qDebug() << "Failed to open file" << file.fileName(); + return QVariantMap(); + } + QJsonDocument parser; + return parser.fromJson(file.readAll()).toVariant().toMap(); +} -//设置主屏按钮 -void Widget::primaryButtonEnable(){ - if (!mConfig) { +void Widget::writeGlobal(const KScreen::OutputPtr &output) +{ + // get old values and subsequently override + QVariantMap info = getGlobalData(output); + if (!writeGlobalPart(output, info, nullptr)) { + return; + } + QFile file(globalFileName(output->hashMd5())); + if (!file.open(QIODevice::WriteOnly)) { + qWarning() << "Failed to open global output file for writing! " << file.errorString(); return; } - int index = ui->primaryCombo->currentIndex(); ; - ui->mainScreenButton->setEnabled(false); - const KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); - // qDebug()<<"按下主屏按钮---->"<setPrimaryOutput(newPrimary); - Q_EMIT changed(); + file.write(QJsonDocument::fromVariant(info).toJson()); + return; } -void Widget::checkOutputScreen(bool judge){ -// qDebug()<<"is enable screen---->"<primaryCombo->currentIndex(); - const KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); -// if(ui->primaryCombo->count()<=1&&judge ==false) -// return ; -// qDebug()<<"newPrimary---------->"<primaryOutput(); -// qDebug()<<"mainScreen is------------>"<setPrimaryOutput(newPrimary); - } - newPrimary->setEnabled(judge); - ui->primaryCombo->setCurrentIndex(index); - Q_EMIT changed(); -} - -//亮度调节UI -void Widget::initBrightnessUI(){ - //亮度调节 -// ui->brightnesswidget->setStyleSheet("background-color:#F4F4F4;border-radius:6px"); - - ui->brightnessSlider->setRange(0.2*100,100); - ui->brightnessSlider->setTracking(true); - - QString screenName = getScreenName(); - - setBrightnesSldierValue(screenName); - - connect(ui->brightnessSlider,&QSlider::valueChanged, - this,&Widget::setBrightnessScreen); - - connect(ui->primaryCombo, &QComboBox::currentTextChanged, - this, &Widget::setBrightnesSldierValue); -} - - -QString Widget::getScreenName(QString screenname){ - if("" == screenname ) - screenname = ui->primaryCombo->currentText(); - int startPos = screenname.indexOf('('); - int endPos = screenname.indexOf(')'); - return screenname.mid(startPos+1,endPos-startPos-1); -} - -QStringList Widget::getscreenBrightnesName(){ - QByteArray ba; - FILE * fp = NULL; - char cmd[1024]; - char buf[1024]; - - sprintf(cmd, "xrandr | grep \" connected\" | awk '{ print$1 }'"); - if ((fp = popen(cmd, "r")) != NULL){ - rewind(fp); - while(!feof(fp)){ - fgets(buf, sizeof (buf), fp); - ba.append(buf); - } - pclose(fp); - fp = NULL; - - }else{ - qDebug()<<"popen文件打开失败"<"<"<keys(); - if (keys.contains("brightnessAc")) { - powerSettings->set(POWER_KEY, index); - } - } - if (!powerSettings) { - delete powerSettings; - } -// QStringList nameList = getscreenBrightnesName(); -// QString sliderValue = QString::number(ui->brightnessSlider->value()/100.0); - -// QString screenName = getScreenName(); - -// float value = index/100.0 >0.2?index/100.0:0.2; -// QString brightnessValue = QString::number(value); - -// QProcess *process = new QProcess; -// QMLOutput *base = mScreen->primaryOutput(); -// //qDebug()<<"primaryOutput---->"<outputs()) { -// if (output->output()->isConnected() && output->output()->isEnabled()) { -// base = output; -// break; -// } -// } - -// if (!base) { -// // WTF? -// return; -// } -// } -// if(base->isCloneMode() == false) { -// process->start("xrandr",QStringList()<<"--output"<waitForFinished(); -// const QString &cmd = "xrandr --output "+ screenName+" --brightness "+ brightnessValue; -// } else { -// for(int i = 0; i < nameList.length(); i++ ){ -// if(nameList.at(i) != ""){ -// process->start("xrandr",QStringList()<<"--output"<waitForFinished(); -// } -// } -// } -} - - -//保存屏幕亮度配置 -void Widget::saveBrigthnessConfig(){ - - QStringList cmdList; - QStringList nameList = getscreenBrightnesName(); - QStringList valueList = getscreenBrightnesValue(); - QString sliderValue = QString::number(ui->brightnessSlider->value()/100.0); - int len = std::min(nameList.length(),valueList.length()); - -// qDebug()<<"QStringList------------------>"<isClone == "false"){ - tmpcmd = "xrandr --output "+ nameList.at(i)+" --brightness "+ valueList.at(i); - } else { - tmpcmd = "xrandr --output "+ nameList.at(i)+" --brightness "+ sliderValue; - } +bool Widget::writeGlobalPart(const KScreen::OutputPtr &output, QVariantMap &info, + const KScreen::OutputPtr &fallback) +{ + info[QStringLiteral("id")] = output->hash(); + info[QStringLiteral("metadata")] = metadata(output); + info[QStringLiteral("rotation")] = output->rotation(); - cmdList.append(tmpcmd); - } + // Round scale to four digits + info[QStringLiteral("scale")] = int(output->scale() * 10000 + 0.5) / 10000.; - QFile fp(brightnessFile); - if(!fp.open(QIODevice::WriteOnly)){ - qDebug()<<"写入文件失败"<currentMode() && output->isEnabled()) { + refreshRate = output->currentMode()->refreshRate(); + modeSize = output->currentMode()->size(); + } else if (fallback && fallback->currentMode()) { + refreshRate = fallback->currentMode()->refreshRate(); + modeSize = fallback->currentMode()->size(); } - QTextStream cmdOuput(&fp); - for(int i=0;i"<"< brightnessMap; + modeInfo[QStringLiteral("refresh")] = refreshRate; -// for(int i = 0;i < len;i++){ -// brightnessMap.insert(nameList.at(i).trimmed(),valueList.at(i).toFloat()); -// } + QVariantMap modeSizeMap; + modeSizeMap[QStringLiteral("width")] = modeSize.width(); + modeSizeMap[QStringLiteral("height")] = modeSize.height(); + modeInfo[QStringLiteral("size")] = modeSizeMap; -// ui->brightnessSlider->setValue(brightnessMap[screename]*100); + info[QStringLiteral("mode")] = modeInfo; - QGSettings *powerSettings; - int value = 99; - if (QGSettings::isSchemaInstalled(POWER_SCHMES)) { - QByteArray id(POWER_SCHMES); - powerSettings = new QGSettings(id); - QStringList keys = powerSettings->keys(); - if (keys.contains("brightnessAc")) { - value = powerSettings->get(POWER_KEY).toInt(); + return true; +} + +bool Widget::writeFile(const QString &filePath) +{ + const KScreen::OutputList outputs = mConfig->outputs(); + const auto oldConfig = mPrevConfig; + KScreen::OutputList oldOutputs; + if (oldConfig) { + oldOutputs = oldConfig->outputs(); + } + QVariantList outputList; + for (const KScreen::OutputPtr &output : outputs) { + QVariantMap info; + const auto oldOutputIt = std::find_if(oldOutputs.constBegin(), oldOutputs.constEnd(), + [output](const KScreen::OutputPtr &out) { + return out->hashMd5() == output->hashMd5(); + }); + const KScreen::OutputPtr oldOutput = oldOutputIt != oldOutputs.constEnd() ? *oldOutputIt + : nullptr; + if (!output->isConnected()) { + continue; } + + writeGlobalPart(output, info, oldOutput); + info[QStringLiteral("primary")] = !output->name().compare( + getPrimaryWaylandScreen(), Qt::CaseInsensitive); + info[QStringLiteral("enabled")] = output->isEnabled(); + + auto setOutputConfigInfo = [&info](const KScreen::OutputPtr &out) { + if (!out) { + return; + } + + QVariantMap pos; + pos[QStringLiteral("x")] = out->pos().x(); + pos[QStringLiteral("y")] = out->pos().y(); + info[QStringLiteral("pos")] = pos; + }; + setOutputConfigInfo(output->isEnabled() ? output : oldOutput); + + if (output->isEnabled()) { + // try to update global output data + writeGlobal(output); + } + outputList.append(info); } - if (!powerSettings) { - delete powerSettings; + + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly)) { + qWarning() << "Failed to open config file for writing! " << file.errorString(); + return false; } - ui->brightnessSlider->setValue(value); -} + file.write(QJsonDocument::fromVariant(outputList).toJson()); + qDebug() << "Config saved on: " << file.fileName(); -//亮度配置文件位置 -void Widget::setBrigthnessFile(){ - brightnessFile = getenv("HOME"); - brightnessFile += "/.xprofile"; + return true; } -void Widget::initTemptSlider() { - ui->temptSlider->setRange(1.1*1000,6500); - ui->temptSlider->setTracking(true); - - for (int i = 0; i < 24; i++) { - ui->opHourCom->addItem(QString::number(i)); - ui->clHourCom->addItem(QString::number(i)); +void Widget::scaleChangedSlot(double scale) +{ + this->mScreenScale = scale; + if (scaleGSettings->get(SCALE_KEY).toDouble() != this->mScreenScale) { + mIsScaleChanged = true; + } else { + mIsScaleChanged = false; } +} - for (int i = 0; i < 60; i++) { - ui->opMinCom->addItem(QString::number(i)); - ui->clMinCom->addItem(QString::number(i)); +void Widget::changedSlot() +{ + mConfigChanged = true; +} + +void Widget::propertiesChangedSlot(QString property, QMap propertyMap, + QStringList propertyList) +{ + Q_UNUSED(property); + Q_UNUSED(propertyList); + if (propertyMap.keys().contains("OnBattery")) { + mOnBattery = propertyMap.value("OnBattery").toBool(); } } -void Widget::initConfigFile() { - QString filename = QDir::homePath() + "/.config/redshift.conf"; - m_qsettings = new QSettings(filename, QSettings::IniFormat); +// 是否禁用主屏按钮 +void Widget::mainScreenButtonSelect(int index) +{ + QtConcurrent::run(std::mem_fn(&Widget::setBrightSliderVisible), this); - m_qsettings->beginGroup("redshift"); + if (!mConfig || ui->primaryCombo->count() <= 0) { + return; + } - QString optime = m_qsettings->value("dusk-time", "").toString(); - QString cltime = m_qsettings->value("dawn-time", "").toString(); - QString temptValue = m_qsettings->value("temp-night", "").toString(); + const KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); + int connectCount = mConfig->connectedOutputs().count(); - if ("" != optime){ - QString ophour = optime.split(":").at(0); - QString opmin = optime.split(":").at(1); + if (mIsWayland) { + if (!getPrimaryWaylandScreen().compare(newPrimary->name(), Qt::CaseInsensitive)) { + ui->mainScreenButton->setEnabled(false); + } else { + ui->mainScreenButton->setEnabled(true); + } + } else { + if (newPrimary == mConfig->primaryOutput()) { + ui->mainScreenButton->setEnabled(false); + } else { + ui->mainScreenButton->setEnabled(true); + } + } -// qDebug()<<"optime is----->"<setEnabled(true); + ui->showMonitorframe->setVisible(connectCount > 1 && !mUnifyButton->isChecked()); - ui->opHourCom->setCurrentIndex(ophour.toInt()); - ui->opMinCom->setCurrentIndex(opmin.toInt()); - } + // 初始化时不要发射信号 + mCloseScreenButton->blockSignals(true); + mCloseScreenButton->setChecked(newPrimary->isEnabled()); + mCloseScreenButton->blockSignals(false); - if ("" != cltime) { - QString clhour = cltime.split(":").at(0); - QString clmin = cltime.split(":").at(1); + ui->brightnessframe->setVisible(newPrimary->isEnabled() && isVisibleBrightness()); + mControlPanel->activateOutput(newPrimary); - ui->clHourCom->setCurrentIndex(clhour.toInt()); - ui->clMinCom->setCurrentIndex(clmin.toInt()); + mScreen->setActiveOutputByCombox(newPrimary->id()); +} + +// 设置主屏按钮 +void Widget::primaryButtonEnable(bool status) +{ + Q_UNUSED(status); + if (!mConfig) { + return; } + int index = ui->primaryCombo->currentIndex(); + ui->mainScreenButton->setEnabled(false); + const KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); + mConfig->setPrimaryOutput(newPrimary); + mScreenId = newPrimary->id(); - if ("" != temptValue) { - int value = temptValue.toInt(); - ui->temptSlider->setValue(value); - } + Q_EMIT changed(); +} - m_qsettings->endGroup(); +void Widget::checkOutputScreen(bool judge) +{ + int index = ui->primaryCombo->currentIndex(); + KScreen::OutputPtr newPrimary = mConfig->output(ui->primaryCombo->itemData(index).toInt()); + KScreen::OutputPtr mainScreen = mConfig->primaryOutput(); - m_qsettings->beginGroup("switch");; + if (!mainScreen) { + mConfig->setPrimaryOutput(newPrimary); + } + mainScreen = mConfig->primaryOutput(); - bool unionjudge = m_qsettings->value("unionswitch", unionjudge).toBool(); - bool nightjudge = m_qsettings->value("nightjudge", nightjudge).toBool(); - bool sunjudge = m_qsettings->value("sunjudge", sunjudge).toBool(); - bool manualjudge = m_qsettings->value("manualjudge", manualjudge).toBool(); + newPrimary->setEnabled(judge); -// qDebug()<<"unionjudge is-------->"<setChecked(unionjudge); - nightButton->setChecked(nightjudge); + int enabledOutput = 0; + Q_FOREACH (KScreen::OutputPtr outptr, mConfig->outputs()) { + if (outptr->isEnabled()) { + enabledOutput++; + } + if (mainScreen != outptr && outptr->isConnected()) { + newPrimary = outptr; + } - if (!(sunjudge && manualjudge)) { - ui->sunradioBtn->setChecked(sunjudge); - ui->customradioBtn->setChecked(manualjudge); - } else { - ui->sunradioBtn->setCheckable(true); + if (enabledOutput >= 2) { + // 设置副屏在主屏右边 + newPrimary->setPos(QPoint(mainScreen->pos().x() + mainScreen->geometry().width(), + mainScreen->pos().y())); + } } - m_qsettings->endGroup(); + ui->primaryCombo->setCurrentIndex(index); + Q_EMIT changed(); } -void Widget::writeScreenXml(int count){ - Q_UNUSED(count) - - QString homePath = getenv("HOME"); - QString monitorFile = homePath+"/.config/monitors.xml"; - //qDebug()<"<"< 3){ - -// qDebug()<<"e2 count is---->"< 3) { - for(; e2.count()>3;){ - QDomNode node2 = e2.at(2); - qDebug() << " "<< node2.toElement().tagName() - <"<brightnessSlider->setRange(0, 100); + if (mIsWayland && !mIsBattery) { + connect(ui->brightnessSlider, &QSlider::valueChanged, this, &Widget::setDDCBrightness); + } else { + connect(ui->brightnessSlider, &QSlider::valueChanged, this, &Widget::setBrightnessScreen); } - if(!file.open(QFile::WriteOnly | QFile::Truncate)){ - qDebug()<<"save file failed"<darkLabel->setVisible(false); + ui->brihghtLabel->setVisible(false); + } else { + ui->brightValueLabel->setVisible(false); } - - QTextStream out_stream(&file); - doc.save(out_stream,4); - file.close(); } +void Widget::initConnection() +{ + connect(mNightButton, SIGNAL(checkedChanged(bool)), this, SLOT(showNightWidget(bool))); + connect(mThemeButton, SIGNAL(checkedChanged(bool)), this, SLOT(slotThemeChanged(bool))); + connect(singleButton, SIGNAL(buttonClicked(int)), this, SLOT(showCustomWiget(int))); + connect(ui->primaryCombo, static_cast(&QComboBox::currentIndexChanged), + this, &Widget::mainScreenButtonSelect); -void Widget::initScreenXml(int count){ - QString homePath = getenv("HOME"); - QString monitorFile = homePath+"/.config/monitors.xml"; - //qDebug()<mainScreenButton, SIGNAL(clicked(bool)), this, SLOT(primaryButtonEnable(bool))); + mControlPanel = new ControlPanel(this); + connect(mControlPanel, &ControlPanel::changed, this, &Widget::changed); + connect(this, &Widget::changed, this, &Widget::changedSlot); + connect(mControlPanel, &ControlPanel::scaleChanged, this, &Widget::scaleChangedSlot); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)){ - qDebug()<<"open file failed"<controlPanelLayout->addWidget(mControlPanel); - xmlWriter.setAutoFormatting(true); - xmlWriter.writeStartElement("monitors"); - xmlWriter.writeAttribute("version","1"); - xmlWriter.writeStartElement("configuration"); - xmlWriter.writeTextElement("clone","no"); + connect(ui->applyButton, &QPushButton::clicked, this, [=]() { + save(); + }); - for(int i = 0; i < count; ++i){ - xmlWriter.writeStartElement("output"); - xmlWriter.writeAttribute("name",inputXml[i].outputName); - xmlWriter.writeTextElement("vendor",inputXml[i].vendorName); - xmlWriter.writeTextElement("product",inputXml[i].productName); - xmlWriter.writeTextElement("serial",inputXml[i].serialNum); - xmlWriter.writeTextElement("width",inputXml[i].widthValue); - xmlWriter.writeTextElement("height",inputXml[i].heightValue); - xmlWriter.writeTextElement("rate",inputXml[i].rateValue); - xmlWriter.writeTextElement("x",inputXml[i].posxValue); - xmlWriter.writeTextElement("y",inputXml[i].posyValue); - xmlWriter.writeTextElement("rotation",inputXml[i].rotationValue); - xmlWriter.writeTextElement("reflect_x","no"); - xmlWriter.writeTextElement("reflect_y","no"); - xmlWriter.writeTextElement("primary",inputXml[i].isPrimary); - xmlWriter.writeEndElement(); - } - xmlWriter.writeEndElement(); - xmlWriter.writeEndElement(); -} + connect(ui->advancedBtn, &QPushButton::clicked, this, [=] { + DisplayPerformanceDialog *dialog = new DisplayPerformanceDialog; + dialog->exec(); + }); + connect(mUnifyButton, &SwitchButton::checkedChanged, + [this] { + slotUnifyOutputs(); + }); + connect(mCloseScreenButton, &SwitchButton::checkedChanged, + this, [=](bool checked) { + checkOutputScreen(checked); + }); -void Widget::getEdidInfo(QString monitorName,xmlFile *xml) { - int i; - int modelDec; - int serialDec; + connect(QApplication::desktop(), &QDesktopWidget::resized, this, [=] { + QTimer::singleShot(1500, this, [=]{ + kdsScreenchangeSlot(); + }); + }); - GList *justTurnedOn; + connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, [=] { + QTimer::singleShot(1500, this, [=] { + kdsScreenchangeSlot(); + }); + }); - MateRRScreen *rwScreen; - MateRRConfig *config; - MateRROutputInfo **outputs; + QDBusConnection::sessionBus().connect(QString(), + QString("/ColorCorrect"), + "org.ukui.kwin.ColorCorrect", + "nightColorConfigChanged", + this, + SLOT(nightChangedSlot(QHash))); - rwScreen = mate_rr_screen_new (gdk_screen_get_default (), NULL); - config = mate_rr_config_new_current (rwScreen, NULL); - justTurnedOn = NULL; - outputs = mate_rr_config_get_outputs (config); + mOutputTimer = new QTimer(this); + connect(mOutputTimer, &QTimer::timeout, + this, &Widget::clearOutputIdentifiers); - for (i = 0; outputs[i] != NULL; i++) { - MateRROutputInfo *output = outputs[i]; - if (mate_rr_output_info_is_connected (output) && !mate_rr_output_info_is_active (output)) { - justTurnedOn = g_list_prepend (justTurnedOn, GINT_TO_POINTER (i)); - } - } + mApplyShortcut = new QShortcut(QKeySequence("Ctrl+A"), this); + connect(mApplyShortcut, SIGNAL(activated()), this, SLOT(save())); +} - for (i = 0; outputs[i] != NULL; i++){ - MateRROutputInfo *output = outputs[i]; - if (g_list_find (justTurnedOn, GINT_TO_POINTER (i))) { - continue; - } +void Widget::setBrightnessScreen(int value) +{ + qDebug() << Q_FUNC_INFO << value; + ui->brightValueLabel->setText(QString::number(value)); + mPowerGSettings->set(POWER_KEY, value); +} - if (mate_rr_output_info_is_active (output)){ - g_assert (mate_rr_output_info_is_connected (output)); - char *name = mate_rr_output_info_get_name(output);; - unsigned int product = mate_rr_output_info_get_product(output); - unsigned int serial = mate_rr_output_info_get_serial(output); - qDebug()<<"the product and serial is------->"<brightValueLabel->setText(QString::number(value)); + if (!isLaptopScreen()) { + setDDCBrighthessSlot(value); + } else { + setBrightnessScreen(value); } +} - for (GList *l = justTurnedOn; l; l = l->next) { - MateRROutputInfo *output; - i = GPOINTER_TO_INT (l->data); - output = outputs[i]; - if (mate_rr_output_info_is_active(output)) { - g_assert (mate_rr_output_info_is_connected (output)); - char *name = mate_rr_output_info_get_name(output); - unsigned int product = mate_rr_output_info_get_product(output); - unsigned int serial = mate_rr_output_info_get_serial(output); - qDebug()<<"the product and serial is------->"<isChecked()) { + ui->brightnessframe->setVisible(isVisibleBrightness()); + if (isLaptopScreen()) { + value = getLaptopBrightness(); + ui->brightValueLabel->setText(QString::number(value)); + ui->brightnessSlider->blockSignals(true); + ui->brightnessSlider->setValue(value); + ui->brightnessSlider->blockSignals(false); + } + } else { + int times = 100; + while(times--) { + value = getDDCBrighthess(); + if ((times == 99 && value == 0) || value > 0){ + ui->brightValueLabel->setText(QString::number(value)); + ui->brightnessSlider->blockSignals(true); + ui->brightnessSlider->setValue(value); + ui->brightnessSlider->blockSignals(false); + if (value > 0) + return; } + usleep(100000); } } - - xml->productName = "0x"+QString("%1").arg(modelDec,4,16,QLatin1Char('0')); - xml->serialNum = "0x"+QString("%1").arg(serialDec,4,16,QLatin1Char('0')); - - g_list_free (justTurnedOn); - g_object_unref (config); + return; } -void Widget::setNightMode(const bool nightMode){ - QProcess process; - QString cmd; - QString serverCmd; +// 滑块改变 +void Widget::setBrightnesSldierValue() +{ + int value = 99; + value = getLaptopBrightness(); - if(nightMode) { - cmd = "restart"; - serverCmd = "enable"; + if (mIsWayland && !mIsBattery) { + int realValue = getDDCBrighthess(); + ui->brightValueLabel->setText(QString::number(realValue)); + ui->brightnessSlider->setValue(realValue); } else { - cmd = "stop"; - serverCmd = "disable"; + ui->brightValueLabel->setText(QString::number(value)); + ui->brightnessSlider->setValue(value); } +} - process.startDetached("systemctl", QStringList() << "--user" << serverCmd << "redshift.service"); +void Widget::initTemptSlider() +{ + ui->temptSlider->setRange(1.1*1000, 6500); + ui->temptSlider->setTracking(true); - process.startDetached("systemctl", QStringList() << "--user" << cmd << "redshift.service"); - updateNightStatus(); -} + for (int i = 0; i < 24; i++) { + ui->opHourCom->addItem(QStringLiteral("%1").arg(i, 2, 10, QLatin1Char('0'))); + ui->clHourCom->addItem(QStringLiteral("%1").arg(i, 2, 10, QLatin1Char('0'))); + } + for (int i = 0; i < 60; i++) { + ui->opMinCom->addItem(QStringLiteral("%1").arg(i, 2, 10, QLatin1Char('0'))); + ui->clMinCom->addItem(QStringLiteral("%1").arg(i, 2, 10, QLatin1Char('0'))); + } +} -void Widget::updateNightStatus(){ - QProcess *process = new QProcess; +void Widget::writeScreenXml() +{ + MateRRScreen *rr_screen; + MateRRConfig *rr_config; - connect(process, &QProcess::readyRead, this, [=] { - setIsNightMode(process->readAll().replace("\n","") == "active"); + /* Normally, mate_rr_config_save() creates a backup file based on the + * old monitors.xml. However, if *that* file didn't exist, there is + * nothing from which to create a backup. So, here we'll save the + * current/unchanged configuration and then let our caller call + * mate_rr_config_save() again with the new/changed configuration, so + * that there *will* be a backup file in the end. + */ - process->deleteLater(); - }); + rr_screen = mate_rr_screen_new(gdk_screen_get_default(), NULL); /* NULL-GError */ + if (!rr_screen) + return; - process->start("systemctl", QStringList() << "--user" << "is-active" << "redshift.service"); - process->close(); -} + rr_config = mate_rr_config_new_current(rr_screen, NULL); + mate_rr_config_save(rr_config, NULL); /* NULL-GError */ + char *backup_filename = mate_rr_config_get_backup_filename(); + unlink(backup_filename); -void Widget::setIsNightMode(bool isNightMode) { - if(m_isNightMode == isNightMode){ - return ; - } - qDebug()<<"isNightMode----->"<"<sunradioBtn->isChecked()) { + mNightConfig["EveningBeginFixed"] = "17:55:00"; + mNightConfig["MorningBeginFixed"] = "05:55:04"; + } else if (ui->customradioBtn->isChecked()) { + mNightConfig["EveningBeginFixed"] = ui->opHourCom->currentText() + ":" + + ui->opMinCom->currentText() + ":00"; + mNightConfig["MorningBeginFixed"] = ui->clHourCom->currentText() + ":" + + ui->clMinCom->currentText() + ":00"; + } + mNightConfig["NightTemperature"] = ui->temptSlider->value(); } - QTextStream textStream(&file); - for(int i = 0; i < content.length(); i++) { - textStream<addButton(ui->sunradioBtn); singleButton->addButton(ui->customradioBtn); - singleButton->setId(ui->sunradioBtn, SUN); singleButton->setId(ui->customradioBtn, CUSTOM); - MODE value = ui->customradioBtn->isChecked() == SUN ? SUN : CUSTOM; - showNightWidget(nightButton->isChecked()); - if (nightButton->isChecked()) { + showNightWidget(mNightButton->isChecked()); + if (mNightButton->isChecked()) { showCustomWiget(value); } - //ubuntukylin youker DBus interface - QDBusInterface *brightnessInterface = new QDBusInterface("org.freedesktop.UPower", - "/org/freedesktop/UPower/devices/DisplayDevice", - "org.freedesktop.DBus.Properties", - QDBusConnection::systemBus()); - if (!brightnessInterface->isValid()) { + QDBusInterface brightnessInterface("org.freedesktop.UPower", + "/org/freedesktop/UPower/devices/DisplayDevice", + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + if (!brightnessInterface.isValid()) { qDebug() << "Create UPower Interface Failed : " << QDBusConnection::systemBus().lastError(); return; } QDBusReply briginfo; - briginfo = brightnessInterface ->call("Get", "org.freedesktop.UPower.Device", "PowerSupply"); - if (!briginfo.isValid()) { - qDebug()<<"brightness info is invalid"<brightnessframe->setVisible(false); - } else { - bool status = briginfo.value().toBool(); - ui->brightnessframe->setVisible(status); - } -} + briginfo = brightnessInterface.call("Get", "org.freedesktop.UPower.Device", "PowerSupply"); + mIsBattery = briginfo.value().toBool(); -void Widget::setRedShiftIsValid(bool redshiftIsValid){ - if(m_redshiftIsValid == redshiftIsValid) { - return ; + mUPowerInterface = QSharedPointer( + new QDBusInterface("org.freedesktop.UPower", + "/org/freedesktop/UPower", + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus())); + + if (!mUPowerInterface.get()->isValid()) { + qDebug() << "Create UPower Battery Interface Failed : " << + QDBusConnection::systemBus().lastError(); + return; } - m_redshiftIsValid = redshiftIsValid; - - emit redShiftValidChanged(redshiftIsValid); -} - -void Widget::initNightStatus(){ - - QProcess *process = new QProcess; - const bool isRedShiftValid = (0 == process->execute("which",QStringList() << "redshift")); -// qDebug()<<"isRedshitValid-------------->"< batteryInfo; + batteryInfo = mUPowerInterface.get()->call("Get", "org.freedesktop.UPower", "OnBattery"); + if (batteryInfo.isValid()) { + mOnBattery = batteryInfo.value().toBool(); + } + + mUPowerInterface.get()->connection().connect("org.freedesktop.UPower", + "/org/freedesktop/UPower", + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + this, + SLOT(propertiesChangedSlot(QString,QMap, + QStringList))); +} + +void Widget::initNightStatus() +{ + QDBusInterface colorIft("org.ukui.KWin", + "/ColorCorrect", + "org.ukui.kwin.ColorCorrect", + QDBusConnection::sessionBus()); + if (colorIft.isValid() && Utils::isExistEffect() && !mIsWayland) { + this->mRedshiftIsValid = true; + } else { + qWarning() << "create org.ukui.kwin.ColorCorrect failed"; + return; + } + QDBusMessage result = colorIft.call("nightColorInfo"); - QProcess *process_2 = new QProcess; - process_2->start("systemctl", QStringList() << "--user" << "is-active" << "redshift.service"); - process_2->waitForFinished(); + QList outArgs = result.arguments(); + QVariant first = outArgs.at(0); + QDBusArgument dbvFirst = first.value(); + QVariant vFirst = dbvFirst.asVariant(); + const QDBusArgument &dbusArgs = vFirst.value(); + + QVector nightColor; + + dbusArgs.beginArray(); + while (!dbusArgs.atEnd()) { + ColorInfo color; + dbusArgs >> color; + nightColor.push_back(color); + } + dbusArgs.endArray(); + + for (ColorInfo it : nightColor) { + mNightConfig.insert(it.arg, it.out.variant()); + } + + this->mIsNightMode = mNightConfig["Active"].toBool(); + ui->temptSlider->setValue(mNightConfig["CurrentColorTemperature"].toInt()); + if (0 == mNightConfig["Mode"].toInt()) { + ui->sunradioBtn->setChecked(true); + } else if (2 == mNightConfig["Mode"].toInt()) { + ui->customradioBtn->setChecked(true); + QString openTime = mNightConfig["EveningBeginFixed"].toString(); + QString ophour = openTime.split(":").at(0); + QString opmin = openTime.split(":").at(1); - QByteArray qbaOutput = process_2->readAllStandardOutput(); + ui->opHourCom->setCurrentIndex(ophour.toInt()); + ui->opMinCom->setCurrentIndex(opmin.toInt()); - QString tmpNight = qbaOutput; - m_isNightMode = (tmpNight=="active\n" ? true : false); -// qDebug()<<"m_isNightMode is------------->"<clHourCom->setCurrentIndex(clhour.toInt()); + ui->clMinCom->setCurrentIndex(clmin.toInt()); + } +} - if (isRedShiftValid){ - updateNightStatus(); +void Widget::nightChangedSlot(QHash nightArg) +{ + if (this->mRedshiftIsValid) { + mNightButton->setChecked(nightArg["Active"].toBool()); } - setRedShiftIsValid(isRedShiftValid); } diff -Nru ukui-control-center-2.0.3/plugins/system/display/widget.h ukui-control-center-3.0.3/plugins/system/display/widget.h --- ukui-control-center-2.0.3/plugins/system/display/widget.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/display/widget.h 2021-05-20 13:08:14.000000000 +0000 @@ -1,6 +1,7 @@ #ifndef WIDGET_H #define WIDGET_H +#include #include #include #include @@ -10,6 +11,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include @@ -17,8 +25,6 @@ #include "slider.h" #include "SwitchButton/switchbutton.h" -const QString tempDayBrig = "6500"; - class QLabel; class QMLOutput; class QMLScreen; @@ -32,30 +38,12 @@ class QQuickWidget; class QStyledItemDelegate; -typedef struct xml{ - QString isClone; - QString outputName; - QString vendorName; - QString productName; - QString serialNum; - QString widthValue; - QString heightValue; - QString rateValue; - QString posxValue; - QString posyValue; - QString rotationValue; - QString isPrimary; - bool isEnable; -}xmlFile; - typedef enum { SUN, CUSTOM, }MODE; - -namespace KScreen -{ +namespace KScreen { class ConfigOperation; } @@ -67,7 +55,7 @@ { Q_OBJECT - public: +public: explicit Widget(QWidget *parent = nullptr); ~Widget() override; @@ -75,43 +63,34 @@ KScreen::ConfigPtr currentConfig() const; void slotFocusedOutputChangedNoParam(); - // 亮度调节UI void initBrightnessUI(); + void initConnection(); QString getScreenName(QString name = ""); - // 获得显示器名称(shell获得) - QStringList getscreenBrightnesName(); - // 获得显示器名称(shell获得) - QStringList getscreenBrightnesValue(); - // 获取配置文件位置 - void setBrigthnessFile(); void initTemptSlider(); - void initConfigFile(); - // 获取屏幕xml文件 - void writeScreenXml(int count); - // 初始化屏幕配置文件 - void initScreenXml(int count); - //获取edid信息 - void getEdidInfo(QString monitorName,xmlFile *xml); - void setIsNightMode(bool isNightMode); + void writeScreenXml(); - QStringList readFile(const QString& filepath); - void writeFile(const QString& filepath, const QStringList& content); + bool writeFile(const QString &filePath); + void writeGlobal(const KScreen::OutputPtr &output); + bool writeGlobalPart(const KScreen::OutputPtr &output, QVariantMap &info, + const KScreen::OutputPtr &fallback); + QString globalFileName(const QString &hash); + QVariantMap getGlobalData(KScreen::OutputPtr output); float converToScale(const int value); int scaleToSlider(const float value); void initUiComponent(); - protected: +protected: bool eventFilter(QObject *object, QEvent *event) override; - Q_SIGNALS: +Q_SIGNALS: void changed(); void nightModeChanged(const bool nightMode) const; void redShiftValidChanged(const bool isValid) const; - private Q_SLOTS: +private Q_SLOTS: void slotFocusedOutputChanged(QMLOutput *output); void slotOutputEnabledChanged(); @@ -131,98 +110,121 @@ void showNightWidget(bool judge); void showCustomWiget(int index); - // 按钮选择主屏确认按钮 - void primaryButtonEnable(); - // 是否禁用设置主屏按钮 - void mainScreenButtonSelect(int index); - // 是否禁用屏幕 - void checkOutputScreen(bool judge); - // 设置屏幕亮度 - void setBrightnessScreen(int brightnessValue); - // 设置亮度滑块数值 - void setBrightnesSldierValue(QString screeName); - // 保存屏幕亮度配置 - void saveBrigthnessConfig(); - // 设置夜间模式 - void setNightMode(const bool nightMode); - // redshitf是否合法 - void setRedShiftIsValid(bool redshiftIsValid); - // 更新夜间模式状态 - void updateNightStatus(); - // 初始化夜间模式 - void initNightStatus(); + void slotThemeChanged(bool judge); + + void primaryButtonEnable(bool); // 按钮选择主屏确认按钮 + void mainScreenButtonSelect(int index); // 是否禁用设置主屏按钮 + void checkOutputScreen(bool judge); // 是否禁用屏幕 + void setBrightnessScreen(int value); // 设置屏幕亮度 + void setDDCBrightness(int value); + void setBrightSliderVisible(); // 笔记本外接屏幕不可调整亮度 + + void setBrightnesSldierValue(); // 设置亮度滑块数值 + void setNightMode(const bool nightMode); // 设置夜间模式 + + void initNightStatus(); // 初始化夜间模式 + void nightChangedSlot(QHash nightArg); + + void callMethod(QRect geometry, QString name);// 设置wayland主屏幕 + QString getPrimaryWaylandScreen(); + void isWayland(); + + void setDDCBrighthessSlot(int brightnessValue);// 设置外接显示器亮度 + void kdsScreenchangeSlot(); - public Q_SLOTS: +public Q_SLOTS: void save(); - void scaleChangedSlot(int index); + void scaleChangedSlot(double scale); + void changedSlot(); + void propertiesChangedSlot(QString, QMap, QStringList); - private: +private: void loadQml(); void resetPrimaryCombo(); void addOutputToPrimaryCombo(const KScreen::OutputPtr &output); KScreen::OutputPtr findOutput(const KScreen::ConfigPtr &config, const QVariantMap &info); -// float scaleRet(); - void writeScale(int scale); + void setHideModuleInfo(); + void setTitleLabel(); + void writeScale(double scale); void initGSettings(); - bool getNightModeGSetting(const QString &key); - void setNightModebyPanel(bool judge); - void setSessionScale(int scale); - void writeConfigFile(); + void setcomBoxScale(); + void initNightUI(); - private: + bool isRestoreConfig(); // 是否恢复应用之前的配置 + bool isCloneMode(); + bool isBacklight(); + bool isLaptopScreen(); + bool isVisibleBrightness(); + + QString getCpuInfo(); + QString getMonitorType(); + + int getDDCBrighthess(); + int getLaptopBrightness() const; + int getPrimaryScreenID(); + +private: Ui::DisplayWindow *ui; QMLScreen *mScreen = nullptr; #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - KScreen::ConfigPtr mConfig ; - KScreen::ConfigPtr mPrevConfig ; - //这是outPutptr结果 - KScreen::OutputPtr res ; + KScreen::ConfigPtr mConfig; + KScreen::ConfigPtr mPrevConfig; + KScreen::OutputPtr res; // 这是outPutptr结果 #else KScreen::ConfigPtr mConfig = nullptr; KScreen::ConfigPtr mPrevConfig = nullptr; - // outPutptr结果 KScreen::OutputPtr res = nullptr; #endif ControlPanel *mControlPanel = nullptr; - // 设置主显示器相关控件 - OutputConfig *mOutputConfig = nullptr; + OutputConfig *mOutputConfig = nullptr; // 设置主显示器相关控件 - QList mOutputIdentifiers; + QList mOutputIdentifiers; QTimer *mOutputTimer = nullptr; - bool m_blockChanges = false; + QMutex mLock; + + QString mCPU; + QString mDir; + QStringList mPowerKeys; + + SwitchButton *mNightButton = nullptr; + SwitchButton *mCloseScreenButton = nullptr; + SwitchButton *mUnifyButton = nullptr; + SwitchButton *mThemeButton = nullptr; - // 亮度配置文件位置 - QString brightnessFile = nullptr; - // xml文件 - xmlFile inputXml[100]; - - SwitchButton *nightButton = nullptr; - SwitchButton *closeScreenButton = nullptr; - SwitchButton *m_unifybutton = nullptr; QLabel *nightLabel = nullptr; - // 是否为夜间模式 - bool m_isNightMode = false; - bool m_redshiftIsValid = false; + QGSettings *mGsettings = nullptr; + QGSettings *scaleGSettings = nullptr; + QGSettings *mPowerGSettings = nullptr; - // profile文件内容 - QStringList proRes; + QSettings *mQsettings = nullptr; - Slider *slider; - QGSettings *m_gsettings = nullptr; - QGSettings *scaleGSettings = nullptr; - QSettings *m_qsettings = nullptr; QButtonGroup *singleButton; - int screenScale = 1; - bool isScaleChanged = false; - bool oriApply; + QSharedPointer mUPowerInterface; + + QHash mNightConfig; + + double mScreenScale = 1.0; + int mScreenId = -1; + + bool mIsNightMode = false; + bool mRedshiftIsValid = false; + bool mIsScaleChanged = false; + bool mOriApply; + bool mConfigChanged = false; + bool mOnBattery = false; + bool mBlockChanges = false; + bool mFirstLoad = true; + bool mIsWayland = false; + bool mIsBattery = false; + + QShortcut *mApplyShortcut; }; #endif // WIDGET_H - diff -Nru ukui-control-center-2.0.3/plugins/system/power/power.cpp ukui-control-center-3.0.3/plugins/system/power/power.cpp --- ukui-control-center-2.0.3/plugins/system/power/power.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/power/power.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -22,6 +22,21 @@ #include "powermacrodata.h" #include +#include +#include +#include +#include + +#include "../../../shell/utils/utils.h" + +/* qt会将glib里的signals成员识别为宏,所以取消该宏 + * 后面如果用到signals时,使用Q_SIGNALS代替即可 + **/ +#ifdef signals +#undef signals +#endif + +#include "libupower-glib/upower.h" typedef enum { BALANCE, @@ -34,76 +49,110 @@ ALWAYS }ICONDISPLAY; -/** - * 平衡:关闭显示器10分钟;计算机进入睡眠30分钟 - * 节能:关闭显示器20分钟;计算机进入睡眠2小时 - * 自定义 - */ - -#define DISPLAY_BALANCE 10 * 60 -#define COMPUTER_BALANCE 30 * 60 -#define DISPLAY_SAVING 20 * 60 -#define COMPUTER_SAVING 2 * 60 * 60 - +// 平衡模式 +const int DISPLAY_BAT_BALANCE = 10 * 60; +const int DISPLAY_AC_BALANCE = 30 * 60; +const int COMPUTER_BALANCE = 0; + +// 节能模式 +const int DISPLAY_SAVING = 5 * 60; +const int COMPUTER_SAVING = 10 * 60; + +const QStringList kHibernate { QObject::tr("Never"),QObject::tr("10min"), QObject::tr("20min"), + QObject::tr("40min"), QObject::tr("80min")}; + +// 电源按钮操作 +const QStringList kLid { QObject::tr("interactive"), QObject::tr("suspend"), QObject::tr("hibernate"), QObject::tr("shutdown") }; +const QStringList kEnkLid { "interactive", "suspend", "hibernate", "shutdown"}; + +// 低电量操作 +const QStringList kBattery { QObject::tr("nothing"), QObject::tr("blank"), QObject::tr("suspend"), QObject::tr("hibernate"), QObject::tr("shutdown") }; +const QStringList kEnBattery { "nothing", "blank", "suspend", "hibernate", "shutdown" }; - -Power::Power() +Power::Power() : mFirstLoad(true) { - ui = new Ui::Power; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); - ui->setupUi(pluginWidget); - pluginName = tr("Power"); pluginType = SYSTEM; - - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - - settingsCreate = false; - - const QByteArray id(POWERMANAGER_SCHEMA); - - setupStylesheet(); - setupComponent(); - isPowerSupply(); - if (QGSettings::isSchemaInstalled(id)){ - settingsCreate = true; - settings = new QGSettings(id); - setupConnect(); - initModeStatus(); - initPowerOtherStatus(); - } else { - qCritical() << POWERMANAGER_SCHEMA << "not installed!\n"; - } - } -Power::~Power() -{ - delete ui; - if (settingsCreate) - delete settings; +Power::~Power() { + if (!mFirstLoad) { + delete ui; + ui = nullptr; + } } -QString Power::get_plugin_name(){ +QString Power::get_plugin_name() { return pluginName; } -int Power::get_plugin_type(){ +int Power::get_plugin_type() { return pluginType; } -QWidget * Power::get_plugin_ui(){ +QWidget * Power::get_plugin_ui() { + if (mFirstLoad) { + ui = new Ui::Power; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + const QByteArray id(POWERMANAGER_SCHEMA); + const QByteArray sessionId(SESSION_SCHEMA); + const QByteArray personalizeId(PERSONALSIE_SCHEMA); + + initTitleLabel(); + initDbus(); + initDeviceStatus(); + isPowerSupply(); + isLidPresent(); + setupComponent(); + + if (QGSettings::isSchemaInstalled(id)) { + settings = new QGSettings(id, QByteArray(), this); + sessionSetting = new QGSettings(sessionId, QByteArray(), this); + mUkccpersonpersonalize = new QGSettings(personalizeId, QByteArray(), this); + + mPowerKeys = settings->keys(); + + initGeneralSet(); + initModeStatus(); + setupConnect(); + initPowerOtherStatus(); + } else { + qCritical() << POWERMANAGER_SCHEMA << "not installed!\n"; + } + } return pluginWidget; } -void Power::plugin_delay_control(){ +void Power::plugin_delay_control() { + +} + +const QString Power::name() const { + + return QStringLiteral("power"); +} +void Power::initTitleLabel() +{ + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); +} + +void Power::initSearText() { + //~ contents_path /power/Balance (suggest) + ui->balanceLabel->setText(tr("Balance (suggest)")); + //~ contents_path /power/Saving + ui->saveLabel->setText(tr("Saving")); + //~ contents_path /power/Custom + ui->customLabel->setText(tr("Custom")); } -void Power::isPowerSupply(){ - //ubuntukylin youker DBus interface +void Power::isPowerSupply() { QDBusInterface *brightnessInterface = new QDBusInterface("org.freedesktop.UPower", "/org/freedesktop/UPower/devices/DisplayDevice", "org.freedesktop.DBus.Properties", @@ -115,44 +164,75 @@ QDBusReply briginfo; briginfo = brightnessInterface ->call("Get", "org.freedesktop.UPower.Device", "PowerSupply"); - if (!briginfo.isValid()) { - qDebug()<<"brightness info is invalid"<batteryBtn->setVisible(false); + ui->verticalSpacer_2->changeSize(0, 0); } else { - qDebug() << "brightness info is valid"; + isExitsPower = true ; bool status = briginfo.value().toBool(); ui->batteryBtn->setVisible(status); } + delete brightnessInterface; } -void Power::setupStylesheet(){ -// pluginWidget->setStyleSheet("background: #ffffff;"); +void Power::isLidPresent() { + QDBusInterface *LidInterface = new QDBusInterface("org.freedesktop.UPower", + "/org/freedesktop/UPower", + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); -// ui->balanceWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); -// ui->savingWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); -// ui->customWidget->setStyleSheet("QWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); -// ui->custom1Widget->setStyleSheet("QWidget{background: #F4F4F4;}"); -// ui->custom2Widget->setStyleSheet("QWidget{background: #F4F4F4;}" -// "QWidget#custom2Widget{border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); -// ui->acBtn->setStyleSheet("QPushButton#acBtn:checked{background: #3D6BE5; border-radius: 4px; color: #ffffff;}" -// "QPushButton#acBtn:!checked{background: #ffffff; border-radius: 4px;}"); -// ui->batteryBtn->setStyleSheet("QPushButton#batteryBtn:checked{background: #3D6BE5; border-radius: 4px; color: #ffffff;}" -// "QPushButton#batteryBtn:!checked{background: #ffffff; border-radius: 4px; color: #000000;}"); + if (!LidInterface->isValid()) { + qDebug() << "Create UPower Lib Interface Failed : " << + QDBusConnection::systemBus().lastError(); + return; + } + QDBusReply LidInfo; + LidInfo = LidInterface->call("Get", "org.freedesktop.UPower", "LidIsPresent"); + if (!LidInfo.value().toBool()) { + isExitsLid = false ; + } else { + isExitsLid = true ; + } + delete LidInterface; +} + +void Power::setIdleTime(int idleTime) { -// ui->iconWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); + int sleeptime = ui->sleepComboBox->currentData(Qt::UserRole).toInt(); + int closetime = ui->closeComboBox->currentData(Qt::UserRole).toInt(); + if (ui->sleepComboBox->currentIndex()) { + ui->sleepLabel->setText(QString(tr("Enter idle state %1 min and sleep after %2 min :")).arg(idleTime).arg(idleTime + sleeptime)); + } + if (ui->closeComboBox->currentIndex()) { + ui->closeLabel->setText(QString(tr("Enter idle state %1 min and close after %2 min :")).arg(idleTime).arg(idleTime + closetime)); + } } -void Power::setupComponent(){ - // +void Power::setHibernateTime(QString hibernate) { + mUkccInterface->call("setSuspendThenHibernate", hibernate); +} + +void Power::setupComponent() { + + if (!hasBat){ + ui->iconFrame->hide(); + } + + /* 通用设置无功能,隐藏标题 */ + if (!isExitsPower && !hasBat){ + ui->title2Label->hide(); + } + ui->powerModeBtnGroup->setId(ui->balanceRadioBtn, BALANCE); ui->powerModeBtnGroup->setId(ui->savingRadioBtn, SAVING); ui->powerModeBtnGroup->setId(ui->custdomRadioBtn, CUSTDOM); - //电脑睡眠延迟 + // 电脑睡眠延迟 sleepStringList << tr("never") << tr("10 min") << tr("20 min") << tr("30 min") << tr("60 min") << tr("120 min") << tr("300 min"); -// ui->sleepComboBox->addItems(sleepStringList); ui->sleepComboBox->insertItem(0, sleepStringList.at(0), QVariant::fromValue(0)); ui->sleepComboBox->insertItem(1, sleepStringList.at(1), QVariant::fromValue(10)); ui->sleepComboBox->insertItem(2, sleepStringList.at(2), QVariant::fromValue(20)); @@ -161,10 +241,8 @@ ui->sleepComboBox->insertItem(5, sleepStringList.at(5), QVariant::fromValue(120)); ui->sleepComboBox->insertItem(6, sleepStringList.at(6), QVariant::fromValue(300)); - - //显示器关闭延迟 + // 显示器关闭延迟 closeStringList << tr("never") << tr("1 min") << tr("5 min") << tr("10 min") << tr("20 min") << tr("30 min") << tr("60 min") << tr("120 min"); -// ui->closeComboBox->addItems(closeStringList); ui->closeComboBox->insertItem(0, closeStringList.at(0), QVariant::fromValue(0)); ui->closeComboBox->insertItem(1, closeStringList.at(1), QVariant::fromValue(1)); ui->closeComboBox->insertItem(2, closeStringList.at(2), QVariant::fromValue(5)); @@ -174,15 +252,17 @@ ui->closeComboBox->insertItem(6, closeStringList.at(6), QVariant::fromValue(60)); ui->closeComboBox->insertItem(7, closeStringList.at(7), QVariant::fromValue(120)); - //合盖 - closeLidStringList << tr("nothing") << tr("blank") << tr("suspend") << tr("hibernate") << tr("shutdown"); + // 合盖 + closeLidStringList << tr("nothing") << tr("blank") << tr("suspend") << tr("shutdown"); ui->closeLidCombo->insertItem(0, closeLidStringList.at(0), "nothing"); ui->closeLidCombo->insertItem(1, closeLidStringList.at(1), "blank"); ui->closeLidCombo->insertItem(2, closeLidStringList.at(2), "suspend"); - ui->closeLidCombo->insertItem(3, closeLidStringList.at(3), "hibernate"); - ui->closeLidCombo->insertItem(4, closeLidStringList.at(4), "shutdown"); - - //使用电池时屏幕变暗 + ui->closeLidCombo->insertItem(3, closeLidStringList.at(3), "shutdown"); + if (!Utils::isWayland()){ + closeLidStringList << tr("hibernate"); + ui->closeLidCombo->insertItem(4, closeLidStringList.at(4), "hibernate"); + } + // 使用电池时屏幕变暗 darkenStringList << tr("never") << tr("1 min") << tr("5 min") << tr("10 min") << tr("20 min"); ui->darkenCombo->insertItem(0, darkenStringList.at(0), QVariant::fromValue(0)); ui->darkenCombo->insertItem(1, darkenStringList.at(1), QVariant::fromValue(1)); @@ -190,113 +270,113 @@ ui->darkenCombo->insertItem(3, darkenStringList.at(3), QVariant::fromValue(10)); ui->darkenCombo->insertItem(4, darkenStringList.at(4), QVariant::fromValue(20)); - - //默认电源 + // 默认电源 ui->acBtn->setChecked(true); - //电源不显示变暗功能 + // 电源不显示变暗功能 ui->darkenFrame->hide(); - //s3tos4先隐藏 - ui->s3Tos4Frame->hide(); - - //电源图标 + // 电源图标 iconShowList << tr("always") << tr("present") << tr("charge"); ui->iconComboBox->insertItem(0, iconShowList.at(0), "always"); ui->iconComboBox->insertItem(1, iconShowList.at(1), "present"); ui->iconComboBox->insertItem(2, iconShowList.at(2), "charge"); + refreshUI(); +} +void Power::initDeviceStatus(){ + /* 默认机器没有电池 */ + hasBat = false; +// GError *error = NULL; + UpClient * client = up_client_new (); + GPtrArray *devices = NULL; + UpDevice * device; + UpDeviceKind kind; + + devices = up_client_get_devices2(client); + + for (guint i=0; i< devices->len; i++) { + device = (UpDevice *)g_ptr_array_index (devices, i); + g_object_get (device, "kind", &kind, NULL); + if (kind == UP_DEVICE_KIND_BATTERY) + hasBat = true; + } + g_ptr_array_unref (devices); - //lid -// lidStringList << tr("nothing") << tr("blank") << tr("suspend") << tr("shutdown"); -// ui->aclidComboBox->addItems(lidStringList); -// ui->batlidComboBox->addItems(lidStringList); - - //button -// buttonStringList << tr("interactive") << tr("suspend") << tr("shutdown"); -// ui->powerbtnComboBox->addItems(buttonStringList); -// ui->suspendComboBox->addItems(buttonStringList); - - // -// ui->icondisplayBtnGroup->setId(ui->presentRadioBtn, PRESENT); -// ui->icondisplayBtnGroup->setId(ui->alwaysRadioBtn, ALWAYS); - - refreshUI(); } -void Power::setupConnect(){ +void Power::setupConnect() { #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) connect(ui->powerModeBtnGroup, static_cast(&QButtonGroup::buttonClicked), [=](int id){ #else - connect(ui->powerModeBtnGroup, QOverload::of(&QButtonGroup::buttonClicked), [=](int id){ + connect(ui->powerModeBtnGroup, QOverload::of(&QButtonGroup::buttonClicked), [=](int id) { #endif refreshUI(); - if (id == BALANCE){ - //设置显示器关闭 - settings->set(SLEEP_DISPLAY_AC_KEY, DISPLAY_BALANCE); - settings->set(SLEEP_DISPLAY_BATT_KEY, DISPLAY_BALANCE); - //设置计算机睡眠 - settings->set(SLEEP_COMPUTER_AC_KEY, COMPUTER_BALANCE); - settings->set(SLEEP_COMPUTER_BATT_KEY, COMPUTER_BALANCE); - } else if (id == SAVING){ - //设置显示器关闭 - settings->set(SLEEP_DISPLAY_AC_KEY, DISPLAY_SAVING); - settings->set(SLEEP_DISPLAY_BATT_KEY, DISPLAY_SAVING); - //设置计算机睡眠 - settings->set(SLEEP_COMPUTER_AC_KEY, COMPUTER_SAVING); - settings->set(SLEEP_COMPUTER_BATT_KEY, COMPUTER_SAVING); + // 平衡模式 + if (id == BALANCE) { + mUkccpersonpersonalize->set("custompower", false); + // 省电模式 + settings->set(POWER_POLICY_KEY, 1); + } else if (id == SAVING) { + mUkccpersonpersonalize->set("custompower", false); + // 省电模式 + settings->set(POWER_POLICY_KEY, 2); } else { - resetCustomPlanStatus(); + //自定义模式下的POWER_POLICY_KEY的值与切换前的模式有关,这里不做设置 + mUkccpersonpersonalize->set("custompower", true); + initCustomPlanStatus(); } - }); - #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) connect(ui->powerTypeBtnGroup, static_cast(&QButtonGroup::buttonClicked), this, [=]{ #else - connect(ui->powerTypeBtnGroup, QOverload::of(&QButtonGroup::buttonClicked), this, [=]{ + connect(ui->powerTypeBtnGroup, QOverload::of(&QButtonGroup::buttonClicked), this, [=] { #endif initCustomPlanStatus(); }); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - connect(ui->sleepComboBox, static_cast(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->sleepComboBox, static_cast(&QComboBox::currentIndexChanged), this, [=](int index) { #else - connect(ui->sleepComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->sleepComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { #endif Q_UNUSED(index) int value = ui->sleepComboBox->currentData(Qt::UserRole).toInt() * 60; - if (ui->acBtn->isChecked()){ + if (ui->acBtn->isChecked()) { settings->set(SLEEP_COMPUTER_AC_KEY, QVariant(value)); } - if (ui->batteryBtn->isChecked()){ + if (ui->batteryBtn->isChecked()) { settings->set(SLEEP_COMPUTER_BATT_KEY, QVariant(value)); } + + ui->sleepLabel->setText(tr("Change PC sleep time:")); }); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - connect(ui->closeComboBox, static_cast(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->closeComboBox, static_cast(&QComboBox::currentIndexChanged), this, [=](int index) { #else - connect(ui->closeComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->closeComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { #endif Q_UNUSED(index) int value = ui->closeComboBox->currentData(Qt::UserRole).toInt() * 60; - if (ui->acBtn->isChecked()){ + if (ui->acBtn->isChecked()) { settings->set(SLEEP_DISPLAY_AC_KEY, QVariant(value)); } - if (ui->batteryBtn->isChecked()){ + if (ui->batteryBtn->isChecked()) { settings->set(SLEEP_DISPLAY_BATT_KEY, QVariant(value)); } + + ui->closeLabel->setText(tr("Change DP close time:"));; }); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - connect(ui->iconComboBox,static_cast(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->iconComboBox,static_cast(&QComboBox::currentIndexChanged), this, [=](int index) { #else - connect(ui->iconComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->iconComboBox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { #endif Q_UNUSED(index) @@ -305,167 +385,262 @@ }); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) - connect(ui->closeLidCombo,static_cast(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->closeLidCombo,static_cast(&QComboBox::currentIndexChanged), this, [=](int index) { #else - connect(ui->closeLidCombo, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->closeLidCombo, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { #endif Q_UNUSED(index) QString value = ui->closeLidCombo->currentData(Qt::UserRole).toString(); - if (ui->acBtn->isChecked()){ + if (ui->acBtn->isChecked()) { settings->set(BUTTON_LID_AC_KEY, value); } - if (ui->batteryBtn->isChecked()){ + if (ui->batteryBtn->isChecked()) { settings->set(BUTTON_LID_BATT_KET, value); } }); #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) + connect(ui->darkenCombo,static_cast(&QComboBox::currentIndexChanged), this, [=](int index){ #else - connect(ui->darkenCombo, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index){ + connect(ui->darkenCombo, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { #endif Q_UNUSED(index) - int idleDarken = ui->darkenCombo->currentData(Qt::UserRole).toInt(); + int idleDarken = ui->darkenCombo->currentData(Qt::UserRole).toInt() * 60; settings->set(IDLE_DIM_TIME_KEY, idleDarken); }); } -void Power::initModeStatus(){ - int acsleep = settings->get(SLEEP_COMPUTER_AC_KEY).toInt(); - int acclose = settings->get(SLEEP_DISPLAY_AC_KEY).toInt(); - - int batsleep = settings->get(SLEEP_COMPUTER_BATT_KEY).toInt(); - int batclose = settings->get(SLEEP_DISPLAY_BATT_KEY).toInt(); - - if (acsleep == COMPUTER_BALANCE && batsleep == COMPUTER_BALANCE && - acclose == DISPLAY_BALANCE && batclose == DISPLAY_BALANCE){ +void Power::initModeStatus() { + int power_policy = settings->get(POWER_POLICY_KEY).toInt(); + bool powerStatus = mUkccpersonpersonalize->get("custompower").toBool(); + if (power_policy == 1 && !powerStatus) { ui->balanceRadioBtn->setChecked(true); - - } else if (acsleep == COMPUTER_SAVING && batsleep == COMPUTER_SAVING && - acclose == DISPLAY_SAVING && batclose == DISPLAY_SAVING){ + } else if (power_policy == 2 && !powerStatus) { ui->savingRadioBtn->setChecked(true); } else { ui->custdomRadioBtn->setChecked(true); - // ui->acBtn->setChecked(true); - initCustomPlanStatus(); } refreshUI(); } -void Power::initPowerOtherStatus(){ +void Power::initPowerOtherStatus() { QString value = settings->get(ICONPOLICY).toString(); ui->iconComboBox->blockSignals(true); ui->iconComboBox->setCurrentIndex(ui->iconComboBox->findData(value)); ui->iconComboBox->blockSignals(false); } -void Power::resetCustomPlanStatus(){ - //当其他电源计划切换至自定义时,默认状态为从不 - //设置显示器关闭 +void Power::resetCustomPlanStatus() { + // 当其他电源计划切换至自定义时,默认状态为从不 + // 设置显示器关闭 settings->set(SLEEP_DISPLAY_AC_KEY, 0); settings->set(SLEEP_DISPLAY_BATT_KEY, 0); - //设置计算机睡眠 + // 设置计算机睡眠 settings->set(SLEEP_COMPUTER_AC_KEY, 0); settings->set(SLEEP_COMPUTER_BATT_KEY, 0); - // + settings->set(BUTTON_LID_AC_KEY, "nothing"); settings->set(BUTTON_LID_BATT_KET, "nothing"); ui->acBtn->setChecked(true); initCustomPlanStatus(); - } -void Power::initCustomPlanStatus(){ - //信号阻塞 +void Power::initCustomPlanStatus() { + // 信号阻塞 ui->sleepComboBox->blockSignals(true); ui->closeComboBox->blockSignals(true); ui->darkenCombo->blockSignals(true); - if (ui->acBtn->isChecked()){ - //计算机睡眠延迟 + if (ui->acBtn->isChecked()) { + // 计算机睡眠延迟 int acsleep = settings->get(SLEEP_COMPUTER_AC_KEY).toInt() / FIXES; ui->sleepComboBox->setCurrentIndex(ui->sleepComboBox->findData(acsleep)); - //显示器关闭延迟 + // 显示器关闭延迟 int acclose = settings->get(SLEEP_DISPLAY_AC_KEY).toInt() / FIXES; ui->closeComboBox->setCurrentIndex(ui->closeComboBox->findData(acclose)); - //合盖 + // 合盖 QString aclid = settings->get(BUTTON_LID_AC_KEY).toString(); ui->closeLidCombo->setCurrentIndex(ui->closeLidCombo->findData(aclid)); - //变暗 + // 变暗 ui->darkenFrame->hide(); - } - if (ui->batteryBtn->isChecked()){ - //计算机睡眠延迟 + if (ui->batteryBtn->isChecked()) { + // 计算机睡眠延迟 int batsleep = settings->get(SLEEP_COMPUTER_BATT_KEY).toInt() / FIXES; ui->sleepComboBox->setCurrentIndex(ui->sleepComboBox->findData(batsleep)); - //显示器关闭延迟 + // 显示器关闭延迟 int batclose = settings->get(SLEEP_DISPLAY_BATT_KEY).toInt() / FIXES; ui->closeComboBox->setCurrentIndex(ui->closeComboBox->findData(batclose)); - //合盖 + // 合盖 QString batlid = settings->get(BUTTON_LID_BATT_KET).toString(); ui->closeLidCombo->setCurrentIndex(ui->closeLidCombo->findData(batlid)); - //变暗 - int darkentime = settings->get(IDLE_DIM_TIME_KEY).toInt(); + // 变暗 + int darkentime = settings->get(IDLE_DIM_TIME_KEY).toInt() / FIXES; ui->darkenCombo->setCurrentIndex(ui->darkenCombo->findData(darkentime)); ui->darkenFrame->show(); } - //信号阻塞解除 + ui->sleepLabel->setText(tr("Change PC sleep time:")); + ui->closeLabel->setText(tr("Change DP close time:"));; + + // 信号阻塞解除 ui->sleepComboBox->blockSignals(false); ui->closeComboBox->blockSignals(false); ui->darkenCombo->blockSignals(false); +} - //lid 枚举类型但是toint为零只能toString -// QString aclidString = settings->get(BUTTON_LID_AC_KEY).toString(); -// ui->aclidComboBox->setCurrentText(aclidString); -// QString batlidString = settings->get(BUTTON_LID_BATT_KET).toString(); -// ui->batlidComboBox->setCurrentText(batlidString); - - //power button -// QString powerbtn = settings->get(BUTTON_POWER_KEY).toString(); -// ui->powerbtnComboBox->setCurrentText(powerbtn); -// QString suspentbtn = settings->get(BUTTON_SUSPEND_KEY).toString(); -// ui->suspendComboBox->setCurrentText(suspentbtn); - - //电池图标 枚举类型但是toint为零只能toString -// QString ipvalue = settings->get(ICONPOLICY).toString(); -// if (ipvalue == PRESENT_VALUE) -// ui->presentRadioBtn->setChecked(true); -// else if (ipvalue == ALWAYS_VALUE) -// ui->alwaysRadioBtn->setChecked(true); -} - -void Power::refreshUI(){ - if (ui->powerModeBtnGroup->checkedId() != CUSTDOM){ -// ui->custom1Widget->setEnabled(false); -// ui->custom2Widget->setEnabled(false); +void Power::refreshUI() { + if (ui->powerModeBtnGroup->checkedId() != CUSTDOM) { ui->custom1Frame->hide(); ui->custom2Frame->hide(); ui->closeLidFrame->hide(); - if (ui->batteryBtn->isChecked()) + if (ui->batteryBtn->isChecked()) { ui->darkenFrame->hide(); -// ui->customWidget->setStyleSheet("QWidget{background: #F4F4F4; border-radius: 6px;}"); - - + } } else { -// ui->custom1Widget->setEnabled(true); -// ui->custom2Widget->setEnabled(true); ui->custom1Frame->show(); ui->custom2Frame->show(); - ui->closeLidFrame->show(); -// ui->customWidget->setStyleSheet("QWidget{background: #F4F4F4; border-top-left-radius: 6px; border-top-right-radius: 6px;}"); + ui->closeLidFrame->setVisible(isExitsLid); + } +} + +// 空闲时间 +int Power::getIdleTime() { + return sessionSetting->get(IDLE_DELAY_KEY).toInt(); +} + +void Power::initGeneralSet() { + + if (isExitsPower || Utils::isWayland()) { + // 电源按钮操作 + mPowerBtn = new ComboxFrame(tr("When the power button is pressed:"), pluginWidget); + + mPowerBtn->mHLayout->setSpacing(48); + mPowerBtn->mHLayout->setContentsMargins(16, 0, 16, 0); + + mPowerBtn->mTitleLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + mPowerBtn->mTitleLabel->setMinimumWidth(300); + ui->powerLayout->addWidget(mPowerBtn); + + for(int i = 0; i < kLid.length(); i++) { + mPowerBtn->mCombox->insertItem(i, kLid.at(i), kEnkLid.at(i)); + } + + QString btnStaus = settings->get(BUTTON_POWER_KEY).toString(); + mPowerBtn->mCombox->setCurrentIndex(mPowerBtn->mCombox->findData(btnStaus)); + + connect(mPowerBtn->mCombox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { + settings->set(BUTTON_POWER_KEY, mPowerBtn->mCombox->itemData(index)); + }); + } + + + if (isExitsPower) { + + // 低电量操作 + mBatteryAct = new ComboxFrame(true, tr("Perform operations when battery is low:"), pluginWidget); + mBatteryAct->mTitleLabel->setMinimumWidth(300); + mBatteryAct->mHLayout->setContentsMargins(16, 0, 16, 0); + + mBatteryAct->mNumCombox->setMaximumWidth(230); + + ui->powerLayout->addWidget(mBatteryAct); + + int batteryRemain = settings->get(PER_ACTION_CRI).toInt(); + for(int i = 1; i < batteryRemain; i++) { + mBatteryAct->mNumCombox->insertItem(i - 1, QString("%1%").arg(i)); + } + + for(int i = 0; i < kBattery.length(); i++) { + mBatteryAct->mCombox->insertItem(i, kBattery.at(i), kEnBattery.at(i)); + } + + int actionBattery = settings->get(PER_ACTION_KEY).toInt(); + mBatteryAct->mNumCombox->setCurrentIndex(actionBattery - 1); + + QString actionCriBty = settings->get(ACTION_CRI_BTY).toString(); + mBatteryAct->mCombox->setCurrentIndex(mBatteryAct->mCombox->findData(actionCriBty)); + + connect(mBatteryAct->mNumCombox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { + settings->set(PER_ACTION_KEY, index + 1); + }); + + connect(mBatteryAct->mCombox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { + Q_UNUSED(index) + settings->set(ACTION_CRI_BTY, mBatteryAct->mCombox->itemData(index)); + }); + + } + + /* 休眠接口后续开放 + if (getHibernateStatus() && mPowerKeys.contains("afterIdleAction")) { + mHibernate = new ComboxFrame(tr("After suspending this time, the system will go to sleep:"), pluginWidget); + + + ui->powerLayout->addWidget(mHibernate); + + ui->powerLayout->addStretch(); + + for(int i = 0; i < kHibernate.length(); i++) { + mHibernate->mCombox->addItem(kHibernate.at(i)); + } + + if (getHibernateTime().isEmpty()) { + mHibernate->mCombox->setCurrentIndex(0); + } else { + mHibernate->mCombox->setCurrentText(getHibernateTime()); + } + + connect(mHibernate->mCombox, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { + setHibernateTime(mHibernate->mCombox->currentText()); + if (index) { + settings->set(HIBERNATE_KEY, "suspend-then-hibernate"); + } else { + settings->set(HIBERNATE_KEY, "suspend"); + } + }); + } + */ +} + +bool Power::getHibernateStatus() { + + QDBusInterface loginInterface("org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + QDBusConnection::systemBus()); + + if (loginInterface.isValid()) { + QDBusReply reply = loginInterface.call("CanSuspendThenHibernate"); + return reply.value() == "yes" ? true : false; } + return true; +} + +QString Power::getHibernateTime() { + QDBusReply hibernateTime = mUkccInterface->call("getSuspendThenHibernate"); + if (hibernateTime.isValid()) { + return hibernateTime.value(); + } + return ""; +} + +void Power::initDbus() { + mUkccInterface = new QDBusInterface("com.control.center.qt.systemdbus", + "/", + "com.control.center.interface", + QDBusConnection::systemBus()); } diff -Nru ukui-control-center-2.0.3/plugins/system/power/power.h ukui-control-center-3.0.3/plugins/system/power/power.h --- ukui-control-center-2.0.3/plugins/system/power/power.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/power/power.h 2021-05-20 13:08:14.000000000 +0000 @@ -29,6 +29,8 @@ #include "shell/interface.h" +#include "commonComponent/ComboxFrame/comboxframe.h" + namespace Ui { class Power; } @@ -44,13 +46,15 @@ ~Power(); public: - QString get_plugin_name() Q_DECL_OVERRIDE; - int get_plugin_type() Q_DECL_OVERRIDE; - QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget *get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; public: - void setupStylesheet(); + void initTitleLabel(); + void initSearText(); void setupComponent(); void setupConnect(); void initModeStatus(); @@ -58,17 +62,18 @@ void resetCustomPlanStatus(); void initPowerOtherStatus(); void isPowerSupply(); - + void isLidPresent(); void refreshUI(); + int getIdleTime(); private: Ui::Power *ui; -private: - QWidget * pluginWidget; + QWidget *pluginWidget; -private: - QGSettings * settings; + QGSettings *settings; + QGSettings *sessionSetting; + QGSettings *mUkccpersonpersonalize; QString pluginName; int pluginType; @@ -81,8 +86,31 @@ QStringList buttonStringList; QStringList iconShowList; -private: + QStringList mPowerKeys; + bool settingsCreate; + bool isExitsPower; + bool mFirstLoad; + bool isExitsLid; + + bool hasBat; + + ComboxFrame *mHibernate; + ComboxFrame *mPowerBtn; + ComboxFrame *mBatteryAct; + + QDBusInterface *mUkccInterface; + +private: + void initGeneralSet(); + bool getHibernateStatus(); + QString getHibernateTime(); + void initDbus(); + void initDeviceStatus(); + +private slots: + void setIdleTime(int idleTime); + void setHibernateTime(QString hibernate); }; #endif // POWER_H diff -Nru ukui-control-center-2.0.3/plugins/system/power/powermacrodata.h ukui-control-center-3.0.3/plugins/system/power/powermacrodata.h --- ukui-control-center-2.0.3/plugins/system/power/powermacrodata.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/power/powermacrodata.h 2021-04-14 01:27:20.000000000 +0000 @@ -20,24 +20,33 @@ #ifndef POWERMACRODATA_H #define POWERMACRODATA_H - -#define POWERMANAGER_SCHEMA "org.ukui.power-manager" -#define ICONPOLICY "icon-policy" -#define SLEEP_COMPUTER_AC_KEY "sleep-computer-ac" +#define POWERMANAGER_SCHEMA "org.ukui.power-manager" +#define ICONPOLICY "icon-policy" +#define SLEEP_COMPUTER_AC_KEY "sleep-computer-ac" #define SLEEP_COMPUTER_BATT_KEY "sleep-computer-battery" -#define SLEEP_DISPLAY_AC_KEY "sleep-display-ac" -#define SLEEP_DISPLAY_BATT_KEY "sleep-display-battery" -#define BUTTON_LID_AC_KEY "button-lid-ac" -#define BUTTON_LID_BATT_KET "button-lid-battery" -#define BUTTON_SUSPEND_KEY "button-suspend" -#define BUTTON_POWER_KEY "button-power" -#define IDLE_DIM_TIME_KEY "idle-dim-time" - -#define PRESENT_VALUE "present" -#define ALWAYS_VALUE "always" -#define CHARGE_VALUE "charge" +#define SLEEP_DISPLAY_AC_KEY "sleep-display-ac" +#define SLEEP_DISPLAY_BATT_KEY "sleep-display-battery" +#define BUTTON_LID_AC_KEY "button-lid-ac" +#define BUTTON_LID_BATT_KET "button-lid-battery" +#define BUTTON_SUSPEND_KEY "button-suspend" +#define BUTTON_POWER_KEY "button-power" +#define IDLE_DIM_TIME_KEY "idle-dim-time" +#define HIBERNATE_KEY "after-idle-action" +#define PER_ACTION_KEY "percentage-action" +#define ACTION_CRI_BTY "action-critical-battery" +#define PER_ACTION_CRI "percentage-critical" +#define POWER_POLICY_KEY "power-policy-current" + +#define PRESENT_VALUE "present" +#define ALWAYS_VALUE "always" +#define CHARGE_VALUE "charge" + +#define SESSION_SCHEMA "org.ukui.session" +#define IDLE_DELAY_KEY "idle-delay" #define FIXES 60 +#define PERSONALSIE_SCHEMA "org.ukui.control-center.personalise" +#define PERSONALSIE_POWER_KEY "custompower" #endif // POWERMACRODATA_H diff -Nru ukui-control-center-2.0.3/plugins/system/power/power.pro ukui-control-center-3.0.3/plugins/system/power/power.pro --- ukui-control-center-2.0.3/plugins/system/power/power.pro 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/power/power.pro 2021-04-14 01:27:20.000000000 +0000 @@ -1,8 +1,9 @@ +include(../../../env.pri) QT += widgets dbus TEMPLATE = lib CONFIG += plugin -include(../../../env.pri) +include($$PROJECT_COMPONENTSOURCE/comboxframe.pri) TARGET = $$qtLibraryTarget(power) DESTDIR = ../.. @@ -12,13 +13,16 @@ INCLUDEPATH += \ $$PROJECT_ROOTDIR \ -LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt +LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -lupower-glib CONFIG += \ link_pkgconfig \ c++11 PKGCONFIG += gsettings-qt \ + gio-2.0 \ + gio-unix-2.0 \ + upower-glib FORMS += \ power.ui diff -Nru ukui-control-center-2.0.3/plugins/system/power/power.ui ukui-control-center-3.0.3/plugins/system/power/power.ui --- ukui-control-center-2.0.3/plugins/system/power/power.ui 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/power/power.ui 2021-04-14 01:27:20.000000000 +0000 @@ -72,7 +72,7 @@ 0 - + 8 @@ -156,7 +156,7 @@ 16 - + 0 @@ -266,7 +266,7 @@ 16 - + 0 @@ -384,7 +384,7 @@ 16 - + 0 @@ -588,7 +588,7 @@ 16 - + 0 @@ -608,7 +608,7 @@ - Change pc sleep time: + Change PC sleep time: false @@ -690,7 +690,7 @@ 16 - + 0 @@ -705,12 +705,12 @@ - 300 + 16777215 16777215 - Change dp close time: + Change DP close time: false @@ -810,7 +810,7 @@ - 200 + 16777215 16777215 @@ -890,7 +890,7 @@ - 200 + 16777215 16777215 @@ -947,7 +947,7 @@ - Power Other Settings + General Settings @@ -1005,13 +1005,13 @@ - 200 + 300 0 - 200 + 16777215 16777215 @@ -1022,129 +1022,52 @@ - - - 0 - 0 - - - - - 16777215 - 32 - - - - - - - - - - - - - - - - - 0 - 50 - - - - - 16777215 - 50 - - - - QFrame::Box - - - QFrame::Plain - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 48 - - - 16 - - - 16 - - - - + 0 0 - 200 + 0 0 - 200 - 16777215 + 16777215 + 32 - - QFrame::NoFrame - - - S3 to S4 when: + + - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - + + + + Qt::Vertical + + + + 20 + 40 + + + + diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmloutputcomponent.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmloutputcomponent.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmloutputcomponent.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmloutputcomponent.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,63 @@ +/* + Copyright (C) 2012 Dan Vratil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "qmloutputcomponent.h" +#include "qmloutput.h" +#include "qmlscreen.h" + +#include + +#include +#include +#include +#include +#include + +Q_DECLARE_METATYPE(KScreen::OutputPtr) +Q_DECLARE_METATYPE(QMLScreen*) + +QMLOutputComponent::QMLOutputComponent(QQmlEngine *engine, QMLScreen *parent): + QQmlComponent(engine, parent), + m_engine(engine) +{ + loadUrl(QUrl("qrc:/qml/Output.qml")); +} + +QMLOutputComponent::~QMLOutputComponent() +{ +} + +QMLOutput* QMLOutputComponent::createForOutput(const KScreen::OutputPtr &output) +{ + QObject *instance = beginCreate(m_engine->rootContext()); + if (!instance) { + qWarning() << errorString(); + return nullptr; + } + + bool success = instance->setProperty("outputPtr", QVariant::fromValue(qobject_cast(output))); + + Q_ASSERT(success); + success = instance->setProperty("screen", QVariant::fromValue(qobject_cast(parent()))); + Q_ASSERT(success); + Q_UNUSED(success); + + completeCreate(); + + return qobject_cast(instance); +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmloutputcomponent.h ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmloutputcomponent.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmloutputcomponent.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmloutputcomponent.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,45 @@ +/* + Copyright (C) 2012 Dan Vratil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef QMLOUTPUTCOMPONENT_H +#define QMLOUTPUTCOMPONENT_H + +#include + +#include + + +class QMLScreen; +class QMLOutput; + +class QMLOutputComponent : public QQmlComponent +{ + Q_OBJECT + + public: + explicit QMLOutputComponent(QQmlEngine *engine, QMLScreen *parent); + ~QMLOutputComponent() override; + + QMLOutput* createForOutput(const KScreen::OutputPtr &output); + + private: + QQmlEngine *m_engine; + +}; + +#endif // QMLOUTPUTCOMPONENT_H diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmloutput.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmloutput.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmloutput.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmloutput.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,650 @@ +/* + Copyright (C) 2012 Dan Vratil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "qmloutput.h" +#include "qmlscreen.h" + +#include + +#include +#include +#include +#include + +const static int sMargin = 0; +const static int sSnapArea = 20; +const static int sSnapAlignArea = 6; + +Q_DECLARE_METATYPE(KScreen::ModePtr) + +bool operator>(const QSize &sizeA, const QSize &sizeB) +{ + return ((sizeA.width() > sizeB.width()) && (sizeA.height() > sizeB.height())); +} + +QMLOutput::QMLOutput(QQuickItem *parent): + QQuickItem(parent), + m_screen(nullptr), + m_cloneOf(nullptr), + m_leftDock(nullptr), + m_topDock(nullptr), + m_rightDock(nullptr), + m_bottomDock(nullptr), + m_isCloneMode(false) +{ + connect(this, &QMLOutput::xChanged, + this, static_cast(&QMLOutput::moved)); + connect(this, &QMLOutput::yChanged, + this, static_cast(&QMLOutput::moved)); +} + +KScreen::Output* QMLOutput::output() const +{ + return m_output.data(); +} + +KScreen::OutputPtr QMLOutput::outputPtr() const +{ + return m_output; +} + +void QMLOutput::setOutputPtr(const KScreen::OutputPtr &output) +{ + //qDebug()<<"setOutputPtr------> qmloutput"<currentMode(); + if (!mode) { + if (m_output->isConnected()) { + mode = bestMode(); + if (!mode) { + return 1000; + } + m_output->setCurrentModeId(mode->id()); + } else { + return 1000; + } + } + //qDebug()<<"mode->size().height()---->"<size()<size().height() ;/// m_output->scale(); +} + +//返回上面小屏幕宽度 +int QMLOutput::currentOutputWidth() const +{ + if (!m_output) { + return 0; + } + + KScreen::ModePtr mode = m_output->currentMode(); + if (!mode) { + if (m_output->isConnected()) { + mode = bestMode(); + if (!mode) { + return 1000; + } + m_output->setCurrentModeId(mode->id()); + } else { + return 1000; + } + } +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) + return mode->size().width();// / m_output->scale(); +#else + return mode->size().width() / m_output->scale(); +#endif + +} + +void QMLOutput::currentModeIdChanged() +{ + //qDebug()<<"currentModeIdChanged---->"<outputScale(); + setX((m_screen->width() - newWidth) / 2); + const float newHeight = currentOutputHeight() * m_screen->outputScale(); + setY((m_screen->height() - newHeight) / 2); + } else { + if (m_rightDock) { + QMLOutput *rightDock = m_rightDock; + float newWidth = currentOutputWidth() * m_screen->outputScale(); + setX(rightDock->x() - newWidth); + setRightDockedTo(rightDock); + } + + if (m_bottomDock) { + QMLOutput *bottomDock = m_bottomDock; + float newHeight = currentOutputHeight() * m_screen->outputScale(); + setY(bottomDock->y() - newHeight); + setBottomDockedTo(bottomDock); + } + } + + Q_EMIT currentOutputSizeChanged(); +} + + +int QMLOutput::outputX() const +{ + //qDebug()<<"outputX--->"<pos().x()<pos().x(); +} + +void QMLOutput::setOutputX(int x) +{ +// qDebug()<<"setOutputX--->"<pos().rx() == x) { + return; + } + + QPoint pos = m_output->pos(); + pos.setX(x); + m_output->setPos(pos); + Q_EMIT outputXChanged(); +} + +int QMLOutput::outputY() const +{ + //qDebug()<<"outputY--->"<pos().y()<pos().y(); +} + +void QMLOutput::setOutputY(int y) +{ +// qDebug()<<"setOutputY--->"<pos().ry() == y) { + return; + } + + QPoint pos = m_output->pos(); + pos.setY(y); + m_output->setPos(pos); + Q_EMIT outputYChanged(); +} + +bool QMLOutput::isCloneMode() const +{ + return m_isCloneMode; +} + +void QMLOutput::setIsCloneMode(bool isCloneMode) +{ + if (m_isCloneMode == isCloneMode) { + return; + } + + m_isCloneMode = isCloneMode; + Q_EMIT isCloneModeChanged(); +} + +void QMLOutput::dockToNeighbours() +{ + //qDebug()<<"dockToNeighbours---->"<outputs()) { + if (otherQmlOutput == this) { + continue; + } + + if (!otherQmlOutput->output()->isConnected() || !otherQmlOutput->output()->isEnabled()) { + continue; + } + + const QRect geom = m_output->geometry(); + + const QRect otherGeom = otherQmlOutput->output()->geometry(); + + //qDebug()<<"geom is ------>"<modes(); + KScreen::ModePtr bestMode; + Q_FOREACH (const KScreen::ModePtr &mode, modes) { + if (!bestMode || (mode->size() > bestMode->size())) { + bestMode = mode; + } + } + + return bestMode; +} + +bool QMLOutput::collidesWithOutput(QObject *other) +{ + QQuickItem* otherItem = qobject_cast(other); + return boundingRect().intersects(otherItem->boundingRect()); +} + +bool QMLOutput::maybeSnapTo(QMLOutput *other) +{ + //qDebug()<<"maybeSnapTo---->"<x(); + const qreal y2 = other->y(); + const qreal height2 = other->height(); + const qreal width2 = other->width(); + const qreal centerX2 = x2 + (width2 / 2.0); + const qreal centerY2 = y2 + (height2 / 2.0); + + /* left of other */ + if ((x() + width() > x2 - sSnapArea) && (x() + width() < x2 + sSnapArea) && + (y() + height() > y2) && (y() < y2 + height2)) + { + setX(x2 - width() + sMargin); + centerX = x() + (width() / 2.0); + setRightDockedTo(other); + other->setLeftDockedTo(this); + //output.cloneOf = null; + + /* output is snapped to other on left and their + * upper sides are aligned */ + if ((y() < y2 + sSnapAlignArea) && (y() > y2 - sSnapAlignArea)) { + setY(y2); + return true; + } + + /* output is snapped to other on left and they + * are centered */ + if ((centerY < centerY2 + sSnapAlignArea) && (centerY > centerY2 - sSnapAlignArea)) { + setY(centerY2 - (height() / 2.0)); + return true; + } + + /* output is snapped to other on left and their + * bottom sides are aligned */ + if ((y() + height() < y2 + height2 + sSnapAlignArea) && + (y() + height() > y2 + height2 - sSnapAlignArea)) + { + setY(y2 + height2 - height()); + return true; + } + + return true; + } + + /* output is right of other */ + if ((x() > x2 + width2 - sSnapArea) && (x() < x2 + width2 + sSnapArea) && + (y() + height() > y2) && (y() < y2 + height2)) + { + setX(x2 + width2 - sMargin); + centerX = x() + (width() / 2.0); + setLeftDockedTo(other); + other->setRightDockedTo(this); + //output.cloneOf = null; + + /* output is snapped to other on right and their + * upper sides are aligned */ + if ((y() < y2 + sSnapAlignArea) && (y() > y2 - sSnapAlignArea)) { + setY(y2); + return true; + } + + /* output is snapped to other on right and they + * are centered */ + if ((centerY < centerY2 + sSnapAlignArea) && (centerY > centerY2 - sSnapAlignArea)) { + setY(centerY2 - (height() / 2.0)); + return true; + } + + /* output is snapped to other on right and their + * bottom sides are aligned */ + if ((y() + height() < y2 + height2 + sSnapAlignArea) && + (y() + height() > y2 + height2 - sSnapAlignArea)) + { + setY(y2 + height2 - height()); + return true; + } + + return true; + } + + /* output is above other */ + if ((y() + height() > y2 - sSnapArea) && (y() + height() < y2 + sSnapArea) && + (x() + width() > x2) && (x() < x2 + width2)) + { + setY(y2 - height() + sMargin); + centerY = y() + (height() / 2.0); + setBottomDockedTo(other); + other->setTopDockedTo(this); + //output.cloneOf = null; + + /* output is snapped to other on top and their + * left sides are aligned */ + if ((x() < x2 + sSnapAlignArea) && (x() > x2 - sSnapAlignArea)) { + setX(x2); + return true; + } + + /* output is snapped to other on top and they + * are centered */ + if ((centerX < centerX2 + sSnapAlignArea) && (centerX > centerX2 - sSnapAlignArea)) { + setX(centerX2 - (width() / 2.0)); + return true; + } + + /* output is snapped to other on top and their + * right sides are aligned */ + if ((x() + width() < x2 + width2 + sSnapAlignArea) && + (x() + width() > x2 + width2 - sSnapAlignArea)) + { + setX(x2 + width2 - width()); + return true; + } + + return true; + } + + /* output is below other */ + if ((y() > y2 + height2 - sSnapArea) && (y() < y2 + height2 + sSnapArea) && + (x() + width() > x2) && (x() < x2 + width2)) + { + setY(y2 + height2 - sMargin); + centerY = y() + (height() / 2.0); + setTopDockedTo(other); + other->setBottomDockedTo(this); + //output.cloneOf = null; + + /* output is snapped to other on bottom and their + * left sides are aligned */ + if ((x() < x2 + sSnapAlignArea) && (x() > x2 - sSnapAlignArea)) { + setX(x2); + return true; + } + + /* output is snapped to other on bottom and they + * are centered */ + if ((centerX < centerX2 + sSnapAlignArea) && (centerX > centerX2 - sSnapAlignArea)) { + setX(centerX2 - (width() / 2.0)); + return true; + } + + /* output is snapped to other on bottom and their + * right sides are aligned */ + if ((x() + width() < x2 + width2 + sSnapAlignArea) && + (x() + width() > x2 + width2 - sSnapAlignArea)) + { + setX(x2 + width2 - width()); + return true; + } + + return true; + } + if ((x() + width()) > 550) { + setPosition(QPointF(550 - width(), y())); + } + if ((y() + height()) > 300) { + setPosition(QPointF(x(), 350 - height())); + } + + // 矩形是否相交 + if (!(x() + width() < x2 || x2 + width2 < x() || + y() > y2 +height2 || y2 > y() + height()) && + (x() != x2 || y() != y2) && + other->output()->isConnected()) { + + if ((x() + width() > x2) && (x() < x2)) { + setX(x2 - width() + sMargin); + setRightDockedTo(other); + other->setLeftDockedTo(this); + } else if ((x() < x2 + width2) && (x() + width() > x2 + width2)) { + setX(x2 + width2 - sMargin); + setLeftDockedTo(other); + other->setRightDockedTo(this); + } else if ((y() + height() > y2) && (y() < y2 + height2)) { + setY(y2 - height() + sMargin); + setBottomDockedTo(other); + other->setTopDockedTo(this); + } else if ((y() < y2 + height2) && (y() + height() > y2 + height2)) { + setY(y2 + height2 - sMargin); + setTopDockedTo(other); + other->setBottomDockedTo(this); + } + } + + if (x() == x2 && y() == y2 && other->output()->isConnected()) { + if (x() == 0) { + setX(x() + width()); + } else if (x() + width() == 550){ + setX(x() - width()); + } + } + return false; +} + +void QMLOutput::moved() +{ +// qDebug()<<"moved----->"< siblings = screen()->childItems(); + + // First, if we have moved, then unset the "cloneOf" flag + setCloneOf(nullptr); + + disconnect(this, &QMLOutput::xChanged, this, static_cast(&QMLOutput::moved)); + disconnect(this, &QMLOutput::yChanged, this, static_cast(&QMLOutput::moved)); + Q_FOREACH (QQuickItem *sibling, siblings) { + QMLOutput *otherOutput = qobject_cast(sibling); + if (!otherOutput || otherOutput == this) { + continue; + } + + if (!maybeSnapTo(otherOutput)) { + if (m_leftDock == otherOutput) { + m_leftDock->undockRight(); + undockLeft(); + } + if (m_topDock == otherOutput) { + m_topDock->undockBottom(); + undockTop(); + } + if (m_rightDock == otherOutput) { + m_rightDock->undockLeft(); + undockRight(); + } + if (m_bottomDock == otherOutput) { + m_bottomDock->undockTop(); + undockBottom(); + } + } + } + connect(this, &QMLOutput::xChanged, this, static_cast(&QMLOutput::moved)); + connect(this, &QMLOutput::yChanged, this, static_cast(&QMLOutput::moved)); + + Q_EMIT moved(m_output->name()); +} + + +/* Transformation of an item (rotation of the MouseArea) is only visual. + * The coordinates and dimensions are still the same (when you rotated + * 100x500 rectangle by 90 deg, it will still be 100x500, although + * visually it will be 500x100). + * + * This method calculates the real-visual coordinates and dimensions of + * the MouseArea and updates root item to match them. This makes snapping + * work correctly regardless off visual rotation of the output + */ + +//旋转时计算坐标更改方向 +void QMLOutput::updateRootProperties() +{ + //qDebug()<<"updateRootProperties----->"<isHorizontal() ? currentOutputWidth() : currentOutputHeight()) * m_screen->outputScale(); + const float transformedHeight = (m_output->isHorizontal() ? currentOutputHeight() : currentOutputWidth()) * m_screen->outputScale(); + + const float transformedX = x() + (width() / 2.0) - (transformedWidth / 2.0); + const float transformedY = y() + (height() / 2.0) - (transformedHeight / 2.0); + + //qDebug()<<"transformedWidth: "< + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef QMLOUTPUT_H +#define QMLOUTPUT_H + +#include +#include + +class QStandardItemModel; +class QAbstractItemModel; + +class ModesProxyModel; +class QMLScreen; + + +class QMLOutput : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(KScreen::Output* output + READ output + NOTIFY outputChanged) + + Q_PROPERTY(KScreen::OutputPtr outputPtr + READ outputPtr + WRITE setOutputPtr + NOTIFY outputChanged) + + Q_PROPERTY(bool isCloneMode + READ isCloneMode + WRITE setIsCloneMode + NOTIFY isCloneModeChanged) + + Q_PROPERTY(QMLScreen* screen + READ screen + WRITE setScreen + NOTIFY screenChanged) + + Q_PROPERTY(QMLOutput* cloneOf + READ cloneOf + WRITE setCloneOf + NOTIFY cloneOfChanged) + + Q_PROPERTY(QMLOutput* leftDockedTo + READ leftDockedTo + WRITE setLeftDockedTo + RESET undockLeft + NOTIFY leftDockedToChanged) + + Q_PROPERTY(QMLOutput* topDockedTo + READ topDockedTo + WRITE setTopDockedTo + RESET undockTop + NOTIFY topDockedToChanged) + + Q_PROPERTY(QMLOutput* rightDockedTo + READ rightDockedTo + WRITE setRightDockedTo + RESET undockRight + NOTIFY rightDockedToChanged) + + Q_PROPERTY(QMLOutput* bottomDockedTo + READ bottomDockedTo + WRITE setBottomDockedTo + RESET undockBottom + NOTIFY bottomDockedToChanged) + + Q_PROPERTY(int currentOutputHeight + READ currentOutputHeight + NOTIFY currentOutputSizeChanged) + + Q_PROPERTY(int currentOutputWidth + READ currentOutputWidth + NOTIFY currentOutputSizeChanged) + + /* Workaround for possible QML bug when calling output.pos.y = VALUE works, + * but output.pos.x = VALUE has no effect */ + Q_PROPERTY(int outputX + READ outputX + WRITE setOutputX + NOTIFY outputXChanged) + + Q_PROPERTY(int outputY + READ outputY + WRITE setOutputY + NOTIFY outputYChanged) + + public: + enum { + ModeRole = Qt::UserRole, + ModeIdRole, + SizeRole, + RefreshRateRole + }; + + explicit QMLOutput(QQuickItem *parent = nullptr); + + KScreen::Output* output() const; // For QML + + KScreen::OutputPtr outputPtr() const; + void setOutputPtr(const KScreen::OutputPtr &output); + + QMLScreen* screen() const; + void setScreen(QMLScreen *screen); + + QMLOutput* leftDockedTo() const; + void setLeftDockedTo(QMLOutput *output); + void undockLeft(); + + QMLOutput* topDockedTo() const; + void setTopDockedTo(QMLOutput *output); + void undockTop(); + + QMLOutput* rightDockedTo() const; + void setRightDockedTo(QMLOutput *output); + void undockRight(); + + QMLOutput* bottomDockedTo() const; + void setBottomDockedTo(QMLOutput *output); + void undockBottom(); + + Q_INVOKABLE bool collidesWithOutput(QObject *other); + Q_INVOKABLE bool maybeSnapTo(QMLOutput *other); + + void setCloneOf(QMLOutput *other); + QMLOutput* cloneOf() const; + + int currentOutputHeight() const; + int currentOutputWidth() const; + + int outputX() const; + void setOutputX(int x); + + int outputY() const; + void setOutputY(int y); + + void setIsCloneMode(bool isCloneMode); + bool isCloneMode() const; + + void dockToNeighbours(); + + public Q_SLOTS: + void updateRootProperties(); + + Q_SIGNALS: + void changed(); + + void moved(const QString &self); + + /* Property notifications */ + void outputChanged(); + void screenChanged(); + void cloneOfChanged(); + void currentOutputSizeChanged(); + + void leftDockedToChanged(); + void topDockedToChanged(); + void rightDockedToChanged(); + void bottomDockedToChanged(); + + void outputYChanged(); + void outputXChanged(); + + void isCloneModeChanged(); + + private Q_SLOTS: + void moved(); + void currentModeIdChanged(); + + private: + /** + * Returns the biggest resolution available assuming it's the preferred one + */ + KScreen::ModePtr bestMode() const; + + KScreen::OutputPtr m_output; + QMLScreen *m_screen; + + QMLOutput *m_cloneOf; + QMLOutput *m_leftDock; + QMLOutput *m_topDock; + QMLOutput *m_rightDock; + QMLOutput *m_bottomDock; + + bool m_isCloneMode; +}; + +#endif // QMLOUTPUT_H + diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmlscreen.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmlscreen.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmlscreen.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmlscreen.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,402 @@ +/* + Copyright (C) 2012 Dan Vratil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "qmlscreen.h" +#include "qmloutputcomponent.h" +#include "qmloutput.h" + +#include +#include + +#include +#include + +Q_DECLARE_METATYPE(KScreen::OutputPtr) + +QMLScreen::QMLScreen(QQuickItem *parent) + : QQuickItem(parent) +{ + connect(this, &QMLScreen::widthChanged, this, &QMLScreen::viewSizeChanged); + connect(this, &QMLScreen::heightChanged, this, &QMLScreen::viewSizeChanged); +} + +QMLScreen::~QMLScreen() +{ + qDeleteAll(m_outputMap); + m_outputMap.clear(); +} + +KScreen::ConfigPtr QMLScreen::config() const +{ + return m_config; +} + +void QMLScreen::setConfig(const KScreen::ConfigPtr &config) +{ + qDeleteAll(m_outputMap); + m_outputMap.clear(); + m_manuallyMovedOutputs.clear(); + m_bottommost = m_leftmost = m_rightmost = m_topmost = nullptr; + m_connectedOutputsCount = 0; + m_enabledOutputsCount = 0; + + if (m_config) { + m_config->disconnect(this); + } + + m_config = config; + connect(m_config.data(), &KScreen::Config::outputAdded, + this, [this](const KScreen::OutputPtr &output) { + addOutput(output); + updateOutputsPlacement(); + }); + connect(m_config.data(), &KScreen::Config::outputRemoved, + this, &QMLScreen::removeOutput); + //qDebug()<<"所要拿取的配置为------>"<outputs()) { +// qDebug()<<"\noutput类型----debug------>"<"<(output))<<" "<output()->isConnected() && qmlOutput->output()->isEnabled()) { + //qDebug()<<"qmlOutput---->"<dockToNeighbours(); + } + } +} + + +void QMLScreen::addOutput(const KScreen::OutputPtr &output) +{ + //qDebug()<<"qmlscreen.cpp-------> output类型------->"<setParentItem(this); + qmloutput->setZ(m_outputMap.count()); + + connect(output.data(), &KScreen::Output::isConnectedChanged, + this, &QMLScreen::outputConnectedChanged); + connect(output.data(), &KScreen::Output::isEnabledChanged, + this, &QMLScreen::outputEnabledChanged); + connect(output.data(), &KScreen::Output::posChanged, + this, &QMLScreen::outputPositionChanged); + connect(qmloutput, &QMLOutput::yChanged, + [this, qmloutput]() { + qmlOutputMoved(qmloutput); + }); + connect(qmloutput, &QMLOutput::xChanged, + [this, qmloutput]() { + qmlOutputMoved(qmloutput); + }); + //在这里点击上面小屏幕 + connect(qmloutput, SIGNAL(clicked()), + this, SLOT(setActiveOutput())); + + qmloutput->updateRootProperties(); +} + +void QMLScreen::removeOutput(int outputId) +{ + for (const KScreen::OutputPtr &output : m_outputMap.keys()) { + if (output->id() == outputId) { + QMLOutput *qmlOutput = m_outputMap.take(output); + qmlOutput->setParentItem(nullptr); + qmlOutput->setParent(nullptr); + qmlOutput->deleteLater(); + return; + } + } +} + + +int QMLScreen::connectedOutputsCount() const +{ + return m_connectedOutputsCount; +} + +int QMLScreen::enabledOutputsCount() const +{ + return m_enabledOutputsCount; +} + +QMLOutput *QMLScreen::primaryOutput() const +{ + Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { + if (qmlOutput->output()->isPrimary()) { + return qmlOutput; + } + } + + return nullptr; +} + +QList QMLScreen::outputs() const +{ + return m_outputMap.values(); +} + + +void QMLScreen::setActiveOutput(QMLOutput *output) +{ + Q_FOREACH (QMLOutput *qmlOutput, m_outputMap) { + if (qmlOutput->z() > output->z()) { + qmlOutput->setZ(qmlOutput->z() - 1); + } + } + + output->setZ(m_outputMap.count()); + //选中屏幕 + output->setFocus(true); + Q_EMIT focusedOutputChanged(output); +} + +QSize QMLScreen::maxScreenSize() const +{ + //qDebug()<<"m_config->screen()->maxSize()--->"<screen()->maxSize()<screen()->maxSize(); +} + +float QMLScreen::outputScale() const +{ + return m_outputScale; +} + +void QMLScreen::outputConnectedChanged() +{ + int connectedCount = 0; + + Q_FOREACH (const KScreen::OutputPtr &output, m_outputMap.keys()) { + if (output->isConnected()) { + ++connectedCount; + } + } + + if (connectedCount != m_connectedOutputsCount) { + m_connectedOutputsCount = connectedCount; + Q_EMIT connectedOutputsCountChanged(); + updateOutputsPlacement(); + } +} + +void QMLScreen::outputEnabledChanged() +{ + const KScreen::OutputPtr output(qobject_cast(sender()), [](void *){}); + if (output->isEnabled()) { + updateOutputsPlacement(); + } + int enabledCount = 0; + + Q_FOREACH (const KScreen::OutputPtr &output, m_outputMap.keys()) { + if (output->isEnabled()) { + ++enabledCount; + } + } + + if (enabledCount == m_enabledOutputsCount) { + m_enabledOutputsCount = enabledCount; + Q_EMIT enabledOutputsCountChanged(); + } +} + +void QMLScreen::outputPositionChanged() +{ + /* TODO: Reposition the QMLOutputs */ +} + +void QMLScreen::qmlOutputMoved(QMLOutput *qmlOutput) +{ + //qDebug()<<"qmlOutputMoved------>"<isCloneMode()) { + return; + } + if (!m_manuallyMovedOutputs.contains(qmlOutput)) + m_manuallyMovedOutputs.append(qmlOutput); + + updateCornerOutputs(); + + if (m_leftmost) { + m_leftmost->setOutputX(0); + } + if (m_topmost) { + m_topmost->setOutputY(0); + } + + if (qmlOutput == m_leftmost) { + Q_FOREACH (QMLOutput *other, m_outputMap) { + if (other == m_leftmost) { + continue; + } + + if (!other->output()->isConnected() || !other->output()->isEnabled()) { + continue; + } + + other->setOutputX(float(other->x() - m_leftmost->x()) / outputScale()); + } + } else if (m_leftmost) { + qmlOutput->setOutputX(float(qmlOutput->x() - m_leftmost->x()) / outputScale()); + } + + if (qmlOutput == m_topmost) { + Q_FOREACH (QMLOutput *other, m_outputMap) { + if (other == m_topmost) { + continue; + } + + if (!other->output()->isConnected() || !other->output()->isEnabled()) { + continue; + } + + other->setOutputY(float(other->y() - m_topmost->y()) / outputScale()); + } + } else if (m_topmost) { + qmlOutput->setOutputY(float(qmlOutput->y() - m_topmost->y()) / outputScale()); + } +} + +void QMLScreen::viewSizeChanged() +{ + updateOutputsPlacement(); +} + +void QMLScreen::updateCornerOutputs() +{ + m_leftmost = nullptr; + m_topmost = nullptr; + m_rightmost = nullptr; + m_bottommost = nullptr; + + Q_FOREACH (QMLOutput *output, m_outputMap) { + if (!output->output()->isConnected() || !output->output()->isEnabled()) { + continue; + } + + QMLOutput *other = m_leftmost; + if (!other || output->x() < other->x()) { + m_leftmost = output; + } + + if (!other || output->y() < other->y()) { + m_topmost = output; + } + + if (!other || output->x() + output->width() > other->x() + other->width()) { + m_rightmost = output; + } + + if (!other || output->y() + output->height() > other->y() + other->height()) { + m_bottommost = output; + } + } +} + +void QMLScreen::setOutputScale(float scale) +{ + if (qFuzzyCompare(scale, m_outputScale)) + return; + m_outputScale = scale; + emit outputScaleChanged(); +} + +//应该是画坐标的地方? +void QMLScreen::updateOutputsPlacement() +{ + //qDebug()<<"updateOutputsPlacement---->"<(item); + if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled()) { + continue; + } + + if (qmlOutput->outputX() + qmlOutput->currentOutputWidth() > initialActiveScreenSize.width()) { + // qDebug()<outputX()<currentOutputWidth()<outputX() + qmlOutput->currentOutputWidth()); + } + if (qmlOutput->outputY() + qmlOutput->currentOutputHeight() > initialActiveScreenSize.height()) { + initialActiveScreenSize.setHeight(qmlOutput->outputY() + qmlOutput->currentOutputHeight()); + } + } + + auto initialScale = outputScale(); + + //qDebug() << " -----debug0--->outputScale" << initialScale; + auto scale = initialScale; + qreal lastX = -1.0; + do { + auto activeScreenSize = initialActiveScreenSize * scale; + + const QPointF offset((width() - activeScreenSize.width()) / 2.0, + (height() - activeScreenSize.height()) / 2.0); + + // qDebug() << " ----------debug1--->offset-->" << offset; + + lastX = -1.0; + qreal lastY = -1.0; + Q_FOREACH (QQuickItem *item, childItems()) { + QMLOutput *qmlOutput = qobject_cast(item); + if (!qmlOutput->output()->isConnected() || !qmlOutput->output()->isEnabled() || + m_manuallyMovedOutputs.contains(qmlOutput)) { + continue; + } + + qmlOutput->blockSignals(true); + qmlOutput->setPosition(QPointF(offset.x() + (qmlOutput->outputX() * scale), + offset.y() + (qmlOutput->outputY() * scale))); + lastX = qMax(lastX, qmlOutput->position().x() + qmlOutput->width() / initialScale * scale); + lastY = qMax(lastY, qmlOutput->position().y()); + // qDebug()<<"坐标---->"<blockSignals(false); + } + + Q_FOREACH (QQuickItem *item, childItems()) { + QMLOutput *qmlOutput = qobject_cast(item); + if (qmlOutput->output()->isConnected() && !qmlOutput->output()->isEnabled() && + !m_manuallyMovedOutputs.contains(qmlOutput)) { + qmlOutput->blockSignals(true); + qmlOutput->setPosition(QPointF(lastX, lastY)); + lastX += qmlOutput->width() / initialScale * scale; + qmlOutput->blockSignals(false); + } + } + // calculate the scale dynamically, so all screens fit to the dialog + if (lastX > width()) { + scale *= 0.8; + } + } while (lastX > width()); + // Use a timer to avoid binding loop on width() + QTimer::singleShot(0, this, [scale, this] { + setOutputScale(scale); + }); +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmlscreen.h ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmlscreen.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/declarative/qmlscreen.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/declarative/qmlscreen.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,119 @@ +/* + Copyright (C) 2012 Dan Vratil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef QMLSCREEN_H +#define QMLSCREEN_H + +#include + +#include +#include "qmloutput.h" + +class QQmlEngine; + +namespace KScreen { +class Output; +class Config; +} + +class QMLScreen : public QQuickItem +{ + Q_OBJECT + + Q_PROPERTY(QSize maxScreenSize + READ maxScreenSize + CONSTANT) + + Q_PROPERTY(int connectedOutputsCount + READ connectedOutputsCount + NOTIFY connectedOutputsCountChanged) + + Q_PROPERTY(int enabledOutputsCount + READ enabledOutputsCount + NOTIFY enabledOutputsCountChanged) + + Q_PROPERTY(float outputScale + READ outputScale + NOTIFY outputScaleChanged) + + public: + explicit QMLScreen(QQuickItem *parent = nullptr); + ~QMLScreen() override; + + int connectedOutputsCount() const; + int enabledOutputsCount() const; + + QMLOutput* primaryOutput() const; + QList outputs() const; + + QSize maxScreenSize() const; + + float outputScale() const; + + KScreen::ConfigPtr config() const; + void setConfig(const KScreen::ConfigPtr &config); + + void updateOutputsPlacement(); + + void setActiveOutput(QMLOutput *output); + + public Q_SLOTS: + void setActiveOutput() { + setActiveOutput(qobject_cast(sender())); + } + + + Q_SIGNALS: + void connectedOutputsCountChanged(); + void enabledOutputsCountChanged(); + + void outputScaleChanged(); + + void focusedOutputChanged(QMLOutput *output); + + private Q_SLOTS: + void addOutput(const KScreen::OutputPtr &output); + void removeOutput(int outputId); + + void outputConnectedChanged(); + void outputEnabledChanged(); + void outputPositionChanged(); + + void viewSizeChanged(); + + private: + void qmlOutputMoved(QMLOutput *qmlOutput); + void updateCornerOutputs(); + void setOutputScale(float scale); + + KScreen::ConfigPtr m_config; + QHash m_outputMap; + QVector m_manuallyMovedOutputs; + int m_connectedOutputsCount = 0; + int m_enabledOutputsCount = 0; + + float m_outputScale = 1.0 / 8.0;//缩放比例 + + QMLOutput *m_leftmost = nullptr; + QMLOutput *m_topmost = nullptr; + QMLOutput *m_rightmost = nullptr; + QMLOutput *m_bottommost = nullptr; + +}; + +#endif // QMLSCREEN_H diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/monitorinputtask.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/monitorinputtask.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/monitorinputtask.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/monitorinputtask.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,140 @@ +#include "monitorinputtask.h" + +//#include "xinputmanager.h" + +MonitorInputTask* MonitorInputTask::instance(QObject *parent) +{ + static MonitorInputTask *_instance = nullptr; + QMutex mutex; + mutex.lock(); + if(!_instance) + _instance = new MonitorInputTask(parent); + mutex.unlock(); + return _instance; +} + +MonitorInputTask::MonitorInputTask(QObject *parent): + QObject(parent), + m_running(false) +{ + initConnect(); +} + +void MonitorInputTask::initConnect() +{ + +} + +void MonitorInputTask::StartManager() +{ + qDebug() << "info: [MonitorInputTask][StartManager]: thread id = " << QThread::currentThreadId(); + QTimer::singleShot(0, this, &MonitorInputTask::ListeningToInputEvent); +} + +int MonitorInputTask::EventSift(XIHierarchyEvent *event, int flag) +{ + int device_id = -1; + int cnt = event->num_info; + XIHierarchyInfo *event_list = event->info; + for(int i = 0;i < cnt;i++) + { + if(event_list[i].flags & flag) + { + device_id = event_list[i].deviceid; + } + } + return device_id; +} + +void MonitorInputTask::ListeningToInputEvent() +{ + qDebug() << "info: [MonitorInputTask][ListeningToInputEvent]: Start ListeningToInputEvent!"; + + Display *display = NULL; + // open display + display = XOpenDisplay(NULL); + if (display == NULL) + { + qDebug() << "info: [MonitorInputTask][ListeningToInputEvent]: Failed to open display."; + return; + } + XIEventMask mask[2]; + XIEventMask *m; + Window win; + + win = DefaultRootWindow(display); + + m = &mask[0]; + m->deviceid = XIAllDevices; + m->mask_len = XIMaskLen(XI_LASTEVENT); + m->mask = (unsigned char*)calloc(m->mask_len, sizeof(char)); + XISetMask(m->mask, XI_HierarchyChanged); + + m = &mask[1]; + m->deviceid = XIAllMasterDevices; + m->mask_len = XIMaskLen(XI_LASTEVENT); + m->mask = (unsigned char*)calloc(m->mask_len, sizeof(char)); + + XISelectEvents(display, win, &mask[0], 2); + XSync(display, False); + + free(mask[0].mask); + free(mask[1].mask); + mask[0].mask = NULL; + mask[1].mask = NULL; + + while(true) + { + XEvent ev; + XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie; + XNextEvent(display, (XEvent*)&ev); + // 判断当前事件监听是否还要继续 + // 保证效率 m_running[*bool] 的访问不需要加锁 + if(!m_running) break; + + if (XGetEventData(display, cookie) && + cookie->type == GenericEvent) + { + if(XI_HierarchyChanged == cookie->evtype) + { + + XIHierarchyEvent *hev = (XIHierarchyEvent*)cookie->data; + if(hev->flags & XIMasterRemoved) + { + Q_EMIT masterRemoved(EventSift(hev, XIMasterRemoved)); + } + else if(hev->flags & XISlaveAdded) + { + Q_EMIT slaveAdded(EventSift(hev, XISlaveAdded)); + } + else if(hev->flags & XISlaveRemoved) + { + Q_EMIT slaveRemoved(EventSift(hev, XISlaveRemoved)); + } + else if(hev->flags & XISlaveAttached) + { + Q_EMIT slaveAttached(EventSift(hev, XISlaveAttached)); + } + else if(hev->flags & XISlaveDetached) + { + Q_EMIT slaveDetached(EventSift(hev, XISlaveDetached)); + } + else if(hev->flags & XIDeviceEnabled) + { + Q_EMIT deviceEnable(EventSift(hev, XIDeviceEnabled)); + } + else if(hev->flags & XIDeviceDisabled) + { + Q_EMIT deviceDisable(EventSift(hev, XIDeviceDisabled)); + } + else if(hev->flags & XIMasterAdded) + { + Q_EMIT masterAdded(EventSift(hev, XIMasterAdded)); + } + } + } + XFreeEventData(display, cookie); + } + + XDestroyWindow(display, win); +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/monitorinputtask.h ukui-control-center-3.0.3/plugins/system/touchscreen/monitorinputtask.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/monitorinputtask.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/monitorinputtask.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,87 @@ +#ifndef MONITORINPUTTASK_H +#define MONITORINPUTTASK_H + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +class MonitorInputTask : public QObject +{ + Q_OBJECT +public: + bool m_running; + +public: + static MonitorInputTask* instance(QObject *parent = nullptr); + +public Q_SLOTS: + void StartManager(); + +Q_SIGNALS: + /*! + * \brief slaveAdded 从设备添加 + * \param device_id + */ + void slaveAdded(int device_id); + /*! + * \brief slaveRemoved 从设备移除 + * \param device_id + */ + void slaveRemoved(int device_id); + /*! + * \brief masterAdded 主分支添加 + * \param device_id + */ + void masterAdded(int device_id); + /*! + * \brief masterRemoved 主分支移除 + * \param device_id + */ + void masterRemoved(int device_id); + /*! + * \brief deviceEnable 设备启用 + * \param device_id + */ + void deviceEnable(int device_id); + /*! + * \brief deviceDisable 设备禁用 + * \param device_id + */ + void deviceDisable(int device_id); + /*! + * \brief slaveAttached 从设备附加 + * \param device_id + */ + void slaveAttached(int device_id); + /*! + * \brief slaveDetached 从设备分离 + * \param device_id + */ + void slaveDetached(int device_id); + +private: + MonitorInputTask(QObject *parent = nullptr); + void initConnect(); + /*! + * \brief ListeningToInputEvent 监听所有输入设备的事件 + */ + void ListeningToInputEvent(); + /*! + * \brief EventSift 筛选出发生事件的设备ID + * \param event 所有设备的事件信息 + * \param flag 当前发生的事件 + * \return 查找失败 return -1; 查找成功 return device_id; + */ + int EventSift(XIHierarchyEvent *event, int flag); + +}; + +#endif // MONITORINPUTTASK_H diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/qml/main.qml ukui-control-center-3.0.3/plugins/system/touchscreen/qml/main.qml --- ukui-control-center-2.0.3/plugins/system/touchscreen/qml/main.qml 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/qml/main.qml 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,79 @@ +/* + Copyright (C) 2012 Dan Vratil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +import QtQuick 2.1 +import QtQuick.Controls 1.1 as Controls +//import org.kde.plasma.core 2.0 as PlasmaCore +//import org.kde.kquickcontrols 2.0 +import org.kde.kscreen 1.0 + +Item { + id: root; + + property variant virtualScreen: null; + + objectName: "root"; + focus: true; + + SystemPalette { + id: palette; + } + + Rectangle { + id: background; + + anchors.fill: parent; + focus: true; + +// color: "#000000"; + color: "transparent"; +// color: palette.button; +// opacity: 0.6; +// radius: 6 //设置矩形圆角弧度 + + FocusScope { + + id: outputViewFocusScope; + + anchors.fill: parent; + focus: true; + + QMLScreen { + + id: outputView; + + anchors.fill: parent; + clip: true; + + objectName: "outputView"; + } + } + + Column { + + anchors { + left: parent.left; + //right: identifyButton.left; + bottom: parent.bottom; + margins: 5; + } + + spacing: 5; + } + } +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/qml/Output.qml ukui-control-center-3.0.3/plugins/system/touchscreen/qml/Output.qml --- ukui-control-center-2.0.3/plugins/system/touchscreen/qml/Output.qml 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/qml/Output.qml 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,322 @@ +/* + Copyright (C) 2012 Dan Vratil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +import QtQuick 2.1 +import QtGraphicalEffects 1.0 +import org.kde.kscreen 1.0 + +QMLOutput { + + id: root; + + signal clicked(); + signal primaryTriggered(string self); + signal enabledToggled(string self); + signal mousePressed(); + signal mouseReleased(); + + property bool isDragged: monitorMouseArea.drag.active; + property bool isDragEnabled: true; + property bool isToggleButtonVisible: false; + property bool hasMoved: false; + + width: monitorMouseArea.width; + height: monitorMouseArea.height; + + + visible: (opacity > 0); + opacity: output.connected ? 1.0 : 0.0; + + + Component.onCompleted: { + root.updateRootProperties(); + } + + SystemPalette { + + id: palette; + } + + MouseArea { + + id: monitorMouseArea; + + width: root.currentOutputWidth * screen.outputScale; + height: root.currentOutputHeight * screen.outputScale + + anchors.centerIn: parent; + + //是否激活时的透明度 + opacity: root.output.enabled ? 1.0 : 0.3; + transformOrigin: Item.Center; + rotation: { + if (output.rotation === KScreenOutput.None) { + return 0; + } else if (output.rotation === KScreenOutput.Left) { + return 270; + } else if (output.rotation === KScreenOutput.Inverted) { + return 180; + } else { + return 90; + } + } + + hoverEnabled: true; + preventStealing: true; + + drag { + target: root.isDragEnabled && !root.isCloneMode ? root : null; + axis: Drag.XandYAxis; + minimumX: 0; + maximumX: screen.maxScreenSize.width - root.width; + minimumY: 0; + maximumY: screen.maxScreenSize.height - root.height; + + filterChildren: false; + } + + drag.onActiveChanged: { + /* If the drag is shorter then the animation then make sure + * we won't end up in an inconsistent state */ +// console.log("宽度------>"+width) +// console.log("高度------>"+height) + if (dragActiveChangedAnimation.running) { + dragActiveChangedAnimation.complete(); + } + + dragActiveChangedAnimation.running = true; + } + + onPressed: root.clicked(); + + /* FIXME: This could be in 'Behavior', but MouseArea had + * some complaints...to tired to investigate */ + PropertyAnimation { + id: dragActiveChangedAnimation; + + target: monitor; + property: "opacity"; + from: monitorMouseArea.drag.active ? 0.7 : 1.0 + to: monitorMouseArea.drag.active ? 1.0 : 0.7 + duration: 100; + easing.type: "OutCubic"; + } + + Behavior on opacity { + PropertyAnimation { + property: "opacity"; + easing.type: "OutCubic"; + duration: 250; + } + } + + Behavior on rotation { + RotationAnimation { + easing.type: "OutCubic" + duration: 250; + direction: RotationAnimation.Shortest; + } + } + + Behavior on width { + PropertyAnimation { + property: "width"; + easing.type: "OutCubic"; + duration: 150; + } + } + + Behavior on height { + PropertyAnimation { + property: "height"; + easing.type: "OutCubic"; + duration: 150; + } + } + + Rectangle { + + id: monitor; + + anchors.fill: parent; + + //圆角 + radius: 8; + //是否点击到屏幕 + color: root.focus? "#3D6BE5" : "#AEACAD"; + smooth: true; + clip: true; + + border { + color: root.focus ? "#3498DB" : "#AED6F1"; + width: 1; + + Behavior on color { + PropertyAnimation { + duration: 150; + } + } + } + + Rectangle { + + id: posLabel; + + y: 4; + x: 4; + + width: childrenRect.width + 5; + height: childrenRect.height + 2; + + radius: 8; + + opacity: root.output.enabled && monitorMouseArea.drag.active ? 1.0 : 0.0; + visible: opacity != 0.0; + + color: "#101010"; + + Text { + id: posLabelText; + + text: root.outputX + "," + root.outputY; + + color: "white"; + + y: 2; + x: 2; + } + } + + Item { + //文字位置 + y: ((parent.height - orientationPanel.height) / 2) - (implicitHeight / 2) + + anchors { + left: parent.left; + right: parent.right; + leftMargin: 5; + rightMargin: 5; + } + + Text { + id: nameLabel + text: if (root.isCloneMode === true) { + return ""; + } else if (root.output.type !== KScreenOutput.Panel && root.output.edid && root.output.edid.name) { + return root.output.edid.name; + } else { + return ""; + } + + //上面文字颜色 + color: "#FFFFFF"; + font.pixelSize: 12; + + anchors { + horizontalCenter: parent.horizontalCenter; + bottom: labelVendor.top; + topMargin: 5; + } + } + + Text { + id: labelVendor; + text: if (root.isCloneMode) { + return ("Unified Outputs"); + } else if (root.output.type === KScreenOutput.Panel) { + return ("Laptop Screen"); + } else if (root.output.edid && root.output.edid.vendor) { + + return root.output.edid.vendor; + } else { + return root.output.name; + } + + anchors { + verticalCenter: parent.verticalCenter; + left: parent.left; + right: parent.right; + } + horizontalAlignment: Text.AlignHCenter; + //下面文字颜色 + //color: palette.text; + color: "#FFFFFF"; + font.pixelSize: 10; + elide: Text.ElideRight; + } + + Text { + id: label + text: (labelVendor.text === root.output.name) ? "" : root.output.name + + color: palette.text; + font.pixelSize: 10; + + anchors { + horizontalCenter: parent.horizontalCenter; + top: labelVendor.bottom; + topMargin: 5; + } + } + } + } + Item { + id: orientationPanelContainer; + + anchors.fill: monitor; + + visible: false + + Rectangle { + id: orientationPanel; + + //注释底部不会变色拖动时候 +// anchors { +// left: parent.left; +// right: parent.right; +// bottom: parent.bottom; +// } + + height: 10; + //color: root.focus ? palette.highlight : palette.shadow; + //底部颜色 + color: palette.highlight ; + smooth: true; + + Behavior on color { + PropertyAnimation { + duration: 150; + } + } + } + } + + OpacityMask { + anchors.fill: orientationPanelContainer; + source: orientationPanelContainer; + maskSource: monitor; + } + } + + Behavior on opacity { + PropertyAnimation { + duration: 200; + easing.type: "OutCubic"; + } + } +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/qml/ui_touchscreen.h ukui-control-center-3.0.3/plugins/system/touchscreen/qml/ui_touchscreen.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/qml/ui_touchscreen.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/qml/ui_touchscreen.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,154 @@ +/******************************************************************************** +** Form generated from reading UI file 'touchscreen.ui' +** +** Created by: Qt User Interface Compiler version 5.12.8 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_TOUCHSCREEN_H +#define UI_TOUCHSCREEN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_TouchScreen +{ +public: + QFrame *screenframe; + QHBoxLayout *horizontalLayout; + QLabel *monitorLabel; + QComboBox *monitorCombo; + QFrame *screenframe_2; + QHBoxLayout *horizontalLayout_2; + QLabel *touchLabel; + QComboBox *touchscreenCombo; + QWidget *layoutWidget; + QFormLayout *formLayout; + QPushButton *mapButton; + QPushButton *CalibrationButton; + QSpacerItem *horizontalSpacer_4; + QLabel *touchscreenLabel; + QLabel *touchnameContent; + + void setupUi(QWidget *TouchScreen) + { + if (TouchScreen->objectName().isEmpty()) + TouchScreen->setObjectName(QString::fromUtf8("TouchScreen")); + TouchScreen->resize(917, 349); + screenframe = new QFrame(TouchScreen); + screenframe->setObjectName(QString::fromUtf8("screenframe")); + screenframe->setGeometry(QRect(0, 110, 741, 50)); + screenframe->setMinimumSize(QSize(550, 50)); + screenframe->setMaximumSize(QSize(960, 50)); + screenframe->setFrameShape(QFrame::Box); + horizontalLayout = new QHBoxLayout(screenframe); + horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + monitorLabel = new QLabel(screenframe); + monitorLabel->setObjectName(QString::fromUtf8("monitorLabel")); + monitorLabel->setMinimumSize(QSize(118, 30)); + monitorLabel->setMaximumSize(QSize(118, 30)); + + horizontalLayout->addWidget(monitorLabel); + + monitorCombo = new QComboBox(screenframe); + monitorCombo->setObjectName(QString::fromUtf8("monitorCombo")); + monitorCombo->setMinimumSize(QSize(200, 0)); + monitorCombo->setMaximumSize(QSize(16777215, 30)); + monitorCombo->setStyleSheet(QString::fromUtf8("")); + + horizontalLayout->addWidget(monitorCombo); + + screenframe_2 = new QFrame(TouchScreen); + screenframe_2->setObjectName(QString::fromUtf8("screenframe_2")); + screenframe_2->setGeometry(QRect(0, 170, 741, 50)); + screenframe_2->setMinimumSize(QSize(550, 50)); + screenframe_2->setMaximumSize(QSize(960, 50)); + screenframe_2->setFrameShape(QFrame::Box); + horizontalLayout_2 = new QHBoxLayout(screenframe_2); + horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + touchLabel = new QLabel(screenframe_2); + touchLabel->setObjectName(QString::fromUtf8("touchLabel")); + touchLabel->setMinimumSize(QSize(118, 30)); + touchLabel->setMaximumSize(QSize(118, 30)); + + horizontalLayout_2->addWidget(touchLabel); + + touchscreenCombo = new QComboBox(screenframe_2); + touchscreenCombo->setObjectName(QString::fromUtf8("touchscreenCombo")); + touchscreenCombo->setMinimumSize(QSize(200, 0)); + touchscreenCombo->setMaximumSize(QSize(16777215, 30)); + touchscreenCombo->setStyleSheet(QString::fromUtf8("")); + + horizontalLayout_2->addWidget(touchscreenCombo); + + layoutWidget = new QWidget(TouchScreen); + layoutWidget->setObjectName(QString::fromUtf8("layoutWidget")); + layoutWidget->setGeometry(QRect(0, 230, 741, 38)); + formLayout = new QFormLayout(layoutWidget); + formLayout->setObjectName(QString::fromUtf8("formLayout")); + formLayout->setContentsMargins(0, 0, 0, 0); + mapButton = new QPushButton(layoutWidget); + mapButton->setObjectName(QString::fromUtf8("mapButton")); + mapButton->setMinimumSize(QSize(120, 36)); + mapButton->setMaximumSize(QSize(16777215, 36)); + mapButton->setLayoutDirection(Qt::LeftToRight); + + + CalibrationButton = new QPushButton(layoutWidget); + CalibrationButton->setObjectName(QString::fromUtf8("CalibrationButton")); + CalibrationButton->setMinimumSize(QSize(120, 36)); + CalibrationButton->setMaximumSize(QSize(16777215, 36)); + CalibrationButton->setLayoutDirection(Qt::LeftToRight); + CalibrationButton->setGeometry(QRect(100,100,100,22)); + + formLayout->setWidget(0, QFormLayout::LabelRole, mapButton); + + horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + formLayout->setItem(0, QFormLayout::FieldRole, horizontalSpacer_4); + + touchscreenLabel = new QLabel(TouchScreen); + touchscreenLabel->setObjectName(QString::fromUtf8("touchscreenLabel")); + touchscreenLabel->setGeometry(QRect(0, 0, 913, 22)); + + touchnameContent = new QLabel(TouchScreen); + touchnameContent->setObjectName(QString::fromUtf8("touchnameContent")); + touchnameContent->setGeometry(QRect(0, 230, 431, 22)); + + QWidget::setTabOrder(monitorCombo, touchscreenCombo); + QWidget::setTabOrder(touchscreenCombo, mapButton); + + retranslateUi(TouchScreen); + + QMetaObject::connectSlotsByName(TouchScreen); + } // setupUi + + void retranslateUi(QWidget *TouchScreen) + { + TouchScreen->setWindowTitle(QApplication::translate("TouchScreen", "TouchScreen", nullptr)); + monitorLabel->setText(QApplication::translate("TouchScreen", "monitor", nullptr)); + touchLabel->setText(QApplication::translate("TouchScreen", "touch screen", nullptr)); + mapButton->setText(QApplication::translate("TouchScreen", "map", nullptr)); + touchscreenLabel->setText(QApplication::translate("TouchScreen", "TouchScreen", nullptr)); + } // retranslateUi + +}; + +namespace Ui { + class TouchScreen: public Ui_TouchScreen {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_TOUCHSCREEN_H diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/qml.qrc ukui-control-center-3.0.3/plugins/system/touchscreen/qml.qrc --- ukui-control-center-2.0.3/plugins/system/touchscreen/qml.qrc 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/qml.qrc 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,6 @@ + + + qml/Output.qml + qml/main.qml + + diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/touchscreen.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/touchscreen.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/touchscreen.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/touchscreen.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,45 @@ +#include "touchscreen.h" +#include "ui_touchscreen.h" + + +#include +#include +#include + +TouchScreen::TouchScreen() : mFirstLoad(true) +{ + pluginName = tr("TouchScreen"); + pluginType = SYSTEM; +} + +TouchScreen::~TouchScreen() { +} + +QWidget *TouchScreen::get_plugin_ui() { + if (mFirstLoad) { + mFirstLoad = false; + pluginWidget = new Widget; + QObject::connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, + [&](KScreen::ConfigOperation *op) { + pluginWidget->setConfig(qobject_cast(op)->config()); + }); + } + return pluginWidget; +} + +QString TouchScreen::get_plugin_name() { + return pluginName; +} + +int TouchScreen::get_plugin_type() { + return pluginType; +} + +void TouchScreen::plugin_delay_control() { + +} + +const QString TouchScreen::name() const { + + return QStringLiteral("touchscreen"); +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/touchscreen.h ukui-control-center-3.0.3/plugins/system/touchscreen/touchscreen.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/touchscreen.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/touchscreen.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,39 @@ +#ifndef TOUCHSCREEN_H +#define TOUCHSCREEN_H + +#include +#include +#include + +#include "shell/interface.h" +#include "widget.h" + + +namespace Ui { class TouchScreen; } + + +class TouchScreen : public QObject, CommonInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kycc.CommonInterface") + Q_INTERFACES(CommonInterface) + +public: + TouchScreen(); + ~TouchScreen(); + + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; + +private: + Ui::TouchScreen *ui; + QString pluginName; + int pluginType; + Widget * pluginWidget; + + bool mFirstLoad; +}; +#endif // TOUCHSCREEN_H diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/touchscreen.pro ukui-control-center-3.0.3/plugins/system/touchscreen/touchscreen.pro --- ukui-control-center-2.0.3/plugins/system/touchscreen/touchscreen.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/touchscreen.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,70 @@ + + +include(../../../env.pri) +include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) + +QT += widgets core gui quickwidgets quick xml KScreen KI18n KConfigCore KConfigWidgets KWidgetsAddons dbus +TEMPLATE = lib +CONFIG += c++11 link_pkgconfig plugin + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked 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 + +UI_DIR=./ + +# You can also make your code fail to compile if it uses 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 + +TARGET = $$qtLibraryTarget(touchscreen) +DESTDIR = ../.. +target.path = $${PLUGIN_INSTALL_DIRS} +INSTALLS += target + +INCLUDEPATH += \ + $$PROJECT_COMPONENTSOURCE \ + $$PROJECT_ROOTDIR \ + +LIBS += -L$$[QT_INSTALL_LIBS] -lgsettings-qt -ludev + +PKGCONFIG += gsettings-qt \ + gtk+-3.0 \ +# glib-2.0 \ + mate-desktop-2.0 \ + libudev \ + + +SOURCES += \ + declarative/qmloutput.cpp \ + declarative/qmloutputcomponent.cpp \ + declarative/qmlscreen.cpp \ + monitorinputtask.cpp \ + touchscreen.cpp \ + touchserialquery.cpp \ + utils.cpp \ + widget.cpp \ + xinputmanager.cpp + +HEADERS += \ + declarative/qmloutput.h \ + declarative/qmloutputcomponent.h \ + declarative/qmlscreen.h \ + monitorinputtask.h \ + touchscreen.h \ + touchserialquery.h \ + utils.h \ + widget.h \ + xinputmanager.h + +FORMS += \ + touchscreen.ui + +RESOURCES += \ + qml.qrc + + diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/touchscreen.ui ukui-control-center-3.0.3/plugins/system/touchscreen/touchscreen.ui --- ukui-control-center-2.0.3/plugins/system/touchscreen/touchscreen.ui 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/touchscreen.ui 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,301 @@ + + + TouchScreen + + + + 0 + 0 + 779 + 461 + + + + TouchScreen + + + + + + TouchScreen + + + + + + + + 550 + 50 + + + + + 16777215 + 50 + + + + QFrame::Box + + + + + + + 118 + 30 + + + + + 118 + 30 + + + + monitor + + + monitorCombo + + + + + + + + 200 + 0 + + + + + 16777215 + 30 + + + + false + + + + + + + + + + + + + + 550 + 50 + + + + + 16777215 + 50 + + + + QFrame::Box + + + + + + + 118 + 30 + + + + + 118 + 30 + + + + touch id + + + touchscreenCombo + + + + + + + + 200 + 0 + + + + + 16777215 + 30 + + + + + + + + + + + + + + + 550 + 50 + + + + + 16777215 + 50 + + + + QFrame::Box + + + QFrame::Plain + + + + + + true + + + + 118 + 30 + + + + + 118 + 30 + + + + input device + + + + + + + TextLabel + + + + + + + + + + + + + 120 + 36 + + + + + 16777215 + 36 + + + + Qt::LeftToRight + + + map + + + + + + + + 120 + 36 + + + + + 16777215 + 36 + + + + Qt::LeftToRight + + + calibration + + + + + + + Qt::Horizontal + + + + 268 + 20 + + + + + + + + + + 16 + + + + + No touch screen found + + + + + + + + + Qt::Vertical + + + + 558 + 150 + + + + + + + + monitorCombo + touchscreenCombo + mapButton + + + + diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/touchserialquery.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/touchserialquery.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/touchserialquery.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/touchserialquery.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,166 @@ +extern "C"{ +#include +#include +#include +#include +#include +} + +static int find_event_from_touchId(int pId ,char *_event,char *devnode,int max_len) +{ + Display *_dpy = XOpenDisplay(NULL); + int ret = -1; + if(NULL == _dpy || NULL == _event) + { + printf("[%s%d] NULL ptr. \n", __FUNCTION__, __LINE__); + return ret; + } + int i = 0; + int j = 0; + int num_devices = 0; + XDeviceInfo *pXDevs_info = NULL; + XDevice *pXDev = NULL; + unsigned char *cNode = NULL; + const char cName[] = "event"; + const char *cEvent = NULL; + int nprops = 0; + Atom *props = NULL; + char *name; + Atom act_type; + int act_format; + unsigned long nitems, bytes_after; + unsigned char *data; + + + pXDevs_info = XListInputDevices(_dpy, &num_devices); + for(i = 0; i < num_devices; i++) + { + pXDev = XOpenDevice(_dpy, pXDevs_info[i].id); + if (!pXDev) + { + printf("unable to open device '%s'\n", pXDevs_info[i].name); + continue; + } + + props = XListDeviceProperties(_dpy, pXDev, &nprops); + if (!props) + { + printf("Device '%s' does not report any properties.\n", pXDevs_info[i].name); + continue; + } + //printf("pId=%d, pXDevs_info[i].id=%d \n",pId,pXDevs_info[i].id); + if(pId == pXDevs_info[i].id) + { + for(j = 0; j < nprops; j++) + { + name = XGetAtomName(_dpy, props[j]); + if(0 != strcmp(name, "Device Node")) + { + continue; + } + XGetDeviceProperty(_dpy, pXDev, props[j], 0, 1000, False, + AnyPropertyType, &act_type, &act_format, + &nitems, &bytes_after, &data); + cNode = data; + } + if(NULL == cNode) + { + continue; + } + cEvent = strstr((const char*)cNode, cName); + if(NULL == cEvent) + { + continue; + } + strcpy(devnode,(const char*)cNode); + strncpy(_event, cEvent, max_len>0?(max_len-1):max_len); + //printf("cNode=%s,cEvent=%s,_event=%s\n",cNode,cEvent,_event); + ret = Success; + break; + } + + } + + return ret; +} + +static int find_serial_from_event(char *_name, char *_event, char *_serial, int max_len) +{ + int ret = -1; + if((NULL == _name) || (NULL == _event)) + { + printf("[%s%d] NULL ptr. \n", __FUNCTION__, __LINE__); + return ret; + } + + struct udev *udev; + struct udev_enumerate *enumerate; + struct udev_list_entry *devices, *dev_list_entry; + struct udev_device *dev; + + udev = udev_new(); + enumerate = udev_enumerate_new(udev); + + udev_enumerate_add_match_subsystem(enumerate, "input"); + udev_enumerate_scan_devices(enumerate); + devices = udev_enumerate_get_list_entry(enumerate); + + udev_list_entry_foreach(dev_list_entry, devices) + { + const char *pPath; + const char *pEvent; + const char cName[] = "event"; + pPath = udev_list_entry_get_name(dev_list_entry); + //printf("[%s%d] path: %s\n",__FUNCTION__, __LINE__, pPath); + dev = udev_device_new_from_syspath(udev, pPath); + //touchScreen is usb_device + dev = udev_device_get_parent_with_subsystem_devtype( + dev, + "usb", + "usb_device"); + if (!dev) + { + //printf("Unable to find parent usb device. \n"); + continue; + } + + const char *pProduct = udev_device_get_sysattr_value(dev,"product"); + pEvent = strstr(pPath, cName); + if(NULL == pEvent || (NULL == pProduct)) + { + continue; + } + //printf("pEvent=%s,_event=%s\n",pEvent,_event); + //printf("_name=%s,pProduct=%s\n",_name,pProduct); + char *ret=strstr(_name, pProduct); + if((NULL!=ret) && (0 == strcmp(_event, pEvent))) + { + const char *pSerial = udev_device_get_sysattr_value(dev, "serial"); + //printf(" _serial:%s\n pSerial: %s\n",_serial, pSerial); + if(NULL == pSerial) + { + continue; + } + strncpy(_serial, pSerial, max_len>0?(max_len-1):max_len); + ret = Success; + //printf(" _serial:%s\n pSerial: %s\n",_serial, pSerial); + break; + } + + udev_device_unref(dev); + } + udev_enumerate_unref(enumerate); + udev_unref(udev); + + return ret; +} + +int findSerialFromId(int touchid,char *touchname,char *_touchserial,char *devnode,int maxlen) +{ + char event[32]={0}; + int ret=find_event_from_touchId(touchid, event,devnode, 32); + ret=find_serial_from_event(touchname, event,_touchserial,maxlen); + if(!strcmp(_touchserial,"")) + strncpy(_touchserial,"kydefault",maxlen>0?(maxlen-1):maxlen); + return ret; +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/touchserialquery.h ukui-control-center-3.0.3/plugins/system/touchscreen/touchserialquery.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/touchserialquery.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/touchserialquery.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,6 @@ +#ifndef TOUCHSERIALQUERY_H +#define TOUCHSERIALQUERY_H + +int findSerialFromId(int touchid,char *touchname,char *_touchserial,char *devnode,int maxlen); + +#endif // TOUCHSERIALQUERY_H diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/utils.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/utils.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/utils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/utils.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,35 @@ +#include "utils.h" + +#include +#include + +QString Utils::outputName(const KScreen::OutputPtr& output) +{ + return outputName(output.data()); +} + +QString Utils::outputName(const KScreen::Output *output) +{ + + if (output->edid()) { + // The name will be "VendorName ModelName (ConnectorName)", + // but some components may be empty. + QString name; + if (!(output->edid()->vendor().isEmpty())) { + name = output->edid()->vendor() + QLatin1Char(' '); + } + if (!output->edid()->name().isEmpty()) { + name += output->edid()->name() + QLatin1Char(' '); + } + if (!name.trimmed().isEmpty()) { + //return name + QLatin1Char('(') + output->name() + QLatin1Char(')'); + return output->name(); + } + } + return output->name(); +} + +QString Utils::sizeToString(const QSize &size) +{ + return QStringLiteral("%1x%2").arg(size.width()).arg(size.height()); +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/utils.h ukui-control-center-3.0.3/plugins/system/touchscreen/utils.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/utils.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/utils.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,20 @@ +#ifndef UTILS_H +#define UTILS_H + +#include +#include + +#include +#include + +//获取显示器名字和ID类 +namespace Utils +{ + QString outputName(const KScreen::Output *output); + QString outputName(const KScreen::OutputPtr &output); + + QString sizeToString(const QSize &size); +} + + +#endif // UTILS_H diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/widget.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/widget.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/widget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/widget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,680 @@ +extern "C" { +#define MATE_DESKTOP_USE_UNSTABLE_API +#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 + +#include "declarative/qmloutput.h" +#include "declarative/qmlscreen.h" +#include "utils.h" +#include "ui_touchscreen.h" +#include "widget.h" + +#include "touchserialquery.h" +#include "xinputmanager.h" + + +#ifdef signals +#undef signals +#endif + +#define QML_PATH "kcm_kscreen/qml/" + +#define UKUI_CONTORLCENTER_PANEL_SCHEMAS "org.ukui.control-center.panel.plugins" + +#define FONT_RENDERING_DPI "org.ukui.SettingsDaemon.plugins.xsettings" + +#define ADVANCED_SCHEMAS "org.ukui.session.required-components" +#define ADVANCED_KEY "windowmanager" +#define TOUCHSCREEN_CFG_PATH "/.config/touchcfg.ini" + +Q_DECLARE_METATYPE(KScreen::OutputPtr) + +Widget::Widget(QWidget *parent) + : QWidget(parent) + , ui(new Ui::TouchScreen()) +{ + qRegisterMetaType(); + gdk_init(NULL, NULL); + + m_pXinputManager=new XinputManager; + + m_pXinputManager->start(); + + ui->setupUi(this); + ui->touchscreenLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); + +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) + oriApply = true; +#else + mOriApply = false; + +#endif + + initConnection(); + initui(); + loadQml(); +} + +void Widget::initui(){ + + if (findTouchScreen()){ + qDebug() << "Touch Screen Devices Available"; + ui->tipLabel->hide(); + ui->screenFrame->show(); + ui->touchscreenFrame->show(); + ui->deviceinfoFrame->show(); + ui->mapButton->show(); + ui->CalibrationButton->show(); + //initTouchScreenStatus(); + } else { + qDebug() << "Touch Screen Devices Unavailable"; + ui->screenFrame->hide(); + ui->touchscreenFrame->hide(); + ui->deviceinfoFrame->hide(); + ui->mapButton->hide(); + ui->CalibrationButton->hide(); + ui->tipLabel->show(); + } +} + +void Widget::loadQml() { + +} + +Widget::~Widget() { + //clearOutputIdentifiers(); + delete ui; + ui = nullptr; +} + +//接收触摸事件 +bool Widget::event(QEvent *event) +{ + + switch( event->type() ) + { + case QEvent::TouchBegin: + { + QTouchEvent* touch = static_cast(event); + QList touch_list = touch->touchPoints(); + touch_list.at(0).pos().x(); + touch_list.at(0).pos().y(); + event->accept(); + return true; + + } + + case QEvent::TouchUpdate: + { + QTouchEvent* touch = static_cast(event); + + if(touch->touchPointStates() & Qt::TouchPointPressed){ + //判断是否有触摸点处于TouchPointPressed或TouchPointMoved或TouchPointStationary或TouchPointReleased + } + event->accept(); + return true; + } + case QEvent::TouchEnd: + { + //QTouchEvent* touch = static_cast(event); + event->accept(); + return true; + } + default:break; + + } + return QWidget::event(event); +} + +void Widget::setConfig(const KScreen::ConfigPtr &config) { + if (mConfig) { + KScreen::ConfigMonitor::instance()->removeConfig(mConfig); + for (const KScreen::OutputPtr &output : mConfig->outputs()) { + output->disconnect(this); + } + mConfig->disconnect(this); + } + + mConfig = config; + mPrevConfig = config->clone(); + + KScreen::ConfigMonitor::instance()->addConfig(mConfig); + resetPrimaryCombo(); + resettouchscreenCombo(); + connect(mConfig.data(), &KScreen::Config::outputAdded, + this, &Widget::outputAdded); + connect(mConfig.data(), &KScreen::Config::outputRemoved, + this, &Widget::outputRemoved); + for (const KScreen::OutputPtr &output : mConfig->outputs()) { + outputAdded(output); + } +} + +KScreen::ConfigPtr Widget::currentConfig() const { + return mConfig; +} + + +void Widget::resetPrimaryCombo() { + + // Don't emit currentIndexChanged when resetting + bool blocked = ui->monitorCombo->blockSignals(true); + ui->monitorCombo->clear(); + ui->monitorCombo->blockSignals(blocked); + + if (!mConfig) { + return; + } + + for (auto &output: mConfig->outputs()) { + addOutputToMonitorCombo(output); + } +} + +void Widget::resettouchscreenCombo() { + + // Don't emit currentIndexChanged when resetting + bool blocked = ui->touchscreenCombo->blockSignals(true); + ui->touchscreenCombo->clear(); + ui->touchscreenCombo->blockSignals(blocked); + + findTouchScreen(); + +} + +void Widget::addOutputToMonitorCombo(const KScreen::OutputPtr &output) { + // 注释后让他显示全部屏幕下拉框 + if (!output->isConnected()) { + return; + } + + ui->monitorCombo->addItem(Utils::outputName(output), output->id()); + if (output->isPrimary()) { + Q_ASSERT(mConfig); + int lastIndex = ui->monitorCombo->count() - 1; + ui->monitorCombo->setCurrentIndex(lastIndex); + } +} + +//这里从屏幕点击来读取输出 +void Widget::slotFocusedOutputChanged(QMLOutput *output) { + + //读取屏幕点击选择下拉框 + Q_ASSERT(mConfig); + int index = output->outputPtr().isNull() ? 0 : ui->monitorCombo->findData(output->outputPtr()->id()); + if (index == -1 || index == ui->monitorCombo->currentIndex()) { + return; + } + ui->monitorCombo->setCurrentIndex(index); +} + +void Widget::slotOutputConnectedChanged() { + resetPrimaryCombo(); +} + +// FIXME: Copy-pasted from KDED's Serializer::findOutput() +KScreen::OutputPtr Widget::findOutput(const KScreen::ConfigPtr &config, const QVariantMap &info) { + KScreen::OutputList outputs = config->outputs(); + Q_FOREACH(const KScreen::OutputPtr &output, outputs) { + if (!output->isConnected()) { + continue; + } + + const QString outputId = (output->edid() && output->edid()->isValid()) ? output->edid()->hash() : output->name(); + if (outputId != info[QStringLiteral("id")].toString()) { + continue; + } + + QVariantMap posInfo = info[QStringLiteral("pos")].toMap(); + QPoint point(posInfo[QStringLiteral("x")].toInt(), posInfo[QStringLiteral("y")].toInt()); + output->setPos(point); + output->setPrimary(info[QStringLiteral("primary")].toBool()); + output->setEnabled(info[QStringLiteral("enabled")].toBool()); + output->setRotation(static_cast(info[QStringLiteral("rotation")].toInt())); + + QVariantMap modeInfo = info[QStringLiteral("mode")].toMap(); + QVariantMap modeSize = modeInfo[QStringLiteral("size")].toMap(); + QSize size(modeSize[QStringLiteral("width")].toInt(), modeSize[QStringLiteral("height")].toInt()); + + const KScreen::ModeList modes = output->modes(); + Q_FOREACH(const KScreen::ModePtr &mode, modes) { + if (mode->size() != size) { + continue; + } + if (QString::number(mode->refreshRate()) != modeInfo[QStringLiteral("refresh")].toString()) { + continue; + } + + output->setCurrentModeId(mode->id()); + break; + } + return output; + } + + return KScreen::OutputPtr(); +} + +void Widget::outputAdded(const KScreen::OutputPtr &output) { + connect(output.data(), &KScreen::Output::isConnectedChanged, + this, &Widget::slotOutputConnectedChanged); + //addOutputToMonitorCombo(output); +} + +void Widget::outputRemoved(int outputId) { + KScreen::OutputPtr output = mConfig->output(outputId); + if (!output.isNull()) { + output->disconnect(this); + } + + const int index = ui->monitorCombo->findData(outputId); + if (index == -1) { + return; + } + + if (index == ui->monitorCombo->currentIndex()) { + // We'll get the actual primary update signal eventually + // Don't emit currentIndexChanged + const bool blocked = ui->monitorCombo->blockSignals(true); + ui->monitorCombo->setCurrentIndex(0); + ui->monitorCombo->blockSignals(blocked); + } + ui->monitorCombo->removeItem(index); +} + +void Widget::touchscreenAdded() { + //initui(); + resettouchscreenCombo(); +} + +void Widget::touchscreenRemoved() { + //initui(); + resettouchscreenCombo(); + +} + +void Widget::primaryOutputSelected(int index) { + if (!mConfig) { + return; + } + + const KScreen::OutputPtr newPrimary = index == 0 ? KScreen::OutputPtr() : mConfig->output(ui->monitorCombo->itemData(index).toInt()); + if (newPrimary == mConfig->primaryOutput()) { + return; + } + + mConfig->setPrimaryOutput(newPrimary); + Q_EMIT changed(); +} + +void Widget::initConnection() { + + connect(ui->monitorCombo, static_cast(&QComboBox::currentIndexChanged), + this, &Widget::curOutoutChanged); + + connect(ui->touchscreenCombo, static_cast(&QComboBox::currentIndexChanged), + this, &Widget::curTouchScreenChanged); + + // TODO: Find out why adjusting the screen orientation does not take effect + connect(ui->mapButton, &QPushButton::clicked, this, [=]() { + maptooutput(); + }); + connect(ui->CalibrationButton, &QPushButton::clicked, this, [=]() { + CalibratTouch(); + }); + + connect(m_pXinputManager, &XinputManager::xinputSlaveAdded, this, &Widget::touchscreenAdded); + connect(m_pXinputManager, &XinputManager::xinputSlaveRemoved, this, &Widget::touchscreenRemoved); + +} + +void Widget::curOutoutChanged(int index) +{ + const KScreen::OutputPtr &output=mConfig->output(ui->monitorCombo->itemData(index).toInt()); + CurMonitorName = output.data()->name(); +} + +void Widget::curTouchScreenChanged(int index) +{ + int CurDevicesId; + CurTouchScreenName= ui->touchscreenCombo->itemText(ui->touchscreenCombo->currentIndex()); + CurDevicesId=ui->touchscreenCombo->itemText(ui->touchscreenCombo->currentIndex()).toInt(); + CurDevicesName=findTouchScreenName(CurDevicesId); + ui->touchnameContent->setText(CurDevicesName); +} + +//触摸映射 +void Widget::maptooutput() { + + Display *dpy=XOpenDisplay(NULL); + + QLibrary lib("/usr/lib/libkysset.so"); + + std::string touchstr = CurTouchScreenName.toStdString(); + std::string monitorstr = CurMonitorName.toStdString(); + const char* _CurTouchScreenName = touchstr.c_str(); + const char* _CurMonitorName = monitorstr.c_str(); + + if(lib.load()){ + + typedef int(*MapToOutput)(Display *,const char *,const char *); + MapToOutput _maptooutput=(MapToOutput)lib.resolve("MapToOutput"); + + if(!_maptooutput){ + qDebug("maptooutput resolve failed!\n"); + }else{ + int ret=_maptooutput(dpy,_CurTouchScreenName,_CurMonitorName); + if(!ret){ + + save(CurDevicesName,CurTouchScreenName,CurMonitorName); //保存映射关系 + + }else{ + qDebug("MapToOutput exe failed ! ret=%d\n",ret); + } + } + + lib.unload(); + + }else{ + qDebug("/usr/lib/libkysset.so not found!\n"); + } + + XCloseDisplay(dpy); + +} + +/*触摸校准 + * 通过dbus信号与kylin-xinput-calibration应用交互 + * 发送触摸校准事件并传递相关参数 +*/ +void Widget::CalibratTouch() { + + QDBusMessage msg =QDBusMessage::createSignal("/com/control/center/calibrator", "com.control.center.calibrator.interface", "calibratorEvent"); + msg<<(CurTouchScreenName+","+CurMonitorName); + QDBusConnection::systemBus().send(msg); +} + + +void Widget::addTouchScreenToTouchCombo(const QString touchscreenname ){ + + ui->touchscreenCombo->addItem(touchscreenname); +} + +//识别触摸屏设备 +bool Widget::findTouchScreen(){ + + int ndevices = 0; + bool retval=false; + CurTouchscreenNum=0; + Display *dpy = XOpenDisplay(NULL); + XIDeviceInfo *info = XIQueryDevice(dpy, XIAllDevices, &ndevices); + QString devicesid=""; + + for (int i = 0; i < ndevices; i++) + { + XIDeviceInfo* dev = &info[i]; + // 判断当前设备是不是触摸屏 + if(dev->use != XISlavePointer) continue; + if(!dev->enabled) continue; + for (int j = 0; j < dev->num_classes; j++) + { + if (dev->classes[j]->type == XITouchClass) + { + devicesid = tr("%1").arg(dev->deviceid); + addTouchScreenToTouchCombo(devicesid); + retval = true; + CurTouchscreenNum++; + } + } + } + + XIFreeDeviceInfo(info); + XCloseDisplay(dpy); + + return retval; +} + +//获取触摸屏名称 +QString Widget::findTouchScreenName(int devicesid){ + + int ndevices = 0; + Display *dpy = XOpenDisplay(NULL); + XIDeviceInfo *info = XIQueryDevice(dpy, XIAllDevices, &ndevices); + QString devicesname=""; + + for (int i = 0; i < ndevices; i++) + { + XIDeviceInfo* dev = &info[i]; + // 判断当前设备是不是触摸屏 + if(dev->use != XISlavePointer) continue; + if(!dev->enabled) continue; + for (int j = 0; j < dev->num_classes; j++) + { + if (dev->classes[j]->type == XITouchClass) + { + if(dev->deviceid==devicesid) + { + devicesname=dev->name; + return devicesname; + } + } + } + } +} + +/* + *判断映射关系保存时,屏幕是否已更换,不同屏幕通过touch serial区分 + *通过配置中保存的touch name及touch id获取对应touch serial + *然后用该touch serial与配置文件中的touch serial作比较,如果相同则触摸屏设备没有更换 + *否则清空配置文件重新记录 +*/ +int Widget::compareserial(int touchcount){ + + for(int i=1;i<=touchcount;i++) + { + QString str = QString::number(i); + QString mapoption = "MAP"+str; + QString serial = mapoption+"/serial"; + QString name = mapoption+"/name"; + QString id = mapoption+"/id"; + QString touchname = configIni->value(name).toString(); + QString touchserial = configIni->value(serial).toString(); + if( (touchname == "") && (touchserial == "") ) + continue; + int touchid = configIni->value(id).toInt(); + char _touchserial[32]={0}; + char _devnode[32]={0}; + std::string namestr = touchname.toStdString(); + char * _touchname=(char *)namestr.c_str(); + findSerialFromId(touchid,_touchname,_touchserial,_devnode,32); + //qDebug("_touchserial=%s\n",_touchserial); + QString Qtouchserial(_touchserial); + //qDebug("Qtouchserial=%s\n",Qtouchserial.toStdString().data()); + //qDebug("touchserial=%s\n",touchserial.toStdString().data()); + if(Qtouchserial!=touchserial){ + return -1; + } + } + + return Success; +} + +/* + *比较配置文件中同一触摸屏与显示器的映射关系 + *如不同则保存最新的映射关系 +*/ +int Widget::comparescreenname(QString _touchserial,QString _touchname,QString _screenname){ + + int touchcount=configIni->value("COUNT/num").toInt(); + + for(int i=1;i<=touchcount;i++) + { + QString str = QString::number(i); + QString mapoption = "MAP"+str; + QString serial = mapoption+"/serial"; + QString scrname = mapoption+"/scrname"; + QString name = mapoption+"/name"; + QString screenname = configIni->value(scrname).toString(); + QString touchserial = configIni->value(serial).toString(); + QString touchname = configIni->value(name).toString(); + + //qDebug("Qtouchserial=%s\n",screenname.toStdString().data()); + //qDebug("touchserial=%s\n",touchserial.toStdString().data()); + if((_touchserial==touchserial) && (_touchname==touchname)){ + if(screenname!=_screenname){ + configIni->remove(mapoption); + } + } + } + + return Success; +} + +//清空配置文件 +void Widget::cleanTouchConfig(int touchcount){ + + configIni->setValue("COUNT/num",0); + for(int i=1;i<=touchcount;i++) + { + QString str = QString::number(i); + QString mapoption = "MAP"+str; + configIni->remove(mapoption); + } +} + +//对配置文件进行预处理 +void Widget::initTouchConfig(QString touchserial,QString touchname,QString screenname) { + qdir = new QDir; + QString homepath = qdir->homePath(); + QString touchcfgpath = homepath + TOUCHSCREEN_CFG_PATH; //触摸屏映射关系配置文件路径 + configIni = new QSettings(touchcfgpath, QSettings::IniFormat); + + int touchcount = configIni->value("COUNT/num").toInt(); + int devicecount = configIni->value("COUNT/device_num").toInt(); + + if(!touchcount) + return ; + + if(devicecount != CurTouchscreenNum) + cleanTouchConfig(touchcount); + + if(1 == CurTouchscreenNum) + cleanTouchConfig(touchcount); + + if(compareserial(touchcount)!=0){ + + cleanTouchConfig(touchcount); + qDebug("compareserial cleanTouchConfig\n"); + } + comparescreenname(touchserial,touchname,screenname); +} + +/* + *判断配置文件中是否已有该触摸屏配置 + * 并返回相应状态 +*/ +bool Widget::Configserialisexit(QString touchserial, QString devnode ,QString touchname){ + + bool devicesisexit=0; + int touchcount=configIni->value("COUNT/num").toInt(); + + for(int i=0;i<=touchcount;i++){ + + QString numstr = QString::number(i); + QString mapoption = "MAP"+numstr; + QString serial = mapoption+"/serial"; + QString node = mapoption+"/devnode"; + QString name = mapoption+"/name"; + QString _touchserial = configIni->value(serial).toString(); + QString _devnode = configIni->value(node).toString(); + QString _touchname = configIni->value(name).toString(); + if(_touchserial == touchserial && _devnode == devnode && _touchname == touchname){ + devicesisexit=1; + break; + } + + } + if(devicesisexit) + return TRUE; + else + return FALSE; + +} + +//写入配置文件,保存触摸映射关系 +void Widget::writeTouchConfig(QString touchname,QString touchid,QString touchserial,QString devnode,QString screenname) { + + int touchcount = configIni->value("COUNT/num").toInt(); + bool devicesisexit = Configserialisexit(touchserial,devnode,touchname); + if(devicesisexit && touchcount) //如果配置文件中已存在该触摸屏配置,则不重复写入 + return; + + QString str = QString::number(touchcount+1); + QString mapoption = "MAP"+str; + QString serial = mapoption+"/serial"; + QString node = mapoption+"/devnode"; + QString name = mapoption+"/name"; + QString id = mapoption+"/id"; + QString scrname = mapoption+"/scrname"; + + configIni->setValue( "COUNT/num" ,touchcount+1); + configIni->setValue( "COUNT/device_num" ,CurTouchscreenNum); + configIni->setValue( name ,touchname); + configIni->setValue( id ,touchid); + configIni->setValue( serial ,touchserial); + configIni->setValue( node ,devnode); + configIni->setValue( scrname ,screenname); + +} + +/*保存触摸映射关系 + *对保存过程中的各种异常情况做处理 + *如避免重复保存、更换屏幕后删除原映射关系、多屏情况下各屏映射关系保存 + */ +void Widget::save(QString touchname,QString touchid,QString screenname) { + + char _touchserial[32]={0}; + char _devnode[32]={0}; + std::string str = touchname.toStdString(); + char * _touchname=(char *)str.c_str(); + findSerialFromId(touchid.toInt(),_touchname,_touchserial,_devnode,32); + + QString touchserial(_touchserial); + QString devnode(_devnode); + initTouchConfig(touchserial,touchname,screenname); //保存之前先对配置文集进行处理 + writeTouchConfig(touchname,touchid,touchserial,devnode,screenname);//将触摸映射关系写入配置文件 +} diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/widget.h ukui-control-center-3.0.3/plugins/system/touchscreen/widget.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/widget.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/widget.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,135 @@ +#ifndef WIDGET_H +#define WIDGET_H + +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + + + +class QLabel; +class QMLOutput; +class QMLScreen; +class PrimaryOutputCombo; + +class QPushButton; +class QComboBox; +class QStyledItemDelegate; +class XinputManager; + +namespace KScreen +{ +class ConfigOperation; +} + +namespace Ui { +class TouchScreen; +} + +class Widget : public QWidget +{ + Q_OBJECT + + public: + explicit Widget(QWidget *parent = nullptr); + ~Widget() override; + + void setConfig(const KScreen::ConfigPtr &config); + KScreen::ConfigPtr currentConfig() const; + + void slotFocusedOutputChangedNoParam(); + void initConnection(); + void initui(); + QString getScreenName(QString name = ""); + bool event(QEvent *event); + + + protected: + + + Q_SIGNALS: + void changed(); + + private Q_SLOTS: + + void slotFocusedOutputChanged(QMLOutput *output); + + void slotOutputConnectedChanged(); + + void outputAdded(const KScreen::OutputPtr &output); + void outputRemoved(int outputId); + void touchscreenAdded(); + void touchscreenRemoved(); + void curOutoutChanged(int index); + void curTouchScreenChanged(int index); + void primaryOutputSelected(int index); + + public Q_SLOTS: + void maptooutput(); + void CalibratTouch(); + + private: + void loadQml(); + void save(QString touchname,QString touchid,QString screenname); + void initTouchConfig(QString touchserial,QString touchname,QString screenname); + void writeTouchConfig(); + void writeTouchConfig(QString touchname,QString touchid,QString touchserial,QString devnode ,QString screenname); + bool Configserialisexit(QString touchserial,QString devnode,QString touchname); + void cleanTouchConfig(int touchcount); + int compareserial(int touchcount); + int comparescreenname(QString _touchserial,QString _touchname ,QString _screenname); + void resetPrimaryCombo(); + void resettouchscreenCombo(); + void addOutputToMonitorCombo(const KScreen::OutputPtr &output); + void addTouchScreenToTouchCombo(const QString touchscreenname ); + bool findTouchScreen(); + QString findTouchScreenName(int devicesid); + KScreen::OutputPtr findOutput(const KScreen::ConfigPtr &config, const QVariantMap &info); + + private: + Ui::TouchScreen *ui; + XinputManager *m_pXinputManager; + QMLScreen *mScreen = nullptr; + QSettings *configIni; + QDir *qdir; + QString CurTouchScreenName = ""; + QString CurMonitorName = ""; + QString CurDevicesName=""; + int CurTouchscreenNum; + +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) + KScreen::ConfigPtr mConfig ; + KScreen::ConfigPtr mPrevConfig ; + //这是outPutptr结果 + KScreen::OutputPtr res ; +#else + KScreen::ConfigPtr mConfig = nullptr; + KScreen::ConfigPtr mPrevConfig = nullptr; + // outPutptr结果 + KScreen::OutputPtr res = nullptr; +#endif + + QButtonGroup *singleButton; + + + bool mOriApply; + bool mConfigChanged = false; + bool mOnBattery = false; + bool m_blockChanges = false; + +}; + +#endif // WIDGET_H diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/xinputmanager.cpp ukui-control-center-3.0.3/plugins/system/touchscreen/xinputmanager.cpp --- ukui-control-center-2.0.3/plugins/system/touchscreen/xinputmanager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/xinputmanager.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,59 @@ + + +#include "xinputmanager.h" +#include +#include + + +XinputManager::XinputManager(QObject *parent): + QObject(parent) +{ + init(); +} + +void XinputManager::init() +{ + m_pMonitorInputTask = MonitorInputTask::instance(); + connect(this, &XinputManager::sigStartThread, m_pMonitorInputTask, &MonitorInputTask::StartManager); + connect(m_pMonitorInputTask, &MonitorInputTask::slaveAdded, this, &XinputManager::onSlaveAdded); + connect(m_pMonitorInputTask, &MonitorInputTask::slaveRemoved, this, &XinputManager::onSlaveRemoved); + + m_pManagerThread = new QThread(this); + m_pMonitorInputTask->moveToThread(m_pManagerThread); +} + +void XinputManager::start() +{ + qDebug() << "info: [XinputManager][start]: thread id = " << QThread::currentThreadId(); + m_runningMutex.lock(); + m_pMonitorInputTask->m_running = true; + m_runningMutex.unlock(); + + m_pManagerThread->start(); + Q_EMIT sigStartThread(); +} + +void XinputManager::stop() +{ + if(m_pManagerThread->isRunning()) + { + m_runningMutex.lock(); + m_pMonitorInputTask->m_running = false; + m_runningMutex.unlock(); + + m_pManagerThread->quit(); + } +} + +void XinputManager::onSlaveAdded(int device_id) +{ + qDebug() << "info: [XinputManager][onSlaveAdded]: Slave Device(id =" << device_id << ") Added!"; + Q_EMIT xinputSlaveAdded(device_id); +} + +void XinputManager::onSlaveRemoved(int device_id) +{ + qDebug() << "info: [XinputManager][onslaveRemoved]: Slave Device(id =" << device_id << ") Removed!"; + Q_EMIT xinputSlaveRemoved(device_id); +} + diff -Nru ukui-control-center-2.0.3/plugins/system/touchscreen/xinputmanager.h ukui-control-center-3.0.3/plugins/system/touchscreen/xinputmanager.h --- ukui-control-center-2.0.3/plugins/system/touchscreen/xinputmanager.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/system/touchscreen/xinputmanager.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,44 @@ + +#ifndef XINPUTMANAGER_H +#define XINPUTMANAGER_H +#include "monitorinputtask.h" +#include +#include + + + + +class XinputManager : public QObject +{ + Q_OBJECT +public: + XinputManager(QObject *parent = nullptr); + + void start(); + void stop(); + +Q_SIGNALS: + void sigStartThread(); + void xinputSlaveAdded(int device_id); + void xinputSlaveRemoved(int device_id); + +private: + void init(); + +private: + QThread *m_pManagerThread; + QMutex m_runningMutex; + MonitorInputTask *m_pMonitorInputTask; + +private Q_SLOTS: + void onSlaveAdded(int device_id); + void onSlaveRemoved(int device_id); + +private: + void SetPenRotation(int device_id); + +}; + + +#endif // XINPUTMANAGER_H + diff -Nru ukui-control-center-2.0.3/plugins/time-language/area/area.cpp ukui-control-center-3.0.3/plugins/time-language/area/area.cpp --- ukui-control-center-2.0.3/plugins/time-language/area/area.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/area/area.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -35,105 +35,138 @@ #define DATE_FORMATE_KEY "date" #define TIME_KEY "hoursystem" -const QVector CFormats{"zh_SG.UTF-8", "zh_CN.UTF-8", "lt_LT.UTF-8", "en_ZW.UTF-8", "en_ZM.UTF-8", - "en_ZA.UTF-8", "en_US.UTF-8", "en_SG.UTF-8", "en_PH.UTF-8", "en_NZ.UTF-8", - "en_NG.UTF-8", "en_IN.UTF-8", "en_IL.UTF-8", "en_IE.UTF-8", "en_HK.UTF-8", - "en_GB.UTF-8", "en_DK.UTF-8", "en_CA.UTF-8", "en_BW.UTF-8", "en_AU.UTF-8", - "en_AG.UTF-8", "af_ZA.UTF-8"}; - -Area::Area() +Area::Area() : mFirstLoad(true) { - ui = new Ui::Area; - pluginWidget = new QWidget; - pluginWidget->setAttribute(Qt::WA_DeleteOnClose); -// pluginWidget->setStyleSheet("background: #ffffff;"); - ui->setupUi(pluginWidget); - pluginName = tr("Area"); pluginType = DATETIME; +} - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title2Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->title3Label->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - +Area::~Area() +{ + if (!mFirstLoad) { + delete ui; + ui = nullptr; + delete m_itimer; + m_itimer = nullptr; + } +} - const QByteArray id(PANEL_GSCHEMAL); - - if(QGSettings::isSchemaInstalled(id)) { - m_gsettings = new QGSettings(id); - // 监听key的value是否发生了变化 - /* - connect(m_gsettings, &QGSettings::changed, this, [=] (const QString &key) { - initFormatData(); - }); - */ +void Area::cloudChangedSlot(const QString &key) { + if(key == "area") { + initComponent(); } +} - unsigned int uid = getuid(); - objpath = objpath +"/org/freedesktop/Accounts/User"+QString::number(uid); +void Area::connectToServer(){ + cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", + "/org/kylinssoclient/path", + "org.freedesktop.kylinssoclient.interface", + QDBusConnection::sessionBus()); + if (!cloudInterface->isValid()) + { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } +// QDBusConnection::sessionBus().connect(cloudInterface, SIGNAL(shortcutChanged()), this, SLOT(shortcutChangedSlot())); + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), QString("org.freedesktop.kylinssoclient.interface"), "keyChanged", this, SLOT(cloudChangedSlot(QString))); + // 将以后所有DBus调用的超时设置为 milliseconds + cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} +QString Area::get_plugin_name() { + return pluginName; +} - m_areaInterface = new QDBusInterface("org.freedesktop.Accounts", - objpath, - "org.freedesktop.Accounts.User", - QDBusConnection::systemBus()); +int Area::get_plugin_type() { + return pluginType; +} - m_itimer = new QTimer(); - m_itimer->start(1000); - connect(m_itimer,SIGNAL(timeout()), this, SLOT(datetime_update_slot())); +QWidget *Area::get_plugin_ui() { + if (mFirstLoad) { - initUI(); - initComponent(); - connect(ui->langcomboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(change_language_slot(int))); - connect(ui->countrycomboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(change_area_slot(int))); -// connect(ui->addlanBtn, SIGNAL(clicked()), this, SLOT(add_lan_btn_slot())); - connect(ui->chgformButton,SIGNAL(clicked()),this,SLOT(changeform_slot())); + mFirstLoad = false; - connect(ui->countrycomboBox, static_cast(&QComboBox::currentIndexChanged), - [=]{ - KMessageBox::information(ui->languageframe_2, tr("Need to log off to take effect")); - }); + ui = new Ui::Area; + pluginWidget = new QWidget; + pluginWidget->setAttribute(Qt::WA_DeleteOnClose); + ui->setupUi(pluginWidget); + + ui->countrylabel->adjustSize(); + ui->languagelabel->adjustSize(); + ui->formframe->adjustSize(); + + const QByteArray id(PANEL_GSCHEMAL); + + if(QGSettings::isSchemaInstalled(id)) { + m_gsettings = new QGSettings(id, QByteArray(), pluginWidget); + mDateFormat = m_gsettings->get(DATE_FORMATE_KEY).toString(); + connect(m_gsettings, &QGSettings::changed, this, [=](QString key) { + mDateFormat = m_gsettings->get(DATE_FORMATE_KEY).toString(); + if ("hoursystem" == key) { + initFormatData(); + } + }); + } -} + unsigned int uid = getuid(); + objpath = objpath +"/org/freedesktop/Accounts/User"+QString::number(uid); -Area::~Area() -{ - delete ui; - delete m_itimer; -} -QString Area::get_plugin_name(){ - return pluginName; + m_areaInterface = new QDBusInterface("org.freedesktop.Accounts", + objpath, + "org.freedesktop.Accounts.User", + QDBusConnection::systemBus()); + + m_itimer = new QTimer(); + m_itimer->start(1000); + + + initTitleLabel(); + initUI(); + initComponent(); + connectToServer(); + + connect(m_itimer,SIGNAL(timeout()), this, SLOT(datetime_update_slot())); + connect(ui->langcomboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(change_language_slot(int))); + connect(ui->countrycomboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(change_area_slot(int))); + connect(ui->chgformButton,SIGNAL(clicked()),this,SLOT(changeform_slot())); + connect(ui->countrycomboBox, static_cast(&QComboBox::currentIndexChanged), + [=]{ + KMessageBox::information(ui->languageframe_2, tr("Need to log off to take effect")); + }); + } + return pluginWidget; } -int Area::get_plugin_type(){ - return pluginType; -} +void Area::plugin_delay_control() { -QWidget *Area::get_plugin_ui(){ - return pluginWidget; } -void Area::plugin_delay_control(){ +const QString Area::name() const { + return QStringLiteral("area"); } -void Area::run_external_app_slot(){ +void Area::run_external_app_slot() { QString cmd = "gnome-language-selector"; QProcess process(this); process.startDetached(cmd); } -void Area::initUI(){ +void Area::initUI() { + //~ contents_path /area/current area ui->titleLabel->setText(tr("current area")); - ui->countrylabel->setText(tr("display format area")); - ui->title2Label->setText(tr("format of area")); + ui->countrylabel->setText(tr("country")); + //~ contents_path /area/regional format + ui->title2Label->setText(tr("regional format")); ui->calendarlabel->setText(tr("calendar")); ui->weeklabel->setText(tr("first day of week")); ui->datelabel->setText(tr("date")); ui->timelabel->setText(tr("time")); ui->chgformButton->setText(tr("change format of data")); + //~ contents_path /area/first language ui->title3Label->setText(tr("first language")); ui->languagelabel->setText(tr("system language")); @@ -154,26 +187,16 @@ QLabel * textLabel = new QLabel(tr("Add main language")); QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); iconLabel->setPixmap(pixgray); + iconLabel->setProperty("useIconHighlightEffect", true); + iconLabel->setProperty("iconHighlightEffectMode", 1); + addLyt->addWidget(iconLabel); addLyt->addWidget(textLabel); addLyt->addStretch(); addWgt->setLayout(addLyt); - // 悬浮改变Widget状态 - connect(addWgt, &HoverWidget::enterWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "white", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(base);"); - - }); - // 还原状态 - connect(addWgt, &HoverWidget::leaveWidget, this, [=](QString mname){ - QPixmap pixgray = ImageUtil::loadSvg(":/img/titlebar/add.svg", "black", 12); - iconLabel->setPixmap(pixgray); - textLabel->setStyleSheet("color: palette(windowText);"); - }); - - connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname){ + connect(addWgt, &HoverWidget::widgetClicked, this, [=](QString mname) { + Q_UNUSED(mname); add_lan_btn_slot(); }); @@ -183,8 +206,8 @@ void Area::initComponent() { QStringList res = getUserDefaultLanguage(); QString lang = res.at(1); - int langIndex = lang.split(':').at(0) == "en_US" ? 0 : 1;; - int formatIndex = res.at(0) == "en_US.UTF-8" ? 0 : 1; + int langIndex = lang.split(':').at(0) == "zh_CN" ? 1 : 0; + int formatIndex = res.at(0) == "zh_CN.UTF-8" ? 1 : 0; ui->langcomboBox->setCurrentIndex(langIndex); ui->countrycomboBox->setCurrentIndex(formatIndex); @@ -223,8 +246,7 @@ QDateTime current = QDateTime::currentDateTime(); QString currentsecStr ; - QString dateFormat = m_gsettings->get(DATE_FORMATE_KEY).toString(); - if ("cn" == dateFormat) { + if ("cn" == mDateFormat) { currentsecStr = current.toString("yyyy/MM/dd ");; } else { currentsecStr = current.toString("yyyy-MM-dd "); @@ -234,7 +256,7 @@ this->hourformat = m_gsettings->get(TIME_KEY).toString(); } -void Area::change_language_slot(int index){ +void Area::change_language_slot(int index) { QDBusReply res; switch (index) { case 0: @@ -245,10 +267,7 @@ break; } -// if (index == ui->countrycomboBox->currentIndex()) { - KMessageBox::information(ui->languageframe, tr("Need to log off to take effect")); -// } -// ui->countrycomboBox->setCurrentIndex(index); + KMessageBox::information(ui->languageframe, tr("Need to log off to take effect")); } void Area::change_area_slot(int index) { @@ -273,6 +292,14 @@ timeStr = current.toString("AP hh: mm : ss"); } ui->timelabelshow->setText(timeStr); + + QString currentsecStr; + if ("cn" == mDateFormat) { + currentsecStr = current.toString("yyyy/MM/dd ");; + } else { + currentsecStr = current.toString("yyyy-MM-dd "); + } + ui->datelabelshow->setText(currentsecStr); } void Area::add_lan_btn_slot() { @@ -312,35 +339,31 @@ } } +void Area::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->titleLabel->setFont(font); + ui->title2Label->setFont(font); + ui->title3Label->setFont(font); +} + QStringList Area::getUserDefaultLanguage() { - int pos = 0; QString formats; QString language; - QStringList filestr; QStringList result; - QString fname = getenv("HOME"); - fname += "/.pam_environment"; - filestr = this->readFile(fname); -// qDebug()<<"result is------>"< > reply = iproperty->call("GetAll", "org.freedesktop.Accounts.User"); + QDBusInterface iproperty("org.freedesktop.Accounts", + objpath, + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus()); + QDBusReply > reply = iproperty.call("GetAll", "org.freedesktop.Accounts.User"); if (reply.isValid()){ QMap propertyMap; propertyMap = reply.value(); - formats = propertyMap.find("FormatsLocale").value().toString(); - if(language.isEmpty()) { + if (propertyMap.keys().contains("FormatsLocale")) { + formats = propertyMap.find("FormatsLocale").value().toString(); + } + if(language.isEmpty() && propertyMap.keys().contains("Language")) { language = propertyMap.find("Language").value().toString(); } } else { @@ -348,6 +371,5 @@ } result.append(formats); result.append(language); -// qDebug()<<"result is---------->"< + /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ @@ -62,37 +63,40 @@ Area(); ~Area(); - QString get_plugin_name() Q_DECL_OVERRIDE; - int get_plugin_type() Q_DECL_OVERRIDE; - QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; QStringList readFile(const QString& filePath); private: + void initTitleLabel(); void initUI(); void initComponent(); QStringList getUserDefaultLanguage(); + void connectToServer(); private: Ui::Area *ui; int pluginType; - QString qss; QString objpath; QString pluginName; QString hourformat; + QString mDateFormat; QWidget * pluginWidget; QDBusInterface *m_areaInterface; + QGSettings *m_gsettings = nullptr; + QTimer *m_itimer = nullptr; + HoverWidget *addWgt; + QDBusInterface *cloudInterface; - QGSettings *m_gsettings = nullptr; - - QTimer *m_itimer = nullptr; - - HoverWidget *addWgt; + bool mFirstLoad; private slots: void initFormatData(); @@ -102,6 +106,7 @@ void datetime_update_slot(); void add_lan_btn_slot(); void changeform_slot(); + void cloudChangedSlot(const QString &key); }; #endif // AREA_H diff -Nru ukui-control-center-2.0.3/plugins/time-language/area/area.pro ukui-control-center-3.0.3/plugins/time-language/area/area.pro --- ukui-control-center-2.0.3/plugins/time-language/area/area.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/area/area.pro 2021-04-14 01:27:20.000000000 +0000 @@ -13,6 +13,7 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/hoverwidget.pri) include($$PROJECT_COMPONENTSOURCE/imageutil.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) TARGET = $$qtLibraryTarget(area) DESTDIR = ../.. diff -Nru ukui-control-center-2.0.3/plugins/time-language/area/area.ui ukui-control-center-3.0.3/plugins/time-language/area/area.ui --- ukui-control-center-2.0.3/plugins/time-language/area/area.ui 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/area/area.ui 2021-04-14 01:27:20.000000000 +0000 @@ -55,6 +55,22 @@ + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 12 + + + + + @@ -97,13 +113,13 @@ - 209 + 0 0 - 209 + 16777215 16777215 @@ -113,16 +129,29 @@ + + + Qt::Vertical + + + + 20 + 40 + + + + + - + 0 0 - 291 + 0 0 @@ -149,7 +178,7 @@ 32 - 16 + 12 @@ -187,22 +216,31 @@ + + + 0 + 0 + + 550 - 118 + 0 960 - 118 + 16777215 QFrame::Box + + 6 + 20 @@ -210,6 +248,12 @@ + + + 0 + 0 + + 120 @@ -229,6 +273,12 @@ + + + 0 + 0 + + lunar @@ -240,16 +290,22 @@ + + + 0 + 0 + + - 110 - 15 + 120 + 0 - 120 - 15 + 16777215 + 16777215 @@ -270,16 +326,22 @@ + + + 0 + 0 + + 120 - 15 + 0 120 - 15 + 16777215 @@ -300,16 +362,22 @@ + + + 0 + 0 + + 120 - 15 + 0 120 - 15 + 16777215 @@ -339,13 +407,13 @@ 120 - 32 + 35 1000 - 32 + 35 @@ -377,7 +445,7 @@ 9 - 6 + 12 @@ -394,7 +462,7 @@ - TextLabel + first language @@ -416,7 +484,7 @@ - 0 + 16 @@ -461,32 +529,45 @@ - 209 + 0 0 - 209 + 16777215 16777215 - TextLabel + system language + + + Qt::Vertical + + + + 20 + 40 + + + + + - + 0 0 - 291 + 0 0 @@ -504,42 +585,6 @@ - - - - - 0 - 0 - - - - - 550 - 60 - - - - - 960 - 50 - - - - - 20 - - - 6 - - - 6 - - - 10 - - - - diff -Nru ukui-control-center-2.0.3/plugins/time-language/area/dataformat.cpp ukui-control-center-3.0.3/plugins/time-language/area/dataformat.cpp --- ukui-control-center-2.0.3/plugins/time-language/area/dataformat.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/area/dataformat.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -1,5 +1,6 @@ #include "dataformat.h" #include "ui_dataformat.h" +#include "CloseButton/closebutton.h" #include #include @@ -21,9 +22,6 @@ setAttribute(Qt::WA_TranslucentBackground); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); QByteArray id(PANEL_GSCHEMAL); if(QGSettings::isSchemaInstalled(id)) { @@ -40,17 +38,13 @@ DataFormat::~DataFormat() { delete ui; + ui = nullptr; delete m_itimer; + m_itimer = nullptr; } -void DataFormat::initUi() { - -// ui->frame->setStyleSheet("QFrame{background: #ffffff;}"); - //关闭按钮在右上角,窗体radius 6px,所以按钮只得6px - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); +void DataFormat::initUi() { ui->calendarLabel->setText(tr("calendar")); ui->dayLabel->setText(tr("first day of week")); @@ -90,11 +84,6 @@ connect(m_itimer,SIGNAL(timeout()), this, SLOT(datetime_update_slot())); connect(ui->confirmButton, SIGNAL(clicked(bool)), SLOT(confirm_btn_slot())); connect(ui->cancelButton, SIGNAL(clicked()), SLOT(close())); - connect(ui->closeBtn, &QPushButton::clicked, [=](bool checked){ - Q_UNUSED(checked) - close(); - }); - } void DataFormat::initComponent() { @@ -214,6 +203,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); diff -Nru ukui-control-center-2.0.3/plugins/time-language/area/dataformat.h ukui-control-center-3.0.3/plugins/time-language/area/dataformat.h --- ukui-control-center-2.0.3/plugins/time-language/area/dataformat.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/area/dataformat.h 2021-04-14 01:27:20.000000000 +0000 @@ -44,7 +44,6 @@ private slots: void datetime_update_slot(); void confirm_btn_slot(); - }; #endif // DATAFORMAT_H diff -Nru ukui-control-center-2.0.3/plugins/time-language/area/dataformat.ui ukui-control-center-3.0.3/plugins/time-language/area/dataformat.ui --- ukui-control-center-2.0.3/plugins/time-language/area/dataformat.ui 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/area/dataformat.ui 2021-04-14 01:27:20.000000000 +0000 @@ -6,8 +6,8 @@ 0 0 - 400 - 440 + 436 + 436 @@ -18,14 +18,14 @@ - 400 - 440 + 436 + 436 - 400 - 440 + 436 + 436 @@ -49,6 +49,12 @@ + + + 0 + 0 + + QFrame::NoFrame @@ -56,8 +62,20 @@ QFrame::Raised + + 22 + + + 32 + + + 26 + + + 20 + 8 @@ -65,45 +83,6 @@ 8 - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - - - - - - 16 - - @@ -128,6 +107,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -149,19 +141,19 @@ 1 - 16 + 20 - 336 + 350 50 - 336 + 350 50 @@ -185,7 +177,7 @@ - 90 + 125 32 @@ -232,13 +224,13 @@ - 336 + 350 50 - 336 + 350 50 @@ -262,7 +254,7 @@ - 90 + 125 16777215 @@ -309,13 +301,13 @@ - 336 + 350 50 - 336 + 350 50 @@ -339,7 +331,7 @@ - 90 + 125 16777215 @@ -386,13 +378,13 @@ - 336 + 350 50 - 336 + 350 50 @@ -416,7 +408,7 @@ - 90 + 125 16777215 @@ -463,7 +455,7 @@ 17 - 34 + 16 @@ -484,11 +476,17 @@ - 345 + 16777215 50 + + 9 + + + 24 + @@ -496,7 +494,7 @@ - 40 + 20 20 @@ -507,13 +505,13 @@ 120 - 30 + 36 120 - 30 + 36 @@ -532,13 +530,13 @@ 120 - 30 + 36 120 - 30 + 36 @@ -557,7 +555,7 @@ 17 - 34 + 24 diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/changtime.cpp ukui-control-center-3.0.3/plugins/time-language/datetime/changtime.cpp --- ukui-control-center-2.0.3/plugins/time-language/datetime/changtime.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/changtime.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -19,67 +19,46 @@ */ #include "changtime.h" #include "ui_changtime.h" +#include "CloseButton/closebutton.h" #include +#include +#include - -const int BEGINYEAR = 1900; +const int BEGINYEAR = 1971; const int BEGINMD = 1; extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); -ChangtimeDialog::ChangtimeDialog(bool hour,QWidget *parent) :m_isEFHour(hour), - QDialog(parent), - ui(new Ui::changtimedialog) -{ - -// QFile QssFile("://combox.qss"); -// QssFile.open(QFile::ReadOnly); - -// if (QssFile.isOpen()){ -// qss = QLatin1String(QssFile.readAll()); -// QssFile.close(); -// } +const QStringList kmonthName { QObject::tr("January"), QObject::tr("February"), QObject::tr("March"), QObject::tr("April"), QObject::tr("May"), QObject::tr("June"), + QObject::tr("July"), QObject::tr("August"), QObject::tr("September"), QObject::tr("October"), QObject::tr("Novermber"), QObject::tr("December")}; +ChangtimeDialog::ChangtimeDialog(bool hour,QWidget *parent) : QDialog(parent), + ui(new Ui::changtimedialog), + m_isEFHour(hour) +{ ui->setupUi(this); setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); setAttribute(Qt::WA_TranslucentBackground); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - -// ui->frame->setStyleSheet("QFrame{background: #ffffff; border: none; border-radius: 6px;}"); - //关闭按钮在右上角,窗体radius 6px,所以按钮只得6px - ui->closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); -// ui->closeBtn->setStyleSheet("QPushButton#closeBtn{background: #ffffff; border: none; border-radius: 6px;}" -// "QPushButton:hover:!pressed#closeBtn{background: #FA6056; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}" -// "QPushButton:hover:pressed#closeBtn{background: #E54A50; border: none; border-top-left-radius: 2px; border-top-right-radius: 6px; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px;}"); m_datetimeInterface = new QDBusInterface("org.freedesktop.timedate1", "/org/freedesktop/timedate1", "org.freedesktop.timedate1", - QDBusConnection::systemBus()); + QDBusConnection::systemBus(), this); initUi(); initStatus(); m_chtimer = new QTimer(); m_chtimer->start(1000); - connect(m_chtimer, SIGNAL(timeout()), this, SLOT(datetimeUpdateSlot())); - + connect(m_chtimer, SIGNAL(timeout()), this, SLOT(datetimeUpdateSlot())); connect(ui->monthcomboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(dayUpdateSlot())); connect(ui->yearcomboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(dayUpdateSlot())); connect(ui->cancelButton,SIGNAL(clicked()),this,SLOT(close())); connect(ui->confirmButton,SIGNAL(clicked()),this,SLOT(changtimeApplySlot())); - connect(ui->closeBtn, &QPushButton::clicked, [=](bool checked){ - Q_UNUSED(checked) - close(); - }); } @@ -87,7 +66,7 @@ { m_chtimer->stop(); delete ui; - delete m_datetimeInterface; + ui = nullptr; } @@ -97,7 +76,6 @@ QString currentminStr = current.toString("mm"); QString currentsecStr = current.toString("ss"); - ui->seccomboBox->setCurrentIndex(currentsecStr.toInt()); if (currentsecStr.toInt() == 0) { ui->mincomboBox->setCurrentIndex(currentminStr.toInt()); } @@ -153,7 +131,6 @@ } void ChangtimeDialog::changtimeApplySlot(){ -// qDebug()<<"时间应用------------》"<yearcomboBox->currentIndex() + BEGINYEAR; int month = ui->monthcomboBox->currentIndex() + BEGINMD; int day = ui->daycomboBox->currentIndex() + BEGINMD; @@ -170,47 +147,38 @@ QTime tmptime(hour, ui->mincomboBox->currentIndex(),ui->seccomboBox->currentIndex()); QDateTime setdt(tmpdate,tmptime); -// qDebug()<<"tmp time and hour is-->"<call("SetNTP", false, true);//先关闭网络同步 +// for(int i=0; i < 2; i++){ +// m_datetimeInterface->call("SetNTP", false, true);//先关闭网络同步 #if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) m_datetimeInterface->call("SetTime", QVariant::fromValue(setdt.toMSecsSinceEpoch() / 1000 * G_TIME_SPAN_SECOND), false, true); #else m_datetimeInterface->call("SetTime", QVariant::fromValue(setdt.toSecsSinceEpoch() * G_TIME_SPAN_SECOND), false, true); #endif - } +// } this->close(); } void ChangtimeDialog::initUi(){ -// this->setStyleSheet("background: #ffffff;"); ui->timelabel->setText(tr("time")); -// ui->timelabel->setStyleSheet("QLabel#timelabel{background: #F4F4F4;}"); - ui->yearlabel->setText(tr("year")); -// ui->yearlabel->setStyleSheet("QLabel#yearlabel{background: #F4F4F4;}"); - ui->monthlabel->setText(tr("month")); -// ui->monthlabel->setStyleSheet("QLabel#monthlabel{background: #F4F4F4;}"); - ui->daylabel->setText(tr("day")); -// ui->daylabel->setStyleSheet("QLabel#daylabel{background: #F4F4F4;}"); hourComboxSetup(); - for(int m = 0; m < 60; m++){ + for (int m = 0; m < 60; m++) { ui->mincomboBox->addItem(QString::number(m)); } - for(int s = 0; s < 60; s++){ + for (int s = 0; s < 60; s++) { ui->seccomboBox->addItem(QString::number(s)); } - for(int year = 1900; year <= 2100; year++){ - ui->yearcomboBox->addItem(QString::number(year)+tr("year")); + for (int year = 1971; year <= 2035; year++) { + ui->yearcomboBox->addItem(QString::number(year)/*+tr("year")*/); } - for(int month = 1; month <= 12; month++){ - ui->monthcomboBox->addItem(QString::number(month)+tr("month")); + for (int month = 1; month <= 12; month++) { + ui->monthcomboBox->addItem(kmonthName.at(month - 1)/*+tr("month")*/); } ymdComboxSetup(); } @@ -222,14 +190,6 @@ for (int h = 0; h < 24; h++){ ui->hourcomboBox->addItem(QString::number(h)); } - -// if (this->m_isEFHour){ -// for (int h = 0; h < 24; h++) -// ui->hourcomboBox->addItem(QString::number(h)); -// } else { -// for (int h = 1; h <= 12; h++) -// ui->hourcomboBox->addItem(QString::number(h)); -// } } @@ -256,10 +216,8 @@ //if date formate is 24 hour if(this->m_isEFHour) { -// ui->hourcomboBox->setItemText(currenthourStr.toInt()); ui->hourcomboBox->setCurrentIndex(currenthourStr.toInt()); } else { -// qDebug()<<"currenthourStr.toInt() is------------->"< 12) { ui->hourcomboBox->setCurrentIndex(currenthourStr.toInt() - 12); } else { @@ -284,6 +242,7 @@ pixmapPainter.setRenderHint(QPainter::Antialiasing); pixmapPainter.setPen(Qt::transparent); pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); pixmapPainter.drawPath(rectPath); pixmapPainter.end(); diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/changtime.h ukui-control-center-3.0.3/plugins/time-language/datetime/changtime.h --- ukui-control-center-2.0.3/plugins/time-language/datetime/changtime.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/changtime.h 2021-04-14 01:27:20.000000000 +0000 @@ -52,8 +52,7 @@ class changtimedialog; } -class ChangtimeDialog : public QDialog -{ +class ChangtimeDialog : public QDialog { Q_OBJECT public: @@ -75,15 +74,11 @@ QGSettings * m_formatsettings = nullptr; QDBusInterface *m_datetimeInterface = nullptr; bool m_isEFHour; //24小时制 - QString qss; - private slots: void datetimeUpdateSlot(); void dayUpdateSlot(); void changtimeApplySlot(); - - }; #endif // CHANGTIME_H diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/changtime.ui ukui-control-center-3.0.3/plugins/time-language/datetime/changtime.ui --- ukui-control-center-2.0.3/plugins/time-language/datetime/changtime.ui 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/changtime.ui 2021-04-14 01:27:20.000000000 +0000 @@ -6,8 +6,8 @@ 0 0 - 401 - 440 + 421 + 425 @@ -18,14 +18,14 @@ - 401 - 440 + 421 + 412 - 420 - 440 + 421 + 425 @@ -49,18 +49,39 @@ + + + 0 + 0 + + QFrame::NoFrame QFrame::Raised + + 0 + + 24 + + + 16 + + 9 + + 0 + + + 20 + 8 @@ -68,45 +89,6 @@ 8 - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - - - - - - 20 - - @@ -131,6 +113,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -194,7 +189,7 @@ - 38 + 50 16777215 @@ -219,7 +214,7 @@ - 83 + 84 16777215 @@ -244,7 +239,7 @@ - 80 + 84 32 @@ -266,7 +261,7 @@ - 80 + 84 32 @@ -315,7 +310,7 @@ - 36 + 50 16777215 @@ -392,7 +387,7 @@ - 36 + 50 16777215 @@ -466,7 +461,7 @@ - 36 + 50 16777215 @@ -510,7 +505,7 @@ 17 - 34 + 14 @@ -531,11 +526,14 @@ - 345 + 16777215 50 + + 32 + @@ -554,7 +552,7 @@ 120 - 30 + 36 @@ -579,7 +577,7 @@ 120 - 30 + 36 @@ -604,7 +602,7 @@ 17 - 34 + 20 diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/datetime.cpp ukui-control-center-3.0.3/plugins/time-language/datetime/datetime.cpp --- ukui-control-center-2.0.3/plugins/time-language/datetime/datetime.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/datetime.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -27,158 +27,166 @@ #include #include +#include +#include +#include const char kTimezoneDomain[] = "installer-timezones"; -const char kDefaultLocale[] = "en_US.UTF-8"; +const char kDefaultLocale[] = "en_US.UTF-8"; -#define FORMAT_SCHEMA "org.ukui.control-center.panel.plugins" -#define TIME_FORMAT_KEY "hoursystem" -#define DATE_KEY "date" +const QString kcnBj = "北京"; +const QString kenBj = "Asia/Beijing"; -DateTime::DateTime() +#define FORMAT_SCHEMA "org.ukui.control-center.panel.plugins" +#define TIME_FORMAT_KEY "hoursystem" +#define DATE_KEY "date" +#define SYNC_TIME_KEY "synctime" + +volatile bool syncThreadFlag = false; + +DateTime::DateTime() : mFirstLoad(true) { ui = new Ui::DateTime; pluginWidget = new QWidget; pluginWidget->setAttribute(Qt::WA_DeleteOnClose); -// pluginWidget->setStyleSheet("background: #ffffff;"); ui->setupUi(pluginWidget); - - pluginName = tr("Datetime"); + ui->infoFrame->setFrameShape(QFrame::Shape::Box); + pluginName = tr("Date"); pluginType = DATETIME; - ui->titleLabel->setStyleSheet("QLabel{font-size: 18px; color: palette(windowText);}"); - ui->timeClockLable->setStyleSheet("QLabel{color: palette(windowText);}"); - -// qDebug()<<"进入时间日期UI------------------》"<start(1000); - connect(m_itimer,SIGNAL(timeout()), this, SLOT(datetime_update_slot())); - - m_formTimeBtn = new SwitchButton; - m_formTimeLabel = new QLabel(tr("24-hour clock")); - - - //初始化gsettings - const QByteArray id(FORMAT_SCHEMA); - if(QGSettings::isSchemaInstalled(id)) { - const QByteArray id(FORMAT_SCHEMA); - m_formatsettings = new QGSettings(id); - } - connectGSetting(); - //初始化dbus - m_datetimeiface = new QDBusInterface("org.freedesktop.timedate1", - "/org/freedesktop/timedate1", - "org.freedesktop.timedate1", - QDBusConnection::systemBus()); - - m_datetimeiproperties = new QDBusInterface("org.freedesktop.timedate1", - "/org/freedesktop/timedate1", - "org.freedesktop.DBus.Properties", - QDBusConnection::systemBus()); - - - component_init(); - status_init(); - - connect(ui->chgtimebtn,SIGNAL(clicked()),this,SLOT(changetime_slot())); - connect(ui->chgzonebtn,SIGNAL(clicked()),this,SLOT(changezone_slot())); - connect(m_formTimeBtn, SIGNAL(checkedChanged(bool)),this,SLOT(time_format_clicked_slot(bool))); - connect(m_timezone, &TimeZoneChooser::confirmed, this, [this] (const QString &timezone) { -// qDebug()<<"timezone is---------->"<hide(); - const QString locale = QLocale::system().name(); - QString localizedTimezone = m_zoneinfo->getLocalTimezoneName(timezone, locale); - ui->timezoneLabel->setText(localizedTimezone); - }); - connect(ui->synsystimeBtn,SIGNAL(clicked()),this,SLOT(rsync_with_network_slot())); } DateTime::~DateTime() { - delete ui; - delete m_formatsettings; - delete m_datetimeiface; - delete m_datetimeiproperties; + if (!mFirstLoad) { + delete ui; + delete m_zoneinfo; + ui = nullptr; + m_zoneinfo = nullptr; + } } -QString DateTime::get_plugin_name(){ +QString DateTime::get_plugin_name() +{ return pluginName; } -int DateTime::get_plugin_type(){ +int DateTime::get_plugin_type() +{ return pluginType; } -QWidget *DateTime::get_plugin_ui(){ - return pluginWidget; -} +QWidget *DateTime::get_plugin_ui() +{ -void DateTime::plugin_delay_control(){ + if (mFirstLoad) { + mFirstLoad = false; + + initUI(); + initTitleLabel(); + initStatus(); + initComponent(); + initConnect(); + connectToServer(); + } + return pluginWidget; } -void DateTime::component_init(){ - ui->titleLabel->setContentsMargins(0,0,0,16); - ui->timeClockLable->setContentsMargins(0,0,0,16); +void DateTime::plugin_delay_control() +{ -// ui->synsystimeBtn->setStyleSheet("QPushButton{background-color:#E9E9E9;border-radius:4px}" -// "QPushButton:hover{background-color: #3D6BE5;color:white;};border-radius:4px"); +} - ui->synsystimeBtn->setText(tr("Sync system time")); +const QString DateTime::name() const +{ -// ui->chgtimebtn->setStyleSheet("QPushButton{background-color:#E5E7E9;border-radius:4px}" -// "QPushButton:hover{background-color: #3D6BE5;color:white;};border-radius:4px"); + return QStringLiteral("date"); +} - ui->chgtimebtn->setText(tr("Change time")); +void DateTime::initTitleLabel() +{ + QGSettings *m_fontSetting = new QGSettings("org.ukui.style"); + QFont font; + font.setFamily(m_fontSetting->get("systemFont").toString()); + font.setPointSize(m_fontSetting->get("systemFontSize").toInt()); + ui->titleLabel->setFont(font); + ui->timeClockLable->setObjectName("timeClockLable"); + font.setPointSize(font.pointSize() + 8); + font.setBold(true); + ui->timeClockLable->setFont(font); +} -// ui->chgzonebtn->setStyleSheet("QPushButton{background-color:#E5E7E9;border-radius:4px}" -// "QPushButton:hover{background-color: #3D6BE5;color:white;};border-radius:4px"); - ui->chgzonebtn->setText(tr("Change time zone")); +void DateTime::initUI() +{ + m_formTimeBtn = new SwitchButton(pluginWidget); + //~ contents_path /date/24-hour clock + m_formTimeLabel = new QLabel(tr("24-hour clock"), pluginWidget); + syncTimeBtn = new SwitchButton(pluginWidget); + syncNetworkLabel = new QLabel(tr("Sync from network"), pluginWidget); + syncNetworkRetLabel = new QLabel(pluginWidget); + syncNetworkRetLabel->setStyleSheet("QLabel{font-size: 15px; color: #D9F82929;}"); + + m_zoneinfo = new ZoneInfo; + m_timezone = new TimeZoneChooser(pluginWidget); + m_itimer = new QTimer(this); + m_itimer->start(1000); + const QByteArray id(FORMAT_SCHEMA); + if (QGSettings::isSchemaInstalled(id)) { + const QByteArray id(FORMAT_SCHEMA); + m_formatsettings = new QGSettings(id, QByteArray(), this); + connect(m_formatsettings, &QGSettings::changed, this, [=](QString key) { + QString hourFormat = m_formatsettings->get(TIME_FORMAT_KEY).toString(); + bool status = ("24" == hourFormat ? false : true); + timeFormatClickedSlot(status, true); + }); + } - ui->chgLayout->setSpacing(16); + // 初始化dbus + m_datetimeiface = new QDBusInterface("org.freedesktop.timedate1", + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + QDBusConnection::systemBus(), this); -// ui->hourWidget->setStyleSheet("background-color:#E5E7E9;border-radius:6px"); + m_datetimeiproperties = new QDBusInterface("org.freedesktop.timedate1", + "/org/freedesktop/timedate1", + "org.freedesktop.DBus.Properties", + QDBusConnection::systemBus(), this); -// ui->syslabel->setStyleSheet("QLabel#syslabel{background: #3D6BE5;border-radius:4px;}"); - ui->syslabel->setVisible(false); +} -// ui->endlabel->setStyleSheet("QLabel#endlabel{background: #3D6BE5;border-radius:4px;}"); - ui->endlabel->setVisible(false); +void DateTime::initComponent() +{ + ui->titleLabel->setContentsMargins(0,0,0,16); + ui->timeClockLable->setContentsMargins(0,0,0,16); -// m_formTimeBtn->setChecked(false); + //~ contents_path /date/Change time + ui->chgtimebtn->setText(tr("Change time")); + //~ contents_path /date/Change time zone + ui->chgzonebtn->setText(tr("Change time zone")); QHBoxLayout *hourLayout = new QHBoxLayout(ui->hourFrame); hourLayout->addWidget(m_formTimeLabel); hourLayout->addWidget(m_formTimeBtn); + QHBoxLayout *syncLayout = new QHBoxLayout(ui->syncFrame); -// ui->hourwidget->addWidget(formTimeLabel); - + syncLayout->addWidget(syncNetworkLabel); + syncLayout->addStretch(); + syncLayout->addWidget(syncNetworkRetLabel); + syncLayout->addWidget(syncTimeBtn); QDateTime currentime = QDateTime::currentDateTime(); - QString timeAndWeek = currentime.toString("yyyy/MM/dd ddd"); - ui->dateLabel->setText(timeAndWeek); - - - //因为ntpd和systemd的网络时间同步会有冲突,所以安装了ntp的话,禁止使用控制面板设置网络时间同步 - QFileInfo fileinfo("/usr/sbin/ntpd"); - if (fileinfo.exists()){ - ui->synsystimeBtn->setVisible(false); - } + QString timeAndWeek = currentime.toString("yyyy/MM/dd ddd").replace("周","星期"); + ui->dateLabel->setText(timeAndWeek + " " + localizedTimezone); QFile tzfile("://zoneUtc"); - if(!tzfile.open(QIODevice::ReadOnly | QIODevice::Text)){ + if (!tzfile.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug("TZ File Open Failed"); } else { QTextStream txt(&tzfile); int index = 0; - qDebug()<<"TODO------->language problem"< tz = m_datetimeiproperties->call("Get", "org.freedesktop.timedate1", "Timezone"); - QMap::iterator it = tzindexMapEn.find(tz.value().toString()); - if(it != tzindexMapEn.end()){ - for(QMap::iterator itc = tzindexMapCN.begin();itc!=tzindexMapCN.end();itc++) - { - if(itc.value() == it.value()){ - ui->timezoneLabel->setText(getLocalTimezoneName(itc.key(), locale)); - break; - } - } - } else { - QMap::iterator defaultit = tzindexMapEn.find(DEFAULT_TZ); - ui->timezoneLabel->setText(getLocalTimezoneName(defaultit.key(), locale)); - } + localizedTimezone = getLocalTimezoneName(tz.value().toString(), locale); + loadHour(); +} +void DateTime::connectToServer() +{ + m_cloudInterface = new QDBusInterface("org.kylinssoclient.dbus", + "/org/kylinssoclient/path", + "org.freedesktop.kylinssoclient.interface", + QDBusConnection::sessionBus()); + if (!m_cloudInterface->isValid()) { + qDebug() << "fail to connect to service"; + qDebug() << qPrintable(QDBusConnection::systemBus().lastError().message()); + return; + } + QDBusConnection::sessionBus().connect(QString(), QString("/org/kylinssoclient/path"), QString("org.freedesktop.kylinssoclient.interface"), "keyChanged", this, SLOT(keyChangedSlot(QString))); + // 将以后所有DBus调用的超时设置为 milliseconds + m_cloudInterface->setTimeout(2147483647); // -1 为默认的25s超时 +} - loadHour(); +void DateTime::keyChangedSlot(const QString &key) +{ + if (key == "datetime") { + initStatus(); + } } -bool DateTime::fileIsExits(const QString &filepath) { +bool DateTime::fileIsExits(const QString &filepath) +{ QFile file(filepath); if(file.exists()) { return true; @@ -222,52 +239,40 @@ } } -void DateTime::datetime_update_slot(){ +void DateTime::datetimeUpdateSlot() +{ QString dateformat; - if(m_formatsettings) { + if (m_formatsettings) { QStringList keys = m_formatsettings->keys(); if(keys.contains("date")) { - dateformat = m_formatsettings->get(DATE_KEY).toString(); + dateformat = m_formatsettings->get(DATE_KEY).toString(); } } - //当前时间 - current = QDateTime::currentDateTime(); -// qDebug()<<"current time is-------->"<isChecked()){ - currentsecStr = current.toString("hh : mm : ss"); - }else{ - currentsecStr = current.toString("AP hh: mm : ss"); - } QString timeAndWeek; if ("cn" == dateformat) { - timeAndWeek = current.toString("yyyy/MM/dd ddd"); + timeAndWeek = current.toString("yyyy/MM/dd ddd").replace("周","星期"); } else { - timeAndWeek = current.toString("yyyy-MM-dd ddd"); + timeAndWeek = current.toString("yyyy-MM-dd ddd"); } -// qDebug()<<"year is----------->"<dateLabel->setText(timeAndWeek); - ui->timeClockLable->setText(currentsecStr); - + ui->dateLabel->setText(timeAndWeek + " " + localizedTimezone); } -void DateTime::changetime_slot(){ +void DateTime::changetimeSlot() +{ ChangtimeDialog *dialog = new ChangtimeDialog(m_formTimeBtn->isChecked()); dialog->setWindowTitle(tr("change time")); dialog->setAttribute(Qt::WA_DeleteOnClose); m_itimer->stop(); m_itimer->start(); dialog->exec(); - } - -void DateTime::changezone_slot(){ -// qDebug()<<"changezone_slot------->"<screenGeometry(m->screenNumber(QCursor::pos())); int desk_x = desk_rect.width(); @@ -276,23 +281,26 @@ int y = m_timezone->height(); m_timezone->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top()); + m_timezone->setWindowModality(Qt::ApplicationModal); m_timezone->show(); m_timezone->setMarkedTimeZoneSlot(m_zoneinfo->getCurrentTimzone()); } -void DateTime::changezone_slot(QString zone){ +void DateTime::changezoneSlot(QString zone) +{ m_datetimeiface->call("SetTimezone", zone, true); } -void DateTime::time_format_clicked_slot(bool flag){ - if (!m_formatsettings){ +void DateTime::timeFormatClickedSlot(bool flag, bool outChange) +{ + if (!m_formatsettings) { qDebug()<<"org.ukui.control-center.panel.plugins not installed"<keys(); - if (keys.contains("hoursystem")) { - if(flag == true) { + if (keys.contains("hoursystem") && !outChange) { + if (flag == true) { m_formatsettings->set(TIME_FORMAT_KEY, "24"); } else { m_formatsettings->set(TIME_FORMAT_KEY, "12"); @@ -303,67 +311,92 @@ m_itimer->start(1000); } -void DateTime::showendLabel(){ - ui->syslabel->setVisible(false); - if(ui->syslabel->isVisible()){ - ui->endlabel->setVisible(false); - }else { - ui->endlabel->setVisible(true); - } - QTimer::singleShot(2*1000,this,SLOT(hidendLabel())); -} - -void DateTime::hidendLabel(){ - ui->endlabel->setVisible(false); -} - -void DateTime::rsync_with_network_slot(){ -// qDebug()<<"TODO------> sleep waies?"<call("SetNTP", true, true); - -// QMovie *loadgif = new QMovie(":/sys.gif"); -// loadgif->start(); -// ui->syslabel->setVisible(true); -// ui->syslabel->setMovie(loadgif); -// ui->syslabel->setScaledContents(true); -// ui->syslabel->setStyleSheet("QLabel#syslabel{border-radius:4px;}"); - -// QTimer::singleShot(2*1000,this,SLOT(showendLabel())); +QDBusMessage DateTime::rsyncWithNetworkSlot(bool status) +{ + return m_datetimeiface->call("SetNTP", status, true); } -void DateTime::loadHour() { +void DateTime::loadHour() +{ if (!m_formatsettings) { - qDebug()<<"org.ukui.control-center.panel.plugins not installed"<keys(); QString format; + bool formatB; if (keys.contains("hoursystem")) { format = m_formatsettings->get(TIME_FORMAT_KEY).toString(); } + if (format == "24") { m_formTimeBtn->setChecked(true); } else { m_formTimeBtn->setChecked(false); } + + setCurrentTime(); + + if (keys.contains(SYNC_TIME_KEY)) { + formatB = m_formatsettings->get(SYNC_TIME_KEY).toBool(); + syncTimeBtn->setChecked(formatB); + if (formatB != false) { + ui->chgtimebtn->setEnabled(false); + } + } } -void DateTime::connectGSetting() { +void DateTime::setCurrentTime() +{ + + current = QDateTime::currentDateTime(); + QString currentsecStr ; + if (m_formTimeBtn->isChecked()) { + currentsecStr = current.toString("hh : mm : ss"); + } else { + currentsecStr = current.toString("AP hh: mm : ss"); + } + ui->timeClockLable->setText(currentsecStr); +} + +void DateTime::initConnect() +{ + connect(ui->chgtimebtn,SIGNAL(clicked()),this,SLOT(changetimeSlot())); + connect(ui->chgzonebtn,SIGNAL(clicked()),this,SLOT(changezoneSlot())); + + connect(m_formTimeBtn, &SwitchButton::checkedChanged, this, [=](bool status) { + timeFormatClickedSlot(status, false); + }); + + connect(syncTimeBtn, &SwitchButton::checkedChanged, this,[=](bool status) { + synctimeFormatSlot(status,true); //按钮被改变,需要修改 + }); + + connect(m_timezone, &TimeZoneChooser::confirmed, this, [this] (const QString &timezone) { + changezoneSlot(timezone); + m_timezone->hide(); + const QString locale = QLocale::system().name(); + localizedTimezone = m_zoneinfo->getLocalTimezoneName(timezone, locale); + }); + + connect(m_itimer,SIGNAL(timeout()), this, SLOT(datetimeUpdateSlot())); + connect(m_formatsettings, &QGSettings::changed, this, [=] (const QString &key) { -// qDebug()<<"status changed ------------>"<get(TIME_FORMAT_KEY).toString(); bool checked = (value == "24" ? true : false); m_formTimeBtn->setChecked(checked); } - if (key == "date") { - QString value = m_formatsettings->get(DATE_KEY).toString(); + + if (key == SYNC_TIME_KEY){ + bool valueB = m_formatsettings->get(SYNC_TIME_KEY).toBool(); + syncTimeBtn->setChecked(valueB); } }); } -QString DateTime::getLocalTimezoneName(QString timezone, QString locale) { +QString DateTime::getLocalTimezoneName(QString timezone, QString locale) +{ (void) setlocale(LC_ALL, QString(locale + ".UTF-8").toStdString().c_str()); const QString local_name(dgettext(kTimezoneDomain, timezone.toStdString().c_str())); @@ -378,3 +411,129 @@ return (index > -1) ? local_name.mid(index + 1) : local_name; } + +void DateTime::synctimeFormatSlot(bool status,bool outChange) +{ + if (!m_formatsettings) { + qDebug()<<"org.ukui.control-center.panel.plugins not installed"<keys(); + if (keys.contains(SYNC_TIME_KEY) && outChange) { + if (status != false) { + m_formatsettings->set(SYNC_TIME_KEY, true); + } else { + m_formatsettings->set(SYNC_TIME_KEY, false); + } + } + QDBusMessage retDBus = rsyncWithNetworkSlot(status); + if (status != false) { + ui->chgtimebtn->setEnabled(false); + + if (retDBus.type() == QDBusMessage::ReplyMessage) { + QString successMSG = tr(" "); + QString failMSG = tr("Sync from network failed"); + CGetSyncRes *syncThread = new CGetSyncRes(this,successMSG,failMSG); + connect(syncThread,SIGNAL(finished()),syncThread,SLOT(deleteLater())); + syncThread->start(); + } else { + syncNetworkRetLabel->setText(tr("Sync from network failed")); + } + } else { + ui->chgtimebtn->setEnabled(true); + } +} +/*同步硬件时钟*/ +void DateTime::syncRTC() +{ + QDBusInterface * changeRTCinterface = new QDBusInterface("com.control.center.qt.systemdbus", + "/", + "com.control.center.interface", + QDBusConnection::systemBus()); + + if (!changeRTCinterface->isValid()) { + qCritical() << "Create Client Interface Failed When execute gpasswd: " << QDBusConnection::systemBus().lastError(); + return; + } + changeRTCinterface->call("changeRTC"); + delete changeRTCinterface; + changeRTCinterface = nullptr; +} + +CGetSyncRes::CGetSyncRes(DateTime *dataTimeUI,QString successMSG,QString failMSG) +{ + this -> dataTimeUI = dataTimeUI; + this -> successMSG = successMSG; + this -> failMSG = failMSG; +} + +CGetSyncRes::~CGetSyncRes() +{ + +} +void CGetSyncRes::run() +{ + for(qint8 i = 0;i < 80; ++i) { + struct timex txc = {}; + if (adjtimex(&txc) < 0 || txc.maxerror >= 16000000) { //未能同步时间 + int picNum = i - qFloor(i/8)*8; //限制在0~7 + QString pixName = QString(":/img/plugins/upgrade/loading%1.svg").arg(picNum+10); + QPixmap pix(pixName); + this->dataTimeUI->syncTimeBtn->setEnabled(false); + qApp->processEvents(); + this->dataTimeUI->syncNetworkRetLabel->setPixmap(pix); + msleep(70); + continue; + } else { //同步时间成功 + DateTime::syncRTC(); + this->dataTimeUI->syncNetworkRetLabel->setText(successMSG); + this->dataTimeUI->syncTimeBtn->setEnabled(true); + return; + } + } + this->dataTimeUI->syncTimeBtn->setEnabled(true); + this->dataTimeUI->syncNetworkRetLabel->setText(failMSG); + if (syncThreadFlag == false) { //创建线程一直查时间同步是否成功 + CSyncTime *syncTimeThread = new CSyncTime(this->dataTimeUI,successMSG,failMSG); + connect(syncTimeThread,SIGNAL(finished()),syncTimeThread,SLOT(deleteLater())); + syncTimeThread->start(); + syncThreadFlag = true; + } + return; +} + +CSyncTime::CSyncTime(DateTime *dataTimeUI,QString successMSG,QString failMSG) +{ + this -> dataTimeUI = dataTimeUI; + this -> successMSG = successMSG; + this -> failMSG = failMSG; +} + +CSyncTime::~CSyncTime() +{ + +} +void CSyncTime::run() +{ + QDBusInterface *r_datetimeiface = new QDBusInterface("org.freedesktop.timedate1", + "/org/freedesktop/timedate1", + "org.freedesktop.timedate1", + QDBusConnection::systemBus(), this); + while (true) { + if (this->dataTimeUI->syncTimeBtn->isChecked() == false) { + syncThreadFlag = false; + delete r_datetimeiface; + return; + } + r_datetimeiface->call("SetNTP", true, true); + struct timex txc = {}; + if (adjtimex(&txc) > 0 && txc.maxerror < 16000000) { //同步时间成功 + DateTime::syncRTC(); + this->dataTimeUI->syncNetworkRetLabel->setText(successMSG); + syncThreadFlag = false; + delete r_datetimeiface; + return; + } + sleep(2); + } +} diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/datetime.h ukui-control-center-3.0.3/plugins/time-language/datetime/datetime.h --- ukui-control-center-2.0.3/plugins/time-language/datetime/datetime.h 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/datetime.h 2021-04-14 01:27:20.000000000 +0000 @@ -21,8 +21,6 @@ #define DATETIME_H #include -#include - #include "shell/interface.h" #include "changtime.h" @@ -30,9 +28,7 @@ #include #include #include - -#include - +#include #include #include #include @@ -42,12 +38,12 @@ #include #include #include +#include #include "worldMap/timezonechooser.h" #include "worldMap/zoneinfo.h" #include "SwitchButton/switchbutton.h" - /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 **/ @@ -60,7 +56,6 @@ #include } - #define TZ_DATA_FILE "/usr/share/zoneinfo/zoneUtc" #define DEFAULT_TZ "Asia/Shanghai" @@ -78,63 +73,98 @@ DateTime(); ~DateTime(); - QString get_plugin_name() Q_DECL_OVERRIDE; - int get_plugin_type() Q_DECL_OVERRIDE; - QWidget * get_plugin_ui() Q_DECL_OVERRIDE; + QString get_plugin_name() Q_DECL_OVERRIDE; + int get_plugin_type() Q_DECL_OVERRIDE; + QWidget * get_plugin_ui() Q_DECL_OVERRIDE; void plugin_delay_control() Q_DECL_OVERRIDE; + const QString name() const Q_DECL_OVERRIDE; - void component_init(); - void status_init(); - + void initTitleLabel(); + void initUI(); + void initComponent(); + void initStatus(); + void connectToServer(); bool fileIsExits(const QString& filepath); + static void syncRTC(); + +public: + QLabel *syncNetworkRetLabel = nullptr; + SwitchButton *syncTimeBtn = nullptr; //网络时间同步按钮 private: Ui::DateTime *ui; + QString localizedTimezone; + QString pluginName; + int pluginType; + QWidget *pluginWidget; + QGSettings *m_formatsettings = nullptr; - QString pluginName; - int pluginType; - QWidget * pluginWidget; - - QGSettings * m_formatsettings = nullptr; - - - QDBusInterface *m_datetimeiface = nullptr; + QDBusInterface *m_datetimeiface = nullptr; QDBusInterface *m_datetimeiproperties = nullptr; + QDBusInterface *m_cloudInterface; QMap tzindexMapEn; QMap tzindexMapCN; + SwitchButton *m_formTimeBtn = nullptr; + QLabel *m_formTimeLabel = nullptr; + QTimer *m_itimer = nullptr; - SwitchButton *m_formTimeBtn = nullptr; - QLabel *m_formTimeLabel = nullptr; - QTimer * m_itimer = nullptr; + QLabel *syncNetworkLabel = nullptr; TimeZoneChooser *m_timezone; ZoneInfo* m_zoneinfo; QDateTime current; - -// bool m_EFHour = true;//默认为24小时制 + bool mFirstLoad; Q_SIGNALS: void changed(); private slots: - void datetime_update_slot(); - void changetime_slot(); - void changezone_slot(); - void changezone_slot(QString ); - void time_format_clicked_slot(bool); - void rsync_with_network_slot(); - void showendLabel(); - void hidendLabel(); + void datetimeUpdateSlot(); + void changetimeSlot(); + void changezoneSlot(); + void changezoneSlot(QString zone); + void timeFormatClickedSlot(bool, bool); + void synctimeFormatSlot(bool status,bool outChange); + QDBusMessage rsyncWithNetworkSlot(bool status); + void keyChangedSlot(const QString &key); private: void loadHour(); - void connectGSetting(); + void setCurrentTime(); + void initConnect(); QString getLocalTimezoneName(QString timezone, QString locale); +}; + +class CGetSyncRes : public QThread{ + Q_OBJECT +public: + CGetSyncRes(DateTime *dataTimeUI,QString successMSG,QString failMSG); + ~CGetSyncRes(); +protected: + void run()override; +private: + DateTime *dataTimeUI; + QString successMSG; + QString failMSG; + bool changeLableFlag; +}; + +class CSyncTime : public QThread{ + Q_OBJECT +public: + CSyncTime(DateTime *dataTimeUI,QString successMSG,QString failMSG); + ~CSyncTime(); +protected: + void run()override; +private: + DateTime *dataTimeUI; + QString successMSG; + QString failMSG; }; #endif // DATETIME_H diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/datetime.pro ukui-control-center-3.0.3/plugins/time-language/datetime/datetime.pro --- ukui-control-center-2.0.3/plugins/time-language/datetime/datetime.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/datetime.pro 2021-04-14 01:27:20.000000000 +0000 @@ -13,6 +13,8 @@ include(../../../env.pri) include($$PROJECT_COMPONENTSOURCE/switchbutton.pri) +include($$PROJECT_COMPONENTSOURCE/closebutton.pri) +include($$PROJECT_COMPONENTSOURCE/imageutil.pri) TARGET = $$qtLibraryTarget(datetime) DESTDIR = ../.. diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/datetime.ui ukui-control-center-3.0.3/plugins/time-language/datetime/datetime.ui --- ukui-control-center-2.0.3/plugins/time-language/datetime/datetime.ui 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/datetime.ui 2021-05-20 13:08:14.000000000 +0000 @@ -33,7 +33,7 @@ 0 - 32 + 36 @@ -55,268 +55,225 @@ 16777215 - - current date - - - - - - - - 0 - 0 - - - - - 151 - 50 - - - - - 167000 - 167000 - - - 24 - 75 - true + 18 + 50 + false - TextLabel - - - - - - - - 0 - 0 - - - - - 127 - 20 - - - - - 167000 - 18000 - - - - TextLabel + current date - - - - 0 - 0 - - + - 347 - 20 + 552 + 150 - 167000 - 167000 + 960 + 16777215 - - - 10 - - - - timezone - - - - - - - 16 - - - 24 + + QFrame::StyledPanel - - 24 + + QFrame::Raised - - + + + + 16 + 14 + 581 + 45 + + + + + 0 + 0 + + + + + 151 + 36 + + + + + 167000 + 167000 + + + + + 24 + 75 + true + + + + + + + + + + 16 + 59 + 521 + 30 + + + + + 153 + 20 + + + + + + 0 + 0 + 421 + 30 + + - + 0 0 - 130 - 36 - - - - - 16777215 - 16777215 - - - - Qt::LeftToRight - - - Sync system time - - - - - - - - 130 - 36 - - - - - 16777215 - 36 - - - - Change time - - - - - - - - 130 - 36 + 153 + 20 - 16777215 - 36 + 167000 + 18000 - Change time zone + - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - - - - 552 - 50 - - - - - 960 - 50 - - - - QFrame::Box - + + + + + 220 + 100 + 188 + 36 + + + + + 120 + 36 + + + + + 16777215 + 36 + + + + Change time zone + + + + + + 16 + 100 + 188 + 36 + + + + + 120 + 36 + + + + + 16777215 + 36 + + + + Change time + + + timeClockLable + dateWidget + chgtimebtn + chgzonebtn - - - 32 + + + 1 - + + + true + - 120 - 30 + 552 + 50 - 120 - 30 + 960 + 50 - - TextLabel + + QFrame::Box - + - 120 - 30 + 552 + 50 - + - 120 - 30 + 960 + 50 - - Sync complete + + QFrame::Box - - - - Qt::Horizontal - - - - 40 - 20 - - - - diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/poplist.cpp ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/poplist.cpp --- ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/poplist.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/poplist.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -49,7 +49,6 @@ } void PopList::keyPressEvent(QKeyEvent *event) { - qDebug()<<"esc------>"<key() == Qt::Key_Escape) { this->hide(); } diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/timezonechooser.cpp ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/timezonechooser.cpp --- ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/timezonechooser.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/timezonechooser.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -11,14 +11,20 @@ #include #include #include -TimeZoneChooser::TimeZoneChooser():QFrame () + +#include "ImageUtil/imageutil.h" + +const QString kcnBj = "北京"; +const QString kenBj = "Asia/Beijing"; + +TimeZoneChooser::TimeZoneChooser(QWidget *parent) : QFrame(parent) { m_map = new TimezoneMap(this); m_map->show(); m_zoneinfo = new ZoneInfo; - m_searchInput = new QLineEdit; - m_title = new QLabel; - closeBtn = new QPushButton; + m_searchInput = new QLineEdit(this); + m_title = new QLabel(this); + m_closeBtn = new QPushButton(this); m_cancelBtn = new QPushButton(tr("Cancel")); m_confirmBtn = new QPushButton(tr("Confirm")); @@ -26,34 +32,28 @@ setAttribute(Qt::WA_StyledBackground,true); this->setObjectName("MapFrame"); -// this->setStyleSheet("QFrame#MapFrame{background-color: rgb(22, 24, 26);border-radius:4px}"); + this->setStyleSheet("QFrame#MapFrame{background-color: rgb(22, 24, 26);border-radius:4px}"); + this->setWindowTitle(tr("Change time zone")); - closeBtn->setIcon(QIcon("://img/titlebar/close.svg")); - closeBtn->setFlat(true); - closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); + QIcon icon = QIcon::fromTheme("window-close-symbolic"); + m_closeBtn->setIcon(ImageUtil::drawSymbolicColoredPixmap(icon.pixmap(32, 32),"white")); + m_closeBtn->setFlat(true); m_searchInput->setMinimumSize(560,40); m_searchInput->setMaximumSize(560,40); m_searchInput->setMinimumHeight(40); -// m_searchInput->setStyleSheet("background-color: rgb(229, 240, 250 )"); -// m_cancelBtn->setStyleSheet("background-color: rgb(229, 240, 250 )"); -// m_confirmBtn->setStyleSheet("background-color: rgb(229, 240, 250 )"); -/* m_title->setMinimumWidth(179); - m_title->setMinimumHeight(29);*/; m_title->setObjectName("titleLabel"); m_title->setStyleSheet("color: rgb(229, 240, 250 )"); m_title->setText(tr("change timezone")); - initSize(); QHBoxLayout *wbLayout = new QHBoxLayout; wbLayout->setMargin(6); wbLayout->setSpacing(0); wbLayout->addStretch(); - wbLayout->addWidget(closeBtn); + wbLayout->addWidget(m_closeBtn); QHBoxLayout *btnlayout = new QHBoxLayout; btnlayout->addStretch(); @@ -91,7 +91,7 @@ emit this->cancelled(); }); - connect(closeBtn, &QPushButton::clicked, this, [this] { + connect(m_closeBtn, &QPushButton::clicked, this, [this] { hide(); emit cancelled(); }); @@ -108,12 +108,15 @@ m_map->setTimezone(timezone); }); - QTimer::singleShot(0, [this] { - -// qDebug()<<"single slot-------->"<popup()->setAttribute(Qt::WA_InputMethodEnabled); completer->setCompletionMode(QCompleter::PopupCompletion); completer->setCaseSensitivity(Qt::CaseInsensitive); + completer->setFilterMode(Qt::MatchContains); m_searchInput->setCompleter(completer); +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) + connect(completer, static_cast(&QCompleter::activated), + [=](const QString &text){ +#else + //鼠标点击后直接页面跳转(https://doc.qt.io/qt-5/qcompleter.html#activated-1) + connect(completer, QOverload::of(&QCompleter::activated), + [=](const QString &text) { +#endif + Q_UNUSED(text); + QString timezone = m_searchInput->text(); + timezone = m_zoneCompletion.value(timezone,timezone); + m_map->setTimezone(timezone); + }); + m_popup = completer->popup(); m_popup->setAttribute(Qt::WA_TranslucentBackground); m_popup->installEventFilter(this); @@ -167,20 +186,6 @@ return false; } -void TimeZoneChooser::paintEvent(QPaintEvent *e) -{ - QStyleOption opt; - opt.init(this); - QPainter p(this); - p.setBrush(QBrush(QColor(22, 24, 26))); - p.setPen(QColor(22, 24, 26)); - p.setRenderHint(QPainter::Antialiasing); // 反锯齿; - p.drawRoundedRect(opt.rect,6,6); - QPainterPath path; -// setProperty("blurRegion",QRegion(path.toFillPolygon().toPolygon())); - style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, this); - -} //获取适合屏幕的地图大小 QSize TimeZoneChooser::getFitSize(){ const QDesktopWidget *desktop = QApplication::desktop(); @@ -189,9 +194,6 @@ double width = primaryRect.width() - 360/* dcc */ - 20 * 2; double height = primaryRect.height() - 70/* dock */ - 20 * 2; -// double width =1440; -// double height =860; - return QSize(width,height); } @@ -216,11 +218,8 @@ const double heightScale = MapPictureHeight / mapHeight; const double scale = qMax(widthScale, heightScale); -// qDebug()<<"scale------>"<setFixedSize(MapPictureWidth / scale, MapPictureHeight / scale); -// m_searchInput->setFixedWidth(250); - m_cancelBtn->setFixedHeight(36); m_confirmBtn->setFixedHeight(36); m_cancelBtn->setFixedWidth(120); diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/timezonechooser.h ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/timezonechooser.h --- ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/timezonechooser.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/timezonechooser.h 2021-04-14 01:27:20.000000000 +0000 @@ -2,9 +2,9 @@ #define TIMEZONECHOOSER_H #include "timezonemap.h" - #include #include +#include #include #include #include @@ -13,7 +13,7 @@ { Q_OBJECT public: - explicit TimeZoneChooser(); + explicit TimeZoneChooser(QWidget *parent); void setTitle(); public slots: @@ -26,7 +26,6 @@ protected: void keyRealeaseEvent(QKeyEvent* event); bool eventFilter(QObject* obj, QEvent* event); - void paintEvent(QPaintEvent *); private: QSize getFitSize(); @@ -38,14 +37,12 @@ QMap m_zoneCompletion; QAbstractItemView *m_popup; - TimezoneMap* m_map; QLineEdit* m_searchInput; QLabel *m_title; QPushButton *m_cancelBtn; QPushButton *m_confirmBtn; - QPushButton *closeBtn; - + QPushButton *m_closeBtn; }; #endif // TIMEZONECHOOSER_H diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/timezonemap.cpp ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/timezonemap.cpp --- ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/timezonemap.cpp 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/timezonemap.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -38,8 +38,6 @@ { m_totalZones = m_zoninfo->getzoneInforList(); -// qDebug()<initUI(); } @@ -139,7 +137,6 @@ QString locale = QLocale::system().name(); QStringList zoneNames; - qDebug()<<"nearest is--------------->"<getLocalTimezoneName(zone.timezone, locale)); @@ -172,6 +169,7 @@ } void TimezoneMap::setTimezone(QString timezone) { + timezone = (timezone == "Asia/Beijing" ? "Asia/Shanghai" : timezone); m_nearestZones.clear(); int index = m_zoninfo->getZoneInfoByZone(m_totalZones, timezone); if (index > -1) { @@ -188,14 +186,11 @@ m_nearestZones = m_zoninfo->getNearestZones(m_totalZones,100.0, event->x(), event->y(), this->width(), this->height()); -// qDebug()<<"pos------>"<x()<mark(); emit this->timezoneSelected(m_currentZone.timezone); } else { -// qDebug()<<"two add----------->"<popupZoneList(event->pos()); } } else { diff -Nru ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/zoneinfo.cpp ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/zoneinfo.cpp --- ukui-control-center-2.0.3/plugins/time-language/datetime/worldMap/zoneinfo.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/plugins/time-language/datetime/worldMap/zoneinfo.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -11,6 +11,9 @@ const char kDefaultLocale[] = "en_US.UTF-8"; +const QString kcnBj = "北京"; +const QString kenBj = "Asia/Beijing"; + QString ZoneInfo::readRile(const QString& filepath) { QFile file(filepath); if(file.exists()) { @@ -60,10 +63,18 @@ if(index == -1) { index = coordinate.indexOf('-', 3); } -// qDebug()<<"coordinate----->"< -1); - double latitude = convertoPos(coordinate.left(index),2); - double longtitude = convertoPos(coordinate.mid(index),3); + + double latitude = convertoPos(coordinate.left(index), 2); + double longtitude = convertoPos(coordinate.mid(index), 3); +// if ("+3114" == coordinate.left(index)) { +// latitude = convertoPos("+3992", 2); +// } + +// if ("+12128" == coordinate.mid(index)) { +// longtitude = convertoPos("+11646", 3); +// } + ZoneInfo_ zoneinfo_ = {details.at(0), details.at(2), latitude, longtitude,0.0}; list.append(zoneinfo_); @@ -103,6 +114,15 @@ // Reset locale. (void) setlocale(LC_ALL, kDefaultLocale); + +// if ("Asia/Shanghai" == timezone) { +// if (QLocale::system().name() == "zh_CN") { +// return kcnBj; +// } else { +// return kenBj; +// } +// } + return (index > -1) ? local_name.mid(index + 1) : local_name; } diff -Nru ukui-control-center-2.0.3/registeredQDbus/conf/com.control.center.qt.systemdbus.policy ukui-control-center-3.0.3/registeredQDbus/conf/com.control.center.qt.systemdbus.policy --- ukui-control-center-2.0.3/registeredQDbus/conf/com.control.center.qt.systemdbus.policy 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredQDbus/conf/com.control.center.qt.systemdbus.policy 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,23 @@ + + + + + KYLINOS + http://www.kylinos.cn + ues + + + UserInfo + 账户信息 + To change the user pwd, you need to authenticate. + 需要通过管理员认证后才可以修改用户密码 + + auth_admin + auth_admin + auth_admin + + + + diff -Nru ukui-control-center-2.0.3/registeredQDbus/registeredQDbus.pro ukui-control-center-3.0.3/registeredQDbus/registeredQDbus.pro --- ukui-control-center-2.0.3/registeredQDbus/registeredQDbus.pro 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/registeredQDbus/registeredQDbus.pro 2021-04-14 01:27:20.000000000 +0000 @@ -8,6 +8,10 @@ CONFIG += console c++11 link_pkgconfig CONFIG -= app_bundle +PKGCONFIG += gio-2.0 \ + gio-unix-2.0 \ + + DESTDIR = . INCLUDEPATH += . @@ -15,6 +19,8 @@ inst1.path = /usr/share/dbus-1/system-services/ inst2.files += conf/com.control.center.qt.systemdbus.conf inst2.path = /etc/dbus-1/system.d/ +inst3.files += conf/com.control.center.qt.systemdbus.policy +inst3.path = /usr/share/polkit-1/actions/ target.source += $$TARGET target.path = /usr/bin @@ -22,10 +28,13 @@ target \ inst1 \ inst2 \ + inst3 \ HEADERS += \ + run-passwd2.h \ sysdbusregister.h SOURCES += \ main.cpp \ + run-passwd2.cpp \ sysdbusregister.cpp diff -Nru ukui-control-center-2.0.3/registeredQDbus/run-passwd2.cpp ukui-control-center-3.0.3/registeredQDbus/run-passwd2.cpp --- ukui-control-center-2.0.3/registeredQDbus/run-passwd2.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredQDbus/run-passwd2.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,715 @@ + + +/* qt会将glib里的signals成员识别为宏,所以取消该宏 + * 后面如果用到signals时,使用Q_SIGNALS代替即可 + **/ +#ifdef signals +#undef signals +#endif + +extern "C" { +#include +#include + +#include +#include +#include +#include + +} + +#include "run-passwd2.h" + +/* Buffer size for backend output */ +#define BUFSIZE 64 + +/* Passwd states */ +//后端passwd的状态,NONE应该是passwd还没有启动,ERROR表示报错但还没退出 +typedef enum { + PASSWD_STATE_NONE, /* Passwd is not asking for anything */ + PASSWD_STATE_AUTH, /* Passwd is asking for our current password */ + PASSWD_STATE_NEW, /* Passwd is asking for our new password */ + PASSWD_STATE_RETYPE, /* Passwd is asking for our retyped new password */ + PASSWD_STATE_ERR /* Passwd reported an error but has not yet exited */ +} PasswdState; + +struct PasswdHandler { +// GtkBuilder *ui; + + const char *current_password; + const char *new_password; + const char *retyped_password; + + /* Communication with the passwd program */ + GPid backend_pid; + + GIOChannel *backend_stdin; + GIOChannel *backend_stdout; + + GQueue *backend_stdin_queue; /* Write queue to backend_stdin */ + + /* GMainLoop IDs */ + guint backend_child_watch_id; /* g_child_watch_add (PID) */ + guint backend_stdout_watch_id; /* g_io_add_watch (stdout) */ + + /* State of the passwd program */ + PasswdState backend_state; + gboolean changing_password; + + PasswdCallback auth_cb; + gpointer auth_cb_data; + + PasswdCallback chpasswd_cb; + gpointer chpasswd_cb_data; +}; + +//GQuark是一个guint32 +static GQuark +passwd_error_quark (void) +{ + static GQuark q = 0; + + //返回错误的标识码 + if (q == 0) { + q = g_quark_from_static_string("passwd_error"); + } + + return q; +} + +/* Error handling */ +#define PASSWD_ERROR (passwd_error_quark ()) + +static void stop_passwd (PasswdHandler *passwd_handler); + +static void free_passwd_resources (PasswdHandler *passwd_handler); + +static gboolean io_watch_stdout (GIOChannel *source, GIOCondition condition, PasswdHandler *passwd_handler); + + +static void free_passwd_resources (PasswdHandler *passwd_handler) +{ + GError *error = NULL; + + /* Remove the child watcher */ + if (passwd_handler->backend_child_watch_id != 0) { + + g_source_remove (passwd_handler->backend_child_watch_id); + + passwd_handler->backend_child_watch_id = 0; + } + + + /* Close IO channels (internal file descriptors are automatically closed) */ + if (passwd_handler->backend_stdin != NULL) { + + if (g_io_channel_shutdown (passwd_handler->backend_stdin, TRUE, &error) != G_IO_STATUS_NORMAL) { + g_warning ("Could not shutdown backend_stdin IO channel: %s", error->message); + g_error_free (error); + error = NULL; + } + + g_io_channel_unref (passwd_handler->backend_stdin); + passwd_handler->backend_stdin = NULL; + } + + if (passwd_handler->backend_stdout != NULL) { + + if (g_io_channel_shutdown (passwd_handler->backend_stdout, TRUE, &error) != G_IO_STATUS_NORMAL) { + g_warning ("Could not shutdown backend_stdout IO channel: %s", error->message); + g_error_free (error); + error = NULL; + } + + g_io_channel_unref (passwd_handler->backend_stdout); + + passwd_handler->backend_stdout = NULL; + } + + /* Remove IO watcher */ + if (passwd_handler->backend_stdout_watch_id != 0) { + + g_source_remove (passwd_handler->backend_stdout_watch_id); + + passwd_handler->backend_stdout_watch_id = 0; + } + + /* Close PID */ + //因为flag为G_SPAWN_DO_NOT_REAP_CHILD,所以child不会自动的被reap掉,需要在子进程上free + if (passwd_handler->backend_pid != -1) { + + g_spawn_close_pid (passwd_handler->backend_pid); + + passwd_handler->backend_pid = -1; + } + + /* Clear backend state */ + passwd_handler->backend_state = PASSWD_STATE_NONE; +} + +static void authenticate (PasswdHandler *passwd_handler) +{ + gchar *s; + + s = g_strdup_printf ("%s\n", passwd_handler->current_password); + g_queue_push_tail (passwd_handler->backend_stdin_queue, s); +} + +static void io_queue_pop (GQueue *queue, GIOChannel *channel) +{ + gchar *buf; + gsize bytes_written; + GError *error = NULL; + + buf = (gchar *)g_queue_pop_head (queue); + + if (buf != NULL) { + //将队列中的首元素写入到channel中 + if (g_io_channel_write_chars (channel, buf, -1, &bytes_written, &error) != G_IO_STATUS_NORMAL) { + g_warning ("Could not write queue element \"%s\" to channel: %s", buf, error->message); + g_error_free (error); + } + + /* Ensure passwords are cleared from memory */ + //清除内存中的passwords + memset (buf, 0, strlen (buf)); + g_free (buf); + } + +} + +static gboolean is_string_complete (gchar *str, ...) +{ + va_list ap; + gchar *arg; + + if (strlen (str) == 0) { + return FALSE; + } + + va_start (ap, str); + + while ((arg = va_arg (ap, char *)) != NULL) { + if (g_strrstr (str, arg) != NULL) { + va_end (ap); + return TRUE; + } + } + + va_end (ap); + + return FALSE; +} + +static gboolean io_watch_stdout (GIOChannel *source, GIOCondition condition, PasswdHandler *passwd_handler) +{ + static GString *str = NULL; /* Persistent buffer */ + + gchar buf[BUFSIZE]; /* Temporary buffer */ + gsize bytes_read; + GError *gio_error = NULL; /* Error returned by functions */ + GError *error = NULL; /* Error sent to callbacks */ + + //GtkBuilder *dialog; + + gboolean reinit = FALSE; + + /* Initialize buffer */ + if (str == NULL) { + str = g_string_new (""); + } + + //dialog = passwd_handler->ui; + //buf将保存从channel中读取到的数据,bytes_read表示从buf中读取的数据长度 + if (g_io_channel_read_chars (source, buf, BUFSIZE, &bytes_read, &gio_error) + != G_IO_STATUS_NORMAL) { + g_warning ("IO Channel read error: %s", gio_error->message); + g_error_free (gio_error); + + return TRUE; + } + + // g_warning("----------bytes_read=%d",bytes_read); + // g_warning("----------io_watch_buf=%s-------",buf); + + str = g_string_append_len (str, buf, bytes_read); + + /* In which state is the backend? */ + switch (passwd_handler->backend_state) { + case PASSWD_STATE_AUTH: + /* Passwd is asking for our current password */ + + if (is_string_complete (str->str, "assword: ", "failure", "wrong", "error", NULL)) { + + if (g_strrstr (str->str, "assword: ") != NULL) { + /* Authentication successful */ + + passwd_handler->backend_state = PASSWD_STATE_NEW; + + /* Trigger callback to update authentication status */ + if (passwd_handler->auth_cb) + passwd_handler->auth_cb (passwd_handler, + NULL, + passwd_handler->auth_cb_data); + + } else { + /* Authentication failed */ + + error = g_error_new_literal (PASSWD_ERROR, PASSWD_ERROR_AUTH_FAILED, + "Authentication failure!"); + + passwd_handler->changing_password = FALSE; + + /* This error can happen both while authenticating or while changing password: + * if chpasswd_cb is set, this means we're already changing password */ + if (passwd_handler->chpasswd_cb) + passwd_handler->chpasswd_cb (passwd_handler, + error, + passwd_handler->auth_cb_data); + else if (passwd_handler->auth_cb) + passwd_handler->auth_cb (passwd_handler, + error, + passwd_handler->auth_cb_data); + + g_error_free (error); + } + + reinit = TRUE; + } + break; + case PASSWD_STATE_NEW: + /* Passwd is asking for our new password */ + + if (is_string_complete (str->str, "assword: ", NULL)) { + /* Advance to next state */ + passwd_handler->backend_state = PASSWD_STATE_RETYPE; + + /* Pop retyped password from queue and into IO channel */ + io_queue_pop (passwd_handler->backend_stdin_queue, passwd_handler->backend_stdin); + + reinit = TRUE; + } + break; + case PASSWD_STATE_RETYPE: + /* Passwd is asking for our retyped new password */ + + // if (is_string_complete (str->str, + // "successfully", + // "short", + // "longer", + // "palindrome", + // "dictionary", + // "simple", + // "simplistic", + // "similar", + // "different", + // "case", + // "wrapped", + // "recovered", + // "recent", + // "unchanged", + // "match", + // "1 numeric or special", + // "failure", + // "length", + // NULL)) { + if (TRUE){ + + if (g_strrstr (str->str, "successfully") != NULL) { + /* Hooray! */ + + /* Trigger callback to update status */ + if (passwd_handler->chpasswd_cb) + passwd_handler->chpasswd_cb (passwd_handler, + NULL, + passwd_handler->chpasswd_cb_data); + } + else { + /* Ohnoes! */ + + if (g_strrstr (str->str, "recovered") != NULL) { + /* What does this indicate? + * "Authentication information cannot be recovered?" from libpam? */ + error = g_error_new_literal (PASSWD_ERROR, PASSWD_ERROR_UNKNOWN, + str->str); + } else if (g_strrstr (str->str, "short") != NULL || + g_strrstr (str->str, "longer") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "New password length is too short!"); + } else if (g_strrstr (str->str, "palindrome") != NULL || + g_strrstr (str->str, "simple") != NULL || + g_strrstr (str->str, "simplistic") != NULL || + g_strrstr (str->str, "dictionary") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password is too simple!"); + } else if (g_strrstr (str->str, "similar") != NULL || + g_strrstr (str->str, "different") != NULL || + g_strrstr (str->str, "case") != NULL || + g_strrstr (str->str, "wrapped") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password is too similar to the old one!"); + } else if (g_strrstr (str->str, "1 numeric or special") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password must contain numbers or special characters!"); + } else if (g_strrstr (str->str, "unchanged") != NULL || + g_strrstr (str->str, "match") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password is the same as the old one!"); + } else if (g_strrstr (str->str, "recent") != NULL) { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_REJECTED, + "The new password has been used recently!"); + } else if (g_strrstr (str->str, "failure") != NULL) { + /* Authentication failure */ + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_AUTH_FAILED, + "Your password has been changed after you verify!"); + } + else { + error = g_error_new (PASSWD_ERROR, PASSWD_ERROR_UNKNOWN, + "Unknown error"); + } + + /* At this point, passwd might have exited, in which case + * child_watch_cb should clean up for us and remove this watcher. + * On some error conditions though, passwd just re-prompts us + * for our new password. */ + passwd_handler->backend_state = PASSWD_STATE_ERR; + + passwd_handler->changing_password = FALSE; + + /* Trigger callback to update status */ + if (passwd_handler->chpasswd_cb) + passwd_handler->chpasswd_cb (passwd_handler, + error, + passwd_handler->chpasswd_cb_data); + + g_error_free (error); + + } + + reinit = TRUE; + + /* child_watch_cb should clean up for us now */ + } + break; + case PASSWD_STATE_NONE: + /* Passwd is not asking for anything yet */ + if (is_string_complete (str->str, "assword: ", NULL)) { + + /* If the user does not have a password set, + * passwd will immediately ask for the new password, + * so skip the AUTH phase */ + if (is_string_complete (str->str, "new", "New", NULL)) { + gchar *pw; + + passwd_handler->backend_state = PASSWD_STATE_NEW; + + /* since passwd didn't ask for our old password + * in this case, simply remove it from the queue */ + pw = (gchar *)g_queue_pop_head (passwd_handler->backend_stdin_queue); + g_free (pw); + + /* Pop the IO queue, i.e. send new password */ + io_queue_pop (passwd_handler->backend_stdin_queue, passwd_handler->backend_stdin); + } else { + + passwd_handler->backend_state = PASSWD_STATE_AUTH; + + /* Pop the IO queue, i.e. send current password */ + io_queue_pop (passwd_handler->backend_stdin_queue, passwd_handler->backend_stdin); + } + + reinit = TRUE; + } + break; + default: + /* Passwd has returned an error */ + reinit = TRUE; + break; + } + + if (reinit) { + g_string_free (str, TRUE); + str = NULL; + } + + /* Continue calling us */ + return TRUE; +} + +/* Child watcher */ +static void child_watch_cb (GPid pid, gint status, PasswdHandler *passwd_handler) +{ + //子进程正常结束为非0 + if (WIFEXITED (status)) { + //取得子进程正常退出时返回的结束代码 + if (WEXITSTATUS (status) >= 255) { + g_warning ("Child exited unexpectedly"); + } + } + + free_passwd_resources (passwd_handler); +} + +static void stop_passwd (PasswdHandler *passwd_handler) +{ + /* This is the standard way of returning from the dialog with passwd. + * If we return this way we can safely kill passwd as it has completed + * its task. + */ + + if (passwd_handler->backend_pid != -1) { + kill (passwd_handler->backend_pid, 9); + } + + /* We must run free_passwd_resources here and not let our child + * watcher do it, since it will access invalid memory after the + * dialog has been closed and cleaned up. + * + * If we had more than a single thread we'd need to remove + * the child watch before trying to kill the child. + */ + free_passwd_resources (passwd_handler); +} + +static gboolean spawn_passwd (PasswdHandler *passwd_handler, const char * user_name, GError **error) +{ + gchar *argv[3]; + gchar *envp[1]; + gint my_stdin, my_stdout, my_stderr; + + argv[0] = "/usr/bin/passwd"; /* Is it safe to rely on a hard-coded path? */ + argv[1] = g_strdup_printf ("%s", user_name); + argv[2] = NULL; + +// g_warning("spawn_passwd: %s %s", argv[0], argv[1]); + + envp[0] = NULL; /* If we pass an empty array as the environment, + * will the childs environment be empty, and the + * locales set to the C default? From the manual: + * "If envp is NULL, the child inherits its + * parent'senvironment." + * If I'm wrong here, we somehow have to set + * the locales here. + */ + + //创建一个管道,进行通信,子进程执行passwd命令 + if (!g_spawn_async_with_pipes (NULL, /* Working directory */ + argv, /* Argument vector */ + envp, /* Environment */ + G_SPAWN_DO_NOT_REAP_CHILD, /* Flags */ + NULL, /* Child setup (在子进程调用exec()之前,该函数会被调用)*/ + NULL, /* Data to child setup */ + &passwd_handler->backend_pid, /* PID */ + &my_stdin, /* Stdin */ + &my_stdout, /* Stdout */ + &my_stderr, /* Stderr */ + error)) { /* GError */ + + /* An error occured */ + free_passwd_resources (passwd_handler); + + return FALSE; + } + + /* 2>&1 */ + //复制文件描述符,也就是将stderr重定向到stdout + if (dup2 (my_stderr, my_stdout) == -1) { + /* Failed! */ + g_set_error_literal (error, + PASSWD_ERROR, + PASSWD_ERROR_BACKEND, + strerror (errno)); + + /* Clean up */ + stop_passwd (passwd_handler); + + return FALSE; + } + + /* Open IO Channels */ + //指定一个文件描述符,创建一个IO Channel,默认使用UTF-8编码格式 + passwd_handler->backend_stdin = g_io_channel_unix_new (my_stdin); + passwd_handler->backend_stdout = g_io_channel_unix_new (my_stdout); + + /* Set raw encoding */ + /* Set nonblocking mode */ + //设置通道的编码方式为NULL,设置为非阻塞的方式 + if (g_io_channel_set_encoding (passwd_handler->backend_stdin, NULL, error) != G_IO_STATUS_NORMAL || + g_io_channel_set_encoding (passwd_handler->backend_stdout, NULL, error) != G_IO_STATUS_NORMAL || + g_io_channel_set_flags (passwd_handler->backend_stdin, G_IO_FLAG_NONBLOCK, error) != G_IO_STATUS_NORMAL || + g_io_channel_set_flags (passwd_handler->backend_stdout, G_IO_FLAG_NONBLOCK, error) != G_IO_STATUS_NORMAL ) { + + /* Clean up */ + stop_passwd (passwd_handler); + return FALSE; + } + + /* Turn off buffering */ + //只有通道的编码方式为NULL,才能设置缓冲状态为FASLE,其他任何编码,通道必须被缓冲,这里是为了清掉上次的密码 + g_io_channel_set_buffered (passwd_handler->backend_stdin, FALSE); + g_io_channel_set_buffered (passwd_handler->backend_stdout, FALSE); + + /* Add IO Channel watcher */ + //当IO通道的状态为G_IO_IN(从IO通道读数据时)或者G_IO_PRI(读紧急数据时)时,调用io_watch_stdout + passwd_handler->backend_stdout_watch_id = g_io_add_watch (passwd_handler->backend_stdout, + G_IO_IN /*| G_IO_PRI*/, + (GIOFunc) io_watch_stdout, passwd_handler); + + /* Add child watcher */ + //在指定pid的进程退出时,调用child_watch_cb(),进行错误检查,以及资源回收 + passwd_handler->backend_child_watch_id = g_child_watch_add (passwd_handler->backend_pid, (GChildWatchFunc) child_watch_cb, passwd_handler); + + /* Success! */ + + return TRUE; +} + +static void update_password (PasswdHandler *passwd_handler) +{ + gchar *s; + + s = g_strdup_printf ("%s\n", passwd_handler->new_password); + + g_queue_push_tail (passwd_handler->backend_stdin_queue, s); + /* We need to allocate new space because io_queue_pop() g_free()s + * every element of the queue after it's done */ + g_queue_push_tail (passwd_handler->backend_stdin_queue, g_strdup (s)); +} + +gboolean passwd_change_password (PasswdHandler *passwd_handler, const char *user_name, + const char *new_password, + PasswdCallback cb, + const gpointer user_data) +{ + GError *error = NULL; + + passwd_handler->changing_password = TRUE; + + passwd_handler->new_password = new_password; + passwd_handler->chpasswd_cb = cb; + passwd_handler->chpasswd_cb_data = user_data; + + /* Stop passwd if an error occured and it is still running */ + if (passwd_handler->backend_state == PASSWD_STATE_ERR) { + + /* Stop passwd, free resources */ + stop_passwd (passwd_handler); + } + + /* Check that the backend is still running, or that an error + * has occured but it has not yet exited */ + + g_warning("passwd pid is: %d", passwd_handler->backend_pid); + if (passwd_handler->backend_pid == -1) { + /* If it is not, re-run authentication */ + + /* Spawn backend */ + stop_passwd (passwd_handler); + + if (!spawn_passwd (passwd_handler, user_name, &error)) { + g_error_free (error); + + return FALSE; + } + + g_warning("------------1----------------------"); + + /* Add current and new passwords to queue */ + //将当前的密码和新密码入队,新密码会入队两次 + authenticate (passwd_handler); + update_password (passwd_handler); + } else { + g_warning("-----2-----------"); + /* Only add new passwords to queue */ + update_password (passwd_handler); + } + + /* Pop new password through the backend. If user has no password, popping the queue + would output current password, while 'passwd' is waiting for the new one. So wait + for io_watch_stdout() to remove current password from the queue, and output + the new one for us.*/ + //如果密码为空,将新进队列的密码,作为current_passwd弹出 + if (passwd_handler->current_password) + { + io_queue_pop (passwd_handler->backend_stdin_queue, passwd_handler->backend_stdin); + } + + /* Our IO watcher should now handle the rest */ + + return TRUE; +} + +//void passwd_authenticate (PasswdHandler *passwd_handler, +// const char *current_password, +// PasswdCallback cb, +// const gpointer user_data) +//{ +// GError *error = NULL; + +// /* Don't stop if we've already started chaging password */ +// if (passwd_handler->changing_password) +// return; + +// /* Clear data from possible previous attempts to change password */ +// passwd_handler->new_password = NULL; +// passwd_handler->chpasswd_cb = NULL; +// passwd_handler->chpasswd_cb_data = NULL; +// g_queue_foreach (passwd_handler->backend_stdin_queue, (GFunc) g_free, NULL); +// g_queue_clear (passwd_handler->backend_stdin_queue); + +// passwd_handler->current_password = current_password; +// passwd_handler->auth_cb = cb; +// passwd_handler->auth_cb_data = user_data; + +// /* Spawn backend */ +// //重新启动后台passwd +// stop_passwd (passwd_handler); + +// if (!spawn_passwd (passwd_handler, &error)) { +// g_warning ("%s", error->message); +// g_error_free (error); +// return; +// } + +// //将current passwd从尾部插入队列 +// authenticate (passwd_handler); + +// /* Our IO watcher should now handle the rest */ +//} + + +PasswdHandler * passwd_init () +{ + PasswdHandler *passwd_handler; + + passwd_handler = g_new0 (PasswdHandler, 1); + + /* Initialize backend_pid. -1 means the backend is not running */ + //-1代表后台还没启动 + passwd_handler->backend_pid = -1; + + /* Initialize IO Channels */ + passwd_handler->backend_stdin = NULL; + passwd_handler->backend_stdout = NULL; + + /* Initialize write queue */ + passwd_handler->backend_stdin_queue = g_queue_new (); + + /* Initialize watchers */ + passwd_handler->backend_child_watch_id = 0; + passwd_handler->backend_stdout_watch_id = 0; + + /* Initialize backend state */ + passwd_handler->backend_state = PASSWD_STATE_NONE; + passwd_handler->changing_password = FALSE; + + return passwd_handler; +} + + +void passwd_destroy (PasswdHandler *passwd_handler) +{ + g_queue_free (passwd_handler->backend_stdin_queue); + stop_passwd (passwd_handler); + g_free (passwd_handler); +} diff -Nru ukui-control-center-2.0.3/registeredQDbus/run-passwd2.h ukui-control-center-3.0.3/registeredQDbus/run-passwd2.h --- ukui-control-center-2.0.3/registeredQDbus/run-passwd2.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredQDbus/run-passwd2.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,35 @@ +#ifndef RUNPASSWD_H +#define RUNPASSWD_H + + +struct PasswdHandler; + +typedef struct PasswdHandler PasswdHandler; + +typedef void (*PasswdCallback) (PasswdHandler * passwd_handler, GError * error, const gpointer user_data); + +/* Error codes */ +typedef enum { + PASSWD_ERROR_REJECTED, /* New password is not secure enough */ + PASSWD_ERROR_AUTH_FAILED, /* Wrong old password, or PAM failure */ + PASSWD_ERROR_REAUTH_FAILED, /* Password has changed since first authentication */ + PASSWD_ERROR_BACKEND, /* Backend error */ + PASSWD_ERROR_UNKNOWN /* General error */ +} PasswdError; + +PasswdHandler *passwd_init (); + +void passwd_destroy (PasswdHandler *passwd_handler); + +void passwd_authenticate (PasswdHandler *passwd_handler, + const char *current_password, + PasswdCallback cb, + gpointer user_data); + +gboolean passwd_change_password (PasswdHandler *passwd_handler, + const char *user_name, + const char *new_password, + PasswdCallback cb, + const gpointer user_data); + +#endif // RUNPASSWD_H diff -Nru ukui-control-center-2.0.3/registeredQDbus/sysdbusregister.cpp ukui-control-center-3.0.3/registeredQDbus/sysdbusregister.cpp --- ukui-control-center-2.0.3/registeredQDbus/sysdbusregister.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/registeredQDbus/sysdbusregister.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -20,35 +20,52 @@ #include "sysdbusregister.h" #include -#include #include +#include +#include +#include + +/* qt会将glib里的signals成员识别为宏,所以取消该宏 + * 后面如果用到signals时,使用Q_SIGNALS代替即可 + **/ +#ifdef signals +#undef signals +#endif + +extern "C" { +#include +#include + +} + +#include "run-passwd2.h" + +PasswdHandler * passwd_handler = NULL; + +static void chpasswd_cb(PasswdHandler * passwd_handler, GError * error, gpointer user_data); + SysdbusRegister::SysdbusRegister() { + mHibernateFile = "/etc/systemd/sleep.conf"; + mHibernateSet = new QSettings(mHibernateFile, QSettings::IniFormat, this); + mHibernateSet->setIniCodec("UTF-8"); } SysdbusRegister::~SysdbusRegister() { } -//QString SysdbusRegister::name () const{ -// return m_name; -//} - -//void SysdbusRegister::SetName(QString name){ -// m_name = name; -//} - -void SysdbusRegister::exitService(){ +void SysdbusRegister::exitService() { qApp->exit(0); } -QString SysdbusRegister::GetComputerInfo(){ +QString SysdbusRegister::GetComputerInfo() { QByteArray ba; FILE * fp = NULL; char cmd[128]; char buf[1024]; - sprintf(cmd, "dmidecode -t system"); + snprintf(cmd, 128, "dmidecode -t system"); if ((fp = popen(cmd, "r")) != NULL){ rewind(fp); @@ -62,17 +79,13 @@ return QString(ba); } -void SysdbusRegister::systemRun(QString cmd){ - QProcess::execute(cmd); -} - //获取免密登录状态 QString SysdbusRegister::getNoPwdLoginStatus(){ QByteArray ba; FILE * fp = NULL; char cmd[128]; char buf[1024]; - sprintf(cmd, "cat /etc/group |grep nopasswdlogin"); + snprintf(cmd, 128, "cat /etc/group |grep nopasswdlogin"); if ((fp = popen(cmd, "r")) != NULL){ rewind(fp); fgets(buf, sizeof (buf), fp); @@ -86,7 +99,7 @@ } //设置免密登录状态 -void SysdbusRegister::setNoPwdLoginStatus(bool status,QString username){ +void SysdbusRegister::setNoPwdLoginStatus(bool status,QString username) { QString cmd; if(true == status){ @@ -94,18 +107,104 @@ } else{ cmd = QString("gpasswd -d %1 nopasswdlogin").arg(username); } - systemRun(cmd); + QProcess::execute(cmd); } // 设置自动登录状态 -void SysdbusRegister::setAutoLoginStatus(QString username) -{ +void SysdbusRegister::setAutoLoginStatus(QString username) { QString filename = "/etc/lightdm/lightdm.conf"; QSharedPointer autoSettings = QSharedPointer(new QSettings(filename, QSettings::IniFormat)); autoSettings->beginGroup("SeatDefaults"); - autoSettings->clear(); autoSettings->setValue("autologin-user", username); + autoSettings->endGroup(); autoSettings->sync(); } + +QString SysdbusRegister::getSuspendThenHibernate() { + mHibernateSet->beginGroup("Sleep"); + + QString time = mHibernateSet->value("HibernateDelaySec").toString(); + + mHibernateSet->endGroup(); + mHibernateSet->sync(); + + return time; +} + +void SysdbusRegister::setSuspendThenHibernate(QString time) { + mHibernateSet->beginGroup("Sleep"); + + mHibernateSet->setValue("HibernateDelaySec", time); + + mHibernateSet->endGroup(); + mHibernateSet->sync(); +} + +void SysdbusRegister::setPasswdAging(int days, QString username) { + QString cmd; + + cmd = QString("chage -M %1 %2").arg(days).arg(username); + QProcess::execute(cmd); +} + +int SysdbusRegister::changeOtherUserPasswd(QString username, QString pwd){ + + std::string str1 = username.toStdString(); + const char * user_name = str1.c_str(); + + std::string str2 = pwd.toStdString(); + const char * passwd = str2.c_str(); + + passwd_handler = passwd_init(); + + passwd_change_password(passwd_handler, user_name, passwd, chpasswd_cb, NULL); + + return 1; + +} + +void SysdbusRegister::setDDCBrightness(QString brightness, QString type) { + QString program = "/usr/sbin/i2ctransfer"; + QStringList arg; + int br=brightness.toInt(); + QString light = "0x" + QString::number(br,16); + QString c = "0x" + QString::number(168^br,16); + arg << "-f" << "-y" << type << "w7@0x37" << "0x51" << "0x84" << "0x03" + << "0x10" << "0x00" << light << c; + QProcess *vcpPro = new QProcess(this); + vcpPro->start(program, arg); + vcpPro->waitForStarted(); + vcpPro->waitForFinished(); +} + +int SysdbusRegister::getDDCBrightness(QString type) { + QString program = "ddcutil"; + QStringList arg; + arg << "getvcp" << "10" << "--bus" << type; + QProcess *vcpPro = new QProcess(this); + vcpPro->start(program, arg); + vcpPro->waitForFinished(); + + QString result = vcpPro->readAllStandardOutput().trimmed(); + + QRegExp rx("current value =(\\s+)(\\d+)"); + int pos = rx.indexIn(result); + if (pos > -1) { + return rx.cap(2).toInt(); + } + return 0; +} + +static void chpasswd_cb(PasswdHandler *passwd_handler, GError *error, gpointer user_data){ + Q_UNUSED(passwd_handler) + Q_UNUSED(error) + Q_UNUSED(user_data) + g_warning("chpasswd_cb run"); +} + +int SysdbusRegister::changeRTC() { + QString cmd = "hwclock -w"; + return system(cmd.toLatin1().data()); +} diff -Nru ukui-control-center-2.0.3/registeredQDbus/sysdbusregister.h ukui-control-center-3.0.3/registeredQDbus/sysdbusregister.h --- ukui-control-center-2.0.3/registeredQDbus/sysdbusregister.h 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/registeredQDbus/sysdbusregister.h 2021-04-14 01:27:20.000000000 +0000 @@ -23,8 +23,8 @@ #include #include #include - #include +#include class SysdbusRegister : public QObject { @@ -37,29 +37,49 @@ ~SysdbusRegister(); private: -// QString m_name; + QString mHibernateFile; + + QSettings *mHibernateSet; signals: Q_SCRIPTABLE void nameChanged(QString); Q_SCRIPTABLE void computerinfo(QString); public slots: -// Q_SCRIPTABLE QString name() const; -// Q_SCRIPTABLE void SetName(QString name); Q_SCRIPTABLE void exitService(); Q_SCRIPTABLE QString GetComputerInfo(); - Q_SCRIPTABLE void systemRun(QString cmd); - //设置免密登录状态 + // 设置免密登录状态 Q_SCRIPTABLE void setNoPwdLoginStatus(bool status,QString username); - //获取免密登录状态 + // 获取免密登录状态 Q_SCRIPTABLE QString getNoPwdLoginStatus(); - //设置自动登录状态 + // 设置自动登录状态 Q_SCRIPTABLE void setAutoLoginStatus(QString username); + // 获取挂起到休眠时间 + Q_SCRIPTABLE QString getSuspendThenHibernate(); + + // 设置挂起到休眠时间 + Q_SCRIPTABLE void setSuspendThenHibernate(QString time); + + // 设置密码时效 + Q_SCRIPTABLE void setPasswdAging(int days, QString username); + + // 提权修改其他用户密码 + Q_SCRIPTABLE int changeOtherUserPasswd(QString username, QString pwd); + + // 调节外接台式屏幕亮度 + Q_SCRIPTABLE void setDDCBrightness(QString brightness, QString type); + + // 获取外接台式屏幕亮度 + Q_SCRIPTABLE int getDDCBrightness(QString type); + + // 修改硬件时间 + Q_SCRIPTABLE int changeRTC(); + }; #endif // SYSDBUSREGISTER_H diff -Nru ukui-control-center-2.0.3/registeredSession/conf/org.ukui.ukcc.session.service ukui-control-center-3.0.3/registeredSession/conf/org.ukui.ukcc.session.service --- ukui-control-center-2.0.3/registeredSession/conf/org.ukui.ukcc.session.service 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredSession/conf/org.ukui.ukcc.session.service 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.ukui.ukcc.session +Exec=/usr/bin/ukui-control-center-session diff -Nru ukui-control-center-2.0.3/registeredSession/conf/org.ukui.ukcc.session.xml ukui-control-center-3.0.3/registeredSession/conf/org.ukui.ukcc.session.xml --- ukui-control-center-2.0.3/registeredSession/conf/org.ukui.ukcc.session.xml 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredSession/conf/org.ukui.ukcc.session.xml 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/registeredSession/json.cpp ukui-control-center-3.0.3/registeredSession/json.cpp --- ukui-control-center-2.0.3/registeredSession/json.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredSession/json.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,732 @@ +/** + * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa. + * Copyright (C) 2011 Eeli Reilin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file json.cpp + */ + +#include +#include +#include "json.h" + +namespace QtJson { + static QString dateFormat, dateTimeFormat; + static bool prettySerialize = false; + + static QString sanitizeString(QString str); + static QByteArray join(const QList &list, const QByteArray &sep); + static QVariant parseValue(const QString &json, int &index, bool &success); + static QVariant parseObject(const QString &json, int &index, bool &success); + static QVariant parseArray(const QString &json, int &index, bool &success); + static QVariant parseString(const QString &json, int &index, bool &success); + static QVariant parseNumber(const QString &json, int &index); + static int lastIndexOfNumber(const QString &json, int index); + static void eatWhitespace(const QString &json, int &index); + static int lookAhead(const QString &json, int index); + static int nextToken(const QString &json, int &index); + + template + QByteArray serializeMap(const T &map, bool &success, int _level = 0) { + QByteArray newline; + QByteArray tabs; + QByteArray tabsFields; + if (prettySerialize && !map.isEmpty()) { + newline = "\n"; + for (int l=1; l<_level; l++) { + tabs += " "; + } + tabsFields = tabs + " "; + } + + QByteArray str = "{" + newline; + QList pairs; + for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) { + bool otherSuccess = true; + QByteArray serializedValue = serialize(it.value(), otherSuccess, _level); + if (serializedValue.isNull()) { + success = false; + break; + } + pairs << tabsFields + sanitizeString(it.key()).toUtf8() + ":" + (prettySerialize ? " " : "") + serializedValue; + } + + str += join(pairs, "," + newline) + newline; + str += tabs + "}"; + return str; + } + + void insert(QVariant &v, const QString &key, const QVariant &value); + void append(QVariant &v, const QVariant &value); + + template + void cloneMap(QVariant &json, const T &map) { + for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) { + insert(json, it.key(), (*it)); + } + } + + template + void cloneList(QVariant &json, const T &list) { + for (typename T::const_iterator it = list.begin(), itend = list.end(); it != itend; ++it) { + append(json, (*it)); + } + } + + /** + * parse + */ + QVariant parse(const QString &json) { + bool success = true; + return parse(json, success); + } + + /** + * parse + */ + QVariant parse(const QString &json, bool &success) { + success = true; + + // Return an empty QVariant if the JSON data is either null or empty + if (!json.isNull() || !json.isEmpty()) { + QString data = json; + // We'll start from index 0 + int index = 0; + + // Parse the first value + QVariant value = parseValue(data, index, success); + + // Return the parsed value + return value; + } else { + // Return the empty QVariant + return QVariant(); + } + } + + /** + * clone + */ + QVariant clone(const QVariant &data) { + QVariant v; + + if (data.type() == QVariant::Map) { + cloneMap(v, data.toMap()); + } else if (data.type() == QVariant::Hash) { + cloneMap(v, data.toHash()); + } else if (data.type() == QVariant::List) { + cloneList(v, data.toList()); + } else if (data.type() == QVariant::StringList) { + cloneList(v, data.toStringList()); + } else { + v = QVariant(data); + } + + return v; + } + + /** + * insert value (map case) + */ + void insert(QVariant &v, const QString &key, const QVariant &value) { + if (!v.canConvert()) v = QVariantMap(); + QVariantMap *p = (QVariantMap *)v.data(); + p->insert(key, clone(value)); + } + + /** + * append value (list case) + */ + void append(QVariant &v, const QVariant &value) { + if (!v.canConvert()) v = QVariantList(); + QVariantList *p = (QVariantList *)v.data(); + p->append(value); + } + + QByteArray serialize(const QVariant &data) { + bool success = true; + return serialize(data, success); + } + + QByteArray serialize(const QVariant &data, bool &success, int _level /*= 0*/) { + QByteArray newline; + QByteArray tabs; + QByteArray tabsFields; + if (prettySerialize) { + newline = "\n"; + for (int l=0; l<_level; l++) { + tabs += " "; + } + tabsFields = tabs + " "; + } + + QByteArray str; + success = true; + + if (!data.isValid()) { // invalid or null? + str = "null"; + } else if ((data.type() == QVariant::List) || + (data.type() == QVariant::StringList)) { // variant is a list? + QList values; + const QVariantList list = data.toList(); + Q_FOREACH(const QVariant& v, list) { + bool otherSuccess = true; + QByteArray serializedValue = serialize(v, otherSuccess, _level+1); + if (serializedValue.isNull()) { + success = false; + break; + } + values << tabsFields + serializedValue; + } + + if (!values.isEmpty()) { + str = "[" + newline + join( values, "," + newline ) + newline + tabs + "]"; + } else { + str = "[]"; + } + } else if (data.type() == QVariant::Hash) { // variant is a hash? + str = serializeMap<>(data.toHash(), success, _level+1); + } else if (data.type() == QVariant::Map) { // variant is a map? + str = serializeMap<>(data.toMap(), success, _level+1); + } else if ((data.type() == QVariant::String) || + (data.type() == QVariant::ByteArray)) {// a string or a byte array? + str = sanitizeString(data.toString()).toUtf8(); + } else if (data.type() == QVariant::Double) { // double? + double value = data.toDouble(&success); + if (success) { + str = QByteArray::number(value, 'g'); + if (!str.contains(".") && ! str.contains("e")) { + str += ".0"; + } + } + } else if (data.type() == QVariant::Bool) { // boolean value? + str = data.toBool() ? "true" : "false"; + } else if (data.type() == QVariant::ULongLong) { // large unsigned number? + str = QByteArray::number(data.value()); + } else if (data.canConvert()) { // any signed number? + str = QByteArray::number(data.value()); + } else if (data.canConvert()) { //TODO: this code is never executed because all smaller types can be converted to qlonglong + str = QString::number(data.value()).toUtf8(); + } else if (data.type() == QVariant::DateTime) { // datetime value? + str = sanitizeString(dateTimeFormat.isEmpty() + ? data.toDateTime().toString() + : data.toDateTime().toString(dateTimeFormat)).toUtf8(); + } else if (data.type() == QVariant::Date) { // date value? + str = sanitizeString(dateTimeFormat.isEmpty() + ? data.toDate().toString() + : data.toDate().toString(dateFormat)).toUtf8(); + } else if (data.canConvert()) { // can value be converted to string? + // this will catch QUrl, ... (all other types which can be converted to string) + str = sanitizeString(data.toString()).toUtf8(); + } else { + success = false; + } + + if (success) { + return str; + } + return QByteArray(); + } + + QString serializeStr(const QVariant &data) { + return QString::fromUtf8(serialize(data)); + } + + QString serializeStr(const QVariant &data, bool &success) { + return QString::fromUtf8(serialize(data, success)); + } + + + /** + * \enum JsonToken + */ + enum JsonToken { + JsonTokenNone = 0, + JsonTokenCurlyOpen = 1, + JsonTokenCurlyClose = 2, + JsonTokenSquaredOpen = 3, + JsonTokenSquaredClose = 4, + JsonTokenColon = 5, + JsonTokenComma = 6, + JsonTokenString = 7, + JsonTokenNumber = 8, + JsonTokenTrue = 9, + JsonTokenFalse = 10, + JsonTokenNull = 11 + }; + + static QString sanitizeString(QString str) { + str.replace(QLatin1String("\\"), QLatin1String("\\\\")); + str.replace(QLatin1String("\""), QLatin1String("\\\"")); + str.replace(QLatin1String("\b"), QLatin1String("\\b")); + str.replace(QLatin1String("\f"), QLatin1String("\\f")); + str.replace(QLatin1String("\n"), QLatin1String("\\n")); + str.replace(QLatin1String("\r"), QLatin1String("\\r")); + str.replace(QLatin1String("\t"), QLatin1String("\\t")); + return QString(QLatin1String("\"%1\"")).arg(str); + } + + static QByteArray join(const QList &list, const QByteArray &sep) { + QByteArray res; + Q_FOREACH(const QByteArray &i, list) { + if (!res.isEmpty()) { + res += sep; + } + res += i; + } + return res; + } + + /** + * parseValue + */ + static QVariant parseValue(const QString &json, int &index, bool &success) { + // Determine what kind of data we should parse by + // checking out the upcoming token + switch(lookAhead(json, index)) { + case JsonTokenString: + return parseString(json, index, success); + case JsonTokenNumber: + return parseNumber(json, index); + case JsonTokenCurlyOpen: + return parseObject(json, index, success); + case JsonTokenSquaredOpen: + return parseArray(json, index, success); + case JsonTokenTrue: + nextToken(json, index); + return QVariant(true); + case JsonTokenFalse: + nextToken(json, index); + return QVariant(false); + case JsonTokenNull: + nextToken(json, index); + return QVariant(); + case JsonTokenNone: + break; + } + + // If there were no tokens, flag the failure and return an empty QVariant + success = false; + return QVariant(); + } + + /** + * parseObject + */ + static QVariant parseObject(const QString &json, int &index, bool &success) { + QVariantMap map; + int token; + + // Get rid of the whitespace and increment index + nextToken(json, index); + + // Loop through all of the key/value pairs of the object + bool done = false; + while (!done) { + // Get the upcoming token + token = lookAhead(json, index); + + if (token == JsonTokenNone) { + success = false; + return QVariantMap(); + } else if (token == JsonTokenComma) { + nextToken(json, index); + } else if (token == JsonTokenCurlyClose) { + nextToken(json, index); + return map; + } else { + // Parse the key/value pair's name + QString name = parseString(json, index, success).toString(); + + if (!success) { + return QVariantMap(); + } + + // Get the next token + token = nextToken(json, index); + + // If the next token is not a colon, flag the failure + // return an empty QVariant + if (token != JsonTokenColon) { + success = false; + return QVariant(QVariantMap()); + } + + // Parse the key/value pair's value + QVariant value = parseValue(json, index, success); + + if (!success) { + return QVariantMap(); + } + + // Assign the value to the key in the map + map[name] = value; + } + } + + // Return the map successfully + return QVariant(map); + } + + /** + * parseArray + */ + static QVariant parseArray(const QString &json, int &index, bool &success) { + QVariantList list; + + nextToken(json, index); + + bool done = false; + while(!done) { + int token = lookAhead(json, index); + + if (token == JsonTokenNone) { + success = false; + return QVariantList(); + } else if (token == JsonTokenComma) { + nextToken(json, index); + } else if (token == JsonTokenSquaredClose) { + nextToken(json, index); + break; + } else { + QVariant value = parseValue(json, index, success); + if (!success) { + return QVariantList(); + } + list.push_back(value); + } + } + + return QVariant(list); + } + + /** + * parseString + */ + static QVariant parseString(const QString &json, int &index, bool &success) { + QString s; + QChar c; + + eatWhitespace(json, index); + + c = json[index++]; + + bool complete = false; + while(!complete) { + if (index == json.size()) { + break; + } + + c = json[index++]; + + if (c == '\"') { + complete = true; + break; + } else if (c == '\\') { + if (index == json.size()) { + break; + } + + c = json[index++]; + + if (c == '\"') { + s.append('\"'); + } else if (c == '\\') { + s.append('\\'); + } else if (c == '/') { + s.append('/'); + } else if (c == 'b') { + s.append('\b'); + } else if (c == 'f') { + s.append('\f'); + } else if (c == 'n') { + s.append('\n'); + } else if (c == 'r') { + s.append('\r'); + } else if (c == 't') { + s.append('\t'); + } else if (c == 'u') { + int remainingLength = json.size() - index; + if (remainingLength >= 4) { + QString unicodeStr = json.mid(index, 4); + + int symbol = unicodeStr.toInt(0, 16); + + s.append(QChar(symbol)); + + index += 4; + } else { + break; + } + } + } else { + s.append(c); + } + } + + if (!complete) { + success = false; + return QVariant(); + } + + return QVariant(s); + } + + /** + * parseNumber + */ + static QVariant parseNumber(const QString &json, int &index) { + eatWhitespace(json, index); + + int lastIndex = lastIndexOfNumber(json, index); + int charLength = (lastIndex - index) + 1; + QString numberStr; + + numberStr = json.mid(index, charLength); + + index = lastIndex + 1; + bool ok; + + if (numberStr.contains('.')) { + return QVariant(numberStr.toDouble(NULL)); + } else if (numberStr.startsWith('-')) { + int i = numberStr.toInt(&ok); + if (!ok) { + qlonglong ll = numberStr.toLongLong(&ok); + return ok ? ll : QVariant(numberStr); + } + return i; + } else { + uint u = numberStr.toUInt(&ok); + if (!ok) { + qulonglong ull = numberStr.toULongLong(&ok); + return ok ? ull : QVariant(numberStr); + } + return u; + } + } + + /** + * lastIndexOfNumber + */ + static int lastIndexOfNumber(const QString &json, int index) { + int lastIndex; + + for(lastIndex = index; lastIndex < json.size(); lastIndex++) { + if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) { + break; + } + } + + return lastIndex -1; + } + + /** + * eatWhitespace + */ + static void eatWhitespace(const QString &json, int &index) { + for(; index < json.size(); index++) { + if (QString(" \t\n\r").indexOf(json[index]) == -1) { + break; + } + } + } + + /** + * lookAhead + */ + static int lookAhead(const QString &json, int index) { + int saveIndex = index; + return nextToken(json, saveIndex); + } + + /** + * nextToken + */ + static int nextToken(const QString &json, int &index) { + eatWhitespace(json, index); + + if (index == json.size()) { + return JsonTokenNone; + } + + QChar c = json[index]; + index++; + switch(c.toLatin1()) { + case '{': return JsonTokenCurlyOpen; + case '}': return JsonTokenCurlyClose; + case '[': return JsonTokenSquaredOpen; + case ']': return JsonTokenSquaredClose; + case ',': return JsonTokenComma; + case '"': return JsonTokenString; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '-': return JsonTokenNumber; + case ':': return JsonTokenColon; + } + index--; // ^ WTF? + + int remainingLength = json.size() - index; + + // True + if (remainingLength >= 4) { + if (json[index] == 't' && json[index + 1] == 'r' && + json[index + 2] == 'u' && json[index + 3] == 'e') { + index += 4; + return JsonTokenTrue; + } + } + + // False + if (remainingLength >= 5) { + if (json[index] == 'f' && json[index + 1] == 'a' && + json[index + 2] == 'l' && json[index + 3] == 's' && + json[index + 4] == 'e') { + index += 5; + return JsonTokenFalse; + } + } + + // Null + if (remainingLength >= 4) { + if (json[index] == 'n' && json[index + 1] == 'u' && + json[index + 2] == 'l' && json[index + 3] == 'l') { + index += 4; + return JsonTokenNull; + } + } + + return JsonTokenNone; + } + + void setDateTimeFormat(const QString &format) { + dateTimeFormat = format; + } + + void setDateFormat(const QString &format) { + dateFormat = format; + } + + QString getDateTimeFormat() { + return dateTimeFormat; + } + + QString getDateFormat() { + return dateFormat; + } + + void setPrettySerialize(bool enabled) { + prettySerialize = enabled; + } + + bool isPrettySerialize() { + return prettySerialize; + } + + + + QQueue BuilderJsonObject::created_list; + + BuilderJsonObject::BuilderJsonObject() { + // clean objects previous "created" + while (!BuilderJsonObject::created_list.isEmpty()) { + delete BuilderJsonObject::created_list.dequeue(); + } + } + + BuilderJsonObject::BuilderJsonObject(JsonObject &json) { + BuilderJsonObject(); + + obj = json; + } + + BuilderJsonObject *BuilderJsonObject::set(const QString &key, const QVariant &value) { + obj[key] = value; + + return this; + } + + BuilderJsonObject *BuilderJsonObject::set(const QString &key, BuilderJsonObject *builder) { + return set(key, builder->create()); + } + + BuilderJsonObject *BuilderJsonObject::set(const QString &key, BuilderJsonArray *builder) { + return set(key, builder->create()); + } + + JsonObject BuilderJsonObject::create() { + BuilderJsonObject::created_list.enqueue(this); + + return obj; + } + + + QQueue BuilderJsonArray::created_list; + + BuilderJsonArray::BuilderJsonArray() { + // clean objects previous "created" + while (!BuilderJsonArray::created_list.isEmpty()) { + delete BuilderJsonArray::created_list.dequeue(); + } + } + + BuilderJsonArray::BuilderJsonArray(JsonArray &json) { + BuilderJsonArray(); + + array = json; + } + + BuilderJsonArray *BuilderJsonArray::add(const QVariant &element) { + array.append(element); + + return this; + } + + BuilderJsonArray *BuilderJsonArray::add(BuilderJsonObject *builder) { + return add(builder->create()); + } + + BuilderJsonArray *BuilderJsonArray::add(BuilderJsonArray *builder) { + return add(builder->create()); + } + + JsonArray BuilderJsonArray::create() { + BuilderJsonArray::created_list.enqueue(this); + + return array; + } + + + + + BuilderJsonObject *objectBuilder() { + return new BuilderJsonObject(); + } + + BuilderJsonObject *objectBuilder(JsonObject &json) { + return new BuilderJsonObject(json); + } + + BuilderJsonArray *arrayBuilder() { + return new BuilderJsonArray(); + } + + BuilderJsonArray *arrayBuilder(JsonArray &json) { + return new BuilderJsonArray(json); + } + +} //end namespace diff -Nru ukui-control-center-2.0.3/registeredSession/json.h ukui-control-center-3.0.3/registeredSession/json.h --- ukui-control-center-2.0.3/registeredSession/json.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredSession/json.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,265 @@ +/** + * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa. + * Copyright (C) 2011 Eeli Reilin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file json.h + */ + +#ifndef JSON_H +#define JSON_H + +#include +#include +#include + + +/** + * \namespace QtJson + * \brief A JSON data parser + * + * Json parses a JSON data into a QVariant hierarchy. + */ +namespace QtJson { + typedef QVariantMap JsonObject; + typedef QVariantList JsonArray; + + /** + * Clone a JSON object (makes a deep copy) + * + * \param data The JSON object + */ + QVariant clone(const QVariant &data); + + /** + * Insert value to JSON object (QVariantMap) + * + * \param v The JSON object + * \param key The key + * \param value The value + */ + void insert(QVariant &v, const QString &key, const QVariant &value); + + /** + * Append value to JSON array (QVariantList) + * + * \param v The JSON array + * \param value The value + */ + void append(QVariant &v, const QVariant &value); + + /** + * Parse a JSON string + * + * \param json The JSON data + */ + QVariant parse(const QString &json); + + /** + * Parse a JSON string + * + * \param json The JSON data + * \param success The success of the parsing + */ + QVariant parse(const QString &json, bool &success); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * + * \return QByteArray Textual JSON representation in UTF-8 + */ + QByteArray serialize(const QVariant &data); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * \param success The success of the serialization + * + * \return QByteArray Textual JSON representation in UTF-8 + */ + QByteArray serialize(const QVariant &data, bool &success, int _level = 0); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * + * \return QString Textual JSON representation + */ + QString serializeStr(const QVariant &data); + + /** + * This method generates a textual JSON representation + * + * \param data The JSON data generated by the parser. + * \param success The success of the serialization + * + * \return QString Textual JSON representation + */ + QString serializeStr(const QVariant &data, bool &success, int _level = 0); + + /** + * This method sets date(time) format to be used for QDateTime::toString + * If QString is empty, Qt::TextDate is used. + * + * \param format The JSON data generated by the parser. + */ + void setDateTimeFormat(const QString& format); + void setDateFormat(const QString& format); + + /** + * This method gets date(time) format to be used for QDateTime::toString + * If QString is empty, Qt::TextDate is used. + */ + QString getDateTimeFormat(); + QString getDateFormat(); + + /** + * @brief setPrettySerialize enable/disabled pretty-print when serialize() a json + * @param enabled + */ + void setPrettySerialize(bool enabled); + + /** + * @brief isPrettySerialize check if is enabled pretty-print when serialize() a json + * @return + */ + bool isPrettySerialize(); + + + + + /** + * QVariant based Json object + */ + class Object : public QVariant { + template + Object& insertKey(Object* ptr, const QString& key) { + T* p = (T*)ptr->data(); + if (!p->contains(key)) p->insert(key, QVariant()); + return *reinterpret_cast(&p->operator[](key)); + } + template + void removeKey(Object *ptr, const QString& key) { + T* p = (T*)ptr->data(); + p->remove(key); + } + public: + Object() : QVariant() {} + Object(const Object& ref) : QVariant(ref) {} + + Object& operator=(const QVariant& rhs) { + /** It maybe more robust when running under Qt versions below 4.7 */ + QObject * obj = qvariant_cast(rhs); + // setValue(rhs); + setValue(obj); + return *this; + } + Object& operator[](const QString& key) { + if (type() == QVariant::Map) + return insertKey(this, key); + else if (type() == QVariant::Hash) + return insertKey(this, key); + + setValue(QVariantMap()); + + return insertKey(this, key); + } + const Object& operator[](const QString& key) const { + return const_cast(this)->operator[](key); + } + void remove(const QString& key) { + if (type() == QVariant::Map) + removeKey(this, key); + else if (type() == QVariant::Hash) + removeKey(this, key); + } + }; + + + class BuilderJsonArray; + + /** + * @brief The BuilderJsonObject class + */ + class BuilderJsonObject { + + public: + BuilderJsonObject(); + BuilderJsonObject(JsonObject &json); + + BuilderJsonObject *set(const QString &key, const QVariant &value); + BuilderJsonObject *set(const QString &key, BuilderJsonObject *builder); + BuilderJsonObject *set(const QString &key, BuilderJsonArray *builder); + JsonObject create(); + + private: + static QQueue created_list; + + JsonObject obj; + }; + + /** + * @brief The BuilderJsonArray class + */ + class BuilderJsonArray { + + public: + BuilderJsonArray(); + BuilderJsonArray(JsonArray &json); + + BuilderJsonArray *add(const QVariant &element); + BuilderJsonArray *add(BuilderJsonObject *builder); + BuilderJsonArray *add(BuilderJsonArray *builder); + JsonArray create(); + + private: + static QQueue created_list; + + JsonArray array; + }; + + + /** + * @brief Create a BuilderJsonObject + * @return + */ + BuilderJsonObject *objectBuilder(); + + /** + * @brief Create a BuilderJsonObject starting from copy of another json + * @return + */ + BuilderJsonObject *objectBuilder(JsonObject &json); + + /** + * @brief Create a BuilderJsonArray + * @return + */ + BuilderJsonArray *arrayBuilder(); + + /** + * @brief Create a BuilderJsonArray starting from copy of another json + * @return + */ + BuilderJsonArray *arrayBuilder(JsonArray &json); +} + +#endif //JSON_H diff -Nru ukui-control-center-2.0.3/registeredSession/main.cpp ukui-control-center-3.0.3/registeredSession/main.cpp --- ukui-control-center-2.0.3/registeredSession/main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredSession/main.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#include "ukccsessionserver.h" +#include "session_adaptor.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + app.setOrganizationName("Kylin Team"); + app.setApplicationName("ukcc-session-service"); + + ukccSessionServer service; + new InterfaceAdaptor(&service); + + QDBusConnection sessionBus = QDBusConnection::sessionBus(); + if (!sessionBus.registerService("org.ukui.ukcc.session")) { + qCritical() << "QDbus register service failed reason:" << sessionBus.lastError(); + exit(1); + } + + if (!sessionBus.registerObject("/", &service)) { + qCritical() << "QDbus register object failed reason:" << sessionBus.lastError(); + exit(2); + } + return app.exec(); +} diff -Nru ukui-control-center-2.0.3/registeredSession/registeredSession.pro ukui-control-center-3.0.3/registeredSession/registeredSession.pro --- ukui-control-center-2.0.3/registeredSession/registeredSession.pro 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredSession/registeredSession.pro 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,42 @@ +QT += core dbus +QT -= gui +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ukui-control-center-session +TEMPLATE = app + +CONFIG += c++11 console link_pkgconfig +CONFIG -= app_bundle + + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked 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 + + +DBUS_ADAPTORS += conf/org.ukui.ukcc.session.xml +DBUS_INTERFACES += conf/org.ukui.ukcc.session.xml + +inst1.files += conf/org.ukui.ukcc.session.service +inst1.path = /usr/share/dbus-1/services/ +INSTALLS += inst1 + +# You can also make your code fail to compile if it uses 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 += \ + json.cpp \ + main.cpp \ + ukccsessionserver.cpp + +# Default rules for deployment. +target.path = /usr/bin/ +!isEmpty(target.path): INSTALLS += target + +HEADERS += \ + json.h \ + ukccsessionserver.h diff -Nru ukui-control-center-2.0.3/registeredSession/ukccsessionserver.cpp ukui-control-center-3.0.3/registeredSession/ukccsessionserver.cpp --- ukui-control-center-2.0.3/registeredSession/ukccsessionserver.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredSession/ukccsessionserver.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,62 @@ +#include "ukccsessionserver.h" + +#include +#include +#include + +ukccSessionServer::ukccSessionServer() { + +} + +QMap ukccSessionServer::getJsonInfo(const QString &configFile) { + QVariantMap moduleMap; + + QFile file(configFile); + if (file.exists()) { + file.open(QIODevice::ReadOnly); + QByteArray readBy=file.readAll(); + QJsonParseError error; + QJsonDocument readDoc=QJsonDocument::fromJson(readBy,&error); + QJsonArray obj=readDoc.object().value("ukcc").toArray(); + + for (int i = 0 ; i < obj.size(); i++) { + QJsonObject faObj= obj[i].toObject(); + moduleMap.insert(faObj["name"].toString(), faObj["visible"].toVariant()); + QJsonArray childNodeAry = faObj["childnode"].toArray(); + for (int j = 0; j < childNodeAry.size(); j++) { + moduleMap.insert(childNodeAry.at(j).toObject().value("name").toString(), + childNodeAry.at(j).toObject().value("visible").toVariant()); + } + } + } + return moduleMap; +} + +void ukccSessionServer::exitService() { + qApp->exit(); +} + +void ukccSessionServer::ReloadSecurityConfig() +{ + Q_EMIT configChanged(); +} + +QVariantMap ukccSessionServer::getModuleHideStatus() { + QString name = qgetenv("USER"); + if (name.isEmpty()) { + name = qgetenv("USERNAME"); + } + QString filename = QDir::homePath() + "/.config/ukui-control-center-security-config.json"; + + return getJsonInfo(filename); +} + +QString ukccSessionServer::GetSecurityConfigPath() { + QString name = qgetenv("USER"); + if (name.isEmpty()) { + name = qgetenv("USERNAME"); + } + QString filename = QDir::homePath() + "/.config/ukui-control-center-security-config.json"; + + return filename; +} diff -Nru ukui-control-center-2.0.3/registeredSession/ukccsessionserver.h ukui-control-center-3.0.3/registeredSession/ukccsessionserver.h --- ukui-control-center-2.0.3/registeredSession/ukccsessionserver.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/registeredSession/ukccsessionserver.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,41 @@ +#ifndef UKCCSESSIONSERVER_H +#define UKCCSESSIONSERVER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "json.h" + +using QtJson::JsonObject; +using QtJson::JsonArray; + +class ukccSessionServer : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.ukui.ukcc.session.interface") +public: + explicit ukccSessionServer(); + +private: + QMap getJsonInfo(const QString &confFile); + + +Q_SIGNALS: + void configChanged(); + +public slots: + void exitService(); + void ReloadSecurityConfig(); + QVariantMap getModuleHideStatus(); + QString GetSecurityConfigPath(); + +}; + +#endif // UKCCSESSIONSERVER_H diff -Nru ukui-control-center-2.0.3/shell/component/leftmenulist.cpp ukui-control-center-3.0.3/shell/component/leftmenulist.cpp --- ukui-control-center-2.0.3/shell/component/leftmenulist.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/component/leftmenulist.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,30 @@ +#include "leftmenulist.h" + +#include + +LeftMenuList::LeftMenuList(QWidget *parent) : QListWidget(parent) { + +} + +void LeftMenuList::resizeEvent(QResizeEvent *event) { + int maxItemWidth = 0; + for (int i = 0; i < this->count(); i++) { + QWidget *item = this->itemWidget(this->item(i)); + if (item->width() > maxItemWidth) { + maxItemWidth = item->width(); + } + item->setFixedWidth(this->width() - 24); + }; + if (maxItemWidth < 100) { + this->setMinimumWidth(maxItemWidth); + } + + QListWidget::resizeEvent(event); +} + +void LeftMenuList::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + QListWidget::mousePressEvent(event); + } +} diff -Nru ukui-control-center-2.0.3/shell/component/leftmenulist.h ukui-control-center-3.0.3/shell/component/leftmenulist.h --- ukui-control-center-2.0.3/shell/component/leftmenulist.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/component/leftmenulist.h 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,17 @@ +#ifndef LEFTMENULIST_H +#define LEFTMENULIST_H + +#include +#include + +class LeftMenuList : public QListWidget +{ +public: + LeftMenuList(QWidget *parent = nullptr); + +protected: + void resizeEvent(QResizeEvent *event); + void mousePressEvent(QMouseEvent *event); +}; + +#endif // LEFTMENULIST_H diff -Nru ukui-control-center-2.0.3/shell/component/leftwidgetitem.cpp ukui-control-center-3.0.3/shell/component/leftwidgetitem.cpp --- ukui-control-center-2.0.3/shell/component/leftwidgetitem.cpp 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/shell/component/leftwidgetitem.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -24,23 +24,15 @@ #include #include #include +#include LeftWidgetItem::LeftWidgetItem(QWidget *parent) : QWidget(parent) { -// this->setStyleSheet("background: none;"); widget = new QWidget(this); -// widget->setFixedSize(120, 40); -// widget->setStyleSheet("QWidget{background: #FFFFFF;}"); widget->setFixedHeight(40); - iconLabel = new QLabel(widget); - QSizePolicy policy = iconLabel->sizePolicy(); - policy.setHorizontalPolicy(QSizePolicy::Fixed); - policy.setVerticalPolicy(QSizePolicy::Fixed); - iconLabel->setSizePolicy(policy); - iconLabel->setFixedSize(24, 24); textLabel = new QLabel(widget); QSizePolicy policy1 = textLabel->sizePolicy(); @@ -49,9 +41,7 @@ textLabel->setSizePolicy(policy1); textLabel->setScaledContents(true); - QHBoxLayout * mainlayout = new QHBoxLayout(widget); - mainlayout->setSpacing(8); mainlayout->setContentsMargins(8, 0, 0, 0); mainlayout->addWidget(iconLabel, Qt::AlignVCenter); mainlayout->addWidget(textLabel, Qt::AlignVCenter); @@ -59,7 +49,6 @@ widget->setLayout(mainlayout); - QVBoxLayout * baseVerLayout = new QVBoxLayout(this); baseVerLayout->setSpacing(0); baseVerLayout->setMargin(0); @@ -68,6 +57,14 @@ baseVerLayout->addStretch(); setLayout(baseVerLayout); + + const QByteArray id("org.ukui.style"); + QGSettings * fontSetting = new QGSettings(id, QByteArray(), this); + connect(fontSetting, &QGSettings::changed,[=](QString key) { + if ("systemFont" == key || "systemFontSize" ==key) { + changedLabelSlot(); + } + }); } LeftWidgetItem::~LeftWidgetItem() @@ -78,6 +75,7 @@ this->icoName = icoName; QPixmap pix = loadSvg(filename, color); + iconLabel->setFixedSize(24,24);//使用pix.size()时,多倍显示(200%)会有问题 iconLabel->setPixmap(pix); } @@ -88,14 +86,14 @@ } else { fileName = "://img/secondaryleftmenu/"+this->icoName+".svg"; } -// qDebug()<<"file name is-------->"<setPixmap(pix); } -void LeftWidgetItem::setLabelText(QString text){ +void LeftWidgetItem::setLabelText(QString text) { - textLabel->setText(text); + mStr = text; + changedLabelSlot(); } void LeftWidgetItem::setLabelTextIsWhite(bool selected) { @@ -108,14 +106,14 @@ void LeftWidgetItem::setSelected(bool selected){ if (selected) { - widget->setStyleSheet("QWidget{background: #3D6BE5; border-radius: 4px;}"); + widget->setStyleSheet("QWidget{background: palette(Highlight); border-radius: 4px;}"); } else { - widget->setStyleSheet("QWidget{background: palette(base);}"); + widget->setStyleSheet("QListWidget::Item:hover{background:#FF3D6BE5;border-radius: 4px;}"); } } QString LeftWidgetItem::text(){ - return textLabel->text(); + return mStr; } const QPixmap LeftWidgetItem::loadSvg(const QString &fileName, QString color) @@ -171,3 +169,21 @@ return QPixmap::fromImage(img); } +void LeftWidgetItem::resizeEvent(QResizeEvent *event) { + this->textLabel->setFixedWidth(this->width() - 40); + changedLabelSlot(); + QWidget::resizeEvent(event); +} + +void LeftWidgetItem::changedLabelSlot() { + QFontMetrics fontMetrics(textLabel->font()); + int fontSize = fontMetrics.width(mStr); + if (fontSize > textLabel->width()) { + textLabel->setText(fontMetrics.elidedText(mStr, Qt::ElideRight, textLabel->width())); + textLabel->setToolTip(mStr); + } else { + textLabel->setText(mStr); + textLabel->setToolTip(""); + } +} + diff -Nru ukui-control-center-2.0.3/shell/component/leftwidgetitem.h ukui-control-center-3.0.3/shell/component/leftwidgetitem.h --- ukui-control-center-2.0.3/shell/component/leftwidgetitem.h 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/shell/component/leftwidgetitem.h 2021-04-14 01:27:20.000000000 +0000 @@ -25,6 +25,7 @@ #include #include #include +#include class LeftWidgetItem : public QWidget { @@ -44,18 +45,23 @@ QString text(); -private: - // load svg picture + // Load svg picture const QPixmap loadSvg(const QString &fileName, QString color); - // chang svg picture's color + // Chang svg picture's color QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString cgcolor); +protected: + void resizeEvent(QResizeEvent *event); + +private slots: + void changedLabelSlot(); private: QLabel * iconLabel; QLabel * textLabel; QWidget * widget; QString icoName; + QString mStr; }; diff -Nru ukui-control-center-2.0.3/shell/customstyle.cpp ukui-control-center-3.0.3/shell/customstyle.cpp --- ukui-control-center-2.0.3/shell/customstyle.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/customstyle.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -101,17 +101,6 @@ return; break; } -// case CE_ItemViewItem: { -// if (widget->parent() && ((widget->parent()->inherits("QComboBoxPrivateContainer") || -// (qobject_cast(widget->topLevelWidget()) && -// qobject_cast(widget))))) -// { -// break; -// } -// QStyleOptionViewItem item = *qstyleoption_cast(option); -// item.palette.setColor(QPalette::Highlight, item.palette.base().color()); -// return QProxyStyle::drawControl(element, &item, painter, widget); -// } default: break; } @@ -138,9 +127,7 @@ void InternalStyle::polish(QPalette &pal) { QProxyStyle::polish(pal); - pal.setColor(QPalette::Window, pal.base().color()); pal.setColor(QPalette::Inactive, QPalette::Base, pal.base().color()); -// pal.setColor(QPalette::Button, pal.alternateBase().color()); } void InternalStyle::polish(QWidget *widget) @@ -151,4 +138,13 @@ pal.setColor(QPalette::Base, pal.alternateBase().color()); widget->setPalette(pal); } + + // 跳过左侧边栏处理 + if (widget && widget->objectName() == "leftsidebarWidget") { + + } else if (widget){ + QPalette paltte = widget->palette(); + paltte.setColor(QPalette::Window, paltte.base().color()); + widget->setPalette(paltte); + } } diff -Nru ukui-control-center-2.0.3/shell/devicesmonitor.h ukui-control-center-3.0.3/shell/devicesmonitor.h --- ukui-control-center-2.0.3/shell/devicesmonitor.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/devicesmonitor.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,6 @@ +#ifndef DEVICESMONITOR_H +#define DEVICESMONITOR_H + +bool isExitTouchScreen(); + +#endif // DEVICESMONITOR_H diff -Nru ukui-control-center-2.0.3/shell/framelessExtended/framelesshandle.cpp ukui-control-center-3.0.3/shell/framelessExtended/framelesshandle.cpp --- ukui-control-center-2.0.3/shell/framelessExtended/framelesshandle.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/shell/framelessExtended/framelesshandle.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -39,6 +39,7 @@ delete fpri->widgethandleHash.take(widgets[i]); } delete fpri; + fpri = nullptr; } bool FramelessHandle::eventFilter(QObject *watched, QEvent *event){ diff -Nru ukui-control-center-2.0.3/shell/homepagewidget.cpp ukui-control-center-3.0.3/shell/homepagewidget.cpp --- ukui-control-center-2.0.3/shell/homepagewidget.cpp 2020-06-18 07:43:39.000000000 +0000 +++ ukui-control-center-3.0.3/shell/homepagewidget.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -25,7 +25,7 @@ #include #include #include - +#include #include #include "mainwindow.h" @@ -33,28 +33,25 @@ #include "component/clicklabel.h" #include "utils/functionselect.h" #include "component/hoverwidget.h" +#include "./utils/utils.h" HomePageWidget::HomePageWidget(QWidget *parent) : QWidget(parent), ui(new Ui::HomePageWidget) { ui->setupUi(this); - //获取主窗口 + // 获取主窗口 this->setParent(parent); pmainWindow = (MainWindow *)parentWidget(); - // -// ui->listWidget->setStyleSheet("QListWidget#listWidget{border: none;background:#FFFFFF}"); - - - - //初始化首页 + // 初始化首页 initUI(); } HomePageWidget::~HomePageWidget() { delete ui; + ui = nullptr; } void HomePageWidget::initUI(){ @@ -66,7 +63,8 @@ ui->listWidget->setFocusPolicy(Qt::NoFocus); ui->listWidget->setSelectionMode(QAbstractItemView::NoSelection); -// ui->listWidget->setGridSize(QSize(360, 100)); + + mModuleMap = Utils::getModuleHideStatus(); //构建枚举键值转换对象 KeyValueConverter * kvConverter = new KeyValueConverter(); //继承QObject,No Delete @@ -76,7 +74,7 @@ QSignalMapper * moduleSignalMapper = new QSignalMapper(this); - for (int moduleIndex = 0; moduleIndex < TOTALMODULES; moduleIndex++){ + for (int moduleIndex = 0; moduleIndex < TOTALMODULES; moduleIndex++) { //获取插件QMap QMap moduleMap; moduleMap = pmainWindow->exportModule(moduleIndex); @@ -85,13 +83,17 @@ QString modulenameString = kvConverter->keycodeTokeystring(moduleIndex).toLower(); QString modulenamei18nString = kvConverter->keycodeTokeyi18nstring(moduleIndex); - ////构建首页8个模块 + if (mModuleMap.keys().contains(modulenameString)) { + if (!mModuleMap[modulenameString].toBool()) { + continue; + } + } + + //构建首页8个模块 //基础Widget QWidget * baseWidget = new QWidget; baseWidget->setAttribute(Qt::WA_DeleteOnClose); baseWidget->setObjectName("itemBaseWidget"); -// baseWidget->setStyleSheet("QWidget#itemBaseWidget{border: 1px solid #3D68E5;}"); - //解决在20.04悬浮颜色问题 baseWidget->setStyleSheet("QWidget#itemBaseWidget{background: palette(base);}"); //baseWidget 的顶级布局 QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget); @@ -104,27 +106,28 @@ //内容Widget的构建 ResHoverWidget * widget = new ResHoverWidget(modulenameString); -// QWidget * widget = new QWidget; - widget->setFixedSize(QSize(320, 80)); + widget->setMinimumWidth(320); + widget->setMinimumHeight(80); widget->setAttribute(Qt::WA_DeleteOnClose); widget->setObjectName("itemWidget"); - widget->setStyleSheet("ResHoverWidget:hover:!pressed#itemWidget{background: #3D6BE5; border-radius: 4px;}"); - connect(widget, &ResHoverWidget::widgetClicked, [=](QString moduleName){ + widget->setStyleSheet("ResHoverWidget:hover:!pressed#itemWidget{background: palette(Highlight); border-radius: 4px;}"); + connect(widget, &ResHoverWidget::widgetClicked, [=](QString moduleName) { int moduleIndex = kvConverter->keystringTokeycode(moduleName); //获取模块的第一项跳转 QString firstFunc; QList tmpList = FunctionSelect::funcinfoList[moduleIndex]; - for (FuncInfo tmpStruct : tmpList){ - if (moduleMap.keys().contains(tmpStruct.namei18nString)){ - firstFunc = tmpStruct.namei18nString; - //跳转 - pmainWindow->functionBtnClicked(moduleMap.value(firstFunc)); - break; + for (FuncInfo tmpStruct : tmpList) { + if (moduleMap.keys().contains(tmpStruct.namei18nString)) { + if (mModuleMap.isEmpty() || mModuleMap[tmpStruct.nameString.toLower()].toBool()) { + firstFunc = tmpStruct.namei18nString; + //跳转 + pmainWindow->functionBtnClicked(moduleMap.value(firstFunc)); + break; + } } } - }); QHBoxLayout * mainHorLayout = new QHBoxLayout(widget); @@ -132,11 +135,12 @@ mainHorLayout->setSpacing(16); QLabel * logoLabel = new QLabel(widget); + logoLabel->setFixedSize(48, 48); logoLabel->setObjectName("logoLabel"); logoLabel->setScaledContents(true); QString path = (QString(":/img/homepage/%1.svg").arg(modulenameString)); - QPixmap pix = loadSvg(path, BLUE); + QPixmap pix = loadSvg(path, HIGHLIGHT); logoLabel->setPixmap(pix); @@ -148,7 +152,6 @@ titleLabel->setObjectName("mptitleLabel"); titleLabel->setText(modulenamei18nString); -// titleLabel->setStyleSheet("QLabel{font-size: 16px; color: palette(windowText);}"); QHBoxLayout * funcHorLayout = new QHBoxLayout(); //循环填充模块下属功能 @@ -157,16 +160,20 @@ FuncInfo single = tmpList.at(funcIndex); //跳过插件不存在的功能项 if (!moduleMap.contains(single.namei18nString)){ -// qDebug() << single.namei18nString << "plugin object not found"; continue; } //跳过不在首页显示的功能 if (!single.mainShow) continue; + if (mModuleMap.keys().contains(single.nameString.toLower())) { + if (!mModuleMap[single.nameString.toLower()].toBool()) { + continue; + } + } + ClickLabel * label = new ClickLabel(single.namei18nString, widget); label->setStyleSheet("color: palette(Shadow);"); -// palette().color(QPalette::Text) connect(label, SIGNAL(clicked()), moduleSignalMapper, SLOT(map())); moduleSignalMapper->setMapping(label, moduleMap[single.namei18nString]); @@ -195,22 +202,24 @@ //悬浮改变Widget状态 connect(widget, &ResHoverWidget::enterWidget, this, [=](QString mname){ + Q_UNUSED(mname) ResHoverWidget * w = dynamic_cast(QObject::sender()); QPixmap cgPix = loadSvg(path, WHITE); logoLabel->setPixmap(cgPix); - titleLabel->setStyleSheet("color: palette(base);"); + titleLabel->setStyleSheet("color: palette(Light);"); QList clabelList = w->findChildren(); - for (ClickLabel * tmpLabel : clabelList){ - tmpLabel->setStyleSheet("color: palette(base);"); + for (ClickLabel * tmpLabel : clabelList) { + tmpLabel->setStyleSheet("color: palette(Light);"); } }); //还原状态 - connect(widget, &ResHoverWidget::leaveWidget, this, [=](QString mname){ + connect(widget, &ResHoverWidget::leaveWidget, this, [=](QString mname) { + Q_UNUSED(mname) ResHoverWidget * w = dynamic_cast(QObject::sender()); - QPixmap cgPix = loadSvg(path, BLUE); + QPixmap cgPix = loadSvg(path, HIGHLIGHT); logoLabel->setPixmap(cgPix); titleLabel->setStyleSheet("color: palette(windowText);"); @@ -275,7 +284,14 @@ color.setGreen(163); color.setBlue(164); img.setPixelColor(x, y, color); - } else { + } else if(HIGHLIGHT == cgColor){ + QColor highLightColor = palette().color(QPalette::Highlight); + color.setRed(highLightColor.red()); + color.setGreen(highLightColor.green()); + color.setBlue(highLightColor.blue()); + img.setPixelColor(x, y, color); + } + else { return source; } } diff -Nru ukui-control-center-2.0.3/shell/homepagewidget.h ukui-control-center-3.0.3/shell/homepagewidget.h --- ukui-control-center-2.0.3/shell/homepagewidget.h 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/shell/homepagewidget.h 2021-04-14 01:27:20.000000000 +0000 @@ -24,12 +24,14 @@ #include #include #include +#include enum COLOR{ BLUE, WHITE, BLACK, GRAY, + HIGHLIGHT, }; class MainWindow; @@ -61,8 +63,9 @@ private: Ui::HomePageWidget *ui; -private: MainWindow * pmainWindow; + + QVariantMap mModuleMap; }; #endif // HOMEPAGEWIDGET_H diff -Nru ukui-control-center-2.0.3/shell/homepagewidget.ui ukui-control-center-3.0.3/shell/homepagewidget.ui --- ukui-control-center-2.0.3/shell/homepagewidget.ui 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/shell/homepagewidget.ui 2021-04-14 01:27:20.000000000 +0000 @@ -17,7 +17,10 @@ - 40 + 140 + + + 20 diff -Nru ukui-control-center-2.0.3/shell/interface.h ukui-control-center-3.0.3/shell/interface.h --- ukui-control-center-2.0.3/shell/interface.h 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/shell/interface.h 2021-05-20 13:08:14.000000000 +0000 @@ -22,6 +22,7 @@ class QString; class QWidget; +class QStringLiteral; enum FunType{ SYSTEM, @@ -37,6 +38,7 @@ enum SystemIndex{ DISPLAY, + TOUCHSCREEN, DEFAULTAPP, POWER, AUTOBOOT, @@ -50,6 +52,7 @@ KEYBOARD, SHORTCUT, AUDIO, + BLUETOOTH, TOTALDEVICESFUNC, }; @@ -67,6 +70,7 @@ NETCONNECT, VPN, PROXY, + VINO, TOTALNETFUNC, }; @@ -84,13 +88,15 @@ enum SeUpdatesIndex{ SECURITYCENTER, - UPDATES, BACKUP, + UPDATES, + UPGRADE, TOTALSUFUNC, }; enum NoticeAndTasksIndex{ NOTICE, + SEARCH, ABOUT, EXPERIENCEPLAN, TOTALNATFUNC, @@ -103,6 +109,22 @@ virtual int get_plugin_type() = 0; virtual QWidget * get_plugin_ui() = 0; virtual void plugin_delay_control() = 0; + + + /** + * \brief name + * module name (用于搜索?) + */ + virtual const QString name() const = 0; + + /** + * \brief translationPath + * 获取多语言文件路径,用于搜索 + * \return QString + */ + virtual QString translationPath()const { + return QStringLiteral(":/i18n/%1.ts"); + } }; #define CommonInterface_iid "org.kycc.CommonInterface" diff -Nru ukui-control-center-2.0.3/shell/main.cpp ukui-control-center-3.0.3/shell/main.cpp --- ukui-control-center-2.0.3/shell/main.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/main.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -18,119 +18,84 @@ * */ #include "mainwindow.h" -#include -#include "framelessExtended/framelesshandle.h" -#include "customstyle.h" +#include #include #include -#include -#include #include -#include -#include -#include -#include #include -#include #include #include -#include +#include +#include +#include +#include + +#include + +#ifdef KYDEBUG +#include +#endif -void centerToScreen(QWidget* widget) { - if (!widget) - return; - QDesktopWidget* m = QApplication::desktop(); - QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos())); - int desk_x = desk_rect.width(); - int desk_y = desk_rect.height(); - int x = widget->width(); - int y = widget->height(); - widget->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top()); -} - -int getScreenWidth() { - Display *disp = XOpenDisplay(NULL); - Screen *scrn = DefaultScreenOfDisplay(disp); - if (NULL == scrn) { - return 0; - } - int width = scrn->width; +#include "framelessExtended/framelesshandle.h" +#include "customstyle.h" +#include "utils/utils.h" +#include "utils/xatom-helper.h" - if (NULL != disp) { - XCloseDisplay(disp); - } - return width; -} +const QString KLong = "Loongson"; int main(int argc, char *argv[]) { - if (getScreenWidth() > 2560) { - #if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) - QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - #endif + +#ifdef KYDEBUG +#ifndef __sw_64__ + initUkuiLog4qt("ukui-control-center"); +#endif +#endif + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); + + if (Utils::getCpuInfo().startsWith(KLong, Qt::CaseInsensitive)) { + QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software); } - QtSingleApplication a(argc, argv); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) + QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); +#endif + + QString id = QString("ukui-control-center" + QLatin1String(getenv("DISPLAY"))); + QtSingleApplication a(id, argc, argv); if (a.isRunning()) { a.sendMessage(QApplication::arguments().length() > 1 ? QApplication::arguments().at(1) : a.applicationFilePath()); qDebug() << QObject::tr("ukui-control-center is already running!"); return EXIT_SUCCESS; } else { - //加载国际化文件 -// QString locale = QLocale::system().name(); -// QTranslator translator; -// QString qm = locale + ".qm"; -//// qDebug() << "locale is "<< qm <setAttribute(Qt::WA_DeleteOnClose); - - a.setActivationWindow(w); - QObject::connect(&a, SIGNAL(messageReceived(const QString&)),w, SLOT(sltMessageReceived(const QString&))); - w->show(); - - FramelessHandle * pHandle = new FramelessHandle(w); - pHandle->activateOn(w); + MainWindow w; + Utils::centerToScreen(&w); -// auto style = new InternalStyle(nullptr); -// a.setStyle(style); + MotifWmHints hints; + hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; + hints.functions = MWM_FUNC_ALL; + hints.decorations = MWM_DECOR_BORDER; + XAtomHelper::getInstance()->setWindowMotifHint(w.winId(), hints); + + a.setActivationWindow(&w); + QObject::connect(&a, SIGNAL(messageReceived(const QString&)), &w, SLOT(sltMessageReceived(const QString&))); + w.show(); return a.exec(); } diff -Nru ukui-control-center-2.0.3/shell/mainwindow.cpp ukui-control-center-3.0.3/shell/mainwindow.cpp --- ukui-control-center-2.0.3/shell/mainwindow.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/mainwindow.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -21,8 +21,14 @@ #include "ui_mainwindow.h" #include "utils/keyvalueconverter.h" #include "utils/functionselect.h" +#include "utils/utils.h" +#include "../commonComponent/ImageUtil/imageutil.h" +#include "ukccabout.h" +#include "devicesmonitor.h" +#include #include +#include #include #include #include @@ -30,10 +36,19 @@ #include #include #include -#include #include #include #include +#include +#include +#include + +#ifdef WITHKYSEC +#include +#include +#endif + +const QByteArray kVinoSchemas = "org.gnome.Vino"; /* qt会将glib里的signals成员识别为宏,所以取消该宏 * 后面如果用到signals时,使用Q_SIGNALS代替即可 @@ -52,94 +67,200 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), - ui(new Ui::MainWindow) + ui(new Ui::MainWindow), + m_searchWidget(nullptr) { - ui->setupUi(this); - //初始化mixer mate_mixer_init(); - //设置初始大小 - resize(QSize(820, 600)); - //设置窗体无边框 - setWindowFlags(Qt::FramelessWindowHint | Qt::Widget); - this->installEventFilter(this); - ui->closeBtn->setFixedSize(32,32); - //该设置去掉了窗体透明后的黑色背景 - setAttribute(Qt::WA_TranslucentBackground, true); - //将最外层窗体设置为透明 + this->setMinimumSize(958, 630); + logoLabel = new QLabel(tr("Settings"), this); + qApp->installEventFilter(this); + initUI(); +} + +MainWindow::~MainWindow() +{ + delete ui; + ui = nullptr; +} + +void MainWindow::bootOptionsFilter(QString opt) { + if (opt == "--display" || opt == "-m") { + bootOptionsSwitch(SYSTEM, DISPLAY); + }if (opt == "--touchscreen") { + bootOptionsSwitch(SYSTEM, TOUCHSCREEN); + } else if (opt == "--defaultapp") { + bootOptionsSwitch(SYSTEM, DEFAULTAPP); + } else if (opt == "--power" || opt == "-p") { + bootOptionsSwitch(SYSTEM, POWER); + } else if (opt == "--autoboot") { + bootOptionsSwitch(SYSTEM, AUTOBOOT); + } else if (opt == "--printer") { + bootOptionsSwitch(DEVICES, PRINTER); + } else if (opt == "--mouse") { + bootOptionsSwitch(DEVICES, MOUSE); + } else if (opt == "--touchpad") { + bootOptionsSwitch(DEVICES, TOUCHPAD); + } else if (opt == "--keyboard") { + bootOptionsSwitch(DEVICES, KEYBOARD); + } else if (opt == "--shortcut") { + bootOptionsSwitch(DEVICES, SHORTCUT); + } else if (opt == "--audio" || opt == "-s") { + bootOptionsSwitch(DEVICES, AUDIO); + } else if (opt == "--bluetooth") { + bootOptionsSwitch(DEVICES, BLUETOOTH); + } else if (opt == "--background" || opt == "-b") { + bootOptionsSwitch(PERSONALIZED, BACKGROUND); + } else if (opt == "--theme") { + bootOptionsSwitch(PERSONALIZED, THEME); + } else if (opt == "--screenlock") { + bootOptionsSwitch(PERSONALIZED, SCREENLOCK); + } else if (opt == "--screensaver") { + bootOptionsSwitch(PERSONALIZED, SCREENSAVER); + } else if (opt == "--fonts") { + bootOptionsSwitch(PERSONALIZED, FONTS); + } else if (opt == "--desktop" || opt == "-d") { + bootOptionsSwitch(PERSONALIZED, DESKTOP); + } else if (opt == "--netconnect") { + bootOptionsSwitch(NETWORK, NETCONNECT); + } else if (opt == "--vpn" || opt == "-g") { + bootOptionsSwitch(NETWORK, VPN); + } else if (opt == "--proxy") { + bootOptionsSwitch(NETWORK, PROXY); + } else if (opt == "--userinfo" || opt == "-u") { + bootOptionsSwitch(ACCOUNT, USERINFO); + } else if (opt == "--cloudaccount") { + bootOptionsSwitch(ACCOUNT, NETWORKACCOUNT); + } else if (opt == "--datetime" || opt == "-t") { + bootOptionsSwitch(DATETIME, DAT); + } else if (opt == "--area") { + bootOptionsSwitch(DATETIME, AREA); + } else if (opt == "--upgrade") { + bootOptionsSwitch(UPDATE, UPGRADE); + } else if (opt == "--backup") { + bootOptionsSwitch(UPDATE, BACKUP); + } else if (opt == "--notice" || opt == "-n") { + bootOptionsSwitch(NOTICEANDTASKS, NOTICE); + } else if (opt == "--about" || opt == "-a") { + bootOptionsSwitch(NOTICEANDTASKS, ABOUT); + } else if (opt == "--search") { + bootOptionsSwitch(NOTICEANDTASKS, SEARCH); + } +} + +void MainWindow::bootOptionsSwitch(int moduleNum, int funcNum){ + + QList pFuncStructList = FunctionSelect::funcinfoList[moduleNum]; + QString funcStr = pFuncStructList.at(funcNum).namei18nString; + qDebug() << "moduleNum is" << moduleNum << " " << funcNum << " " << funcStr << endl; -// setStyleSheet("QMainWindow#MainWindow{background-color: transparent;}"); + QMap pluginsObjMap = modulesList.at(moduleNum); + + if (pluginsObjMap.keys().contains(funcStr)){ + //开始跳转 + ui->stackedWidget->setCurrentIndex(1); + modulepageWidget->switchPage(pluginsObjMap.value(funcStr)); + } +} + +bool MainWindow::eventFilter(QObject *watched, QEvent *event) { + /* clear m_searchWidget's focus + * MouseButtonPress event happened but not in m_searchWidget + */ + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mEvent = static_cast(event); + QWidget *searchParentWid = static_cast(m_searchWidget->parent()); + QPoint searchPoint = searchParentWid->mapFromGlobal(mEvent->globalPos()); + //qDebug()<geometry()<< mWindowGlobalPoint << mouseGlobalPoint << tPoint; + if (!m_searchWidget->geometry().contains(searchPoint)) { + if (m_isSearching == true) { + m_searchWidget->setFocus(); + m_searchWidget->clearFocus(); + } + } + } + if (this == watched) { + if (event->type() == QEvent::WindowStateChange) { + if (this->windowState() == Qt::WindowMaximized) { + maxBtn->setIcon(QIcon::fromTheme("window-restore-symbolic")); + } else { + maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic")); + } + } else if (event->type() == QEvent::MouseButtonDblClick) { + bool res = dblOnEdge(dynamic_cast(event)); + if (res) { + if (this->windowState() == Qt::WindowMaximized) { + this->showNormal(); + } else { + this->showMaximized(); + } + } + } + } + if (watched == m_searchWidget) { + if (event->type() == QEvent::FocusIn) { + if (m_searchWidget->text().isEmpty()) { + m_animation->stop(); + m_animation->setStartValue(QRect((m_searchWidget->width()-(m_queryIcon->width()+m_queryText->width()+10))/2,0, + m_queryIcon->width()+m_queryText->width()+30,(m_searchWidget->height()+32)/2)); + m_animation->setEndValue(QRect(0, 0, m_queryIcon->width() + 5,(m_searchWidget->height()+32)/2)); + m_animation->setEasingCurve(QEasingCurve::OutQuad); + m_animation->start(); + m_searchWidget->setTextMargins(30, 1, 0, 1); + } + m_isSearching = true; + } else if (event->type() == QEvent::FocusOut) { + m_searchKeyWords.clear(); + if (m_searchWidget->text().isEmpty()) { + if (m_isSearching) { + m_queryText->adjustSize(); + m_animation->setStartValue(QRect(0, 0, + m_queryIcon->width()+5,(m_searchWidget->height()+36)/2)); + m_animation->setEndValue(QRect((m_searchWidget->width() - (m_queryIcon->width()+m_queryText->width()+10))/2,0, + m_queryIcon->width()+m_queryText->width()+30,(m_searchWidget->height()+36)/2)); + m_animation->setEasingCurve(QEasingCurve::InQuad); + m_animation->start(); + } + } + m_isSearching=false; + } + } + return QObject::eventFilter(watched, event); +} + +void MainWindow::initUI() { + ui->setupUi(this); + ui->centralWidget->setStyleSheet("QWidget#centralWidget{background: palette(base); border-radius: 6px;}"); + + m_ModuleMap = Utils::getModuleHideStatus(); + + //this->installEventFilter(this); const QByteArray id("org.ukui.style"); - QGSettings * fontSetting = new QGSettings(id); - connect(fontSetting, &QGSettings::changed,[=](QString key){ + m_fontSetting = new QGSettings(id, QByteArray(), this); + connect(m_fontSetting, &QGSettings::changed, this, [=](QString key) { if ("systemFont" == key || "systemFontSize" ==key) { + changeSearchSlot(); QFont font = this->font(); int width = font.pointSize(); for (auto widget : qApp->allWidgets()) { - widget->setFont(font); + if (widget->objectName() == "timeClockLable") { + QFont fontTime; + fontTime.setPointSize(font.pointSize() + 8); + fontTime.setBold(true); + widget->setFont(fontTime); + } else { + widget->setFont(font); + } } ui->leftsidebarWidget->setMaximumWidth(width * 10 +20); } }); - //设置panel图标 - QIcon panelicon; - if (QIcon::hasThemeIcon("ukui-control-center")) - panelicon = QIcon::fromTheme("ukui-control-center"); -// else -// panelicon = QIcon("://applications-system.svg"); - this->setWindowIcon(panelicon); - this->setWindowTitle(tr("ukcc")); - - ui->searchLineEdit->setVisible(false); - //中部内容区域 - ui->stackedWidget->setStyleSheet("QStackedWidget#stackedWidget{background: palette(base); border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); - //标题栏widget - ui->titlebarWidget->setStyleSheet("QWidget#titlebarWidget{background: palette(base); border-top-left-radius: 6px; border-top-right-radius: 6px;}"); -//// //左上角文字 -//// ui->mainLabel->setStyleSheet("QLabel#mainLabel{font-size: 18px; color: #40000000;}"); - - //左上角返回按钮 - ui->backBtn->setProperty("useIconHighlightEffect", true); - ui->backBtn->setProperty("iconHighlightEffectMode", 1); - ui->backBtn->setFlat(true); - -// ui->backBtn->setStyleSheet("QPushButton#backBtn{background: #ffffff; border: none;}"); -// //顶部搜索框 -// ui->searchLineEdit->setStyleSheet("QLineEdit#searchLineEdit{background: #FFEDEDED; border: none; border-radius: 6px;}"); - //右上角按钮stylesheet - ui->minBtn->setProperty("useIconHighlightEffect", true); - ui->minBtn->setProperty("iconHighlightEffectMode", 1); - ui->minBtn->setFlat(true); - ui->maxBtn->setProperty("useIconHighlightEffect", true); - ui->maxBtn->setProperty("iconHighlightEffectMode", 1); - ui->maxBtn->setFlat(true); - ui->closeBtn->setProperty("useIconHighlightEffect", true); - ui->closeBtn->setProperty("iconHighlightEffectMode", 1); - ui->closeBtn->setFlat(true); - ui->closeBtn->installEventFilter(this); - -// ui->minBtn->setStyleSheet("QPushButton#minBtn{background: #ffffff; border: none;}" -// "QPushButton:hover:!pressed#minBtn{background: #FF3D6BE5; border-radius: 2px;}" -// "QPushButton:hover:pressed#minBtn{background: #415FC4; border-radius: 2px;}"); -// ui->maxBtn->setStyleSheet("QPushButton#maxBtn{background: #ffffff; border: none;}" -// "QPushButton:hover:!pressed#maxBtn{background: #FF3D6BE5; border-radius: 2px;}" -// "QPushButton:hover:pressed#maxBtn{background: #415FC4; border-radius: 2px;}"); - ui->closeBtn->setStyleSheet("QPushButton:hover:!pressed#closeBtn{background: #FA6056; border-radius: 4px;}" - "QPushButton:hover:pressed#closeBtn{background: #E54A50; border-radius: 4px;}"); - - //左侧一级菜单 -// ui->leftsidebarWidget->setStyleSheet("QWidget#leftsidebarWidget{background: #cccccc; border: none; border-top-left-radius: 6px; border-bottom-left-radius: 6px;}"); - ui->leftsidebarWidget->setStyleSheet("QWidget#leftsidebarWidget{background-color: palette(button);border: none; border-top-left-radius: 6px; border-bottom-left-radius: 6px;}"); - - //设置左上角按钮图标 - ui->backBtn->setIcon(QIcon("://img/titlebar/back.svg")); - - //设置右上角按钮图标 - ui->minBtn->setIcon(QIcon::fromTheme("window-minimize-symbolic")); - ui->maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic")); - ui->closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic")); - + initTileBar(); + m_queryWid->setGeometry(QRect((m_searchWidget->width() - (m_queryIcon->width()+m_queryText->width()+10))/2,0, + m_queryIcon->width()+m_queryText->width()+10,(m_searchWidget->height()+36)/2)); + m_queryWid->show(); + initStyleSheet(); //初始化功能列表数据 FunctionSelect::initValue(); @@ -150,51 +271,41 @@ //加载插件 loadPlugins(); - connect(ui->minBtn, SIGNAL(clicked()), this, SLOT(showMinimized())); -// connect(ui->minBtn, &QPushButton::clicked, [=]{ -// KWindowSystem::minimizeWindow(this->winId()); -// }); - connect(ui->maxBtn, &QPushButton::clicked, this, [=]{ - if (isMaximized()){ + connect(mOptionBtn, SIGNAL(clicked()), this, SLOT(showUkccAboutSlot())); + connect(minBtn, SIGNAL(clicked()), this, SLOT(showMinimized())); + connect(maxBtn, &QPushButton::clicked, this, [=] { + if (isMaximized()) { showNormal(); - ui->maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic")); + maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic")); } else { showMaximized(); - ui->maxBtn->setIcon(QIcon::fromTheme("window-restore-symbolic")); + maxBtn->setIcon(QIcon::fromTheme("window-restore-symbolic")); } }); - connect(ui->closeBtn, &QPushButton::clicked, this, [=]{ + connect(closeBtn, &QPushButton::clicked, this, [=] { close(); -// qApp->quit(); }); - -// connect(ui->backBtn, &QPushButton::clicked, this, [=]{ -// if (ui->stackedWidget->currentIndex()) -// ui->stackedWidget->setCurrentIndex(0); -// else -// ui->stackedWidget->setCurrentIndex(1); -// }); - - -// ui->leftsidebarWidget->setVisible(ui->stackedWidget->currentIndex()); connect(ui->stackedWidget, &QStackedWidget::currentChanged, this, [=](int index){ - //左侧边栏显示/不显示 - ui->leftsidebarWidget->setVisible(index); - //左上角显示字符/返回按钮 - ui->backBtn->setVisible(index); - ui->titleLabel->setHidden(index); if (index){ //首页部分组件样式 - //中部内容区域 + titleLabel->setHidden(true); + mTitleIcon->setHidden(true); + ui->leftsidebarWidget->setVisible(true); + //左上角显示字符/返回按钮 + backBtn->setVisible(true); + ui->stackedWidget->setStyleSheet("QStackedWidget#stackedWidget{background: palette(base); border-bottom-right-radius: 6px;}"); - //标题栏widget - ui->titlebarWidget->setStyleSheet("QWidget#titlebarWidget{background: palette(base); border-top-right-radius: 6px;}"); } else { //次页部分组件样式 + //左侧边栏显示/不显示 + ui->leftsidebarWidget->setHidden(true); + titleLabel->setVisible(true); + mTitleIcon->setVisible(true); + //左上角显示字符/返回按钮 + backBtn->setHidden(true); + //中部内容区域 ui->stackedWidget->setStyleSheet("QStackedWidget#stackedWidget{background: palette(base); border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); - //标题栏widget - ui->titlebarWidget->setStyleSheet("QWidget#titlebarWidget{background: palette(base); border-top-left-radius: 6px; border-top-right-radius: 6px;}"); } }); @@ -210,7 +321,7 @@ ui->stackedWidget->addWidget(modulepageWidget); //top left return button - connect(ui->backBtn, &QPushButton::clicked, this, [=]{ + connect(backBtn, &QPushButton::clicked, this, [=]{ FunctionSelect::popRecordValue(); //if recordFuncStack is empty, it means there is no history record. So return to homepage @@ -222,157 +333,152 @@ } }); - //快捷参数 - if (QApplication::arguments().length() > 1){ - + // 快捷参数 + if (QApplication::arguments().length() > 1) { bootOptionsFilter(QApplication::arguments().at(1)); } -} -MainWindow::~MainWindow() -{ - delete ui; + //快捷键 + new QShortcut(QKeySequence(Qt::Key_F1), this, SLOT(onF1ButtonClicked())); } -void MainWindow::bootOptionsFilter(QString opt){ - if (opt == "-m") { - //显示器 - bootOptionsSwitch(SYSTEM, DISPLAY); +void MainWindow::initTileBar() { - } else if (opt == "-b") { - //背景 - bootOptionsSwitch(PERSONALIZED, BACKGROUND); + ui->titleLayout->setContentsMargins(8, 4, 4, 0); + ui->titleLayout->setSpacing(0); + m_searchWidget = new SearchWidget(this); + m_searchWidget->setFocusPolicy(Qt::ClickFocus); + //m_searchWidget->installEventFilter(this); + + m_queryWid = new QWidget; + m_queryWid->setParent(m_searchWidget); + m_queryWid->setFocusPolicy(Qt::NoFocus); + + QHBoxLayout* queryWidLayout = new QHBoxLayout; + queryWidLayout->setContentsMargins(0, 0, 0, 0); + queryWidLayout->setAlignment(Qt::AlignJustify); + queryWidLayout->setSpacing(0); + m_queryWid->setLayout(queryWidLayout); + + QIcon searchIcon = QIcon::fromTheme("edit-find-symbolic"); + m_queryIcon = new QLabel(this); + m_queryIcon->setPixmap(searchIcon.pixmap(searchIcon.actualSize(QSize(16, 16)))); + m_queryIcon->setProperty("useIconHighlightEffect",0x10); + + m_queryText = new QLabel(this); + m_queryText->setText(tr("Search")); + m_queryText->setStyleSheet("background:transparent;color:#626c6e;"); + + queryWidLayout->addWidget(m_queryIcon); + queryWidLayout->addWidget(m_queryText); + + m_searchWidget->setContextMenuPolicy(Qt::NoContextMenu); + m_animation= new QPropertyAnimation(m_queryWid, "geometry", this); + m_animation->setDuration(100); + ui->titleLayout->addWidget(m_searchWidget,Qt::AlignCenter); + connect(m_animation,&QPropertyAnimation::finished,this,&MainWindow::animationFinishedSlot); + + connect(m_searchWidget, &SearchWidget::notifyModuleSearch, this, &MainWindow::switchPage); + + backBtn = new QPushButton(this); + mOptionBtn = new QPushButton(this); + minBtn = new QPushButton(this); + maxBtn = new QPushButton(this); + closeBtn = new QPushButton(this); + mTitleIcon = new QLabel(this); + titleLabel = new QLabel(tr("Settings"), this); + + backBtn->setFixedSize(30, 30); + mOptionBtn->setFixedSize(30, 30); + minBtn->setFixedSize(30, 30); + maxBtn->setFixedSize(30, 30); + closeBtn->setFixedSize(30, 30); + mTitleIcon->setFixedSize(24, 24); + + mOptionBtn->setToolTip(tr("Main menu")); + minBtn->setToolTip(tr("Minimize")); + maxBtn->setToolTip(tr("Maximize/Normal")); + closeBtn->setToolTip(tr("Close")); + + QIcon titleIcon = QIcon::fromTheme("ukui-control-center"); + mTitleIcon->setPixmap(titleIcon.pixmap(titleIcon.actualSize(QSize(24, 24)))); + + titleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + changeSearchSlot(); + m_searchWidget->setFixedWidth(350); + + ui->titleLayout->addWidget(mTitleIcon); + ui->titleLayout->addSpacing(8); + ui->titleLayout->addWidget(titleLabel); + ui->titleLayout->addWidget(backBtn); + ui->titleLayout->addStretch(); + ui->titleLayout->addWidget(m_searchWidget); + ui->titleLayout->addStretch(); + ui->titleLayout->addWidget(mOptionBtn); + ui->titleLayout->addSpacing(4); + ui->titleLayout->addWidget(minBtn); + ui->titleLayout->addSpacing(4); + ui->titleLayout->addWidget(maxBtn); + ui->titleLayout->addSpacing(4); + ui->titleLayout->addWidget(closeBtn); +} +void MainWindow::animationFinishedSlot() +{ + if (m_isSearching) { + m_queryWid->layout()->removeWidget(m_queryText); + m_queryText->setParent(nullptr); + m_searchWidget->setTextMargins(30, 1, 0, 1); + if(!m_searchKeyWords.isEmpty()) { + m_searchWidget->setText(m_searchKeyWords); + m_searchKeyWords.clear(); + } + } else { + m_queryWid->layout()->addWidget(m_queryText); + } +} - } else if (opt == "-d") { - //桌面 - bootOptionsSwitch(PERSONALIZED, DESKTOP); +void MainWindow::onF1ButtonClicked() { + qDebug() << "onF1ButtonClicked"; + QString command = "kylin-user-guide"; - } else if (opt == "-u") { - //账户 - bootOptionsSwitch(ACCOUNT, USERINFO); + QProcess p(0); + QStringList args; - } else if (opt == "-a") { - //关于 - bootOptionsSwitch(NOTICEANDTASKS, ABOUT); + args.append("-A"); + args.append("ukui-control-center"); - } else if (opt == "-p") { - //电源 - bootOptionsSwitch(SYSTEM, POWER); - } else if (opt == "-t") { - // Datetime moudle - bootOptionsSwitch(DATETIME, DAT); - } else if (opt == "-s") { - // Audio module - bootOptionsSwitch(DEVICES, AUDIO); - } else if (opt == "-n") { - // notice module - bootOptionsSwitch(NOTICEANDTASKS, NOTICE); - } + p.startDetached(command,args);//command是要执行的命令,args是参数 + p.waitForFinished(-1); } -void MainWindow::bootOptionsSwitch(int moduleNum, int funcNum){ +void MainWindow::showUkccAboutSlot() { + QMenu* ukccMain = new QMenu(this); + ukccMain->setObjectName("mainMenu"); - QList pFuncStructList = FunctionSelect::funcinfoList[moduleNum]; - QString funcStr = pFuncStructList.at(funcNum).namei18nString; + QAction* ukccHelp = new QAction(tr("Help"),this); + ukccMain->addAction(ukccHelp); + QAction* ukccAbout = new QAction(tr("About"),this); + ukccMain->addAction(ukccAbout); + QAction* ukccExit = new QAction(tr("Exit"),this); + ukccMain->addAction(ukccExit); + QPoint pt= QPoint(mOptionBtn->x() + 10, mOptionBtn->y()+mOptionBtn->height()); - QMap pluginsObjMap = modulesList.at(moduleNum); + connect(ukccExit, SIGNAL(triggered()), this, SLOT(close())); - if (pluginsObjMap.keys().contains(funcStr)){ - //开始跳转 - ui->stackedWidget->setCurrentIndex(1); - modulepageWidget->switchPage(pluginsObjMap.value(funcStr)); - } -} + connect(ukccAbout, &QAction::triggered, this, [=] { + UkccAbout *ukcc = new UkccAbout(this); + ukcc->exec(); + }); -void MainWindow::paintEvent(QPaintEvent *event) { - Q_UNUSED(event); - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); - QPainterPath rectPath; - rectPath.addRoundedRect(this->rect().adjusted(1, 1, -1, -1), 6, 6); - - // 画一个黑底 - QPixmap pixmap(this->rect().size()); - pixmap.fill(Qt::transparent); - QPainter pixmapPainter(&pixmap); - pixmapPainter.setRenderHint(QPainter::Antialiasing); - pixmapPainter.setPen(Qt::transparent); - pixmapPainter.setBrush(Qt::black); - pixmapPainter.drawPath(rectPath); - pixmapPainter.end(); - - // 模糊这个黑底 - QImage img = pixmap.toImage(); - qt_blurImage(img, 5, false, false); - - // 挖掉中心 - pixmap = QPixmap::fromImage(img); - QPainter pixmapPainter2(&pixmap); - pixmapPainter2.setRenderHint(QPainter::Antialiasing); - pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); - pixmapPainter2.setPen(Qt::transparent); - pixmapPainter2.setBrush(Qt::transparent); - pixmapPainter2.drawPath(rectPath); - - // 绘制阴影 - p.drawPixmap(this->rect(), pixmap, pixmap.rect()); - - // 绘制一个背景 - p.save(); - p.fillPath(rectPath,palette().color(QPalette::Base)); -// p.fillPath(rectPath,QColor(0,0,0)); - p.restore(); -} + connect(ukccHelp, &QAction::triggered, this, [=] { + QProcess process(this); + process.startDetached("kylin-user-guide -A ukui-control-center"); + }); -bool MainWindow::eventFilter(QObject *watched, QEvent *event) { - if (this == watched) { - if (event->type() == QEvent::WindowStateChange) { - if (this->windowState() == Qt::WindowMaximized) { - QFont font = this->font(); - int width = font.pointSize(); - ui->leftsidebarWidget->setMaximumWidth(width * 10 +20); - for (int i = 0; i <= 9; i++) { - QPushButton * btn = static_cast(ui->leftsidebarVerLayout->itemAt(i)->widget()); - - if (btn) { - QLayout *layout = btn->layout(); - QLabel * tipLabel = static_cast(layout->itemAt(1)->widget()); - tipLabel->setVisible(true); - } - } - } else { - ui->leftsidebarWidget->setMaximumWidth(60); - for (int i = 0; i <= 9; i++) { - QPushButton * btn = static_cast(ui->leftsidebarVerLayout->itemAt(i)->widget()); - if (btn) { - QLayout *layout = btn->layout(); - QLabel * tipLabel = static_cast(layout->itemAt(1)->widget()); - tipLabel->setVisible(false); - } - } - } - } else if (event->type() == QEvent::MouseButtonDblClick) { - bool res = dblOnEdge(dynamic_cast(event)); - if (res) { - if (this->windowState() == Qt::WindowMaximized) { - this->showNormal(); - } else { - this->showMaximized(); - } - } - } - } - if(ui->closeBtn == watched) { - if(event->type() == QEvent::Enter) { - ui->closeBtn->setIcon(renderSvg(QIcon::fromTheme("window-close-symbolic"),"white")); - }else if(event->type() == QEvent::Leave) { - ui->closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic")); - } - } - return QObject::eventFilter(watched, event); + ukccMain->exec(this->mapToGlobal(pt)); } - -void MainWindow::setBtnLayout(QPushButton * &pBtn){ +void MainWindow::setBtnLayout(QPushButton * &pBtn) { QLabel * imgLabel = new QLabel(pBtn); QSizePolicy imgLabelPolicy = imgLabel->sizePolicy(); imgLabelPolicy.setHorizontalPolicy(QSizePolicy::Fixed); @@ -408,13 +514,24 @@ pluginsDir = QDir(qApp->applicationDirPath() + "/plugins"); } - bool isExistCloud = isExitsCloudAccount(); foreach (QString fileName, pluginsDir.entryList(QDir::Files)){ - if (!fileName.endsWith(".so")) - continue; - if (fileName == "libexperienceplan.so") - continue; - if ("libnetworkaccount.so" == fileName && !isExistCloud) { + //三权分立开启 +#ifdef WITHKYSEC + if (!kysec_is_disabled() && kysec_get_3adm_status() && (getuid() || geteuid())){ + //时间和日期 | 用户账户 | 电源管理 |网络连接 |网络代理 + if (fileName.contains("datetime") || fileName.contains("userinfo") || fileName.contains("power") || \ + fileName.contains("netconnect") || fileName.contains("proxy") || fileName.contains("update") || \ + fileName.contains("upgrade") || fileName.contains("backup")) + continue; + } +#endif + if (!fileName.endsWith(".so") + || (fileName == "libexperienceplan.so") + || ("libnetworkaccount.so" == fileName && !isExitsCloudAccount()) + || (!QGSettings::isSchemaInstalled(kVinoSchemas) && "libvino.so" == fileName) + || ("libbluetooth.so" == fileName && !isExitBluetooth()) + || ("libtouchscreen.so" == fileName && !isExitTouchScreen()) + || ("libupdate.so" == fileName && !Utils::isCommunity())) { continue; } @@ -427,9 +544,14 @@ //屏保功能依赖ukui-session-manager if ((!g_file_test(screensaverFile, G_FILE_TEST_EXISTS) || - !g_file_test(sessionFile, G_FILE_TEST_EXISTS)) && + !g_file_test(sessionFile, G_FILE_TEST_EXISTS)) && (fileName == "libscreensaver.so" || fileName == "libscreenlock.so")) continue; +#ifdef __sw_64__ + if ("libpower.so" == fileName) { + continue; + } +#endif const char * securityCmd = "/usr/sbin/ksc-defender"; @@ -444,6 +566,8 @@ qDebug() << "Load Plugin :" << kvConverter->keycodeTokeyi18nstring(pluginInstance->get_plugin_type()) << "->" << pluginInstance->get_plugin_name() ; + m_searchWidget->addModulesName(pluginInstance->name(), pluginInstance->get_plugin_name(), pluginInstance->translationPath()); + int moduletypeInt = pluginInstance->get_plugin_type(); if (!moduleIndexList.contains(moduletypeInt)) moduleIndexList.append(moduletypeInt); @@ -453,6 +577,7 @@ qDebug() << fileName << "Load Failed: " << loader.errorString() << "\n"; } } + m_searchWidget->setLanguage(QLocale::system().name()); } void MainWindow::initLeftsideBar(){ @@ -461,41 +586,37 @@ leftMicBtnGroup = new QButtonGroup(); //构建左侧边栏返回首页按钮 - QPushButton * hBtn = buildLeftsideBtn("homepage",tr("HOME")); + QPushButton * hBtn = buildLeftsideBtn("homepage",tr("Home")); hBtn->setObjectName("homepage"); connect(hBtn, &QPushButton::clicked, this, [=]{ ui->stackedWidget->setCurrentIndex(0); }); - hBtn->setStyleSheet("QPushButton#homepage{background: palette(button); border: none;}"); -// hBtn->setStyleSheet("QPushButton#homepage{background: palette(base);}"); - ui->leftsidebarVerLayout->addStretch(); + hBtn->setStyleSheet("QPushButton#homepage{background: palette(window); border: none;}"); ui->leftsidebarVerLayout->addWidget(hBtn); - QString locale = QLocale::system().name(); - for(int type = 0; type < TOTALMODULES; type++){ + for(int type = 0; type < TOTALMODULES; type++) { //循环构建左侧边栏一级菜单按钮 if (moduleIndexList.contains(type)){ QString mnameString = kvConverter->keycodeTokeystring(type); QString mnamei18nString = kvConverter->keycodeTokeyi18nstring(type); //设置TEXT + if (m_ModuleMap.keys().contains(mnameString.toLower())) { + if (!m_ModuleMap[mnameString.toLower()].toBool()) { + continue; + } + } + QPushButton * button; QString btnName = "btn" + QString::number(type + 1); - if ("zh_CN" == locale) { - button = buildLeftsideBtn(mnameString,mnamei18nString); - button->setToolTip(mnamei18nString); - } else { - button = buildLeftsideBtn(mnameString,mnameString); - button->setToolTip(mnameString); - } + button = buildLeftsideBtn(mnameString,mnamei18nString); + button->setToolTip(mnamei18nString); + button->setObjectName(btnName); button->setCheckable(true); leftBtnGroup->addButton(button, type); - //设置样式 -// button->setStyleSheet("QPushButton::checked{background: palette(button); border: none; border-image: url('://img/primaryleftmenu/checked.png');}" -// "QPushButton::!checked{background: palette(button);border: none;}"); button->setStyleSheet("QPushButton::checked{background: palette(base); border-top-left-radius: 6px;border-bottom-left-radius: 6px;}" - "QPushButton::!checked{background: palette(button);border: none;}"); + "QPushButton::!checked{background: palette(window);border: none;}"); connect(button, &QPushButton::clicked, this, [=]{ QPushButton * btn = dynamic_cast(QObject::sender()); @@ -507,9 +628,11 @@ QMap currentFuncMap = modulesList[selectedInt]; for (FuncInfo tmpStruct : tmpList){ - if (currentFuncMap.keys().contains(tmpStruct.namei18nString)){ - modulepageWidget->switchPage(currentFuncMap.value(tmpStruct.namei18nString)); - break; + if (currentFuncMap.keys().contains(tmpStruct.namei18nString)) { + if (m_ModuleMap.isEmpty() || m_ModuleMap[tmpStruct.nameString.toLower()].toBool()) { + modulepageWidget->switchPage(currentFuncMap.value(tmpStruct.namei18nString)); + break; + } } } }); @@ -521,14 +644,14 @@ ui->leftsidebarVerLayout->addStretch(); } -QPushButton * MainWindow::buildLeftsideBtn(QString bname,QString tipName){ +QPushButton * MainWindow::buildLeftsideBtn(QString bname,QString tipName) { QString iname = bname.toLower(); int itype = kvConverter->keystringTokeycode(bname); QPushButton * leftsidebarBtn = new QPushButton(); leftsidebarBtn->setAttribute(Qt::WA_DeleteOnClose); leftsidebarBtn->setCheckable(true); -// leftsidebarBtn->setFixedSize(QSize(60, 56)); //Widget Width 60 + // leftsidebarBtn->setFixedSize(QSize(60, 56)); //Widget Width 60 leftsidebarBtn->setFixedHeight(56); QPushButton * iconBtn = new QPushButton(leftsidebarBtn); @@ -536,12 +659,11 @@ iconBtn->setFixedSize(QSize(24, 24)); iconBtn->setFocusPolicy(Qt::NoFocus); - - QString iconHomePageBtnQss = QString("QPushButton{background: palette(button); border: none;}"); + QString iconHomePageBtnQss = QString("QPushButton{background: palette(window); border: none;}"); QString iconBtnQss = QString("QPushButton:checked{background: palette(base); border: none;}" - "QPushButton:!checked{background: palette(button); border: none;}"); + "QPushButton:!checked{background: palette(window); border: none;}"); QString path = QString("://img/primaryleftmenu/%1.svg").arg(iname); - QPixmap pix = loadSvg(path, "default"); + QPixmap pix = ImageUtil::loadSvg(path, "default"); //单独设置HomePage按钮样式 if (iname == "homepage") { iconBtn->setFlat(true); @@ -553,33 +675,32 @@ leftMicBtnGroup->addButton(iconBtn, itype); - connect(iconBtn, &QPushButton::toggled, this, [=] (bool checked){ - QString path = QString("://img/primaryleftmenu/%1.svg").arg(iname); - QPixmap pix; - if (checked) { - pix = loadSvg(path, "blue"); - } else { - pix = loadSvg(path, "default"); - } - iconBtn->setIcon(pix); + connect(iconBtn, &QPushButton::toggled, this, [=] (bool checked) { + QString path = QString("://img/primaryleftmenu/%1.svg").arg(iname); + QPixmap pix; + if (checked) { + pix = ImageUtil::loadSvg(path, "blue"); + } else { + pix = ImageUtil::loadSvg(path, "default"); + } + iconBtn->setIcon(pix); }); connect(iconBtn, &QPushButton::clicked, leftsidebarBtn, &QPushButton::click); - connect(leftsidebarBtn, &QPushButton::toggled, this, [=](bool checked){ + connect(leftsidebarBtn, &QPushButton::toggled, this, [=](bool checked) { iconBtn->setChecked(checked); QString path = QString("://img/primaryleftmenu/%1.svg").arg(iname); QPixmap pix; if (checked) { - pix = loadSvg(path, "blue"); + pix = ImageUtil::loadSvg(path, "blue"); } else { - pix = loadSvg(path, "default"); + pix = ImageUtil::loadSvg(path, "default"); } iconBtn->setIcon(pix); }); QLabel * textLabel = new QLabel(leftsidebarBtn); - textLabel->setVisible(false); textLabel->setText(tipName); QSizePolicy textLabelPolicy = textLabel->sizePolicy(); textLabelPolicy.setHorizontalPolicy(QSizePolicy::Fixed); @@ -615,84 +736,91 @@ return false; } -const QPixmap MainWindow::loadSvg(const QString &fileName, QString color) -{ - int size = 24; - const auto ratio = qApp->devicePixelRatio(); - if ( 2 == ratio) { - size = 48; - } else if (3 == ratio) { - size = 96; - } - QPixmap pixmap(size, size); - QSvgRenderer renderer(fileName); - pixmap.fill(Qt::transparent); - - QPainter painter; - painter.begin(&pixmap); - renderer.render(&painter); - painter.end(); - - pixmap.setDevicePixelRatio(ratio); - return drawSymbolicColoredPixmap(pixmap, color); -} - -QPixmap MainWindow::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); -// color.setAlpha(0.1); - color.setAlphaF(0.9); - 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); -} - -bool MainWindow::dblOnEdge(QMouseEvent *event) -{ +bool MainWindow::dblOnEdge(QMouseEvent *event) { QPoint pos = event->globalPos(); int globalMouseY = pos.y(); int frameY = this->y(); bool onTopEdges = (globalMouseY >= frameY && - globalMouseY <= frameY + dbWitdth); + globalMouseY <= frameY + dbWitdth); return onTopEdges; } -void MainWindow::setModuleBtnHightLight(int id){ +void MainWindow::initStyleSheet() { + // 设置panel图标 + QIcon panelicon; + if (QIcon::hasThemeIcon("ukui-control-center")) + panelicon = QIcon::fromTheme("ukui-control-center"); + + qApp->setWindowIcon(panelicon); + this->setWindowTitle(tr("Settings")); + + // 中部内容区域 + ui->stackedWidget->setStyleSheet("QStackedWidget#stackedWidget{background: palette(base); border-bottom-left-radius: 6px; border-bottom-right-radius: 6px;}"); + + // 左上角返回按钮 + backBtn->setProperty("useIconHighlightEffect", true); + backBtn->setProperty("iconHighlightEffectMode", 1); + backBtn->setFlat(true); + + mOptionBtn->setProperty("useIconHighlightEffect", 0x2); + mOptionBtn->setProperty("isWindowButton", 0x01); + mOptionBtn->setFlat(true); + + minBtn->setProperty("useIconHighlightEffect", 0x2); + minBtn->setProperty("isWindowButton", 0x01); + minBtn->setFlat(true); + + maxBtn->setProperty("useIconHighlightEffect", 0x2); + maxBtn->setProperty("isWindowButton", 0x1); + maxBtn->setFlat(true); + + closeBtn->setProperty("isWindowButton", 0x02); + closeBtn->setProperty("useIconHighlightEffect", 0x08); + closeBtn->setFlat(true); + ui->leftsidebarWidget->setMinimumWidth(153); + ui->leftsidebarWidget->setStyleSheet("QWidget#leftsidebarWidget{background-color: palette(window);border: none; border-top-left-radius: 6px; border-bottom-left-radius: 6px;}"); + + // 设置左上角按钮图标 + backBtn->setIcon(QIcon("://img/titlebar/back.svg")); + + // 设置右上角按钮图标 + mOptionBtn->setIcon(QIcon::fromTheme("open-menu-symbolic")); + minBtn->setIcon(QIcon::fromTheme("window-minimize-symbolic")); + maxBtn->setIcon(QIcon::fromTheme("window-maximize-symbolic")); + closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic")); +} + +bool MainWindow::isExitBluetooth() { + QProcess process; + process.start("rfkill list"); + process.waitForFinished(); + QByteArray output = process.readAllStandardOutput(); + QString str_output = output; + bool isDevice = str_output.contains(QString("bluetooth"), Qt::CaseInsensitive); + bool isAddress = true; + + QByteArray bluetoothId("org.ukui.bluetooth"); + if (QGSettings::isSchemaInstalled(bluetoothId)) { + QGSettings bluetoothGSetting(bluetoothId); + isAddress = bluetoothGSetting.get("adapter-address").toString().isEmpty() ? false : true; + } + + return isDevice && isAddress; +} + +void MainWindow::changeSearchSlot() { + int fontSize = m_fontSetting->get("system-font-size").toInt(); + m_searchWidget->setFixedHeight((fontSize - 11) * 2 + 32); +} + +void MainWindow::setModuleBtnHightLight(int id) { leftBtnGroup->button(id)->setChecked(true); leftMicBtnGroup->button(id)->setChecked(true); } -QMap MainWindow::exportModule(int type){ +QMap MainWindow::exportModule(int type) { QMap emptyMaps; if (type < modulesList.length()) return modulesList[type]; @@ -700,66 +828,37 @@ return emptyMaps; } -void MainWindow::functionBtnClicked(QObject *plugin){ +void MainWindow::functionBtnClicked(QObject *plugin) { ui->stackedWidget->setCurrentIndex(1); modulepageWidget->switchPage(plugin); } void MainWindow::sltMessageReceived(const QString &msg) { - + this->hide(); + this->show(); + showNormal(); bootOptionsFilter(msg); - Qt::WindowFlags flags = windowFlags(); - flags |= Qt::WindowStaysOnTopHint; - setWindowFlags(flags); - show(); - flags &= ~Qt::WindowStaysOnTopHint; - setWindowFlags(flags); - showNormal(); + //Qt::WindowFlags flags = windowFlags(); + //flags |= Qt::WindowStaysOnTopHint; + //setWindowFlags(flags); + //flags &= ~Qt::WindowStaysOnTopHint; + //setWindowFlags(flags); } -const QPixmap MainWindow::renderSvg(const QIcon &icon, QString cgColor) { - int size = 24; - const auto ratio = qApp->devicePixelRatio(); - if ( 2 == ratio) { - size = 48; - } else if (3 == ratio) { - size = 96; - } - QPixmap iconPixmap = icon.pixmap(size,size); - iconPixmap.setDevicePixelRatio(ratio); - QImage img = iconPixmap.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); -// color.setAlpha(0.1); - color.setAlphaF(0.9); - 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 iconPixmap; - } +void MainWindow::switchPage(QString moduleName, QString jumpMoudle) { + + for (int i = 0; i < modulesList.length(); i++) { + auto modules = modulesList.at(i); + //开始跳转 + if (modules.keys().contains(moduleName)) { + if (m_ModuleMap.isEmpty() || m_ModuleMap[jumpMoudle.toLower()].toBool()) { + ui->stackedWidget->setCurrentIndex(1); + modulepageWidget->switchPage(modules.value(moduleName)); + return ; } } } - return QPixmap::fromImage(img); + QMessageBox::information(this, tr("Warnning"), tr("This function has been controlled")); + return; } diff -Nru ukui-control-center-2.0.3/shell/mainwindow.h ukui-control-center-3.0.3/shell/mainwindow.h --- ukui-control-center-2.0.3/shell/mainwindow.h 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/mainwindow.h 2021-05-20 13:08:14.000000000 +0000 @@ -21,17 +21,23 @@ #define MAINWINDOW_H #include +#include #include #include #include #include #include #include +#include +#include +#include #include "interface.h" #include "homepagewidget.h" #include "modulepagewidget.h" +#include "searchwidget.h" +class QLabel; class QPushButton; class QButtonGroup; class KeyValueConverter; @@ -51,12 +57,11 @@ public: QMap exportModule(int); void setModuleBtnHightLight(int id); - + static bool isExitBluetooth(); void bootOptionsFilter(QString opt); void bootOptionsSwitch(int moduleNum, int funcNum); protected: - void paintEvent(QPaintEvent *); bool eventFilter(QObject *watched, QEvent *event); private: @@ -70,31 +75,51 @@ QButtonGroup * leftMicBtnGroup; // QDir pluginsDir; -// QStringList modulesStringList; QList moduleIndexList; QList> modulesList; KeyValueConverter * kvConverter; + SearchWidget * m_searchWidget; + + QPushButton *backBtn; + QPushButton *mOptionBtn; + QPushButton *minBtn; + QPushButton *maxBtn; + QPushButton *closeBtn; + QLabel *titleLabel; + QLabel *mTitleIcon; + QTimer *timer; + QLabel *logoLabel; + QLabel *m_queryIcon; + QLabel *m_queryText = nullptr; + QPropertyAnimation *m_animation = nullptr; + QWidget *m_queryWid = nullptr; + bool m_isSearching = false; + QString m_searchKeyWords; + QVariantMap m_ModuleMap; + QGSettings *m_fontSetting; + private: + void initUI(); + void initTileBar(); void setBtnLayout(QPushButton * &pBtn); void loadPlugins(); void initLeftsideBar(); QPushButton * buildLeftsideBtn(QString bname, QString tipName); bool isExitsCloudAccount(); - // load svg picture - const QPixmap loadSvg(const QString &fileName, QString color); - //Render icon from theme - const QPixmap renderSvg(const QIcon &icon, QString color); - // chang svg picture's color - QPixmap drawSymbolicColoredPixmap(const QPixmap &source, QString color); - bool dblOnEdge(QMouseEvent *event); + void initStyleSheet(); + void changeSearchSlot(); public slots: void functionBtnClicked(QObject * plugin); void sltMessageReceived(const QString &msg); + void switchPage(QString moduleName, QString jumpMoudle); + void animationFinishedSlot(); + void showUkccAboutSlot(); + void onF1ButtonClicked(); }; #endif // MAINWINDOW_H diff -Nru ukui-control-center-2.0.3/shell/mainwindow.ui ukui-control-center-3.0.3/shell/mainwindow.ui --- ukui-control-center-2.0.3/shell/mainwindow.ui 2020-05-21 08:02:13.000000000 +0000 +++ ukui-control-center-3.0.3/shell/mainwindow.ui 2021-04-14 01:27:20.000000000 +0000 @@ -19,28 +19,28 @@ 0 - 1 + 0 - 1 + 0 - 1 + 0 - 2 + 0 - 60 + 140 0 - 60 + 140 16777215 @@ -63,10 +63,10 @@ - 4 + 0 - 3 + 0 30 @@ -81,185 +81,41 @@ 0 + + 0 + + + 0 + - 4 + 0 - - - - 0 - 56 - - - - - 16777215 - 56 - + + + 0 - - - 2 - - - 16 - - - 0 - - - 8 - - - 0 - - - - - - 48 - 32 - - - - - 48 - 32 - - - - - - - - - - - - 0 - 0 - - - - UKCC - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 354 - 32 - - - - - 560 - 32 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - - - - - 32 - 32 - - - - - 48 - 32 - - - - - - - - - + - - - - 16777215 - 16777215 - + + + 0 + + + 0 - + + + + + 16777215 + 16777215 + + + + + diff -Nru ukui-control-center-2.0.3/shell/modulepagewidget.cpp ukui-control-center-3.0.3/shell/modulepagewidget.cpp --- ukui-control-center-2.0.3/shell/modulepagewidget.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/modulepagewidget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -21,14 +21,15 @@ #include "ui_modulepagewidget.h" #include +#include #include "mainwindow.h" #include "interface.h" #include "utils/keyvalueconverter.h" #include "utils/functionselect.h" +#include "utils/utils.h" #include "component/leftwidgetitem.h" - -#include +#include "component/leftmenulist.h" ModulePageWidget::ModulePageWidget(QWidget *parent) : QWidget(parent), @@ -36,49 +37,48 @@ { ui->setupUi(this); - //设置父窗口对象 + // 设置父窗口对象 this->setParent(parent); pmainWindow = (MainWindow *)parentWidget(); - //左侧Widget大小限定 + // 左侧Widget大小限定 ui->leftbarWidget->setMinimumWidth(160); ui->leftbarWidget->setMaximumWidth(216); - //右侧Widget大小限定(限制了最小宽度) + // 右侧Widget大小限定(限制了最小宽度) ui->widget->setMinimumWidth(650); ui->widget->setMaximumWidth(1200); - - // - ui->mtitleLabel->setStyleSheet(tr("QLabel{font-size: 18px; color: palette(Shadow);}")); - //左侧二级菜单样式 + // 左侧二级菜单样式 ui->leftStackedWidget->setStyleSheet("border: none;"); - //上侧二级菜单样式 -// ui->topStackedWidget->setStyleSheet("border: none;"); - //功能区域 -// ui->scrollArea->setStyleSheet("#scrollArea{border: 0px solid;}"); ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -// ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //初始化记录标志位 flagBit = true; - //构建枚举键值转换对象 mkvConverter = new KeyValueConverter(); //继承QObject,No Delete ui->topsideWidget->hide(); + getModuleStatus(); + initTitleLabel(); initUI(); - } ModulePageWidget::~ModulePageWidget() { delete ui; + ui = nullptr; +} + +void ModulePageWidget::initTitleLabel() { + QFont font; + font.setPixelSize(18); + ui->mtitleLabel->setFont(font); } -void ModulePageWidget::initUI(){ +void ModulePageWidget::initUI() { //设置伸缩策略 QSizePolicy leftSizePolicy = ui->leftbarWidget->sizePolicy(); QSizePolicy rightSizePolicy = ui->widget->sizePolicy(); @@ -90,14 +90,15 @@ ui->widget->setSizePolicy(rightSizePolicy); for (int moduleIndex = 0; moduleIndex < TOTALMODULES; moduleIndex++){ - QListWidget * leftListWidget = new QListWidget; + LeftMenuList * leftListWidget = new LeftMenuList; leftListWidget->setObjectName("leftWidget"); - leftListWidget->setStyleSheet("QListWidget::Item:hover{background:palette(base);}"); leftListWidget->setAttribute(Qt::WA_DeleteOnClose); leftListWidget->setResizeMode(QListView::Adjust); leftListWidget->setFocusPolicy(Qt::NoFocus); leftListWidget->setSelectionMode(QAbstractItemView::NoSelection); leftListWidget->setSpacing(12); + leftListWidget->setMinimumWidth(100); + connect(leftListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(currentLeftitemChanged(QListWidgetItem*,QListWidgetItem*))); QListWidget * topListWidget = new QListWidget; topListWidget->setAttribute(Qt::WA_DeleteOnClose); @@ -116,18 +117,25 @@ if (!moduleMap.contains(single.namei18nString)) continue; + if (mModuleMap.keys().contains(single.nameString.toLower())) { + if (!mModuleMap[single.nameString.toLower()].toBool()) { + continue; + } + } + //填充左侧二级菜单 - LeftWidgetItem * leftWidgetItem = new LeftWidgetItem(); + LeftWidgetItem * leftWidgetItem = new LeftWidgetItem(this); leftWidgetItem->setAttribute(Qt::WA_DeleteOnClose); leftWidgetItem->setLabelText(single.namei18nString); - leftWidgetItem->setLabelPixmap(QString("://img/secondaryleftmenu/%1.svg").arg(single.nameString), single.nameString, "default"); QListWidgetItem * item = new QListWidgetItem(leftListWidget); - item->setSizeHint(QSize(ui->leftStackedWidget->width(), 40)); //QSize(120, 40) spacing: 12px; + item->setSizeHint(QSize(ui->leftStackedWidget->width() + 20, 40)); //QSize(120, 40) spacing: 12px; leftListWidget->setItemWidget(item, leftWidgetItem); + leftListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); strItemsMap.insert(single.namei18nString, item); + leftListWidget->setGridSize(QSize(ui->leftStackedWidget->width() + 20,48)); //填充上侧二级菜单 QListWidgetItem * topitem = new QListWidgetItem(topListWidget); @@ -143,34 +151,6 @@ } -// QStringList functionStringList = FunctionSelect::funcsList[moduleIndex]; -// for (int funcIndex = 0; funcIndex < functionStringList.size(); funcIndex++){ -// QString funcnameString = functionStringList.at(funcIndex); -// //跳过插件不存在的功能项 -// if (!moduleMap.contains(funcnameString)) -// continue; - -// //填充左侧二级菜单 -// LeftWidgetItem * leftWidgetItem = new LeftWidgetItem(this); -// leftWidgetItem->setLabelText(funcnameString); -// leftWidgetItem->setLabelPixmap(QString("://img/secondaryleftmenu/%1.png").arg(funcnameString)); - -// QListWidgetItem * item = new QListWidgetItem(leftListWidget); -// item->setSizeHint(QSize(120, 40)); //测试数据 -// leftListWidget->setItemWidget(item, leftWidgetItem); - -// //填充上侧二级菜单 -// QListWidgetItem * topitem = new QListWidgetItem(topListWidget); -// topitem->setSizeHint(QSize(60, 60)); -// topitem->setText(funcnameString); -// topListWidget->addItem(topitem); - -// CommonInterface * pluginInstance = qobject_cast(moduleMap.value(funcnameString)); - -// pluginInstanceMap.insert(funcnameString, pluginInstance); - -// } - ui->leftStackedWidget->addWidget(leftListWidget); ui->topStackedWidget->addWidget(topListWidget); } @@ -260,6 +240,10 @@ toptmpListWidget->setCurrentItem(currentItemList.at(0)); //QMultiMap 后添加的value在前面 } +void ModulePageWidget::getModuleStatus() { + mModuleMap = Utils::getModuleHideStatus(); +} + void ModulePageWidget::currentLeftitemChanged(QListWidgetItem *cur, QListWidgetItem *pre){ //获取当前QListWidget QListWidget * currentLeftListWidget = dynamic_cast(ui->leftStackedWidget->currentWidget()); diff -Nru ukui-control-center-2.0.3/shell/modulepagewidget.h ukui-control-center-3.0.3/shell/modulepagewidget.h --- ukui-control-center-2.0.3/shell/modulepagewidget.h 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/shell/modulepagewidget.h 2021-04-14 01:27:20.000000000 +0000 @@ -22,6 +22,7 @@ #include #include +#include class MainWindow; class CommonInterface; @@ -42,12 +43,16 @@ ~ModulePageWidget(); public: + void initTitleLabel(); void initUI(); void switchPage(QObject * plugin, bool recorded = true); void refreshPluginWidget(CommonInterface * plu); void highlightItem(QString text); private: + void getModuleStatus(); + +private: Ui::ModulePageWidget *ui; private: @@ -55,9 +60,12 @@ KeyValueConverter * mkvConverter; + QVariantMap mModuleMap; + private: QMap pluginInstanceMap; - QMultiMap strItemsMap;//存储功能名与二级菜单item的Map,为了实现高亮 + // 存储功能名与二级菜单item的Map,为了实现高亮 + QMultiMap strItemsMap; bool flagBit; diff -Nru ukui-control-center-2.0.3/shell/modulepagewidget.ui ukui-control-center-3.0.3/shell/modulepagewidget.ui --- ukui-control-center-2.0.3/shell/modulepagewidget.ui 2020-06-18 07:43:39.000000000 +0000 +++ ukui-control-center-3.0.3/shell/modulepagewidget.ui 2021-04-14 01:27:20.000000000 +0000 @@ -35,7 +35,7 @@ 0 - 24 + 0 0 @@ -150,7 +150,7 @@ 0 - 24 + 8 40 @@ -232,7 +232,7 @@ 0 0 - 303 + 330 322 diff -Nru ukui-control-center-2.0.3/shell/pinyin.cpp ukui-control-center-3.0.3/shell/pinyin.cpp --- ukui-control-center-2.0.3/shell/pinyin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/pinyin.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,57 @@ +#include "pinyin.h" + +#include +#include + + +static QHash dict = {}; +const char kDictFile[] = ":/dpinyin.dict"; + +static void InitDict() { + if (!dict.isEmpty()) { + return; + } + + dict.reserve(25333); + + QFile file(kDictFile); + + if (!file.open(QIODevice::ReadOnly)) + return; + + QByteArray content = file.readAll(); + + file.close(); + + QTextStream stream(&content, QIODevice::ReadOnly); + + while (!stream.atEnd()) { + const QString line = stream.readLine(); + const QStringList items = line.split(QChar(':')); + + if (items.size() == 2) { + dict.insert(items[0].toInt(nullptr, 16), items[1]); + } + } +} + +QString Chinese2Pinyin(const QString &words) +{ + InitDict(); + + QString result; + + for (int i = 0; i < words.length(); ++i) { + const uint key = words.at(i).unicode(); + auto find_result = dict.find(key); + + if (find_result != dict.end()) { + result.append(find_result.value()); + } else { + result.append(words.at(i)); + } + } + + return result; +} + diff -Nru ukui-control-center-2.0.3/shell/pinyin.h ukui-control-center-3.0.3/shell/pinyin.h --- ukui-control-center-2.0.3/shell/pinyin.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/pinyin.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,10 @@ +#ifndef KPINYIN_H +#define KPINYIN_H + + +#include +#include + + +QString Chinese2Pinyin(const QString& words); +#endif // KPINYIN_H diff -Nru ukui-control-center-2.0.3/shell/prescene.cpp ukui-control-center-3.0.3/shell/prescene.cpp --- ukui-control-center-2.0.3/shell/prescene.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/prescene.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,118 @@ +#include "prescene.h" + +#include +#include +#include +#include +extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed); + +PreScene::PreScene(QLabel *label, QSize size, QWidget *parent) : QWidget(parent), m_size(size) + , titleLabel(label) +{ + this->setFixedSize(m_size); + this->setObjectName("prescene"); + this->setStyleSheet("PreScene#prescene{background: palette(base); border-radius: 6px;}"); + + titleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + + m_vlayout = new QVBoxLayout; + m_logoLayout = new QHBoxLayout; + + mTitleIcon = new QLabel(this); + mTitleIcon->setFixedSize(24, 24); + + QIcon titleIcon = QIcon::fromTheme("ukui-control-center"); + mTitleIcon->setPixmap(titleIcon.pixmap(titleIcon.actualSize(QSize(24, 24)))); + + titlebar = new QWidget(this); + + logoLabel = new QLabel(this); + logoLabel->setFixedSize(200, 200); + logoLabel->setPixmap(loadSvg(":/img/titlebar/ukui-control-center.svg")); + m_logoLayout->setContentsMargins(70, 160, 0, 0); + m_logoLayout->addWidget(logoLabel); + + m_hlayout = new QHBoxLayout; + m_hlayout->setSpacing(0); + m_hlayout->setContentsMargins(8, 8, 4, 0); + m_hlayout->addWidget(mTitleIcon); + m_hlayout->addSpacing(8); + m_hlayout->addWidget(titleLabel); + m_hlayout->addStretch(); + titlebar->setLayout(m_hlayout); + + m_vlayout->setSpacing(0); + m_vlayout->setContentsMargins(0, 0, 0, 0); + m_vlayout->addWidget(titlebar); + m_vlayout->addLayout(m_logoLayout); + m_vlayout->addStretch(); + + this->setLayout(m_vlayout); +} + +const QPixmap PreScene::loadSvg(const QString &fileName) +{ + int size = 128; + const auto ratio = qApp->devicePixelRatio(); + size *= ratio; + QPixmap pixmap(size, size); + QSvgRenderer renderer(fileName); + pixmap.fill(Qt::transparent); + + QPainter painter; + painter.begin(&pixmap); + renderer.render(&painter); + painter.end(); + + pixmap.setDevicePixelRatio(ratio); + + QImage img = pixmap.toImage(); + return QPixmap::fromImage(img); +} + +PreScene::~PreScene() { + +} + +void PreScene::paintEvent(QPaintEvent *event) { + Q_UNUSED(event); + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + QPainterPath rectPath; + + rectPath.addRoundedRect(this->rect().adjusted(1, 1, -1, -1), 6, 6); + + // 画一个黑底 + QPixmap pixmap(this->rect().size()); + pixmap.fill(Qt::transparent); + QPainter pixmapPainter(&pixmap); + pixmapPainter.setRenderHint(QPainter::Antialiasing); + pixmapPainter.setPen(Qt::transparent); + pixmapPainter.setBrush(Qt::black); + pixmapPainter.setOpacity(0.65); + pixmapPainter.drawPath(rectPath); + pixmapPainter.end(); + + // 模糊这个黑底 + QImage img = pixmap.toImage(); + qt_blurImage(img, 5, false, false); + + // 挖掉中心 + pixmap = QPixmap::fromImage(img); + QPainter pixmapPainter2(&pixmap); + pixmapPainter2.setRenderHint(QPainter::Antialiasing); + pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear); + pixmapPainter2.setPen(Qt::transparent); + pixmapPainter2.setBrush(Qt::transparent); + pixmapPainter2.drawPath(rectPath); + + // 绘制阴影 + p.drawPixmap(this->rect(), pixmap, pixmap.rect()); + + // 绘制一个背景 + p.save(); + p.fillPath(rectPath,palette().color(QPalette::Base)); +// p.fillPath(rectPath,QColor(0,0,0)); + p.restore(); + +} diff -Nru ukui-control-center-2.0.3/shell/prescene.h ukui-control-center-3.0.3/shell/prescene.h --- ukui-control-center-2.0.3/shell/prescene.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/prescene.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,37 @@ +#ifndef PRESCENE_H +#define PRESCENE_H + +#include +#include +#include +#include +#include +#include +#include + + +class PreScene : public QWidget +{ +public: + PreScene(QLabel *label, QSize size, QWidget * parent = nullptr); + ~PreScene(); + +private: + QSize m_size; + QHBoxLayout * m_hlayout; + + QVBoxLayout * m_vlayout; + QWidget * titlebar; + + QLabel * mTitleIcon; + QLabel * titleLabel; + QLabel * logoLabel; + QHBoxLayout * m_logoLayout = nullptr; + +protected: + void paintEvent(QPaintEvent *event); +private: + const QPixmap loadSvg(const QString &fileName); +}; + +#endif // PRESCENE_H diff -Nru ukui-control-center-2.0.3/shell/qtsingleapplication/qtlocalpeer.cpp ukui-control-center-3.0.3/shell/qtsingleapplication/qtlocalpeer.cpp --- ukui-control-center-2.0.3/shell/qtsingleapplication/qtlocalpeer.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/shell/qtsingleapplication/qtlocalpeer.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -176,8 +176,18 @@ if (!socket) return; - while (socket->bytesAvailable() < (int)sizeof(quint32)) + while (true) { + if (socket->state() == QLocalSocket::UnconnectedState) { + qWarning("QtLocalPeer: Peer disconnected"); + delete socket; + socket = nullptr; + return; + } + if (socket->bytesAvailable() >= qint64(sizeof(quint32))) + break; socket->waitForReadyRead(); + } + QDataStream ds(socket); QByteArray uMsg; quint32 remaining; @@ -193,6 +203,7 @@ if (got < 0) { qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); delete socket; + socket = nullptr; return; } QString message(QString::fromUtf8(uMsg)); @@ -200,5 +211,6 @@ socket->waitForBytesWritten(1000); socket->waitForDisconnected(1000); // make sure client reads ack delete socket; + socket = nullptr; emit messageReceived(message); //### (might take a long time to return) } diff -Nru ukui-control-center-2.0.3/shell/qtsingleapplication/qtsingleapplication.cpp ukui-control-center-3.0.3/shell/qtsingleapplication/qtsingleapplication.cpp --- ukui-control-center-2.0.3/shell/qtsingleapplication/qtsingleapplication.cpp 2020-05-08 07:26:17.000000000 +0000 +++ ukui-control-center-3.0.3/shell/qtsingleapplication/qtsingleapplication.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -323,7 +323,7 @@ void QtSingleApplication::activateWindow() { if (actWin) { - actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); + //actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); } diff -Nru ukui-control-center-2.0.3/shell/res/dpinyin.dict ukui-control-center-3.0.3/shell/res/dpinyin.dict --- ukui-control-center-2.0.3/shell/res/dpinyin.dict 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/dpinyin.dict 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,25333 @@ +0x3400:qiu1 +0x3401:tian3 +0x3404:kua4 +0x3405:wu3 +0x3406:yin3 +0x340c:si4 +0x3416:ye4 +0x341c:chou2 +0x3421:nuo4 +0x3424:qiu2 +0x3428:xu4 +0x3429:xing2 +0x342b:xiong1 +0x342c:liu2 +0x342d:lin3 +0x342e:xiang1 +0x342f:yong1 +0x3430:xin4 +0x3431:zhen3 +0x3432:dai4 +0x3433:wu4 +0x3434:pan1 +0x3437:ma3 +0x3438:qian4 +0x3439:yi4 +0x343a:zhong4 +0x343b:n3 +0x343c:cheng4 +0x3441:zhuo1 +0x3442:fang3 +0x3443:ao3 +0x3444:wu3 +0x3445:zuo4 +0x3447:zhou4 +0x3448:dong4 +0x3449:su4 +0x344a:yi4 +0x344b:jiong4 +0x344c:wang1 +0x344d:lei3 +0x344e:nao3 +0x344f:zhu4 +0x3454:xu3 +0x3458:jie4 +0x3459:die2 +0x345a:nuo2 +0x345b:su4 +0x345c:yi4 +0x345d:long4 +0x345e:ying4 +0x345f:beng3 +0x3463:lan2 +0x3464:miao2 +0x3465:yi4 +0x3466:li4 +0x3467:ji4 +0x3468:yu3 +0x3469:luo2 +0x346a:chai2 +0x346e:hun2 +0x346f:xu3 +0x3470:hui4 +0x3471:rao3 +0x3473:zhou4 +0x3475:han4 +0x3476:xi4 +0x3477:tai4 +0x3478:ai3 +0x3479:hui4 +0x347a:jun4 +0x347b:ma4 +0x347c:lve4 +0x347d:tang2 +0x347e:xiao2 +0x347f:tiao2 +0x3480:zha3 +0x3481:yu3 +0x3482:ku4 +0x3483:er4 +0x3484:nang4 +0x3485:qi3 +0x3486:chi4 +0x3487:mu4 +0x3488:han4 +0x3489:tang3 +0x348a:se4 +0x348c:qiong2 +0x348d:lei2 +0x348e:sa3 +0x3491:hui4 +0x3492:pu2 +0x3493:ta4 +0x3494:shu3 +0x3496:ou3 +0x3497:tai2 +0x3499:mian2 +0x349a:wen3 +0x349b:diao4 +0x349c:yu2 +0x349d:mie4 +0x349e:jun4 +0x349f:niao3 +0x34a0:xie4 +0x34a1:you2 +0x34a4:she4 +0x34a6:lei3 +0x34a7:li4 +0x34a9:luo3 +0x34ab:ji4 +0x34b0:quan2 +0x34b2:cai2 +0x34b3:liang3 +0x34b4:gu3 +0x34b5:mao4 +0x34b7:gua3 +0x34b8:sui4 +0x34bb:mao4 +0x34bc:man2 +0x34be:shi4 +0x34bf:li2 +0x34c1:wang3 +0x34c2:kou4 +0x34c3:chui2 +0x34c4:zhen4 +0x34c8:bing4 +0x34c9:huan4 +0x34ca:dong4 +0x34cb:gong4 +0x34ce:lian2 +0x34cf:jiong3 +0x34d0:lu4 +0x34d1:xing4 +0x34d3:nan2 +0x34d4:xie4 +0x34d6:bi4 +0x34d7:jie2 +0x34d8:su4 +0x34dc:you4 +0x34dd:xing2 +0x34de:qi4 +0x34e0:dian4 +0x34e1:fu3 +0x34e2:luo4 +0x34e3:qia4 +0x34e4:jie2 +0x34e7:yan3 +0x34e8:ci2 +0x34ea:lang3 +0x34ed:he2 +0x34ef:li2 +0x34f0:hua4 +0x34f1:tou2 +0x34f2:pian4 +0x34f4:jun4 +0x34f5:e4 +0x34f6:qie4 +0x34f7:yi4 +0x34f8:jue2 +0x34f9:rui4 +0x34fa:jian4 +0x34fc:chi4 +0x34fd:chong2 +0x34fe:chi2 +0x3500:lve4 +0x3502:lin2 +0x3503:jue2 +0x3504:su4 +0x3505:xiao4 +0x3506:chan2 +0x3509:zhu2 +0x350a:dan3 +0x350b:jian4 +0x350c:zhou4 +0x350d:duo3 +0x350e:xie4 +0x350f:li4 +0x3511:chi4 +0x3512:xi2 +0x3513:jian3 +0x3515:ji2 +0x3517:fei4 +0x3518:chu4 +0x3519:bang3 +0x351a:kou3 +0x351c:ba2 +0x351d:liang3 +0x351e:kuai4 +0x3520:he2 +0x3522:jue2 +0x3523:lei2 +0x3524:shen3 +0x3525:pi2 +0x3526:yang3 +0x3527:lv4 +0x3528:bei4 +0x3529:e4 +0x352a:lu3 +0x352d:che4 +0x352e:nuo2 +0x352f:suan3 +0x3530:heng2 +0x3531:yu3 +0x3533:gui3 +0x3534:yi4 +0x3535:xian4 +0x3536:gong4 +0x3537:lou4 +0x3539:le4 +0x353a:shi4 +0x353c:sun3 +0x353d:yao4 +0x353e:jie2 +0x353f:zou4 +0x3541:que4 +0x3542:yin2 +0x3544:zhi4 +0x3545:jia3 +0x3546:hu4 +0x3547:la2 +0x3548:hou4 +0x3549:ke4 +0x354b:jing4 +0x354c:ai4 +0x354e:e4 +0x354f:chu2 +0x3550:xie3 +0x3551:chu2 +0x3552:wei2 +0x3555:huan4 +0x3556:su4 +0x3557:you4 +0x3559:jun4 +0x355a:zhao3 +0x355b:xu4 +0x355c:shi3 +0x355f:kui4 +0x3561:he2 +0x3562:gai4 +0x3563:yan3 +0x3564:qiu2 +0x3565:yi3 +0x3566:hua4 +0x3568:fan4 +0x3569:zhang4 +0x356a:dan3 +0x356b:fang3 +0x356c:song4 +0x356d:ao4 +0x356e:fu3 +0x356f:nei4 +0x3570:he4 +0x3571:you2 +0x3572:hua2 +0x3574:chen2 +0x3575:guo2 +0x3576:ng4 +0x3577:hua4 +0x3578:li4 +0x3579:fa2 +0x357a:hao2 +0x357b:pou3 +0x357d:si4 +0x3580:le4 +0x3581:lin4 +0x3582:yi4 +0x3583:hou3 +0x3585:xu4 +0x3586:qu2 +0x3587:er2 +0x358f:nei4 +0x3590:wei3 +0x3591:xie4 +0x3592:ti2 +0x3593:hong2 +0x3594:tun3 +0x3595:bo4 +0x3596:nie4 +0x3597:yin2 +0x359e:wai1 +0x359f:shou4 +0x35a0:ba4 +0x35a1:ye4 +0x35a2:ji2 +0x35a3:tou4 +0x35a4:han2 +0x35a5:jiong3 +0x35a6:dong3 +0x35a7:wen3 +0x35a8:lu4 +0x35a9:sou3 +0x35aa:guo2 +0x35ab:ling2 +0x35ad:tian3 +0x35ae:lun2 +0x35b6:ye4 +0x35b7:shi2 +0x35b8:xue2 +0x35b9:fen4 +0x35ba:chun3 +0x35bb:rou2 +0x35bc:duo3 +0x35bd:ze2 +0x35be:e4 +0x35bf:xie2 +0x35c1:e4 +0x35c2:sheng3 +0x35c3:wen3 +0x35c4:man2 +0x35c5:hu2 +0x35c6:ge2 +0x35c7:xia2 +0x35c8:man4 +0x35c9:bi4 +0x35ca:ji2 +0x35cb:hou2 +0x35cc:zhi4 +0x35d1:bai4 +0x35d2:ai4 +0x35d5:gou4 +0x35d6:dan4 +0x35d7:bai3 +0x35d8:bo2 +0x35d9:na4 +0x35da:li4 +0x35db:xiao4 +0x35dc:xiu4 +0x35e2:dong4 +0x35e3:ti4 +0x35e4:cu4 +0x35e5:kuo4 +0x35e6:lao2 +0x35e7:zhi4 +0x35e8:ai3 +0x35e9:xi1 +0x35eb:qie4 +0x35f0:chu4 +0x35f1:ji2 +0x35f2:huo4 +0x35f3:ta3 +0x35f4:yan2 +0x35f5:xu4 +0x35f7:sai3 +0x35fc:ye4 +0x35fd:xiang3 +0x35ff:xia4 +0x3600:zuo4 +0x3601:yi4 +0x3602:ci2 +0x3605:xian2 +0x3606:tai2 +0x3607:rong2 +0x3608:yi1 +0x3609:zhi4 +0x360a:yi4 +0x360b:xian2 +0x360c:ju4 +0x360d:ji2 +0x360e:han3 +0x3610:pao4 +0x3611:li4 +0x3613:lan2 +0x3614:can3 +0x3615:han3 +0x3616:yan2 +0x3619:yan2 +0x361a:han3 +0x361c:chi3 +0x361d:nian3 +0x361e:huo4 +0x3620:bi4 +0x3621:xia2 +0x3622:weng3 +0x3623:xuan2 +0x3625:you2 +0x3626:qin2 +0x3627:xu4 +0x3628:nei4 +0x3629:bi4 +0x362a:hao4 +0x362b:jing3 +0x362c:ao4 +0x362d:ao4 +0x3632:ju2 +0x3634:zuo4 +0x3635:bu4 +0x3636:jie2 +0x3637:ai4 +0x3638:zang4 +0x3639:ci2 +0x363a:fa2 +0x363f:nie4 +0x3640:liu4 +0x3641:mang3 +0x3642:dui4 +0x3644:bi4 +0x3645:bao3 +0x3647:chu4 +0x3648:han2 +0x3649:tian3 +0x364a:chang2 +0x364f:fu4 +0x3650:duo3 +0x3651:yu3 +0x3652:ye3 +0x3653:kui2 +0x3654:han2 +0x3655:kuai4 +0x3657:kuai4 +0x3659:long3 +0x365b:bu3 +0x365c:chi2 +0x365d:xie2 +0x365e:nie4 +0x365f:lang3 +0x3660:yi4 +0x3662:man2 +0x3663:zhang4 +0x3664:xia4 +0x3665:gun3 +0x3668:ji4 +0x3669:liao2 +0x366a:ye4 +0x366b:ji2 +0x366c:yin2 +0x366e:da1 +0x366f:yi4 +0x3670:xie4 +0x3671:hao4 +0x3672:yong3 +0x3673:han3 +0x3674:chan4 +0x3675:tai2 +0x3676:tang2 +0x3677:zhi2 +0x3678:bao4 +0x3679:meng2 +0x367a:gui4 +0x367b:chan2 +0x367c:lei3 +0x367e:xi4 +0x3681:qiao2 +0x3682:rang2 +0x3683:yun2 +0x3685:long2 +0x3686:fu4 +0x3689:gu3 +0x368c:hua4 +0x368d:guo2 +0x368f:gao3 +0x3690:tao4 +0x3692:shan3 +0x3693:lai2 +0x3694:nie4 +0x3695:fu2 +0x3696:gao3 +0x3697:qie2 +0x3698:ban4 +0x369b:xi4 +0x369c:xu4 +0x369d:kui2 +0x369e:meng3 +0x369f:chuo4 +0x36a1:ji3 +0x36a2:nu2 +0x36a3:xiao2 +0x36a4:yi4 +0x36a5:yu2 +0x36a6:yi2 +0x36a7:yan3 +0x36a9:ran3 +0x36aa:hao4 +0x36ab:sha4 +0x36ad:you2 +0x36af:xin2 +0x36b0:bi3 +0x36b2:dian3 +0x36b4:bu4 +0x36b6:si4 +0x36b7:er3 +0x36b9:mao3 +0x36ba:yun4 +0x36bd:qiao3 +0x36bf:pao2 +0x36c2:nuo3 +0x36c3:jie2 +0x36c5:er4 +0x36c6:duo3 +0x36ca:duo3 +0x36cd:qie4 +0x36cf:ou4 +0x36d0:sou3 +0x36d1:can4 +0x36d2:dou4 +0x36d4:peng2 +0x36d5:yi4 +0x36d7:zuo4 +0x36d8:po4 +0x36d9:qie4 +0x36da:tong3 +0x36db:xin4 +0x36dc:you2 +0x36dd:bei4 +0x36de:long4 +0x36e5:ta4 +0x36e6:lan3 +0x36e7:man3 +0x36e8:qiang3 +0x36e9:zhou2 +0x36ea:yan4 +0x36ec:lu4 +0x36ee:sao3 +0x36ef:mian3 +0x36f1:rui4 +0x36f2:fa4 +0x36f3:cha4 +0x36f4:nao3 +0x36f6:chou2 +0x36f8:shu4 +0x36f9:pian2 +0x36fb:kui3 +0x36fc:sha4 +0x36fe:xian2 +0x36ff:zhi4 +0x3703:lian4 +0x3704:xun2 +0x3705:xu4 +0x3706:mi4 +0x3707:hui4 +0x3708:mu4 +0x370a:pang4 +0x370b:yi4 +0x370c:gou4 +0x370d:tang2 +0x370e:qi2 +0x370f:yun2 +0x3710:shu4 +0x3711:fu2 +0x3712:yi4 +0x3713:da2 +0x3715:lian2 +0x3716:cao2 +0x3717:can3 +0x3718:ju4 +0x3719:lu4 +0x371a:su4 +0x371b:nen4 +0x371c:ao4 +0x371d:an3 +0x371e:qian4 +0x3723:ran2 +0x3724:shen3 +0x3725:mai2 +0x3726:han4 +0x3727:yue4 +0x3728:er2 +0x3729:ao4 +0x372a:xian3 +0x372b:ma4 +0x372e:lan4 +0x3730:yue4 +0x3731:dong4 +0x3732:weng3 +0x3733:huai2 +0x3734:meng4 +0x3735:niao3 +0x3736:wan3 +0x3737:mi2 +0x3738:nie4 +0x3739:qu2 +0x373a:zan4 +0x373b:lian4 +0x373c:zhi2 +0x373d:zi3 +0x373e:hai2 +0x373f:xu4 +0x3740:hao4 +0x3741:xun2 +0x3742:zhi4 +0x3743:fan4 +0x3744:chun2 +0x3745:gou4 +0x3747:chun2 +0x3748:luan2 +0x3749:zhu4 +0x374a:shou3 +0x374b:liao2 +0x374c:jie2 +0x374d:xie3 +0x374e:ding4 +0x374f:jie4 +0x3750:rong2 +0x3751:mang2 +0x3753:ge2 +0x3754:yao4 +0x3755:ning2 +0x3756:yi2 +0x3757:lang2 +0x3758:yong2 +0x3759:yin2 +0x375b:su4 +0x375d:lin2 +0x375e:ya4 +0x375f:mao2 +0x3760:ming2 +0x3761:zui4 +0x3762:yu3 +0x3763:ye4 +0x3764:gou4 +0x3765:mi3 +0x3766:jun4 +0x3767:wen3 +0x376a:dian4 +0x376b:long2 +0x376d:xing3 +0x376e:cui4 +0x376f:qiao2 +0x3770:mian2 +0x3771:meng4 +0x3772:qin3 +0x3774:wan2 +0x3775:de2 +0x3776:ai4 +0x3778:bian4 +0x3779:nou2 +0x377a:lian2 +0x377b:jin3 +0x377d:chui2 +0x377e:zuo3 +0x377f:bo2 +0x3781:yao4 +0x3782:tui3 +0x3783:ji2 +0x3785:guo3 +0x3786:ji3 +0x3787:wei3 +0x378a:xu4 +0x378b:nian3 +0x378c:yun4 +0x378e:ba3 +0x378f:zhe2 +0x3790:ju1 +0x3791:wei3 +0x3792:xi4 +0x3793:qi3 +0x3794:yi2 +0x3795:xie4 +0x3796:ci4 +0x3797:qiu2 +0x3798:tun2 +0x3799:niao4 +0x379a:qi4 +0x379b:ji3 +0x379f:dian4 +0x37a0:lao2 +0x37a1:zhan3 +0x37a4:yin2 +0x37a5:cen2 +0x37a6:ji3 +0x37a7:hui4 +0x37a8:zai3 +0x37a9:lan2 +0x37aa:nao2 +0x37ab:ju4 +0x37ac:qin4 +0x37ad:dai4 +0x37af:jie2 +0x37b0:xu3 +0x37b2:yong4 +0x37b3:dou3 +0x37b4:chi2 +0x37b6:min3 +0x37b7:huang2 +0x37b8:sui4 +0x37b9:ke3 +0x37ba:zu2 +0x37bb:hao4 +0x37bc:cheng2 +0x37bd:xue4 +0x37be:ni2 +0x37bf:chi4 +0x37c0:lian2 +0x37c1:an4 +0x37c2:chi3 +0x37c4:xiang2 +0x37c5:yang2 +0x37c6:hua2 +0x37c7:cuo2 +0x37c8:qiu2 +0x37c9:lao2 +0x37ca:fu2 +0x37cb:dui4 +0x37cc:mang2 +0x37cd:lang2 +0x37ce:tuo3 +0x37cf:han2 +0x37d0:mang3 +0x37d1:bo2 +0x37d3:qi2 +0x37d4:han2 +0x37d6:long4 +0x37d8:tiao2 +0x37d9:lao3 +0x37da:qi2 +0x37db:zan4 +0x37dc:mi2 +0x37dd:pei2 +0x37de:zhan4 +0x37df:xiang4 +0x37e0:gang3 +0x37e2:qi2 +0x37e4:lu4 +0x37e6:yun4 +0x37e7:e4 +0x37e8:quan2 +0x37e9:min2 +0x37ea:wei3 +0x37eb:quan2 +0x37ec:shu3 +0x37ed:min2 +0x37f0:ming3 +0x37f1:yao3 +0x37f2:jue2 +0x37f3:li4 +0x37f4:kuai4 +0x37f5:gang3 +0x37f6:yuan2 +0x37f7:da5 +0x37f9:lao2 +0x37fa:lou2 +0x37fb:qian4 +0x37fc:ao2 +0x37fd:biao3 +0x37ff:mang2 +0x3800:dao3 +0x3802:ao2 +0x3804:xi2 +0x3805:fu2 +0x3807:jiu4 +0x3808:run4 +0x3809:tong2 +0x380a:qu1 +0x380b:e4 +0x380d:ji2 +0x380e:ji2 +0x380f:hua2 +0x3810:jiao4 +0x3811:zui4 +0x3812:biao3 +0x3813:meng2 +0x3814:bai4 +0x3815:wei3 +0x3816:ji4 +0x3817:ao4 +0x3818:yu3 +0x3819:hao2 +0x381a:dui4 +0x381b:wo4 +0x381c:ni4 +0x381d:cuan2 +0x381f:li2 +0x3820:lu2 +0x3821:niao3 +0x3822:hua4 +0x3823:lai4 +0x3825:lv4 +0x3827:mi2 +0x3828:yu4 +0x382a:ju4 +0x382d:zhan3 +0x382f:yi3 +0x3831:ji4 +0x3832:bi3 +0x3834:ren4 +0x3836:fan2 +0x3837:ge2 +0x3838:ku4 +0x3839:jie4 +0x383a:miao2 +0x383d:tong2 +0x383f:ci3 +0x3840:bi4 +0x3841:kai3 +0x3842:li4 +0x3844:sun3 +0x3845:nuo3 +0x3847:ji2 +0x3848:men2 +0x3849:xian2 +0x384a:qia4 +0x384b:e4 +0x384c:mao4 +0x384f:tou2 +0x3851:qiao3 +0x3854:wu4 +0x3856:chuang2 +0x3857:ti2 +0x3858:lian2 +0x3859:bi4 +0x385b:mang2 +0x385c:xue3 +0x385d:feng4 +0x385e:lei3 +0x3860:zheng4 +0x3861:chu2 +0x3862:man4 +0x3863:long2 +0x3865:yin3 +0x3867:zheng4 +0x3868:qian1 +0x3869:luan2 +0x386a:nie2 +0x386b:yi4 +0x386d:ji4 +0x386e:ji2 +0x386f:zhai2 +0x3870:yu3 +0x3871:jiu3 +0x3872:huan2 +0x3873:di3 +0x3875:ling2 +0x3876:ji4 +0x3877:ben3 +0x3878:zha3 +0x3879:ci4 +0x387a:dan4 +0x387b:liao4 +0x387c:yi4 +0x387d:zhao4 +0x387e:xian4 +0x387f:chi4 +0x3880:ci4 +0x3881:chi3 +0x3882:yan3 +0x3883:lang2 +0x3884:dou4 +0x3885:long4 +0x3886:chan2 +0x3888:tui2 +0x3889:cha2 +0x388a:ai3 +0x388b:chi3 +0x388d:ying2 +0x388e:cha4 +0x388f:tou2 +0x3891:tui2 +0x3892:cha2 +0x3893:yao3 +0x3894:zong3 +0x3897:qiao4 +0x3898:lian2 +0x3899:qin2 +0x389a:lu3 +0x389b:yan4 +0x389e:yi4 +0x389f:chan3 +0x38a0:jiong3 +0x38a1:jiang3 +0x38a3:jing4 +0x38a5:dong4 +0x38a7:juan4 +0x38a8:han4 +0x38a9:di4 +0x38ac:hong2 +0x38ae:chi2 +0x38af:min2 +0x38b0:bi4 +0x38b2:xun4 +0x38b3:lu2 +0x38b5:she4 +0x38b6:bi4 +0x38b8:bi4 +0x38ba:xian2 +0x38bb:wei3 +0x38bc:bie4 +0x38bd:er3 +0x38be:juan4 +0x38c0:zhen4 +0x38c1:bei4 +0x38c2:yi4 +0x38c3:yu3 +0x38c4:qu2 +0x38c5:zan4 +0x38c6:mi2 +0x38c7:ni3 +0x38c8:si4 +0x38cc:shan4 +0x38cd:tai2 +0x38ce:mu4 +0x38cf:jing4 +0x38d0:bian4 +0x38d1:rong2 +0x38d2:ceng4 +0x38d3:can4 +0x38d9:di2 +0x38da:tong2 +0x38db:ta4 +0x38dc:xing2 +0x38de:duo2 +0x38df:xi4 +0x38e0:tong2 +0x38e2:ti2 +0x38e3:shan3 +0x38e4:jian4 +0x38e5:zhi4 +0x38e7:yin4 +0x38ea:huan3 +0x38eb:zhong3 +0x38ec:qi4 +0x38ef:xie4 +0x38f0:xie4 +0x38f1:ze2 +0x38f2:wei2 +0x38f5:ta4 +0x38f6:zhan1 +0x38f7:ning4 +0x38fb:yi4 +0x38fc:ren3 +0x38fd:shu4 +0x38fe:cha4 +0x38ff:zhuo2 +0x3901:mian3 +0x3902:ji2 +0x3903:fang2 +0x3904:pei4 +0x3905:ai4 +0x3906:fan4 +0x3907:ao3 +0x3908:qin4 +0x3909:qia4 +0x390a:xiao4 +0x390d:qiao3 +0x390f:tong2 +0x3911:you4 +0x3913:ben4 +0x3914:fu2 +0x3915:chu4 +0x3916:zhu4 +0x3918:chu4 +0x391a:hang2 +0x391b:nin2 +0x391c:jue2 +0x391e:cha4 +0x391f:kong3 +0x3920:lie4 +0x3921:li4 +0x3922:xu4 +0x3924:yu2 +0x3925:hai4 +0x3926:li4 +0x3927:hou2 +0x3928:gong3 +0x3929:ke4 +0x392a:yuan4 +0x392b:de2 +0x392c:hui4 +0x392e:kuang2 +0x392f:jiong3 +0x3930:zan3 +0x3931:fu4 +0x3932:qie4 +0x3933:bei3 +0x3934:xi2 +0x3935:ci2 +0x3936:pang2 +0x3938:xi4 +0x3939:qiu2 +0x393a:huang3 +0x393d:chou2 +0x393e:san4 +0x3940:de2 +0x3941:de2 +0x3942:te4 +0x3943:men4 +0x3944:ling2 +0x3945:shou4 +0x3946:dian4 +0x3947:can2 +0x3948:die2 +0x3949:che4 +0x394a:peng2 +0x394c:ju2 +0x394d:ji4 +0x394e:lai2 +0x394f:tian3 +0x3950:yuan4 +0x3952:cai3 +0x3953:qi3 +0x3954:yu2 +0x3955:lian2 +0x395a:yu2 +0x395b:ji2 +0x395c:wei4 +0x395d:mi3 +0x395e:cui4 +0x395f:xie2 +0x3960:xu3 +0x3961:xi4 +0x3962:qiu2 +0x3963:hui4 +0x3965:yu2 +0x3966:qie4 +0x3967:shun4 +0x3968:chui2 +0x3969:duo3 +0x396a:lou2 +0x396c:pang2 +0x396d:tai4 +0x396e:zhou4 +0x396f:yin3 +0x3971:fei3 +0x3972:shen4 +0x3973:yuan2 +0x3974:yi2 +0x3975:hun4 +0x3976:se4 +0x3977:ye4 +0x3978:min3 +0x3979:fen3 +0x397a:he2 +0x397c:yin3 +0x397d:ce4 +0x397e:ni4 +0x397f:ao4 +0x3980:feng2 +0x3981:lian2 +0x3982:chang2 +0x3983:chan3 +0x3984:ma2 +0x3985:di4 +0x3987:lu4 +0x3989:yi4 +0x398a:hua2 +0x398c:tui4 +0x398d:e4 +0x398e:hua4 +0x398f:sun3 +0x3990:ni4 +0x3991:lian3 +0x3992:li2 +0x3993:xian4 +0x3994:yan4 +0x3995:long2 +0x3996:men4 +0x3997:jian4 +0x399a:bian3 +0x399b:yu2 +0x399c:huo4 +0x399d:miao3 +0x399e:chou2 +0x399f:hai4 +0x39a1:le4 +0x39a2:jie2 +0x39a3:wei4 +0x39a4:yi4 +0x39a5:huan2 +0x39a6:he4 +0x39a7:can3 +0x39a8:lan2 +0x39a9:yin3 +0x39aa:xie4 +0x39ac:luo3 +0x39ad:ling2 +0x39ae:qian2 +0x39af:huo4 +0x39b1:wo3 +0x39b4:ge2 +0x39b6:die2 +0x39b7:yong3 +0x39b8:ji3 +0x39b9:ang4 +0x39ba:ru3 +0x39bb:xi2 +0x39bc:shuang4 +0x39bd:xu4 +0x39be:yi2 +0x39bf:hu4 +0x39c0:ji2 +0x39c1:qu4 +0x39c2:tian2 +0x39c4:qian3 +0x39c5:mu4 +0x39c7:mao3 +0x39c8:yin3 +0x39c9:gai4 +0x39ca:ba2 +0x39cb:xian3 +0x39cc:mao4 +0x39cd:fang3 +0x39ce:ya2 +0x39d0:song3 +0x39d1:wei2 +0x39d2:xue2 +0x39d4:guai4 +0x39d5:jiu4 +0x39d6:e4 +0x39d7:zi3 +0x39d8:cui4 +0x39d9:bi4 +0x39da:wa3 +0x39dc:lie4 +0x39df:kuai3 +0x39e1:hai4 +0x39e3:zhu4 +0x39e4:chong4 +0x39e5:xian3 +0x39e6:xuan4 +0x39e8:qiu2 +0x39e9:pei4 +0x39ea:gui3 +0x39eb:er2 +0x39ec:gong3 +0x39ed:qiong2 +0x39ef:lao3 +0x39f0:li4 +0x39f1:chen4 +0x39f2:san3 +0x39f3:bo2 +0x39f4:wo3 +0x39f5:pou2 +0x39f7:duo4 +0x39f9:te4 +0x39fa:ta4 +0x39fb:zhi3 +0x39fc:biao4 +0x39fd:gu4 +0x3a00:bing3 +0x3a01:zhi2 +0x3a02:dong3 +0x3a03:cheng2 +0x3a04:zhao4 +0x3a05:nei4 +0x3a06:lin3 +0x3a07:po2 +0x3a08:ji3 +0x3a09:min3 +0x3a0a:wei3 +0x3a0b:che3 +0x3a0c:gou4 +0x3a0e:ru2 +0x3a10:bu3 +0x3a12:kui2 +0x3a13:lao2 +0x3a14:han4 +0x3a15:ying2 +0x3a16:zhi4 +0x3a17:jie2 +0x3a18:xing3 +0x3a19:xie2 +0x3a1a:xun2 +0x3a1b:shan3 +0x3a1c:qian2 +0x3a1d:xie4 +0x3a1e:su4 +0x3a1f:hai2 +0x3a20:mi4 +0x3a21:hun2 +0x3a24:hui4 +0x3a25:na4 +0x3a26:song3 +0x3a27:ben4 +0x3a28:liu4 +0x3a29:jie2 +0x3a2a:huang4 +0x3a2b:lan3 +0x3a2d:hu4 +0x3a2e:dou1 +0x3a2f:huo4 +0x3a30:ge2 +0x3a31:yao2 +0x3a32:ce4 +0x3a33:gui3 +0x3a34:jian4 +0x3a35:jian3 +0x3a36:chou2 +0x3a37:jin4 +0x3a38:ma4 +0x3a39:hui4 +0x3a3a:men2 +0x3a3b:can2 +0x3a3c:lve4 +0x3a3d:pi3 +0x3a3e:yang4 +0x3a3f:ju4 +0x3a40:ju4 +0x3a41:que4 +0x3a44:shai1 +0x3a46:jiu4 +0x3a47:hua4 +0x3a48:xian4 +0x3a49:xie2 +0x3a4b:su4 +0x3a4c:fei4 +0x3a4d:ce4 +0x3a4e:ye4 +0x3a52:qin2 +0x3a53:hui3 +0x3a54:tun2 +0x3a56:qiang2 +0x3a57:xi2 +0x3a58:yi3 +0x3a5a:meng2 +0x3a5b:tuan2 +0x3a5c:lan3 +0x3a5d:hao2 +0x3a5e:ci4 +0x3a5f:zhai4 +0x3a60:piao3 +0x3a61:luo3 +0x3a62:mi2 +0x3a66:xie2 +0x3a67:bo2 +0x3a68:hui4 +0x3a69:qi3 +0x3a6a:xie2 +0x3a6d:bo2 +0x3a6e:qian2 +0x3a6f:ban3 +0x3a70:jiao3 +0x3a71:jue2 +0x3a72:kun3 +0x3a73:song3 +0x3a74:ju2 +0x3a75:e4 +0x3a76:nie4 +0x3a78:die2 +0x3a79:die2 +0x3a7b:gui3 +0x3a7d:qi2 +0x3a7e:chui2 +0x3a80:yu2 +0x3a81:qin2 +0x3a83:ke3 +0x3a84:fu2 +0x3a86:di3 +0x3a87:xian4 +0x3a88:gui4 +0x3a89:he2 +0x3a8a:qun2 +0x3a8b:han4 +0x3a8c:tong3 +0x3a8d:bo2 +0x3a8e:shan3 +0x3a8f:bi3 +0x3a90:lu4 +0x3a91:ye4 +0x3a92:ni2 +0x3a93:chuai2 +0x3a94:san4 +0x3a95:diao4 +0x3a96:lu4 +0x3a97:tou3 +0x3a98:lian3 +0x3a99:ke3 +0x3a9a:san4 +0x3a9b:zhen3 +0x3a9c:chuai3 +0x3a9d:lian4 +0x3a9e:mao4 +0x3aa0:qian4 +0x3aa1:ke3 +0x3aa2:shao3 +0x3aa3:qiao4 +0x3aa4:bi4 +0x3aa6:yin4 +0x3aa8:shan4 +0x3aa9:su4 +0x3aaa:sa4 +0x3aab:rui4 +0x3aac:zhuo2 +0x3aad:lu2 +0x3aae:ling2 +0x3aaf:cha2 +0x3ab1:huan4 +0x3ab4:jia2 +0x3ab5:ban4 +0x3ab6:hu2 +0x3ab7:dou3 +0x3ab9:lou3 +0x3abb:juan4 +0x3abc:ke3 +0x3abd:suo3 +0x3abe:ge2 +0x3abf:zhe2 +0x3ac0:ding3 +0x3ac1:duan4 +0x3ac2:zhu4 +0x3ac3:yan3 +0x3ac4:pang2 +0x3ac5:cha2 +0x3aca:yi3 +0x3acd:you2 +0x3ace:gun3 +0x3acf:yao3 +0x3ad0:yao3 +0x3ad1:shi2 +0x3ad2:gong3 +0x3ad3:qi3 +0x3ad4:gen4 +0x3ad7:hou4 +0x3ad8:mi4 +0x3ad9:fu2 +0x3ada:hu1 +0x3adb:guang4 +0x3adc:dan4 +0x3adf:yan2 +0x3ae2:qu4 +0x3ae4:chang3 +0x3ae5:ming3 +0x3ae7:bao4 +0x3aeb:xian3 +0x3aef:mao4 +0x3af0:lang3 +0x3af1:nan3 +0x3af2:pei4 +0x3af3:chen2 +0x3af6:cou3 +0x3af8:qie4 +0x3af9:dai4 +0x3afb:kun4 +0x3afc:die2 +0x3afd:lu4 +0x3b02:yu2 +0x3b03:tai2 +0x3b04:chan4 +0x3b05:man4 +0x3b06:mian2 +0x3b07:huan4 +0x3b09:nuan3 +0x3b0a:huan3 +0x3b0b:hou2 +0x3b0c:jing4 +0x3b0d:bo2 +0x3b0e:xian3 +0x3b0f:li4 +0x3b10:jin3 +0x3b12:mang3 +0x3b13:piao4 +0x3b14:hao2 +0x3b15:yang2 +0x3b17:xian4 +0x3b18:su4 +0x3b19:wei3 +0x3b1a:che4 +0x3b1c:jin4 +0x3b1d:ceng2 +0x3b1e:he4 +0x3b20:shai4 +0x3b21:ling2 +0x3b23:dui4 +0x3b25:pu4 +0x3b26:yue4 +0x3b27:bo2 +0x3b29:hui4 +0x3b2a:die2 +0x3b2b:yan4 +0x3b2c:ju4 +0x3b2d:jiao4 +0x3b2e:kuai4 +0x3b2f:lie4 +0x3b30:yu2 +0x3b31:ti4 +0x3b33:wu3 +0x3b34:hong3 +0x3b35:xiao2 +0x3b36:hao4 +0x3b3b:huang3 +0x3b3c:fu4 +0x3b3f:dun4 +0x3b41:reng2 +0x3b42:jiao3 +0x3b44:xin4 +0x3b47:yuan4 +0x3b48:jue2 +0x3b49:hua2 +0x3b4b:bang4 +0x3b4c:mou2 +0x3b4f:wei3 +0x3b51:mei4 +0x3b52:si4 +0x3b53:bian4 +0x3b54:lu2 +0x3b58:he2 +0x3b59:she2 +0x3b5a:lv3 +0x3b5b:pai4 +0x3b5c:rong2 +0x3b5d:qiu2 +0x3b5e:lie4 +0x3b5f:gong3 +0x3b60:xian3 +0x3b61:xi4 +0x3b64:niao3 +0x3b68:xie2 +0x3b69:lei4 +0x3b6b:cuan2 +0x3b6c:zhuo2 +0x3b6d:fei4 +0x3b6e:zuo4 +0x3b6f:die2 +0x3b70:ji4 +0x3b71:he2 +0x3b72:ji2 +0x3b78:tu2 +0x3b79:xian2 +0x3b7a:yan3 +0x3b7b:tang2 +0x3b7c:ta4 +0x3b7d:di3 +0x3b7e:jue2 +0x3b7f:ang2 +0x3b80:han2 +0x3b81:yao2 +0x3b82:ju2 +0x3b83:rui2 +0x3b84:bang3 +0x3b86:nie4 +0x3b87:tian4 +0x3b88:nai4 +0x3b8b:you3 +0x3b8c:mian2 +0x3b8f:nai4 +0x3b90:xing3 +0x3b91:qi4 +0x3b93:gen4 +0x3b94:tong2 +0x3b95:er2 +0x3b96:jia2 +0x3b97:qin2 +0x3b98:mao4 +0x3b99:e4 +0x3b9a:li4 +0x3b9b:chi2 +0x3b9d:he2 +0x3b9e:jie2 +0x3b9f:ji2 +0x3ba1:guan4 +0x3ba2:hou2 +0x3ba3:gai4 +0x3ba5:fen4 +0x3ba6:se4 +0x3ba8:ji2 +0x3baa:qiong2 +0x3bab:he2 +0x3bad:xian2 +0x3bae:jie2 +0x3baf:hua2 +0x3bb0:bi2 +0x3bb3:zhen4 +0x3bb6:shi4 +0x3bb8:song4 +0x3bb9:zhi3 +0x3bba:ben3 +0x3bbe:lang3 +0x3bbf:bi4 +0x3bc0:xian3 +0x3bc1:bang4 +0x3bc2:dai4 +0x3bc5:pi2 +0x3bc6:chan3 +0x3bc7:bi4 +0x3bc8:su4 +0x3bc9:huo4 +0x3bca:hen2 +0x3bcb:ying3 +0x3bcc:chuan2 +0x3bcd:jiang3 +0x3bce:nen4 +0x3bcf:gu3 +0x3bd0:fang3 +0x3bd3:ta4 +0x3bd4:cui4 +0x3bd6:de2 +0x3bd7:ran3 +0x3bd8:kuan3 +0x3bd9:che4 +0x3bda:da2 +0x3bdb:hu2 +0x3bdc:cui4 +0x3bdd:lu4 +0x3bde:juan4 +0x3bdf:lu4 +0x3be0:qian4 +0x3be1:pao4 +0x3be2:zhen4 +0x3be4:li4 +0x3be5:cao2 +0x3be6:qi2 +0x3be9:ti4 +0x3bea:ling2 +0x3beb:qu2 +0x3bec:lian3 +0x3bed:lu3 +0x3bee:shu3 +0x3bef:gong4 +0x3bf0:zhe2 +0x3bf1:biao3 +0x3bf2:jin4 +0x3bf3:qing2 +0x3bf6:zong1 +0x3bf7:pu2 +0x3bf8:jin3 +0x3bf9:biao3 +0x3bfa:jian4 +0x3bfb:gun3 +0x3bff:lie4 +0x3c00:li2 +0x3c01:luo3 +0x3c02:shen3 +0x3c03:mian2 +0x3c04:jian4 +0x3c05:di2 +0x3c06:bei4 +0x3c08:lian3 +0x3c0a:xun2 +0x3c0b:pin2 +0x3c0c:que4 +0x3c0d:long2 +0x3c0e:zui4 +0x3c10:jue2 +0x3c12:she2 +0x3c14:xie4 +0x3c16:lan3 +0x3c17:cu4 +0x3c18:yi2 +0x3c19:nuo2 +0x3c1a:li2 +0x3c1b:yue4 +0x3c1d:yi3 +0x3c1f:ji4 +0x3c20:kang4 +0x3c21:xie4 +0x3c23:zi4 +0x3c24:ke3 +0x3c25:hui4 +0x3c26:qu4 +0x3c2a:wa2 +0x3c2c:xun2 +0x3c2e:shen4 +0x3c2f:kou4 +0x3c30:qie4 +0x3c31:sha4 +0x3c32:xu4 +0x3c33:ya4 +0x3c34:po2 +0x3c35:zu2 +0x3c36:you3 +0x3c37:zi4 +0x3c38:lian3 +0x3c39:jin4 +0x3c3a:xia2 +0x3c3b:yi3 +0x3c3c:qie4 +0x3c3d:mi3 +0x3c3e:jiao4 +0x3c40:chi3 +0x3c41:shi4 +0x3c43:yin3 +0x3c44:mo4 +0x3c45:yi4 +0x3c47:se4 +0x3c48:jin4 +0x3c49:ye4 +0x3c4b:que4 +0x3c4c:che4 +0x3c4d:luan2 +0x3c4f:zheng4 +0x3c56:cui4 +0x3c58:an4 +0x3c59:xiu3 +0x3c5a:can2 +0x3c5b:chuan3 +0x3c5c:zha2 +0x3c5e:ji2 +0x3c5f:bo2 +0x3c62:lang2 +0x3c63:tui3 +0x3c65:ling2 +0x3c66:e4 +0x3c67:wo4 +0x3c68:lian4 +0x3c69:du2 +0x3c6a:men4 +0x3c6b:lan4 +0x3c6c:wei3 +0x3c6d:duan4 +0x3c6e:kuai4 +0x3c6f:ai2 +0x3c70:zai3 +0x3c71:hui4 +0x3c72:yi4 +0x3c73:mo4 +0x3c74:zi4 +0x3c75:ben4 +0x3c76:beng4 +0x3c78:bi4 +0x3c79:li4 +0x3c7a:lu2 +0x3c7b:luo3 +0x3c7d:dan4 +0x3c7f:que4 +0x3c80:chen2 +0x3c82:cheng2 +0x3c83:jiu4 +0x3c84:kou4 +0x3c85:ji4 +0x3c86:ling2 +0x3c88:shao2 +0x3c89:kai4 +0x3c8a:rui4 +0x3c8b:chuo4 +0x3c8c:neng4 +0x3c8e:lou2 +0x3c8f:bao3 +0x3c92:bao4 +0x3c93:rong2 +0x3c95:lei4 +0x3c98:qu2 +0x3c9b:zhi3 +0x3c9c:tan2 +0x3c9d:rong3 +0x3c9e:zu2 +0x3c9f:ying3 +0x3ca0:mao2 +0x3ca1:nai4 +0x3ca2:bian4 +0x3ca5:tang2 +0x3ca6:han4 +0x3ca7:zao4 +0x3ca8:rong2 +0x3cab:pu2 +0x3cad:tan3 +0x3caf:ran2 +0x3cb0:ning2 +0x3cb1:lie4 +0x3cb2:die2 +0x3cb3:die2 +0x3cb4:zhong4 +0x3cb6:lv4 +0x3cb7:dan4 +0x3cb9:gui3 +0x3cba:ji2 +0x3cbb:ni4 +0x3cbc:yi4 +0x3cbd:nian4 +0x3cbe:yu3 +0x3cbf:wang3 +0x3cc0:guo4 +0x3cc1:ze4 +0x3cc2:yan2 +0x3cc3:cui4 +0x3cc4:xian2 +0x3cc5:jiao3 +0x3cc6:shu3 +0x3cc7:fu4 +0x3cc8:pei4 +0x3ccd:bu4 +0x3cce:bian4 +0x3ccf:chi3 +0x3cd0:sa4 +0x3cd1:yi4 +0x3cd2:bian4 +0x3cd4:dui4 +0x3cd5:lan2 +0x3cd7:chai4 +0x3cd9:xuan4 +0x3cda:yu4 +0x3cdb:yu2 +0x3ce0:ta4 +0x3ce5:ju4 +0x3ce6:xie4 +0x3ce7:xi2 +0x3ce8:jian3 +0x3cea:pan4 +0x3ceb:ta4 +0x3cec:xuan2 +0x3ced:xian2 +0x3cee:niao4 +0x3cf4:mi4 +0x3cf5:ji4 +0x3cf6:gou4 +0x3cf7:wen3 +0x3cf9:wang3 +0x3cfa:you2 +0x3cfb:ze2 +0x3cfc:bi4 +0x3cfd:mi3 +0x3cff:xie4 +0x3d00:fan4 +0x3d01:yi4 +0x3d03:lei4 +0x3d04:ying2 +0x3d06:jin4 +0x3d07:she4 +0x3d08:yin4 +0x3d09:ji3 +0x3d0b:su4 +0x3d0f:wang3 +0x3d10:mian4 +0x3d11:su4 +0x3d12:yi4 +0x3d13:zai3 +0x3d14:se4 +0x3d15:ji2 +0x3d16:luo4 +0x3d18:mao4 +0x3d19:zha2 +0x3d1a:sui4 +0x3d1b:zhi4 +0x3d1c:bian4 +0x3d1d:li2 +0x3d25:qiao4 +0x3d26:guan4 +0x3d28:zhen4 +0x3d2a:nie4 +0x3d2b:jun4 +0x3d2c:xie4 +0x3d2d:yao3 +0x3d2e:xie4 +0x3d30:neng2 +0x3d33:long3 +0x3d34:chen2 +0x3d35:mi4 +0x3d36:que4 +0x3d38:na4 +0x3d3c:su4 +0x3d3d:xie4 +0x3d3e:bo2 +0x3d3f:ding3 +0x3d40:cuan4 +0x3d42:chuang3 +0x3d43:che4 +0x3d44:han4 +0x3d45:dan4 +0x3d46:hao4 +0x3d4a:shen3 +0x3d4b:mi4 +0x3d4c:chan4 +0x3d4d:men4 +0x3d4e:han3 +0x3d4f:cui3 +0x3d50:jue2 +0x3d51:he4 +0x3d52:fei4 +0x3d53:shi2 +0x3d54:che3 +0x3d55:shen4 +0x3d56:nv4 +0x3d57:fu4 +0x3d58:man4 +0x3d5d:yi4 +0x3d5e:chou2 +0x3d61:bao2 +0x3d62:lei2 +0x3d63:ke3 +0x3d64:dian4 +0x3d65:bi4 +0x3d66:sui2 +0x3d67:ge2 +0x3d68:bi4 +0x3d69:yi4 +0x3d6a:xian2 +0x3d6b:ni3 +0x3d6c:ying2 +0x3d6d:zhu3 +0x3d6e:chun2 +0x3d6f:feng2 +0x3d70:xu4 +0x3d71:piao3 +0x3d72:wu3 +0x3d73:liao2 +0x3d74:cang2 +0x3d75:zou4 +0x3d77:bian4 +0x3d78:yao4 +0x3d79:huan2 +0x3d7a:pai2 +0x3d7b:sou4 +0x3d7d:dui4 +0x3d7e:jing4 +0x3d7f:xi2 +0x3d81:guo2 +0x3d84:yan2 +0x3d85:xue2 +0x3d86:chu2 +0x3d87:heng2 +0x3d88:ying2 +0x3d8c:lian2 +0x3d8d:xian3 +0x3d8e:huan2 +0x3d91:lian4 +0x3d92:shan3 +0x3d93:cang2 +0x3d94:bei4 +0x3d95:jian3 +0x3d96:shu4 +0x3d97:fan4 +0x3d98:dian4 +0x3d9a:ba4 +0x3d9b:yu2 +0x3d9e:nang3 +0x3d9f:lei3 +0x3da0:yi4 +0x3da1:dai4 +0x3da3:chan2 +0x3da4:chao3 +0x3da6:jin4 +0x3da7:nen4 +0x3dab:liao3 +0x3dac:mei2 +0x3dad:jiu4 +0x3daf:liu4 +0x3db0:han2 +0x3db2:yong4 +0x3db3:jin4 +0x3db4:chi3 +0x3db5:ren4 +0x3db6:nong2 +0x3db9:hong4 +0x3dba:tian4 +0x3dbf:bo2 +0x3dc0:qiong2 +0x3dc2:shu4 +0x3dc3:cui3 +0x3dc4:hui4 +0x3dc5:chao3 +0x3dc6:dou4 +0x3dc7:guai4 +0x3dc8:e4 +0x3dc9:wei4 +0x3dca:fen2 +0x3dcb:tan2 +0x3dcd:lun2 +0x3dce:he4 +0x3dcf:yong3 +0x3dd0:hui3 +0x3dd2:yu2 +0x3dd3:zong3 +0x3dd4:yan4 +0x3dd5:qiu2 +0x3dd6:zhao4 +0x3dd7:jiong3 +0x3dd8:tai2 +0x3ddf:tui4 +0x3de0:lin2 +0x3de1:jiong3 +0x3de2:zha3 +0x3de4:he4 +0x3de6:xu4 +0x3dea:cui4 +0x3deb:qing3 +0x3dec:mo4 +0x3def:beng4 +0x3df0:li2 +0x3df3:yan4 +0x3df4:ge2 +0x3df5:mo4 +0x3df6:bei4 +0x3df7:juan3 +0x3df8:die2 +0x3df9:shao4 +0x3dfb:wu2 +0x3dfc:yan4 +0x3dfe:jue2 +0x3e00:tai2 +0x3e01:han3 +0x3e03:dian3 +0x3e04:ji4 +0x3e05:jie2 +0x3e09:xie4 +0x3e0a:la4 +0x3e0b:fan2 +0x3e0c:huo4 +0x3e0d:xi4 +0x3e0e:nie4 +0x3e0f:mi2 +0x3e10:ran2 +0x3e11:cuan4 +0x3e12:yin2 +0x3e13:mi4 +0x3e15:jue2 +0x3e17:tong2 +0x3e18:wan4 +0x3e1a:li3 +0x3e1b:shao2 +0x3e1c:kong4 +0x3e1d:kan3 +0x3e1e:ban3 +0x3e20:tiao3 +0x3e22:bei4 +0x3e23:ye4 +0x3e24:pian4 +0x3e25:chan2 +0x3e26:hu4 +0x3e27:ken4 +0x3e29:an4 +0x3e2a:chun2 +0x3e2b:qian2 +0x3e2c:bei4 +0x3e2e:fen2 +0x3e30:tuo2 +0x3e31:tuo2 +0x3e32:zuo2 +0x3e33:ling2 +0x3e35:gui3 +0x3e37:shi4 +0x3e38:hou3 +0x3e39:lie4 +0x3e3b:si4 +0x3e3d:bei4 +0x3e3e:ren4 +0x3e3f:du2 +0x3e40:bo2 +0x3e41:liang2 +0x3e42:ci4 +0x3e43:bi4 +0x3e44:ji4 +0x3e45:zong3 +0x3e47:he2 +0x3e48:li2 +0x3e49:yuan2 +0x3e4a:yue4 +0x3e4c:chan3 +0x3e4d:di2 +0x3e4e:lei2 +0x3e4f:jin3 +0x3e50:chong2 +0x3e51:si4 +0x3e52:pu3 +0x3e53:yi4 +0x3e56:huan4 +0x3e57:tao2 +0x3e58:ru2 +0x3e59:ying2 +0x3e5a:ying2 +0x3e5b:rao2 +0x3e5c:yin2 +0x3e5d:shi4 +0x3e5e:yin2 +0x3e5f:jue2 +0x3e60:tun2 +0x3e61:xuan2 +0x3e64:qie4 +0x3e65:zhu4 +0x3e68:you4 +0x3e6b:xi4 +0x3e6c:shi3 +0x3e6d:yi4 +0x3e6e:mo4 +0x3e71:hu2 +0x3e72:xiao4 +0x3e73:wu2 +0x3e75:jing4 +0x3e76:ting2 +0x3e77:shi3 +0x3e78:ni2 +0x3e7a:ta4 +0x3e7c:chu3 +0x3e7d:chan3 +0x3e7e:piao3 +0x3e7f:diao3 +0x3e80:nao2 +0x3e81:nao3 +0x3e82:gan3 +0x3e83:gou3 +0x3e84:yu3 +0x3e85:hou2 +0x3e89:hu4 +0x3e8a:yang4 +0x3e8c:xian4 +0x3e8e:rong2 +0x3e8f:lou2 +0x3e90:zhao3 +0x3e91:can2 +0x3e92:liao4 +0x3e93:piao4 +0x3e94:hai4 +0x3e95:fan2 +0x3e96:han3 +0x3e97:dan4 +0x3e98:zhan4 +0x3e9a:ta3 +0x3e9b:zhu4 +0x3e9c:ban3 +0x3e9d:jian4 +0x3e9e:yu2 +0x3e9f:zhuo2 +0x3ea0:you4 +0x3ea1:li4 +0x3ea5:chan2 +0x3ea6:lian2 +0x3ea9:jiu4 +0x3eaa:pu2 +0x3eab:qiu2 +0x3eac:gong3 +0x3ead:zi3 +0x3eae:yu2 +0x3eb1:reng2 +0x3eb2:niu3 +0x3eb3:mei2 +0x3eb5:jiu2 +0x3eb7:xu4 +0x3eb8:ping2 +0x3eb9:bian4 +0x3eba:mao4 +0x3ebf:yi2 +0x3ec0:you2 +0x3ec2:ping2 +0x3ec4:bao3 +0x3ec5:hui4 +0x3ec9:bu4 +0x3eca:mang2 +0x3ecb:la4 +0x3ecc:tu2 +0x3ecd:wu2 +0x3ece:li4 +0x3ecf:ling2 +0x3ed1:ji4 +0x3ed2:jun4 +0x3ed4:duo3 +0x3ed5:jue2 +0x3ed6:dai4 +0x3ed7:bei4 +0x3edd:la4 +0x3ede:bian4 +0x3edf:sui2 +0x3ee0:tu2 +0x3ee1:die2 +0x3ee7:duo4 +0x3eea:sui4 +0x3eeb:bi4 +0x3eec:tu2 +0x3eed:se4 +0x3eee:can4 +0x3eef:tu2 +0x3ef0:mian3 +0x3ef2:lv3 +0x3ef5:zhan4 +0x3ef6:bi3 +0x3ef7:ji2 +0x3ef8:cen2 +0x3efa:li4 +0x3efd:sui4 +0x3eff:shu3 +0x3f02:e2 +0x3f07:qiong2 +0x3f08:luo2 +0x3f09:yin4 +0x3f0a:tun2 +0x3f0b:gu3 +0x3f0c:yu3 +0x3f0d:lei3 +0x3f0e:bei4 +0x3f0f:nei3 +0x3f10:pian2 +0x3f11:lian4 +0x3f12:qiu3 +0x3f13:lian2 +0x3f16:li4 +0x3f17:ding3 +0x3f18:wa3 +0x3f19:zhou4 +0x3f1b:xing2 +0x3f1c:ang4 +0x3f1d:fan4 +0x3f1e:peng4 +0x3f1f:bai2 +0x3f20:tuo2 +0x3f22:e3 +0x3f23:bai3 +0x3f24:qi4 +0x3f25:chu2 +0x3f26:gong3 +0x3f27:tong2 +0x3f28:han2 +0x3f29:cheng2 +0x3f2a:jia2 +0x3f2b:huan4 +0x3f2c:xing4 +0x3f2d:dian4 +0x3f2e:mai2 +0x3f2f:dong4 +0x3f30:e2 +0x3f31:ruan3 +0x3f32:lie4 +0x3f33:sheng3 +0x3f34:ou3 +0x3f35:di4 +0x3f36:yu2 +0x3f37:chuan2 +0x3f38:rong2 +0x3f3a:tang2 +0x3f3b:cong2 +0x3f3c:piao2 +0x3f3d:shuang3 +0x3f3e:lu4 +0x3f3f:tong2 +0x3f40:zheng4 +0x3f41:li4 +0x3f42:sa4 +0x3f47:guai4 +0x3f48:yi4 +0x3f49:han3 +0x3f4a:xie4 +0x3f4b:luo2 +0x3f4c:liu4 +0x3f4e:dan3 +0x3f51:tan2 +0x3f55:you2 +0x3f56:nan2 +0x3f58:gang3 +0x3f59:jun4 +0x3f5a:chi4 +0x3f5b:kou4 +0x3f5c:wan3 +0x3f5d:li4 +0x3f5e:liu2 +0x3f5f:lie4 +0x3f60:xia2 +0x3f62:an3 +0x3f63:yu4 +0x3f64:ju2 +0x3f65:rou2 +0x3f66:xun2 +0x3f68:cuo2 +0x3f69:can4 +0x3f6a:zeng3 +0x3f6b:yong3 +0x3f6c:fu4 +0x3f6d:ruan3 +0x3f6f:xi2 +0x3f70:shu4 +0x3f71:jiao3 +0x3f72:jiao3 +0x3f73:han4 +0x3f74:zhang4 +0x3f77:shui4 +0x3f78:chen2 +0x3f79:fan4 +0x3f7a:ji2 +0x3f7d:gu4 +0x3f7e:wu4 +0x3f80:qie4 +0x3f81:shu4 +0x3f83:tuo2 +0x3f84:du2 +0x3f85:si4 +0x3f86:ran2 +0x3f87:mu4 +0x3f88:fu4 +0x3f89:ling2 +0x3f8a:ji2 +0x3f8b:xiu4 +0x3f8c:xuan3 +0x3f8d:nai2 +0x3f8f:jie4 +0x3f90:li4 +0x3f91:da2 +0x3f92:ji4 +0x3f94:lv3 +0x3f95:shen3 +0x3f96:li3 +0x3f97:lang3 +0x3f98:geng3 +0x3f99:yin3 +0x3f9b:qin3 +0x3f9c:qie4 +0x3f9d:che4 +0x3f9e:you3 +0x3f9f:bu4 +0x3fa0:huang2 +0x3fa1:que4 +0x3fa2:lai4 +0x3fa5:xu4 +0x3fa6:bang4 +0x3fa7:ke4 +0x3fa8:qi3 +0x3faa:sheng3 +0x3fad:zhou4 +0x3fae:huang2 +0x3faf:tui2 +0x3fb0:hu2 +0x3fb1:bei4 +0x3fb5:ji4 +0x3fb6:gu3 +0x3fb8:gao3 +0x3fb9:chai2 +0x3fba:ma4 +0x3fbb:zhu4 +0x3fbc:tui3 +0x3fbd:tui2 +0x3fbe:lian2 +0x3fbf:lang2 +0x3fc3:dai4 +0x3fc4:ai4 +0x3fc5:xian3 +0x3fc7:xi2 +0x3fc9:tui2 +0x3fca:can3 +0x3fcb:sao4 +0x3fcd:jie4 +0x3fce:fen4 +0x3fcf:qun2 +0x3fd1:yao4 +0x3fd2:dao3 +0x3fd3:jia2 +0x3fd4:lei3 +0x3fd5:yan2 +0x3fd6:lu2 +0x3fd7:tui2 +0x3fd8:ying2 +0x3fd9:pi4 +0x3fda:luo4 +0x3fdb:li2 +0x3fdc:bie3 +0x3fde:mao4 +0x3fdf:bai2 +0x3fe2:yao4 +0x3fe3:he2 +0x3fe4:chun3 +0x3fe5:hu2 +0x3fe6:ning4 +0x3fe7:chou2 +0x3fe8:li4 +0x3fe9:tang3 +0x3fea:huan2 +0x3feb:bi4 +0x3fed:che4 +0x3fee:yang4 +0x3fef:da2 +0x3ff0:ao2 +0x3ff1:xue2 +0x3ff5:ran3 +0x3ff7:zao4 +0x3ff8:wan3 +0x3ff9:ta4 +0x3ffa:bao2 +0x3ffc:yan2 +0x3ffe:zhu4 +0x3fff:ya3 +0x4000:fan2 +0x4001:you4 +0x4003:tui2 +0x4004:meng2 +0x4005:she4 +0x4006:jin4 +0x4007:gu3 +0x4008:qi4 +0x4009:qiao2 +0x400a:jiao3 +0x400b:yan2 +0x400d:kan4 +0x400e:mian3 +0x400f:xian4 +0x4010:san3 +0x4011:na4 +0x4013:huan4 +0x4014:niu2 +0x4015:cheng4 +0x4017:jue2 +0x4018:xi2 +0x4019:qi4 +0x401a:ang2 +0x401b:mei4 +0x401c:gu3 +0x401f:fan2 +0x4020:qu2 +0x4021:chan4 +0x4022:shun4 +0x4023:bi4 +0x4024:mao4 +0x4025:shuo4 +0x4026:gu3 +0x4027:hong3 +0x4028:huan4 +0x4029:luo4 +0x402a:hang2 +0x402b:jia2 +0x402c:quan2 +0x402e:mang2 +0x402f:bu3 +0x4030:gu3 +0x4032:mu4 +0x4033:ai4 +0x4034:ying3 +0x4035:shun4 +0x4036:lang3 +0x4037:jie2 +0x4038:di4 +0x4039:jie2 +0x403b:pin4 +0x403c:ren4 +0x403d:yan2 +0x403e:du3 +0x403f:di4 +0x4041:lang3 +0x4042:xian4 +0x4044:xing4 +0x4045:bei4 +0x4046:an3 +0x4047:mi4 +0x4048:qi4 +0x4049:qi4 +0x404a:wo4 +0x404b:she2 +0x404c:yu4 +0x404d:jia4 +0x404e:cheng2 +0x404f:yao3 +0x4050:ying4 +0x4051:yang2 +0x4052:ji2 +0x4053:jie4 +0x4054:han4 +0x4055:min2 +0x4056:lou1 +0x4057:kai3 +0x4058:yao3 +0x4059:yan3 +0x405a:sun3 +0x405b:gui3 +0x405c:huang3 +0x405d:ying2 +0x405e:sheng3 +0x405f:cha2 +0x4060:lian2 +0x4062:xuan2 +0x4063:chuan2 +0x4064:che4 +0x4065:ni4 +0x4066:qu4 +0x4067:miao2 +0x4068:huo4 +0x4069:yu2 +0x406a:nan3 +0x406b:hu2 +0x406c:ceng2 +0x406e:qian2 +0x406f:she4 +0x4070:jiang3 +0x4071:ao4 +0x4072:mai2 +0x4073:mang3 +0x4074:zhan3 +0x4075:bian3 +0x4076:jiao3 +0x4077:jue2 +0x4078:nong2 +0x4079:bi4 +0x407a:shi4 +0x407b:li4 +0x407c:mo4 +0x407d:lie4 +0x407e:mie4 +0x407f:mo4 +0x4080:xi1 +0x4081:chan2 +0x4082:qu2 +0x4083:jiao4 +0x4084:huo4 +0x4086:xu4 +0x4087:nang2 +0x4088:tong2 +0x4089:hou2 +0x408a:yu4 +0x408d:bo2 +0x408e:zuan3 +0x4090:chuo4 +0x4092:jie2 +0x4094:xing4 +0x4095:hui4 +0x4096:shi2 +0x409a:yao2 +0x409b:yu2 +0x409c:bang4 +0x409d:jie2 +0x409e:zhe4 +0x40a0:she2 +0x40a1:di3 +0x40a2:dong3 +0x40a3:ci2 +0x40a4:fu4 +0x40a5:min2 +0x40a6:zhen3 +0x40a7:zhen3 +0x40a9:yan4 +0x40aa:diao4 +0x40ab:hong2 +0x40ac:gong3 +0x40ae:lve4 +0x40af:guai4 +0x40b0:la4 +0x40b1:cui4 +0x40b2:fa3 +0x40b3:cuo3 +0x40b4:yan2 +0x40b6:jie2 +0x40b8:guo2 +0x40b9:suo3 +0x40ba:wan3 +0x40bb:zheng4 +0x40bc:nie4 +0x40bd:diao4 +0x40be:lai3 +0x40bf:ta4 +0x40c0:cui4 +0x40c2:gun3 +0x40c7:mian2 +0x40c9:min2 +0x40ca:ju3 +0x40cb:yu2 +0x40cd:zhao4 +0x40ce:ze2 +0x40d1:pan2 +0x40d2:he2 +0x40d3:gou4 +0x40d4:hong2 +0x40d5:lao2 +0x40d6:wu4 +0x40d7:chuo4 +0x40d9:lu4 +0x40da:cu4 +0x40db:lian2 +0x40dd:qiao4 +0x40de:shu2 +0x40e1:cen2 +0x40e3:hui3 +0x40e4:su4 +0x40e5:chuang2 +0x40e7:long2 +0x40e9:nao2 +0x40ea:tan2 +0x40eb:dan3 +0x40ec:wei3 +0x40ed:gan3 +0x40ee:da2 +0x40ef:li4 +0x40f1:xian4 +0x40f2:pan2 +0x40f3:la4 +0x40f5:niao3 +0x40f6:huai2 +0x40f7:ying2 +0x40f8:xian4 +0x40f9:lan4 +0x40fa:mo2 +0x40fb:ba4 +0x40fd:fu2 +0x40fe:bi3 +0x4100:huo4 +0x4101:yi4 +0x4102:liu4 +0x4105:juan4 +0x4106:huo2 +0x4107:cheng2 +0x4108:dou4 +0x4109:e2 +0x410b:yan3 +0x410c:zhui4 +0x410d:du4 +0x410e:qi3 +0x410f:yu2 +0x4110:quan4 +0x4111:huo2 +0x4112:nie4 +0x4113:heng2 +0x4114:ju3 +0x4115:she4 +0x4118:peng2 +0x4119:ming2 +0x411a:cao2 +0x411b:lou2 +0x411c:li2 +0x411d:chun3 +0x411f:cui4 +0x4120:shan4 +0x4122:qi2 +0x4124:lai4 +0x4125:ling2 +0x4126:liao3 +0x4127:reng2 +0x4128:yu2 +0x4129:nao2 +0x412a:chuo4 +0x412b:qi3 +0x412c:yi2 +0x412d:nian2 +0x412f:jian3 +0x4130:ya2 +0x4132:chui2 +0x4136:bi4 +0x4137:dan4 +0x4138:po4 +0x4139:nian2 +0x413a:zhi4 +0x413b:chao2 +0x413c:tian3 +0x413d:tian3 +0x413e:rou4 +0x413f:yi4 +0x4140:lie4 +0x4141:an4 +0x4142:he2 +0x4143:qiong2 +0x4144:li4 +0x4146:zi4 +0x4147:su4 +0x4148:yuan4 +0x4149:ya4 +0x414a:du4 +0x414b:wan3 +0x414d:dong4 +0x414e:you3 +0x414f:hui4 +0x4150:jian3 +0x4151:rui2 +0x4152:mang2 +0x4153:ju3 +0x4156:an3 +0x4157:sui4 +0x4158:lai2 +0x4159:hun4 +0x415a:qiang3 +0x415c:duo4 +0x415e:na4 +0x415f:can3 +0x4160:ti2 +0x4161:xu3 +0x4162:jiu4 +0x4163:huang2 +0x4164:qi4 +0x4165:jie2 +0x4166:mao2 +0x4167:yan4 +0x4169:zhi3 +0x416a:tui2 +0x416c:ai4 +0x416d:pang2 +0x416e:cang4 +0x416f:tang2 +0x4170:en3 +0x4171:hun4 +0x4172:qi2 +0x4173:chu2 +0x4174:suo3 +0x4175:zhuo2 +0x4176:nou4 +0x4177:tu2 +0x4178:zu2 +0x4179:lou2 +0x417a:miao3 +0x417b:li2 +0x417c:man2 +0x417d:gu3 +0x417e:cen2 +0x417f:hua2 +0x4180:mei3 +0x4182:lian2 +0x4183:dao3 +0x4184:shan4 +0x4185:ci2 +0x4188:zhi4 +0x4189:ba4 +0x418a:cui4 +0x418b:qiu1 +0x418d:long2 +0x418f:fei4 +0x4190:guo2 +0x4191:cheng2 +0x4192:jiu4 +0x4193:e4 +0x4195:jue2 +0x4196:hong2 +0x4197:jiao4 +0x4198:cuan2 +0x4199:yao2 +0x419a:tong2 +0x419b:cha2 +0x419c:you4 +0x419d:shu4 +0x419e:yao3 +0x419f:ge2 +0x41a0:huan4 +0x41a1:lang2 +0x41a2:jue2 +0x41a3:chen2 +0x41a6:shen4 +0x41a8:ming2 +0x41a9:ming2 +0x41ab:chuang1 +0x41ac:yun3 +0x41ae:jin4 +0x41af:chuo4 +0x41b1:tan3 +0x41b3:qiong2 +0x41b5:cheng2 +0x41b7:yu4 +0x41b8:cheng2 +0x41b9:tong3 +0x41bb:qiao4 +0x41bd:ju4 +0x41be:lan2 +0x41bf:yi4 +0x41c0:rong2 +0x41c3:si4 +0x41c5:fa2 +0x41c7:meng2 +0x41c8:gui4 +0x41cb:hai4 +0x41cc:qiao4 +0x41cd:chuo4 +0x41ce:que4 +0x41cf:dui4 +0x41d0:li4 +0x41d1:ba4 +0x41d2:jie4 +0x41d4:luo4 +0x41d6:yun3 +0x41d8:hu4 +0x41d9:yin3 +0x41db:zhi3 +0x41dc:lian3 +0x41de:gan3 +0x41df:jian4 +0x41e0:zhou4 +0x41e1:zhu4 +0x41e2:ku3 +0x41e3:na4 +0x41e4:dui4 +0x41e5:ze2 +0x41e6:yang3 +0x41e7:zhu4 +0x41e8:gong4 +0x41e9:yi4 +0x41ec:chuang3 +0x41ed:lao3 +0x41ee:ren4 +0x41ef:rong2 +0x41f1:na4 +0x41f2:ce4 +0x41f5:yi2 +0x41f6:jue2 +0x41f7:bi3 +0x41f8:cheng2 +0x41f9:jun4 +0x41fa:chou2 +0x41fb:hui4 +0x41fc:chi4 +0x41fd:zhi4 +0x41fe:yan2 +0x4201:lun2 +0x4202:bing4 +0x4203:zhao3 +0x4204:han2 +0x4205:yu4 +0x4206:dai4 +0x4207:zhao4 +0x4208:fei2 +0x4209:sha4 +0x420a:ling2 +0x420b:ta4 +0x420d:mang2 +0x420e:ye4 +0x420f:bao2 +0x4210:kui4 +0x4211:gua3 +0x4212:nan3 +0x4213:ge2 +0x4215:chi2 +0x4217:suo3 +0x4218:ci2 +0x4219:zhou4 +0x421a:tai2 +0x421b:kuai4 +0x421c:qin4 +0x421e:du3 +0x421f:ce4 +0x4220:huan3 +0x4222:sai3 +0x4223:zheng4 +0x4224:qian2 +0x4227:wei3 +0x422a:xi4 +0x422b:na4 +0x422c:pu2 +0x422d:huai2 +0x422e:ju3 +0x4232:pan2 +0x4233:ta4 +0x4234:qian4 +0x4236:rong2 +0x4237:luo4 +0x4238:hu2 +0x4239:sou3 +0x423b:pu2 +0x423c:mie4 +0x423e:shuo4 +0x423f:mai4 +0x4240:shu4 +0x4241:ling2 +0x4242:lei3 +0x4243:jiang3 +0x4244:leng2 +0x4245:zhi4 +0x4246:diao3 +0x4248:san3 +0x4249:hu2 +0x424a:fan4 +0x424b:mei4 +0x424c:sui4 +0x424d:jian3 +0x424e:tang2 +0x424f:xie4 +0x4251:mo2 +0x4252:fan2 +0x4253:lei2 +0x4255:ceng2 +0x4256:ling2 +0x4258:cong2 +0x4259:yun2 +0x425a:meng2 +0x425b:yu4 +0x425c:zhi4 +0x425d:qi3 +0x425e:dan3 +0x425f:huo4 +0x4260:wei2 +0x4261:tan2 +0x4262:se4 +0x4263:xie4 +0x4264:sou3 +0x4265:song3 +0x4267:liu2 +0x4268:yi4 +0x426a:lei4 +0x426b:li2 +0x426c:fei4 +0x426d:lie4 +0x426e:lin4 +0x426f:xian4 +0x4270:yao2 +0x4272:bie4 +0x4273:xian3 +0x4274:rang2 +0x4275:zhuan4 +0x4277:dan4 +0x4278:bian4 +0x4279:ling2 +0x427a:hong2 +0x427b:qi2 +0x427c:liao4 +0x427d:ban3 +0x427e:mi4 +0x427f:hu2 +0x4280:hu2 +0x4282:ce4 +0x4283:pei4 +0x4284:qiong2 +0x4285:ming2 +0x4286:jiu4 +0x4287:bu4 +0x4288:mei2 +0x4289:san3 +0x428a:mei4 +0x428d:li2 +0x428e:quan3 +0x4290:en4 +0x4291:xiang3 +0x4293:shi4 +0x4296:lan3 +0x4297:huang2 +0x4298:jiu4 +0x4299:yan2 +0x429b:sa3 +0x429c:tuan2 +0x429d:xie4 +0x429e:zhe2 +0x429f:men2 +0x42a0:xi4 +0x42a1:man2 +0x42a3:huang2 +0x42a4:tan2 +0x42a5:xiao4 +0x42a6:ya2 +0x42a7:bi4 +0x42a8:luo2 +0x42a9:fan2 +0x42aa:li4 +0x42ab:cui3 +0x42ac:cha4 +0x42ad:chou2 +0x42ae:di2 +0x42af:kuang4 +0x42b0:chu3 +0x42b2:chan3 +0x42b3:mi2 +0x42b4:qian4 +0x42b5:qiu2 +0x42b6:zhen4 +0x42ba:gu3 +0x42bb:yan3 +0x42bc:chi3 +0x42bd:guai4 +0x42be:mu4 +0x42bf:bo2 +0x42c0:kua4 +0x42c1:geng3 +0x42c2:yao2 +0x42c3:mao4 +0x42c4:wang3 +0x42c8:ru2 +0x42c9:jue2 +0x42cb:min2 +0x42cc:jiang3 +0x42ce:zhan4 +0x42cf:zuo4 +0x42d0:yue4 +0x42d1:bing3 +0x42d3:zhou4 +0x42d4:bi4 +0x42d5:ren4 +0x42d6:yu4 +0x42d8:chuo4 +0x42d9:er3 +0x42da:yi4 +0x42db:mi2 +0x42dc:qing4 +0x42de:wang3 +0x42df:ji4 +0x42e0:bu3 +0x42e2:bie4 +0x42e3:fan2 +0x42e4:yao4 +0x42e5:li2 +0x42e6:fan2 +0x42e7:qu2 +0x42e8:fu3 +0x42e9:er2 +0x42ed:huo4 +0x42ee:jin4 +0x42ef:qi3 +0x42f0:ju2 +0x42f1:lai2 +0x42f2:che3 +0x42f3:bei4 +0x42f4:niu4 +0x42f5:yi4 +0x42f6:xu4 +0x42f7:liu2 +0x42f8:xun2 +0x42f9:fu2 +0x42fb:nin2 +0x42fc:ting3 +0x42fd:beng3 +0x42fe:zha3 +0x4302:ou4 +0x4303:shuo4 +0x4304:geng3 +0x4305:tang2 +0x4306:gui4 +0x4307:hui4 +0x4308:ta4 +0x430a:yao2 +0x430c:qi4 +0x430d:han4 +0x430e:lve4 +0x430f:mi4 +0x4310:mi4 +0x4312:lu4 +0x4313:fan2 +0x4314:ou4 +0x4315:mi2 +0x4316:jie2 +0x4317:fu3 +0x4318:mi2 +0x4319:huang3 +0x431a:su4 +0x431b:yao2 +0x431c:nie4 +0x431d:jin4 +0x431e:lian3 +0x431f:bi4 +0x4320:qing4 +0x4321:ti3 +0x4322:ling2 +0x4323:zuan3 +0x4324:zhi3 +0x4325:yin3 +0x4326:dao3 +0x4327:chou2 +0x4328:cai4 +0x4329:mi4 +0x432a:yan2 +0x432b:lan3 +0x432c:chong2 +0x432f:guan4 +0x4330:she4 +0x4331:luo4 +0x4334:luo4 +0x4335:zhu2 +0x4337:chou2 +0x4338:juan4 +0x4339:jiong3 +0x433a:er3 +0x433b:yi4 +0x433c:rui4 +0x433d:cai3 +0x433e:ren2 +0x433f:fu2 +0x4340:lan2 +0x4341:sui4 +0x4342:yu2 +0x4343:yao2 +0x4344:dian3 +0x4345:ling2 +0x4346:zhu4 +0x4347:ta4 +0x4348:ping2 +0x4349:qian2 +0x434a:jue2 +0x434b:chui2 +0x434c:bu4 +0x434d:gu3 +0x434e:cun4 +0x4350:han3 +0x4351:han3 +0x4352:mou3 +0x4353:hu4 +0x4354:hong2 +0x4355:di3 +0x4356:fu2 +0x4357:xuan4 +0x4358:mi2 +0x4359:mei2 +0x435a:lang4 +0x435b:gu4 +0x435c:zhao4 +0x435d:ta4 +0x435e:yu4 +0x435f:zong4 +0x4360:li2 +0x4361:liao4 +0x4362:wu2 +0x4363:lei2 +0x4364:ji3 +0x4365:lei4 +0x4366:li2 +0x4368:bo2 +0x4369:ang3 +0x436a:kui4 +0x436b:tuo2 +0x436e:zhao4 +0x436f:gui3 +0x4371:xu2 +0x4372:nai2 +0x4373:chuo4 +0x4374:duo4 +0x4376:dong4 +0x4377:gui4 +0x4378:bo2 +0x437a:huan2 +0x437b:xuan3 +0x437c:can2 +0x437d:li4 +0x437e:tui2 +0x437f:huang2 +0x4380:xue4 +0x4381:hu2 +0x4382:bao3 +0x4383:ran3 +0x4384:tiao2 +0x4385:fu4 +0x4386:liao4 +0x4388:yi4 +0x4389:shu4 +0x438a:po4 +0x438b:he4 +0x438c:cu4 +0x438e:na4 +0x438f:an4 +0x4390:chao3 +0x4391:lu4 +0x4392:zhan3 +0x4393:ta4 +0x4397:qiao2 +0x4398:su4 +0x439a:guan4 +0x439d:chu2 +0x439f:er2 +0x43a0:er2 +0x43a1:nuan3 +0x43a2:qi3 +0x43a3:si4 +0x43a4:chu2 +0x43a6:yan3 +0x43a7:bang4 +0x43a8:an4 +0x43aa:ne4 +0x43ab:chuang4 +0x43ac:ba4 +0x43ae:ti4 +0x43af:han4 +0x43b0:zuo2 +0x43b1:ba4 +0x43b2:zhe2 +0x43b3:wa4 +0x43b4:sheng4 +0x43b5:bi4 +0x43b6:er4 +0x43b7:zhu4 +0x43b8:wu4 +0x43b9:wen2 +0x43ba:zhi3 +0x43bb:zhou3 +0x43bc:lu4 +0x43bd:wen2 +0x43be:gun3 +0x43bf:qiu2 +0x43c0:la4 +0x43c1:zai3 +0x43c2:sou3 +0x43c3:mian2 +0x43c4:zhi4 +0x43c5:qi4 +0x43c6:cao2 +0x43c7:piao4 +0x43c8:lian2 +0x43ca:long2 +0x43cb:su4 +0x43cc:qi4 +0x43cd:yuan4 +0x43ce:feng2 +0x43d0:jue2 +0x43d1:di4 +0x43d2:pian4 +0x43d3:guan3 +0x43d4:niu3 +0x43d5:ren3 +0x43d6:zhen4 +0x43d7:gai4 +0x43d8:pi3 +0x43d9:tan3 +0x43da:chao3 +0x43db:chun3 +0x43dd:chun2 +0x43de:mo4 +0x43df:bie4 +0x43e0:qi4 +0x43e1:shi4 +0x43e2:bi3 +0x43e3:jue2 +0x43e4:si4 +0x43e6:hua2 +0x43e7:na2 +0x43e8:hui3 +0x43ea:er4 +0x43ec:mou2 +0x43ee:xi2 +0x43ef:zhi4 +0x43f0:ren3 +0x43f1:ju2 +0x43f2:die2 +0x43f3:zhe4 +0x43f4:shao4 +0x43f5:meng3 +0x43f6:bi4 +0x43f7:han4 +0x43f8:yu2 +0x43f9:xian4 +0x43fb:neng2 +0x43fc:can2 +0x43fd:bu4 +0x43ff:qi3 +0x4400:ji4 +0x4401:niao3 +0x4402:lu4 +0x4403:jiong3 +0x4404:han4 +0x4405:yi2 +0x4406:cai3 +0x4407:chun2 +0x4408:zhi2 +0x4409:zi4 +0x440a:da2 +0x440c:tian3 +0x440d:zhou4 +0x440f:chun3 +0x4411:zhe2 +0x4413:rou2 +0x4414:bin4 +0x4415:ji2 +0x4416:yi2 +0x4417:du3 +0x4418:jue2 +0x4419:ge2 +0x441a:ji2 +0x441d:suo3 +0x441e:ruo4 +0x441f:xiang4 +0x4420:huang3 +0x4421:qi2 +0x4422:zhu4 +0x4423:cuo4 +0x4424:chi2 +0x4425:weng3 +0x4427:kao4 +0x4428:gu3 +0x4429:kai3 +0x442a:fan4 +0x442c:cao2 +0x442d:zhi4 +0x442e:chan3 +0x442f:lei2 +0x4432:zhe2 +0x4433:yu2 +0x4434:gui4 +0x4435:huang2 +0x4436:jin3 +0x4438:guo2 +0x4439:sao4 +0x443a:tan4 +0x443c:xi4 +0x443d:man2 +0x443e:duo2 +0x443f:ao2 +0x4440:pi4 +0x4441:wu4 +0x4442:ai3 +0x4443:meng2 +0x4444:pi4 +0x4445:meng2 +0x4446:yang3 +0x4447:zhi4 +0x4448:bo2 +0x4449:ying2 +0x444a:wei2 +0x444b:nao2 +0x444c:lan2 +0x444d:yan4 +0x444e:chan3 +0x444f:quan2 +0x4450:zhen3 +0x4451:pu2 +0x4453:tai2 +0x4454:fei4 +0x4455:shu3 +0x4457:dang4 +0x4458:cha2 +0x4459:ran2 +0x445a:tian2 +0x445b:chi3 +0x445c:ta4 +0x445d:jia3 +0x445e:shun4 +0x445f:huang2 +0x4460:liao3 +0x4464:jin4 +0x4465:e4 +0x4467:fu2 +0x4468:duo4 +0x446a:e4 +0x446c:yao4 +0x446d:di4 +0x446f:di4 +0x4470:bu4 +0x4471:man2 +0x4472:che4 +0x4473:lun2 +0x4474:qi2 +0x4475:mu4 +0x4476:can2 +0x447b:you2 +0x447d:da2 +0x447f:su4 +0x4480:fu2 +0x4481:ji4 +0x4482:jiang3 +0x4483:cao4 +0x4484:bo2 +0x4485:teng2 +0x4486:che4 +0x4487:fu4 +0x4488:bu3 +0x4489:wu3 +0x448b:yang3 +0x448c:ming4 +0x448d:pang3 +0x448e:mang3 +0x4490:meng2 +0x4491:cao3 +0x4492:tiao2 +0x4493:kai3 +0x4494:bai4 +0x4495:xiao3 +0x4496:xin4 +0x4497:qi4 +0x449a:shao3 +0x449b:heng2 +0x449c:niu2 +0x449d:xiao2 +0x449e:chen2 +0x44a0:fan3 +0x44a1:yin3 +0x44a2:ang2 +0x44a3:ran3 +0x44a4:ri4 +0x44a5:fa4 +0x44a6:fan4 +0x44a7:qu4 +0x44a8:shi3 +0x44a9:he2 +0x44aa:bian4 +0x44ab:dai4 +0x44ac:mo4 +0x44ad:deng3 +0x44b2:cha4 +0x44b3:duo3 +0x44b4:you3 +0x44b5:hao4 +0x44b8:xian2 +0x44b9:lei4 +0x44ba:jin3 +0x44bb:qi3 +0x44bd:mei2 +0x44c2:yan2 +0x44c3:yi4 +0x44c4:yin2 +0x44c5:qi2 +0x44c6:zhe2 +0x44c7:xi4 +0x44c8:yi4 +0x44c9:ye2 +0x44ca:e4 +0x44cc:zhi4 +0x44cd:han3 +0x44ce:chuo4 +0x44d0:chun2 +0x44d1:bing3 +0x44d2:kuai3 +0x44d3:chou2 +0x44d5:tuo3 +0x44d6:qiong2 +0x44d8:jiu4 +0x44da:cu2 +0x44db:fu3 +0x44dd:meng2 +0x44de:li4 +0x44df:lie4 +0x44e0:ta4 +0x44e2:gu4 +0x44e3:liang3 +0x44e5:la4 +0x44e6:dian3 +0x44e7:ci4 +0x44eb:ji4 +0x44ed:cha4 +0x44ee:mao4 +0x44ef:du2 +0x44f1:chai2 +0x44f2:rui4 +0x44f3:hen3 +0x44f4:ruan2 +0x44f6:lai4 +0x44f7:xing4 +0x44f9:yi4 +0x44fa:mei3 +0x44fc:he4 +0x44fd:ji4 +0x44ff:han3 +0x4501:li4 +0x4502:zi3 +0x4503:zu3 +0x4504:yao2 +0x4506:li2 +0x4507:qi3 +0x4508:gan3 +0x4509:li4 +0x450e:su4 +0x450f:chou4 +0x4511:xie2 +0x4512:bei4 +0x4513:xu3 +0x4514:jing4 +0x4515:pu2 +0x4516:ling2 +0x4517:xiang2 +0x4518:zuo4 +0x4519:diao4 +0x451a:chun2 +0x451b:qing3 +0x451c:nan2 +0x451e:lv4 +0x451f:chi2 +0x4520:shao3 +0x4521:yu2 +0x4522:hua2 +0x4523:li2 +0x4527:li2 +0x452a:dui4 +0x452c:yi4 +0x452d:ning4 +0x452f:hu2 +0x4530:fu2 +0x4532:cheng2 +0x4533:nan3 +0x4534:ce4 +0x4536:ti2 +0x4537:qin2 +0x4538:biao3 +0x4539:sui4 +0x453a:wei2 +0x453c:se4 +0x453d:ai4 +0x453e:e4 +0x453f:jie4 +0x4540:kuan3 +0x4541:fei3 +0x4543:yin4 +0x4545:sao3 +0x4546:dou4 +0x4547:hui4 +0x4548:xie4 +0x4549:ze2 +0x454a:tan2 +0x454b:chang3 +0x454c:zhi4 +0x454d:yi4 +0x454e:fu2 +0x454f:e2 +0x4551:jun4 +0x4553:cha2 +0x4554:xian2 +0x4555:man4 +0x4557:bi4 +0x4558:ling2 +0x4559:jie2 +0x455a:kui4 +0x455b:jia2 +0x455e:lang4 +0x4560:fei4 +0x4561:lu3 +0x4562:zha3 +0x4563:he2 +0x4565:ni3 +0x4566:ying2 +0x4567:xiao4 +0x4568:teng2 +0x4569:lao3 +0x456a:ze2 +0x456b:kui2 +0x456d:qian2 +0x456e:ju2 +0x456f:piao2 +0x4570:ban4 +0x4571:dou3 +0x4572:lin3 +0x4573:mi2 +0x4574:zhuo2 +0x4575:xie2 +0x4576:hu4 +0x4577:mi2 +0x4579:za2 +0x457a:cong2 +0x457b:ge2 +0x457c:nan2 +0x457d:zhu2 +0x457e:yan2 +0x457f:han4 +0x4581:yi4 +0x4582:luan2 +0x4583:yue4 +0x4584:ran2 +0x4585:ling2 +0x4586:niang4 +0x4587:yu4 +0x4588:nve4 +0x458a:yi2 +0x458b:nve4 +0x458c:qin2 +0x458d:qian2 +0x458e:xia2 +0x458f:chu3 +0x4590:jin4 +0x4591:mi4 +0x4593:na4 +0x4594:han4 +0x4595:zu3 +0x4596:xia2 +0x4597:yan2 +0x4598:tu2 +0x459b:suo3 +0x459c:yin2 +0x459d:chong2 +0x459e:zhou3 +0x459f:mang3 +0x45a0:yuan2 +0x45a1:nv4 +0x45a2:miao2 +0x45a3:sao4 +0x45a4:wan3 +0x45a5:li2 +0x45a7:na4 +0x45a8:shi2 +0x45a9:bi4 +0x45aa:ci2 +0x45ab:bang4 +0x45ad:juan4 +0x45ae:xiang3 +0x45af:gui4 +0x45b0:pai4 +0x45b2:xun2 +0x45b3:zha4 +0x45b4:yao2 +0x45b8:e2 +0x45b9:yang2 +0x45ba:tiao2 +0x45bb:you2 +0x45bc:jue2 +0x45bd:li2 +0x45bf:li2 +0x45c1:ji4 +0x45c2:hu3 +0x45c3:zhan4 +0x45c4:fu3 +0x45c5:chang2 +0x45c6:guan3 +0x45c7:ju2 +0x45c8:meng2 +0x45ca:cheng2 +0x45cb:mou2 +0x45cd:li3 +0x45d1:yi4 +0x45d2:bing4 +0x45d4:hou2 +0x45d5:wan3 +0x45d6:chi4 +0x45d8:ge2 +0x45d9:han2 +0x45da:bo2 +0x45dc:liu2 +0x45dd:can2 +0x45de:can2 +0x45df:yi4 +0x45e0:xuan2 +0x45e1:yan2 +0x45e2:suo3 +0x45e3:gao3 +0x45e4:yong2 +0x45e8:yu2 +0x45ea:zhe4 +0x45eb:ma2 +0x45ee:shuang3 +0x45ef:jin4 +0x45f0:guan4 +0x45f1:pu2 +0x45f2:lin4 +0x45f4:ting2 +0x45f6:la4 +0x45f7:yi4 +0x45f9:ci4 +0x45fa:yan3 +0x45fb:jie2 +0x45fd:wei4 +0x45fe:xian3 +0x45ff:ning2 +0x4600:fu4 +0x4601:ge2 +0x4603:mo4 +0x4604:fu4 +0x4605:nai2 +0x4606:xian3 +0x4607:wen2 +0x4608:li4 +0x4609:can2 +0x460a:mie4 +0x460c:ni4 +0x460d:chai4 +0x460f:xu4 +0x4610:nv4 +0x4611:mai4 +0x4613:kan4 +0x4615:hang2 +0x4618:yu4 +0x4619:wei4 +0x461a:zhu2 +0x461d:yi4 +0x4620:fu2 +0x4621:bi3 +0x4622:zhu3 +0x4623:zi3 +0x4624:shu4 +0x4625:xia2 +0x4626:ni2 +0x4628:jiao3 +0x4629:xuan4 +0x462b:nou4 +0x462c:rong2 +0x462d:die2 +0x462e:sa4 +0x4631:yu4 +0x4635:lu4 +0x4636:han4 +0x4638:yi4 +0x4639:zui4 +0x463a:zhan4 +0x463b:su4 +0x463c:wan3 +0x463d:ni2 +0x463e:guan3 +0x463f:jue2 +0x4640:beng3 +0x4641:can2 +0x4643:duo4 +0x4644:qi4 +0x4645:yao4 +0x4646:gui4 +0x4647:nuan3 +0x4648:hou2 +0x4649:xun2 +0x464a:xie4 +0x464c:hui4 +0x464e:xie2 +0x464f:bo2 +0x4650:ke4 +0x4652:xu4 +0x4653:bai3 +0x4655:chu4 +0x4657:ti4 +0x4658:chu3 +0x4659:chi2 +0x465a:niao3 +0x465b:guan4 +0x465c:feng2 +0x465d:xie4 +0x465f:duo4 +0x4660:jue2 +0x4661:hui4 +0x4662:zeng4 +0x4663:sa4 +0x4664:duo3 +0x4665:ling2 +0x4666:meng2 +0x4668:guo3 +0x4669:meng2 +0x466a:long2 +0x466c:ying4 +0x466e:guan4 +0x466f:cu4 +0x4670:li2 +0x4671:du2 +0x4673:e4 +0x4677:de2 +0x4678:de2 +0x4679:jiang3 +0x467a:lian2 +0x467c:shao4 +0x467d:xi4 +0x467f:wei4 +0x4682:he4 +0x4683:you2 +0x4684:lu4 +0x4685:lai2 +0x4686:ou3 +0x4687:sheng3 +0x4688:juan4 +0x4689:qi4 +0x468b:yun4 +0x468d:qi4 +0x468f:leng4 +0x4690:ji2 +0x4691:mai2 +0x4692:chuang2 +0x4693:nian3 +0x4695:li4 +0x4696:ling2 +0x4698:chen2 +0x469a:xian3 +0x469b:hu2 +0x469d:zu2 +0x469e:dai3 +0x469f:dai3 +0x46a0:hun4 +0x46a2:che4 +0x46a3:ti2 +0x46a5:nuo4 +0x46a6:zhi4 +0x46a7:liu2 +0x46a8:fei4 +0x46a9:jiao3 +0x46ab:ao2 +0x46ac:lin2 +0x46ae:reng2 +0x46af:tao3 +0x46b0:pi3 +0x46b1:xin4 +0x46b2:shan4 +0x46b3:xie4 +0x46b4:wa4 +0x46b5:tao3 +0x46b7:xi4 +0x46b8:xie4 +0x46b9:pi3 +0x46ba:yao2 +0x46bb:yao2 +0x46bc:nv4 +0x46bd:hao4 +0x46be:nin2 +0x46bf:yin4 +0x46c0:fan3 +0x46c1:nan2 +0x46c2:chi2 +0x46c3:wang4 +0x46c4:yuan3 +0x46c5:xia2 +0x46c6:zhou4 +0x46c7:yuan3 +0x46c8:shi4 +0x46c9:mi4 +0x46cb:ge2 +0x46cc:pao2 +0x46cd:fei4 +0x46ce:hu4 +0x46cf:ni2 +0x46d0:ci2 +0x46d1:mi4 +0x46d2:bian4 +0x46d4:na2 +0x46d5:yu4 +0x46d6:e4 +0x46d7:zhi3 +0x46d8:nin2 +0x46d9:xu4 +0x46da:lve4 +0x46db:hui4 +0x46dc:xun4 +0x46dd:nao2 +0x46de:han3 +0x46df:jia2 +0x46e0:dou4 +0x46e1:hua4 +0x46e4:cu4 +0x46e5:xi4 +0x46e6:song4 +0x46e7:mi2 +0x46e8:xin4 +0x46e9:wu4 +0x46ea:qiong2 +0x46eb:zheng4 +0x46ec:chou2 +0x46ed:xing4 +0x46ee:jiu4 +0x46ef:ju4 +0x46f0:hun2 +0x46f1:ti2 +0x46f2:man2 +0x46f3:jian3 +0x46f4:qi3 +0x46f5:shou4 +0x46f6:lei3 +0x46f7:wan3 +0x46f8:che4 +0x46f9:can4 +0x46fa:jie4 +0x46fb:you4 +0x46fc:hui3 +0x46fd:zha3 +0x46fe:su4 +0x46ff:ge2 +0x4700:nao3 +0x4701:xi4 +0x4704:chi2 +0x4705:wei2 +0x4706:mo4 +0x4707:gun3 +0x470a:zao4 +0x470b:hui4 +0x470c:luan2 +0x470d:liao2 +0x470e:lao2 +0x4711:qia4 +0x4712:ao4 +0x4713:nie4 +0x4714:sui2 +0x4715:mai4 +0x4716:tan4 +0x4717:xin4 +0x4718:jing3 +0x4719:an2 +0x471a:ta4 +0x471b:chan2 +0x471c:wei4 +0x471d:tuan3 +0x471e:ji4 +0x471f:chen2 +0x4720:che4 +0x4721:xu4 +0x4722:xian3 +0x4723:xin1 +0x4727:nao3 +0x4729:yan4 +0x472a:qiu2 +0x472b:hong2 +0x472c:song3 +0x472d:jun4 +0x472e:liao2 +0x472f:ju2 +0x4731:man3 +0x4732:lie4 +0x4734:chu4 +0x4735:chi3 +0x4736:xiang2 +0x4738:mei3 +0x4739:shu4 +0x473a:ce4 +0x473b:chi3 +0x473c:gu2 +0x473d:yu2 +0x4740:liao2 +0x4741:lao2 +0x4742:shu4 +0x4743:zhe2 +0x4748:e4 +0x474a:sha4 +0x474b:zong4 +0x474c:jue2 +0x474d:jun4 +0x474f:lou2 +0x4750:wei2 +0x4752:zhu4 +0x4753:la4 +0x4755:zhe2 +0x4756:zhao3 +0x4758:yi4 +0x475a:ni2 +0x475d:yi3 +0x475e:hao4 +0x475f:ya4 +0x4760:huan2 +0x4761:man4 +0x4762:man4 +0x4763:qu2 +0x4764:lao3 +0x4765:hao2 +0x4767:men2 +0x4768:xian2 +0x4769:zhen4 +0x476a:shu2 +0x476b:zuo2 +0x476c:zhu4 +0x476d:gou4 +0x476e:xuan4 +0x476f:yi4 +0x4770:ti2 +0x4772:jin4 +0x4773:can2 +0x4775:bu4 +0x4776:liang2 +0x4777:zhi4 +0x4778:ji4 +0x4779:wan3 +0x477a:guan4 +0x477c:qing2 +0x477d:ai4 +0x477e:fu4 +0x477f:gui4 +0x4780:gou4 +0x4781:xian4 +0x4782:ruan3 +0x4783:zhi4 +0x4784:biao4 +0x4785:yi2 +0x4786:suo3 +0x4787:die2 +0x4788:gui3 +0x4789:sheng4 +0x478a:xun4 +0x478b:chen4 +0x478c:she2 +0x478d:qing2 +0x4790:chun3 +0x4791:hong2 +0x4792:dong4 +0x4793:cheng1 +0x4794:wei3 +0x4795:die2 +0x4796:shu3 +0x4798:ji2 +0x4799:za2 +0x479a:qi2 +0x479c:fu4 +0x479d:ao3 +0x479e:fu2 +0x479f:po4 +0x47a1:tan3 +0x47a2:zha4 +0x47a3:che3 +0x47a4:qu2 +0x47a5:you4 +0x47a6:he2 +0x47a7:hou4 +0x47a8:gui3 +0x47a9:e4 +0x47aa:jiang4 +0x47ab:yun3 +0x47ac:tou4 +0x47ad:qiu3 +0x47af:fu4 +0x47b0:zuo2 +0x47b1:hu2 +0x47b3:bo2 +0x47b5:jue3 +0x47b6:di4 +0x47b7:jue2 +0x47b8:fu4 +0x47b9:huang2 +0x47bb:yong3 +0x47bc:chui3 +0x47bd:suo3 +0x47be:chi2 +0x47c2:man2 +0x47c3:ca4 +0x47c4:qi4 +0x47c5:jian4 +0x47c6:bi4 +0x47c8:zhi2 +0x47c9:zhu2 +0x47ca:qu2 +0x47cb:zhan3 +0x47cc:ji2 +0x47cd:dian2 +0x47cf:li4 +0x47d0:li4 +0x47d1:la3 +0x47d2:quan2 +0x47d4:fu4 +0x47d5:cha4 +0x47d6:tang4 +0x47d7:shi4 +0x47d8:hang4 +0x47d9:qie4 +0x47da:qi2 +0x47db:bo2 +0x47dc:na4 +0x47dd:tou4 +0x47de:chu2 +0x47df:cu4 +0x47e0:yue4 +0x47e1:di4 +0x47e2:chen2 +0x47e3:chu4 +0x47e4:bi4 +0x47e5:mang2 +0x47e6:ba2 +0x47e7:tian2 +0x47e8:min2 +0x47e9:lie3 +0x47ea:feng3 +0x47ec:qiu4 +0x47ed:tiao2 +0x47ee:fu2 +0x47ef:kuo4 +0x47f0:jian3 +0x47f4:zhen4 +0x47f5:qiu2 +0x47f6:cuo4 +0x47f7:chi4 +0x47f8:kui2 +0x47f9:lie4 +0x47fa:bang3 +0x47fb:du4 +0x47fc:wu3 +0x47fe:jue3 +0x47ff:lu4 +0x4800:chang3 +0x4802:chu2 +0x4803:liang3 +0x4804:tian3 +0x4805:kun3 +0x4806:chang2 +0x4807:jue2 +0x4808:tu2 +0x4809:hua4 +0x480a:fei4 +0x480b:bi3 +0x480d:qia2 +0x480e:wo4 +0x480f:ji4 +0x4810:qu4 +0x4811:kui3 +0x4812:hu2 +0x4813:cu4 +0x4814:sui4 +0x4817:qiu4 +0x4818:pi4 +0x4819:bei4 +0x481a:wa4 +0x481b:jiao3 +0x481c:rong2 +0x481e:cu4 +0x481f:die2 +0x4820:chi4 +0x4821:cuo2 +0x4822:meng4 +0x4823:xuan3 +0x4824:duo3 +0x4825:bie2 +0x4826:zhe4 +0x4827:chu2 +0x4828:chan4 +0x4829:gui4 +0x482a:duan4 +0x482b:zou4 +0x482c:deng4 +0x482d:lai2 +0x482e:teng2 +0x482f:yue4 +0x4830:quan2 +0x4831:shu3 +0x4832:ling2 +0x4834:qin3 +0x4835:fu4 +0x4836:she4 +0x4837:tiao3 +0x4839:ai2 +0x483b:qiong2 +0x483c:diao4 +0x483d:hai2 +0x483e:shan3 +0x483f:wai4 +0x4840:zhan3 +0x4841:long3 +0x4842:jiu4 +0x4843:li4 +0x4845:min3 +0x4846:rong2 +0x4847:yue4 +0x4848:jue2 +0x4849:kang3 +0x484a:fan2 +0x484b:qi2 +0x484c:hong2 +0x484d:fu2 +0x484e:lu2 +0x484f:hong2 +0x4850:tuo2 +0x4851:min2 +0x4852:tian2 +0x4853:juan4 +0x4854:qi3 +0x4855:zheng3 +0x4856:jing4 +0x4857:gong3 +0x4858:tian2 +0x4859:lang2 +0x485a:mao4 +0x485b:yin4 +0x485c:lu4 +0x485d:yun3 +0x485e:ju2 +0x485f:pi4 +0x4861:xie2 +0x4862:bian4 +0x4865:rong2 +0x4866:sang3 +0x4867:wu3 +0x4868:cha4 +0x4869:gu3 +0x486a:chan2 +0x486b:peng2 +0x486c:man4 +0x486f:shuang4 +0x4870:keng3 +0x4871:zhuan3 +0x4872:chan2 +0x4874:chuang2 +0x4875:sui4 +0x4876:bei4 +0x4877:kai4 +0x4879:zhi4 +0x487a:wei4 +0x487b:min2 +0x487c:ling2 +0x487e:nei4 +0x487f:ling2 +0x4880:qi4 +0x4881:yue4 +0x4883:yi4 +0x4884:xi3 +0x4885:chen2 +0x4887:rong3 +0x4888:chen2 +0x4889:nong2 +0x488a:you2 +0x488b:ji4 +0x488c:bo2 +0x488d:fang3 +0x4890:cu2 +0x4891:di3 +0x4893:yu2 +0x4894:ge2 +0x4895:xu4 +0x4896:lv4 +0x4897:he2 +0x4899:bai4 +0x489a:gong4 +0x489b:jiong3 +0x489d:ya4 +0x489e:nu4 +0x489f:you2 +0x48a0:song4 +0x48a1:xie4 +0x48a2:cang4 +0x48a3:yao2 +0x48a4:shu4 +0x48a5:yan2 +0x48a6:shuai4 +0x48a7:liao4 +0x48a9:yu4 +0x48aa:bo2 +0x48ab:sui2 +0x48ad:yan4 +0x48ae:lei4 +0x48af:lin2 +0x48b0:tai2 +0x48b1:du2 +0x48b2:yue4 +0x48b3:ji3 +0x48b5:yun2 +0x48b9:ju3 +0x48bb:chen2 +0x48bd:xiang4 +0x48be:xian3 +0x48c0:gui3 +0x48c1:yu3 +0x48c2:lei3 +0x48c4:tu2 +0x48c5:chen2 +0x48c6:xing2 +0x48c7:qiu2 +0x48c8:hang4 +0x48ca:dang3 +0x48cb:cai3 +0x48cc:di3 +0x48cd:yan3 +0x48d1:chan2 +0x48d3:li2 +0x48d4:suo3 +0x48d5:ma3 +0x48d6:ma3 +0x48d8:tang2 +0x48d9:pei2 +0x48da:lou2 +0x48dc:cuo2 +0x48dd:tu2 +0x48de:e4 +0x48df:can2 +0x48e0:jie2 +0x48e1:ti2 +0x48e2:ji2 +0x48e3:dang3 +0x48e4:jiao4 +0x48e5:bi3 +0x48e6:lei4 +0x48e7:yi4 +0x48e8:chun2 +0x48e9:chun2 +0x48ea:po4 +0x48eb:li2 +0x48ec:zai3 +0x48ed:tai4 +0x48ee:po4 +0x48ef:tian3 +0x48f0:ju4 +0x48f1:xu4 +0x48f2:fan4 +0x48f4:xu4 +0x48f5:er4 +0x48f6:huo2 +0x48f8:ran3 +0x48f9:fa2 +0x48fc:liang2 +0x48fd:ti3 +0x48fe:mi4 +0x4901:cen2 +0x4902:mei2 +0x4903:yin4 +0x4904:mian3 +0x4905:tu2 +0x4906:kui2 +0x4909:mi4 +0x490a:rong2 +0x490b:guo2 +0x490d:mi2 +0x490e:ju2 +0x490f:pi3 +0x4910:jin3 +0x4911:wang4 +0x4912:ji3 +0x4913:meng2 +0x4914:jian4 +0x4915:xue4 +0x4916:bao4 +0x4917:gan3 +0x4918:chan3 +0x4919:li4 +0x491a:li3 +0x491b:qiu2 +0x491c:dun4 +0x491d:ying4 +0x491e:yun3 +0x491f:chen2 +0x4920:ji1 +0x4921:ran3 +0x4923:lve4 +0x4925:gui3 +0x4926:yue4 +0x4927:hui4 +0x4928:pi4 +0x4929:cha2 +0x492a:duo3 +0x492b:chan2 +0x492d:kuan4 +0x492e:she4 +0x492f:xing2 +0x4930:weng3 +0x4931:shi4 +0x4932:chi4 +0x4933:ye4 +0x4934:han2 +0x4935:fei4 +0x4936:ye4 +0x4937:yan2 +0x4938:zuan4 +0x493a:yin3 +0x493b:duo4 +0x493c:xian4 +0x493f:qie4 +0x4940:chan3 +0x4941:han2 +0x4942:meng4 +0x4943:yue4 +0x4944:cu4 +0x4945:qian4 +0x4946:jin3 +0x4947:shan4 +0x4948:mu3 +0x494c:zheng4 +0x494d:zhi4 +0x494e:chun2 +0x494f:yu3 +0x4950:mou2 +0x4951:wan4 +0x4952:chou2 +0x4954:su4 +0x4955:pie3 +0x4956:tian2 +0x4957:kuan3 +0x4958:cu4 +0x4959:sui4 +0x495b:jie2 +0x495c:jian4 +0x495d:ao2 +0x495e:jiao3 +0x495f:ye4 +0x4961:ye4 +0x4962:long2 +0x4963:zao2 +0x4964:bao2 +0x4965:lian2 +0x4967:huan2 +0x4968:lv4 +0x4969:wei2 +0x496a:xian3 +0x496b:tie3 +0x496c:bo2 +0x496d:zheng4 +0x496e:zhu2 +0x496f:ba4 +0x4970:meng4 +0x4971:xie3 +0x4975:xiao3 +0x4976:li4 +0x4977:zha2 +0x4978:mi2 +0x497a:ye2 +0x497e:xie3 +0x4982:shan4 +0x4985:shan4 +0x4986:jue2 +0x4987:ji4 +0x4988:fang3 +0x498a:niao3 +0x498b:ao2 +0x498c:chu4 +0x498d:wu4 +0x498e:guan3 +0x498f:xie4 +0x4990:ting3 +0x4991:xie4 +0x4992:dang4 +0x4994:tan3 +0x4996:xia2 +0x4997:xu4 +0x4998:bi4 +0x4999:si4 +0x499a:huo4 +0x499b:zheng4 +0x499c:wu2 +0x499e:run4 +0x499f:chuai4 +0x49a0:shi3 +0x49a1:huan2 +0x49a2:kuo4 +0x49a3:fu4 +0x49a4:chuai4 +0x49a5:xian2 +0x49a6:qin2 +0x49a7:qie2 +0x49a8:lan2 +0x49aa:ya4 +0x49ac:que4 +0x49ae:chun3 +0x49af:zhi4 +0x49b1:kui3 +0x49b2:qian4 +0x49b3:hang4 +0x49b4:yi4 +0x49b5:ni3 +0x49b6:zheng4 +0x49b7:chuai4 +0x49b9:shi2 +0x49bb:ci4 +0x49bc:jue2 +0x49bd:xu4 +0x49be:yun3 +0x49c1:chu4 +0x49c2:dao4 +0x49c3:dian4 +0x49c4:ge4 +0x49c5:ti4 +0x49c6:hong2 +0x49c7:ni3 +0x49c9:li3 +0x49cb:xian3 +0x49cd:xi4 +0x49ce:xuan4 +0x49d2:lai2 +0x49d4:mu4 +0x49d5:cheng2 +0x49d6:jian4 +0x49d7:bi4 +0x49d8:qi2 +0x49d9:ling2 +0x49da:hao4 +0x49db:bang4 +0x49dc:tang2 +0x49dd:di4 +0x49de:fu4 +0x49df:xian4 +0x49e0:shuan4 +0x49e4:pu2 +0x49e5:hui4 +0x49e6:wei2 +0x49e7:yi3 +0x49e8:ye4 +0x49ea:che4 +0x49eb:hao2 +0x49ee:xian3 +0x49ef:chan2 +0x49f0:hun4 +0x49f2:han4 +0x49f3:ci2 +0x49f5:qi2 +0x49f6:kui2 +0x49f7:rou2 +0x49fa:xiong2 +0x49fc:hu2 +0x49fd:cui3 +0x49ff:que4 +0x4a00:di2 +0x4a01:che4 +0x4a04:yan4 +0x4a05:liao2 +0x4a06:bi2 +0x4a0b:nve4 +0x4a0c:bao2 +0x4a0d:ying3 +0x4a0e:hong2 +0x4a0f:ci2 +0x4a10:qia4 +0x4a11:ti2 +0x4a12:yu4 +0x4a13:lei2 +0x4a14:bao2 +0x4a16:ji4 +0x4a17:fu2 +0x4a18:xian4 +0x4a19:cen2 +0x4a1b:se4 +0x4a1e:yu3 +0x4a20:ai3 +0x4a21:han2 +0x4a22:dan4 +0x4a23:ge2 +0x4a24:di2 +0x4a25:hu4 +0x4a26:pang2 +0x4a29:ling2 +0x4a2a:mai2 +0x4a2b:mai4 +0x4a2c:lian2 +0x4a2e:xue3 +0x4a2f:zhen4 +0x4a30:po4 +0x4a31:fu4 +0x4a32:nou2 +0x4a33:xi4 +0x4a34:dui4 +0x4a35:dan4 +0x4a36:yun3 +0x4a37:xian4 +0x4a38:yin3 +0x4a3a:dui4 +0x4a3b:beng4 +0x4a3c:hu4 +0x4a3d:fei3 +0x4a3e:fei3 +0x4a3f:qian2 +0x4a40:bei4 +0x4a43:shi4 +0x4a44:tian3 +0x4a45:zhan3 +0x4a46:jian3 +0x4a48:hui4 +0x4a49:fu3 +0x4a4a:wan3 +0x4a4b:mo3 +0x4a4c:qiao2 +0x4a4d:liao3 +0x4a4f:mie4 +0x4a50:ge2 +0x4a51:hong2 +0x4a52:yu2 +0x4a53:qi2 +0x4a54:duo4 +0x4a55:ang2 +0x4a57:ba4 +0x4a58:di4 +0x4a59:xuan4 +0x4a5a:di4 +0x4a5b:bi4 +0x4a5c:zhou4 +0x4a5d:pao2 +0x4a5e:nian2 +0x4a5f:yi2 +0x4a61:jia2 +0x4a62:da2 +0x4a63:duo3 +0x4a64:xi4 +0x4a65:dan4 +0x4a66:tiao2 +0x4a67:xie4 +0x4a68:chang4 +0x4a69:yuan3 +0x4a6a:guan3 +0x4a6b:liang3 +0x4a6c:beng3 +0x4a6e:lu4 +0x4a6f:ji2 +0x4a70:xuan4 +0x4a71:shu4 +0x4a73:shu3 +0x4a74:hu2 +0x4a75:yun4 +0x4a76:chan3 +0x4a78:rong2 +0x4a79:e2 +0x4a7b:ba4 +0x4a7c:feng2 +0x4a7e:zhe4 +0x4a7f:fen2 +0x4a80:guan3 +0x4a81:bu3 +0x4a82:ge2 +0x4a84:huang2 +0x4a85:du2 +0x4a86:ti3 +0x4a87:bo2 +0x4a88:qian3 +0x4a89:la4 +0x4a8a:long2 +0x4a8b:wei4 +0x4a8c:zhan4 +0x4a8d:lan2 +0x4a8f:na4 +0x4a90:bi4 +0x4a91:tuo2 +0x4a92:jiao4 +0x4a94:bu3 +0x4a95:ju2 +0x4a96:po4 +0x4a97:xia2 +0x4a98:wei3 +0x4a99:fu2 +0x4a9a:he4 +0x4a9b:fan2 +0x4a9c:chan4 +0x4a9d:hu4 +0x4a9e:za2 +0x4aa4:fan2 +0x4aa5:die2 +0x4aa6:hong2 +0x4aa7:chi2 +0x4aa8:bao2 +0x4aa9:yin2 +0x4aac:bo2 +0x4aad:ruan3 +0x4aae:chou3 +0x4aaf:ying2 +0x4ab1:gai3 +0x4ab3:yun3 +0x4ab4:zhen3 +0x4ab5:ya3 +0x4ab7:hou4 +0x4ab8:min2 +0x4ab9:pei2 +0x4aba:ge2 +0x4abb:bian4 +0x4abd:hao4 +0x4abe:mi2 +0x4abf:sheng3 +0x4ac0:gen3 +0x4ac1:bi4 +0x4ac2:duo3 +0x4ac3:chun2 +0x4ac4:chua4 +0x4ac5:san4 +0x4ac6:cheng2 +0x4ac7:ran2 +0x4ac8:zen4 +0x4ac9:mao4 +0x4aca:bo2 +0x4acb:tui2 +0x4acc:pi3 +0x4acd:fu3 +0x4ad0:lin2 +0x4ad2:men2 +0x4ad3:wu2 +0x4ad4:qi4 +0x4ad5:zhi4 +0x4ad6:chen3 +0x4ad7:xia2 +0x4ad8:he2 +0x4ad9:sang3 +0x4adb:hou2 +0x4add:fu3 +0x4ade:rao2 +0x4adf:hun2 +0x4ae0:pei2 +0x4ae1:qian4 +0x4ae3:xi2 +0x4ae4:ming2 +0x4ae5:kui3 +0x4ae6:ge2 +0x4ae8:ao4 +0x4ae9:san3 +0x4aea:shuang3 +0x4aeb:lou2 +0x4aec:zhen3 +0x4aed:hui4 +0x4aee:can2 +0x4af0:lin4 +0x4af1:na2 +0x4af2:han4 +0x4af3:du2 +0x4af4:jin4 +0x4af5:mian2 +0x4af6:fan2 +0x4af7:e4 +0x4af8:nao2 +0x4af9:hong2 +0x4afa:hong2 +0x4afb:xue2 +0x4afc:xue4 +0x4afe:bi4 +0x4b00:you3 +0x4b01:yi2 +0x4b02:xue4 +0x4b03:sa4 +0x4b04:yu4 +0x4b05:li4 +0x4b06:li4 +0x4b07:yuan4 +0x4b08:dui4 +0x4b09:hao4 +0x4b0a:qie4 +0x4b0b:leng2 +0x4b0e:guo2 +0x4b0f:bu4 +0x4b10:wei3 +0x4b11:wei4 +0x4b13:an4 +0x4b14:xu4 +0x4b15:shang3 +0x4b16:heng2 +0x4b17:yang2 +0x4b19:yao2 +0x4b1b:bi4 +0x4b1d:heng2 +0x4b1e:tao2 +0x4b1f:liu2 +0x4b21:zhu4 +0x4b23:qi4 +0x4b24:chao2 +0x4b25:yi4 +0x4b26:dou4 +0x4b27:yuan2 +0x4b28:cu4 +0x4b2a:bo2 +0x4b2b:can3 +0x4b2c:yang3 +0x4b2e:yi2 +0x4b2f:nian2 +0x4b30:shao4 +0x4b31:ben4 +0x4b33:ban3 +0x4b34:mo4 +0x4b35:ai4 +0x4b36:en4 +0x4b37:she3 +0x4b39:zhi4 +0x4b3a:yang4 +0x4b3b:jian4 +0x4b3c:yuan4 +0x4b3d:dui4 +0x4b3e:ti2 +0x4b3f:wei3 +0x4b40:xun4 +0x4b41:zhi4 +0x4b42:yi4 +0x4b43:ren3 +0x4b44:shi4 +0x4b45:hu2 +0x4b46:ne4 +0x4b47:yi4 +0x4b48:jian4 +0x4b49:sui3 +0x4b4a:ying3 +0x4b4b:bao3 +0x4b4c:hu2 +0x4b4d:hu2 +0x4b4e:xie2 +0x4b50:yang4 +0x4b51:lian2 +0x4b53:en4 +0x4b55:jian4 +0x4b56:zhu4 +0x4b57:ying3 +0x4b58:yan4 +0x4b59:jin3 +0x4b5a:chuang2 +0x4b5b:dan4 +0x4b5d:kuai4 +0x4b5e:yi4 +0x4b5f:ye4 +0x4b60:jian3 +0x4b61:en4 +0x4b62:ning2 +0x4b63:ci2 +0x4b64:qian3 +0x4b65:xue4 +0x4b66:bo2 +0x4b67:mi3 +0x4b68:shui4 +0x4b69:mi4 +0x4b6a:liang2 +0x4b6b:qi3 +0x4b6c:qi3 +0x4b6d:shou3 +0x4b6e:bi4 +0x4b6f:bo2 +0x4b70:beng3 +0x4b71:bie2 +0x4b72:ni3 +0x4b73:wei4 +0x4b74:huan2 +0x4b75:fan2 +0x4b76:qi2 +0x4b77:liu2 +0x4b78:fu4 +0x4b79:ang2 +0x4b7a:ang2 +0x4b7c:qi2 +0x4b7d:qun2 +0x4b7e:tuo2 +0x4b7f:yi4 +0x4b80:bo2 +0x4b81:pian2 +0x4b82:bo2 +0x4b84:xuan2 +0x4b87:yu4 +0x4b88:chi2 +0x4b89:lu2 +0x4b8a:yi2 +0x4b8b:li4 +0x4b8d:niao3 +0x4b8e:xi4 +0x4b8f:wu2 +0x4b91:lei4 +0x4b93:zhao4 +0x4b94:zui3 +0x4b95:chuo4 +0x4b97:an4 +0x4b98:er2 +0x4b99:yu4 +0x4b9a:leng4 +0x4b9b:fu4 +0x4b9c:sha4 +0x4b9d:huan2 +0x4b9e:chu4 +0x4b9f:sou3 +0x4ba1:bi4 +0x4ba2:die2 +0x4ba4:di2 +0x4ba5:li4 +0x4ba7:han2 +0x4ba8:zai3 +0x4ba9:gu2 +0x4baa:cheng2 +0x4bab:lou2 +0x4bac:mo4 +0x4bad:mi4 +0x4bae:mai4 +0x4baf:ao4 +0x4bb0:dan3 +0x4bb1:zhu2 +0x4bb2:huang2 +0x4bb3:fan2 +0x4bb4:deng4 +0x4bb5:tong2 +0x4bb7:du2 +0x4bb8:hu2 +0x4bb9:wei4 +0x4bba:ji4 +0x4bbb:chi4 +0x4bbc:lin2 +0x4bbe:pang2 +0x4bbf:jian3 +0x4bc0:nie4 +0x4bc1:luo2 +0x4bc2:ji2 +0x4bc5:nie4 +0x4bc6:yi4 +0x4bc8:wan2 +0x4bc9:ya4 +0x4bca:qia4 +0x4bcb:bo2 +0x4bcd:ling2 +0x4bce:gan4 +0x4bcf:huo2 +0x4bd0:hai2 +0x4bd2:heng2 +0x4bd3:kui2 +0x4bd4:cen2 +0x4bd6:lang2 +0x4bd7:bi4 +0x4bd8:huan4 +0x4bd9:po4 +0x4bda:ou3 +0x4bdb:jian3 +0x4bdc:ti4 +0x4bdd:sui3 +0x4bdf:dui4 +0x4be0:ao3 +0x4be1:jian3 +0x4be2:mo2 +0x4be3:gui4 +0x4be4:kuai4 +0x4be5:an4 +0x4be6:ma4 +0x4be7:qing3 +0x4be8:fen2 +0x4bea:kao3 +0x4beb:hao4 +0x4bec:duo3 +0x4bee:nai2 +0x4bf0:jie4 +0x4bf1:fu4 +0x4bf2:pa2 +0x4bf4:chang2 +0x4bf5:nie4 +0x4bf6:man2 +0x4bf8:ci4 +0x4bfa:kuo4 +0x4bfc:di2 +0x4bfd:fu3 +0x4bfe:tiao2 +0x4bff:zu2 +0x4c00:wo3 +0x4c01:fei4 +0x4c02:cai4 +0x4c03:peng2 +0x4c04:shi4 +0x4c06:rou2 +0x4c07:qi2 +0x4c08:cha3 +0x4c09:pan2 +0x4c0a:bo2 +0x4c0b:man2 +0x4c0c:zong3 +0x4c0d:ci4 +0x4c0e:gui4 +0x4c0f:ji4 +0x4c10:lan2 +0x4c12:meng2 +0x4c13:mian2 +0x4c14:pan2 +0x4c15:lu2 +0x4c16:cuan2 +0x4c18:liu2 +0x4c19:yi3 +0x4c1a:wen2 +0x4c1b:li4 +0x4c1c:li4 +0x4c1d:zeng4 +0x4c1e:zhu3 +0x4c1f:hun2 +0x4c20:shen2 +0x4c21:chi4 +0x4c22:xing4 +0x4c23:wang3 +0x4c25:huo4 +0x4c26:pi3 +0x4c28:mei4 +0x4c29:che3 +0x4c2a:mei4 +0x4c2b:chao2 +0x4c2c:ju2 +0x4c2d:nou4 +0x4c2f:ni3 +0x4c30:ru2 +0x4c31:ling2 +0x4c32:ya4 +0x4c34:qi4 +0x4c37:bang4 +0x4c39:ze2 +0x4c3a:jie4 +0x4c3b:yu2 +0x4c3c:xin2 +0x4c3d:bei4 +0x4c3e:ba4 +0x4c3f:tuo2 +0x4c41:qiao2 +0x4c42:you3 +0x4c43:di3 +0x4c44:jie4 +0x4c45:mo4 +0x4c46:sheng2 +0x4c47:shan4 +0x4c48:qi2 +0x4c49:shan4 +0x4c4a:mi3 +0x4c4b:dan3 +0x4c4c:yi2 +0x4c4d:geng4 +0x4c4e:geng4 +0x4c4f:tou3 +0x4c51:xue2 +0x4c52:yi4 +0x4c53:ting2 +0x4c54:tiao2 +0x4c55:mou2 +0x4c56:liu2 +0x4c58:li2 +0x4c5a:lu4 +0x4c5b:xu4 +0x4c5c:cuo4 +0x4c5d:ba4 +0x4c5e:liu2 +0x4c5f:ju4 +0x4c60:zhan4 +0x4c61:ju2 +0x4c63:zu2 +0x4c64:xian4 +0x4c65:zhi2 +0x4c68:zhi4 +0x4c6b:la4 +0x4c6d:geng4 +0x4c6e:e2 +0x4c6f:mu2 +0x4c70:zhong4 +0x4c71:di4 +0x4c72:yan2 +0x4c74:geng4 +0x4c76:lang2 +0x4c77:yu2 +0x4c79:na4 +0x4c7a:hai2 +0x4c7b:hua2 +0x4c7c:zhan3 +0x4c7e:lou2 +0x4c7f:chan4 +0x4c80:die2 +0x4c81:wei4 +0x4c82:xuan2 +0x4c83:zao3 +0x4c84:min2 +0x4c8a:tuo3 +0x4c8b:cen2 +0x4c8c:kuan3 +0x4c8d:teng2 +0x4c8e:nei3 +0x4c8f:lao2 +0x4c90:lu3 +0x4c91:yi2 +0x4c92:xie4 +0x4c93:yan3 +0x4c94:qing2 +0x4c95:pu3 +0x4c96:chou2 +0x4c97:xian2 +0x4c98:guan3 +0x4c99:jie2 +0x4c9a:lai4 +0x4c9b:meng2 +0x4c9c:ye4 +0x4c9e:li4 +0x4c9f:yin4 +0x4ca2:teng2 +0x4ca3:yu2 +0x4ca6:cha2 +0x4ca7:du4 +0x4ca8:hong2 +0x4caa:xi4 +0x4cac:qi2 +0x4cae:yuan2 +0x4caf:ji2 +0x4cb0:yun4 +0x4cb1:fang3 +0x4cb3:hang2 +0x4cb4:zhen4 +0x4cb5:hu4 +0x4cb8:jie4 +0x4cb9:pei2 +0x4cba:gan4 +0x4cbb:xuan2 +0x4cbd:dao3 +0x4cbe:qiao3 +0x4cbf:ci2 +0x4cc0:die2 +0x4cc1:ba2 +0x4cc2:tiao2 +0x4cc3:wan3 +0x4cc4:ci2 +0x4cc5:zhi3 +0x4cc6:bai2 +0x4cc7:wu3 +0x4cc8:bao3 +0x4cc9:dan4 +0x4cca:ba2 +0x4ccb:tong2 +0x4cce:jiu4 +0x4ccf:gui4 +0x4cd0:ci4 +0x4cd1:you3 +0x4cd2:yuan2 +0x4cd3:lao3 +0x4cd4:jiu4 +0x4cd5:fou2 +0x4cd6:nei4 +0x4cd7:e2 +0x4cd8:e2 +0x4cd9:xing3 +0x4cda:he2 +0x4cdb:yan4 +0x4cdc:tu2 +0x4cdd:bu4 +0x4cde:beng3 +0x4cdf:kou4 +0x4ce0:chui2 +0x4ce2:qi2 +0x4ce3:yuan2 +0x4ce7:hou2 +0x4ce8:huang2 +0x4cea:juan4 +0x4ceb:kui2 +0x4cec:e4 +0x4ced:ji2 +0x4cee:mo4 +0x4cef:chong2 +0x4cf0:bao3 +0x4cf1:wu4 +0x4cf2:zhen4 +0x4cf3:xu4 +0x4cf4:da2 +0x4cf5:chi4 +0x4cf7:cong2 +0x4cf8:ma2 +0x4cf9:kou4 +0x4cfa:yan4 +0x4cfb:can2 +0x4cfd:he4 +0x4cff:lan2 +0x4d00:tong2 +0x4d01:yu4 +0x4d02:hang4 +0x4d03:nao2 +0x4d04:li4 +0x4d05:fen2 +0x4d06:pu2 +0x4d07:ling2 +0x4d08:ao3 +0x4d09:xuan2 +0x4d0a:yi2 +0x4d0b:xuan2 +0x4d0c:meng2 +0x4d0e:lei3 +0x4d0f:yan4 +0x4d10:bao3 +0x4d11:die2 +0x4d12:ling2 +0x4d13:shi1 +0x4d14:jiao1 +0x4d15:lie4 +0x4d16:jing1 +0x4d17:ju2 +0x4d18:ti1 +0x4d19:pi4 +0x4d1a:gang3 +0x4d1b:jiao3 +0x4d1c:huai2 +0x4d1d:bu4 +0x4d1e:di2 +0x4d1f:huan2 +0x4d20:yao3 +0x4d21:li4 +0x4d22:mi2 +0x4d26:ren2 +0x4d29:piao2 +0x4d2a:lu4 +0x4d2b:ling2 +0x4d2c:yi4 +0x4d2d:cai2 +0x4d2e:shan4 +0x4d30:shu2 +0x4d31:tuo2 +0x4d32:mo4 +0x4d33:he4 +0x4d34:tie4 +0x4d35:bing3 +0x4d36:peng2 +0x4d37:hun2 +0x4d39:guo3 +0x4d3a:bu4 +0x4d3b:li2 +0x4d3c:chan3 +0x4d3d:bai4 +0x4d3e:cuo2 +0x4d3f:meng2 +0x4d40:suo3 +0x4d41:qiang4 +0x4d42:zhi2 +0x4d43:kuang4 +0x4d44:bi2 +0x4d45:ao2 +0x4d46:meng2 +0x4d47:xian4 +0x4d49:tou2 +0x4d4b:wei3 +0x4d4f:lao3 +0x4d50:chan3 +0x4d51:ni4 +0x4d52:ni4 +0x4d53:li2 +0x4d54:dong3 +0x4d55:ju4 +0x4d56:jian4 +0x4d57:fu2 +0x4d58:sha4 +0x4d59:zha3 +0x4d5a:tao3 +0x4d5b:jian4 +0x4d5c:nong3 +0x4d5d:ya4 +0x4d5e:jing4 +0x4d5f:gan3 +0x4d60:di2 +0x4d61:jian3 +0x4d62:mei4 +0x4d63:da2 +0x4d64:jian3 +0x4d65:she4 +0x4d66:xie4 +0x4d67:zai4 +0x4d68:mang2 +0x4d69:li2 +0x4d6a:gun4 +0x4d6b:yu4 +0x4d6c:ta4 +0x4d6d:zhe4 +0x4d6e:yang4 +0x4d6f:tuan3 +0x4d71:he4 +0x4d72:diao4 +0x4d73:wei4 +0x4d74:yun4 +0x4d75:zha2 +0x4d76:qu2 +0x4d7a:ting3 +0x4d7b:gu3 +0x4d7d:ca4 +0x4d7e:fu2 +0x4d7f:tie4 +0x4d80:ta4 +0x4d81:ta4 +0x4d82:zhuo2 +0x4d83:han2 +0x4d84:ping2 +0x4d85:he2 +0x4d87:zhou4 +0x4d88:bo2 +0x4d89:liu2 +0x4d8a:nv4 +0x4d8c:pao4 +0x4d8d:di4 +0x4d8e:sha4 +0x4d8f:ti3 +0x4d90:kuai4 +0x4d91:ti4 +0x4d92:qi2 +0x4d93:ji4 +0x4d94:chi2 +0x4d95:pa2 +0x4d96:jin4 +0x4d97:ke4 +0x4d98:li4 +0x4d99:ju4 +0x4d9a:qu3 +0x4d9b:la4 +0x4d9c:gu4 +0x4d9d:qia4 +0x4d9e:qi2 +0x4d9f:xian4 +0x4da0:jian3 +0x4da1:shi2 +0x4da2:xian2 +0x4da3:ai2 +0x4da4:hua2 +0x4da5:ju3 +0x4da6:ze2 +0x4da7:yao3 +0x4da9:ji4 +0x4daa:cha2 +0x4dab:kan3 +0x4dae:yan2 +0x4db1:tong2 +0x4db2:nan2 +0x4db3:yue4 +0x4db5:chi2 +0x4e00:yi1 +0x4e01:ding1 +0x4e02:kao3 +0x4e03:qi1 +0x4e04:shang4 +0x4e05:xia4 +0x4e07:wan4 +0x4e08:zhang4 +0x4e09:san1 +0x4e0a:shang4 +0x4e0b:xia4 +0x4e0c:ji1 +0x4e0d:bu4 +0x4e0e:yu3 +0x4e0f:mian3 +0x4e10:gai4 +0x4e11:chou3 +0x4e12:chou3 +0x4e13:zhuan1 +0x4e14:qie3 +0x4e15:pi1 +0x4e16:shi4 +0x4e17:shi4 +0x4e18:qiu1 +0x4e19:bing3 +0x4e1a:ye4 +0x4e1b:cong2 +0x4e1c:dong1 +0x4e1d:si1 +0x4e1e:cheng2 +0x4e1f:diu1 +0x4e20:qiu1 +0x4e21:liang3 +0x4e22:diu1 +0x4e23:you3 +0x4e24:liang3 +0x4e25:yan2 +0x4e26:bing4 +0x4e27:sang1 +0x4e28:gun3 +0x4e29:jiu1 +0x4e2a:ge4 +0x4e2b:ya1 +0x4e2c:qiang2 +0x4e2d:zhong1 +0x4e2e:ji3 +0x4e2f:jie4 +0x4e30:feng1 +0x4e31:guan4 +0x4e32:chuan4 +0x4e33:chan3 +0x4e34:lin2 +0x4e35:zhuo3 +0x4e36:zhu3 +0x4e38:wan2 +0x4e39:dan1 +0x4e3a:wei4 +0x4e3b:zhu3 +0x4e3c:jing3 +0x4e3d:li4 +0x4e3e:ju3 +0x4e3f:pie3 +0x4e40:fu2 +0x4e41:yi2 +0x4e42:yi4 +0x4e43:nai3 +0x4e45:jiu3 +0x4e46:jiu3 +0x4e47:zhe2 +0x4e48:yao1 +0x4e49:yi4 +0x4e4b:zhi1 +0x4e4c:wu1 +0x4e4d:zha4 +0x4e4e:hu1 +0x4e4f:fa2 +0x4e50:le4 +0x4e51:zhong4 +0x4e52:ping1 +0x4e53:pang1 +0x4e54:qiao2 +0x4e55:hu3 +0x4e56:guai1 +0x4e57:cheng2 +0x4e58:cheng2 +0x4e59:yi3 +0x4e5a:yin3 +0x4e5c:mie1 +0x4e5d:jiu3 +0x4e5e:qi3 +0x4e5f:ye3 +0x4e60:xi2 +0x4e61:xiang1 +0x4e62:gai4 +0x4e63:jiu3 +0x4e66:shu1 +0x4e68:shi3 +0x4e69:ji1 +0x4e6a:nang2 +0x4e6b:jia1 +0x4e6d:shi2 +0x4e70:mai3 +0x4e71:luan4 +0x4e73:ru3 +0x4e74:xue2 +0x4e75:yan3 +0x4e76:fu3 +0x4e77:sha1 +0x4e78:na3 +0x4e79:gan1 +0x4e7e:gan1 +0x4e7f:chi4 +0x4e80:gui1 +0x4e81:gan1 +0x4e82:luan4 +0x4e83:lin2 +0x4e84:yi4 +0x4e85:jue2 +0x4e86:le5 +0x4e88:yu2 +0x4e89:zheng1 +0x4e8a:shi4 +0x4e8b:shi4 +0x4e8c:er4 +0x4e8d:chu4 +0x4e8e:yu2 +0x4e8f:yu2 +0x4e90:yu2 +0x4e91:yun2 +0x4e92:hu4 +0x4e93:qi2 +0x4e94:wu3 +0x4e95:jing3 +0x4e96:si4 +0x4e97:sui4 +0x4e98:gen4 +0x4e99:gen4 +0x4e9a:ya4 +0x4e9b:xie1 +0x4e9c:ya4 +0x4e9d:qi2 +0x4e9e:ya4 +0x4e9f:ji2 +0x4ea0:tou2 +0x4ea1:wang2 +0x4ea2:kang4 +0x4ea3:ta4 +0x4ea4:jiao1 +0x4ea5:hai4 +0x4ea6:yi4 +0x4ea7:chan3 +0x4ea8:heng1 +0x4ea9:mu3 +0x4eab:xiang3 +0x4eac:jing1 +0x4ead:ting2 +0x4eae:liang4 +0x4eaf:xiang3 +0x4eb0:jing1 +0x4eb1:ye4 +0x4eb2:qin1 +0x4eb3:bo2 +0x4eb4:you4 +0x4eb5:xie4 +0x4eb6:dan3 +0x4eb7:lian2 +0x4eb8:duo3 +0x4eb9:wei3 +0x4eba:ren2 +0x4ebb:ren2 +0x4ebc:ji2 +0x4ebe:wang2 +0x4ebf:yi4 +0x4ec0:shi2 +0x4ec1:ren2 +0x4ec2:le4 +0x4ec3:ding1 +0x4ec4:ze4 +0x4ec5:jin3 +0x4ec6:pu1 +0x4ec7:chou2 +0x4ec8:ba1 +0x4ec9:zhang3 +0x4eca:jin1 +0x4ecb:jie4 +0x4ecc:bing1 +0x4ecd:reng2 +0x4ece:cong2 +0x4ecf:fo2 +0x4ed0:san3 +0x4ed1:lun2 +0x4ed3:cang1 +0x4ed4:zi3 +0x4ed5:shi4 +0x4ed6:ta1 +0x4ed7:zhang4 +0x4ed8:fu4 +0x4ed9:xian1 +0x4eda:xian1 +0x4edb:tuo1 +0x4edc:hong2 +0x4edd:tong2 +0x4ede:ren4 +0x4edf:qian1 +0x4ee0:gan2 +0x4ee1:yi4 +0x4ee2:di2 +0x4ee3:dai4 +0x4ee4:ling4 +0x4ee5:yi3 +0x4ee6:chao4 +0x4ee7:chang2 +0x4ee8:sa1 +0x4eea:yi2 +0x4eeb:mu4 +0x4eec:men5 +0x4eed:ren4 +0x4eee:jia3 +0x4eef:chao4 +0x4ef0:yang3 +0x4ef1:qian2 +0x4ef2:zhong4 +0x4ef3:pi3 +0x4ef4:wan4 +0x4ef5:wu3 +0x4ef6:jian4 +0x4ef7:jia4 +0x4ef8:yao3 +0x4ef9:feng1 +0x4efa:cang1 +0x4efb:ren4 +0x4efc:wang2 +0x4efd:fen4 +0x4efe:di1 +0x4eff:fang3 +0x4f00:zhong1 +0x4f01:qi3 +0x4f02:pei4 +0x4f03:yu2 +0x4f04:diao4 +0x4f05:dun4 +0x4f06:wen4 +0x4f07:yi4 +0x4f08:xin3 +0x4f09:kang4 +0x4f0a:yi1 +0x4f0b:ji2 +0x4f0c:ai4 +0x4f0d:wu3 +0x4f0e:ji4 +0x4f0f:fu2 +0x4f10:fa2 +0x4f11:xiu1 +0x4f12:jin4 +0x4f13:bei1 +0x4f14:dan3 +0x4f15:fu1 +0x4f16:tang3 +0x4f17:zhong4 +0x4f18:you1 +0x4f19:huo3 +0x4f1a:hui4 +0x4f1b:yu3 +0x4f1c:cui4 +0x4f1d:chuan2 +0x4f1e:san3 +0x4f1f:wei3 +0x4f20:chuan2 +0x4f21:che1 +0x4f22:ya2 +0x4f23:xian4 +0x4f24:shang1 +0x4f25:chang1 +0x4f26:lun2 +0x4f27:cang1 +0x4f28:xun4 +0x4f29:xin4 +0x4f2a:wei3 +0x4f2b:zhu4 +0x4f2d:xuan2 +0x4f2e:nu2 +0x4f2f:bo2 +0x4f30:gu1 +0x4f31:ni3 +0x4f32:ni3 +0x4f33:xie4 +0x4f34:ban4 +0x4f35:xu4 +0x4f36:ling2 +0x4f37:zhou4 +0x4f38:shen1 +0x4f39:qu1 +0x4f3a:si4 +0x4f3b:beng1 +0x4f3c:si4 +0x4f3d:qie2 +0x4f3e:pi1 +0x4f3f:yi4 +0x4f40:si4 +0x4f41:ai3 +0x4f42:zheng1 +0x4f43:dian4 +0x4f44:han2 +0x4f45:mai4 +0x4f46:dan4 +0x4f47:zhu4 +0x4f48:bu4 +0x4f49:qu1 +0x4f4a:bi3 +0x4f4b:shao4 +0x4f4c:ci3 +0x4f4d:wei4 +0x4f4e:di1 +0x4f4f:zhu4 +0x4f50:zuo3 +0x4f51:you4 +0x4f52:yang1 +0x4f53:ti3 +0x4f54:zhan4 +0x4f55:he2 +0x4f56:bi4 +0x4f57:tuo2 +0x4f58:she2 +0x4f59:yu2 +0x4f5a:yi4 +0x4f5b:fo2 +0x4f5c:zuo4 +0x4f5d:kou4 +0x4f5e:ning4 +0x4f5f:tong2 +0x4f60:ni3 +0x4f61:xuan1 +0x4f62:qu2 +0x4f63:yong4 +0x4f64:wa3 +0x4f65:qian1 +0x4f67:ka3 +0x4f69:pei4 +0x4f6a:hui2 +0x4f6b:he4 +0x4f6c:lao3 +0x4f6d:xiang2 +0x4f6e:ge2 +0x4f6f:yang2 +0x4f70:bai3 +0x4f71:fa3 +0x4f72:ming2 +0x4f73:jia1 +0x4f74:er4 +0x4f75:bing4 +0x4f76:ji2 +0x4f77:hen3 +0x4f78:huo2 +0x4f79:gui3 +0x4f7a:quan2 +0x4f7b:tiao1 +0x4f7c:jiao3 +0x4f7d:ci4 +0x4f7e:yi4 +0x4f7f:shi3 +0x4f80:xing2 +0x4f81:shen1 +0x4f82:tuo1 +0x4f83:kan3 +0x4f84:zhi2 +0x4f85:gai1 +0x4f86:lai2 +0x4f87:yi2 +0x4f88:chi3 +0x4f89:kua1 +0x4f8a:guang1 +0x4f8b:li4 +0x4f8c:yin1 +0x4f8d:shi4 +0x4f8e:mi3 +0x4f8f:zhu1 +0x4f90:xu4 +0x4f91:you4 +0x4f92:an1 +0x4f93:lu4 +0x4f94:mou2 +0x4f95:er2 +0x4f96:lun2 +0x4f97:tong1 +0x4f98:cha4 +0x4f99:chi4 +0x4f9a:xun4 +0x4f9b:gong1 +0x4f9c:zhou1 +0x4f9d:yi1 +0x4f9e:ru3 +0x4f9f:jian4 +0x4fa0:xia2 +0x4fa1:jia4 +0x4fa2:zai4 +0x4fa3:lv3 +0x4fa5:jiao3 +0x4fa6:zhen1 +0x4fa7:ce4 +0x4fa8:qiao2 +0x4fa9:kuai4 +0x4faa:chai2 +0x4fab:ning4 +0x4fac:nong2 +0x4fad:jin3 +0x4fae:wu3 +0x4faf:hou2 +0x4fb0:jiong3 +0x4fb1:cheng3 +0x4fb2:zhen4 +0x4fb3:zuo4 +0x4fb4:chou3 +0x4fb5:qin1 +0x4fb6:lv3 +0x4fb7:ju2 +0x4fb8:shu4 +0x4fb9:ting3 +0x4fba:shen4 +0x4fbb:tuo1 +0x4fbc:bo2 +0x4fbd:nan2 +0x4fbe:hao1 +0x4fbf:bian4 +0x4fc0:tui3 +0x4fc1:yu3 +0x4fc2:xi4 +0x4fc3:cu4 +0x4fc4:e2 +0x4fc5:qiu2 +0x4fc6:xu2 +0x4fc7:kuang3 +0x4fc8:ku4 +0x4fc9:wu4 +0x4fca:jun4 +0x4fcb:yi4 +0x4fcc:fu3 +0x4fcd:lang2 +0x4fce:zu3 +0x4fcf:qiao4 +0x4fd0:li4 +0x4fd1:yong3 +0x4fd2:hun4 +0x4fd3:jing4 +0x4fd4:xian4 +0x4fd5:san4 +0x4fd6:pai3 +0x4fd7:su2 +0x4fd8:fu2 +0x4fd9:xi1 +0x4fda:li3 +0x4fdb:fu3 +0x4fdc:ping1 +0x4fdd:bao3 +0x4fde:yu2 +0x4fdf:si4 +0x4fe0:xia2 +0x4fe1:xin4 +0x4fe2:xiu1 +0x4fe3:yu3 +0x4fe4:ti4 +0x4fe5:che1 +0x4fe6:chou2 +0x4fe8:yan3 +0x4fe9:lia3 +0x4fea:li4 +0x4feb:lai2 +0x4fed:jian3 +0x4fee:xiu1 +0x4fef:fu3 +0x4ff0:he4 +0x4ff1:ju4 +0x4ff2:xiao4 +0x4ff3:pai2 +0x4ff4:jian4 +0x4ff5:biao4 +0x4ff6:chu4 +0x4ff7:fei4 +0x4ff8:feng4 +0x4ff9:ya4 +0x4ffa:an3 +0x4ffb:bei4 +0x4ffc:yu4 +0x4ffd:xin1 +0x4ffe:bi3 +0x4fff:jian4 +0x5000:chang1 +0x5001:chi2 +0x5002:bing4 +0x5003:zan2 +0x5004:yao2 +0x5005:cui4 +0x5006:lia3 +0x5007:wan3 +0x5008:lai2 +0x5009:cang1 +0x500a:zong4 +0x500b:ge4 +0x500c:guan1 +0x500d:bei4 +0x500e:tian1 +0x500f:shu1 +0x5010:shu1 +0x5011:men5 +0x5012:dao3 +0x5013:tan2 +0x5014:jue2 +0x5015:chui2 +0x5016:xing4 +0x5017:peng2 +0x5018:tang3 +0x5019:hou4 +0x501a:yi3 +0x501b:qi1 +0x501c:ti4 +0x501d:gan4 +0x501e:jing4 +0x501f:jie4 +0x5020:sui1 +0x5021:chang4 +0x5022:jie2 +0x5023:fang3 +0x5024:zhi2 +0x5025:kong1 +0x5026:juan4 +0x5027:zong1 +0x5028:ju4 +0x5029:qian4 +0x502a:ni2 +0x502b:lun2 +0x502c:zhuo1 +0x502d:wei1 +0x502e:luo3 +0x502f:song1 +0x5030:leng2 +0x5031:hun4 +0x5032:dong1 +0x5033:zi4 +0x5034:ben4 +0x5035:wu3 +0x5036:ju4 +0x5037:nai4 +0x5038:cai3 +0x5039:jian3 +0x503a:zhai4 +0x503b:ye1 +0x503c:zhi2 +0x503d:sha4 +0x503e:qing1 +0x5040:ying1 +0x5041:cheng1 +0x5042:jian1 +0x5043:yan3 +0x5044:nuan4 +0x5045:zhong4 +0x5046:chun3 +0x5047:jia3 +0x5048:jie2 +0x5049:wei3 +0x504a:yu3 +0x504b:bing3 +0x504c:ruo4 +0x504d:ti2 +0x504e:wei1 +0x504f:pian1 +0x5050:yan4 +0x5051:feng1 +0x5052:tang3 +0x5053:wo4 +0x5054:e4 +0x5055:xie2 +0x5056:che3 +0x5057:sheng3 +0x5058:kan3 +0x5059:di4 +0x505a:zuo4 +0x505b:cha1 +0x505c:ting2 +0x505d:bei4 +0x505e:ye4 +0x505f:huang2 +0x5060:yao3 +0x5061:zhan4 +0x5062:chou3 +0x5063:yan1 +0x5064:you3 +0x5065:jian4 +0x5066:xu1 +0x5067:zha1 +0x5068:ci1 +0x5069:fu4 +0x506a:bi1 +0x506b:zhi4 +0x506c:zong3 +0x506d:mian3 +0x506e:ji2 +0x506f:yi3 +0x5070:xie4 +0x5071:xun2 +0x5072:si1 +0x5073:duan1 +0x5074:ce4 +0x5075:zhen1 +0x5076:ou3 +0x5077:tou1 +0x5078:tou1 +0x5079:bei4 +0x507a:za2 +0x507b:lv3 +0x507c:jie2 +0x507d:wei3 +0x507e:fen4 +0x507f:chang2 +0x5080:gui1 +0x5081:sou3 +0x5082:zhi4 +0x5083:su4 +0x5084:xia1 +0x5085:fu4 +0x5086:yuan4 +0x5087:rong3 +0x5088:li4 +0x5089:ru4 +0x508a:yun3 +0x508b:gou4 +0x508c:ma4 +0x508d:bang4 +0x508e:dian1 +0x508f:tang2 +0x5090:hao4 +0x5091:jie2 +0x5092:xi1 +0x5093:shan4 +0x5094:qian4 +0x5095:jue2 +0x5096:cang1 +0x5097:chu4 +0x5098:san3 +0x5099:bei4 +0x509a:xiao4 +0x509b:yong3 +0x509c:yao2 +0x509d:tan4 +0x509e:suo1 +0x509f:yang3 +0x50a0:fa1 +0x50a1:bing4 +0x50a2:jia1 +0x50a3:dai3 +0x50a4:zai4 +0x50a5:tang3 +0x50a7:bin4 +0x50a8:chu3 +0x50a9:nuo2 +0x50aa:can1 +0x50ab:lei3 +0x50ac:cui1 +0x50ad:yong1 +0x50ae:zao1 +0x50af:zong3 +0x50b0:peng2 +0x50b1:song3 +0x50b2:ao4 +0x50b3:chuan2 +0x50b4:yu3 +0x50b5:zhai4 +0x50b6:cou4 +0x50b7:shang1 +0x50b8:qiang3 +0x50b9:jing4 +0x50ba:chi4 +0x50bb:sha3 +0x50bc:han4 +0x50bd:zhang1 +0x50be:qing1 +0x50bf:yan4 +0x50c0:di4 +0x50c1:xi1 +0x50c2:lv3 +0x50c3:bei4 +0x50c4:piao4 +0x50c5:jin3 +0x50c6:lian2 +0x50c7:lu4 +0x50c8:man4 +0x50c9:qian1 +0x50ca:xian1 +0x50cb:tan4 +0x50cc:ying2 +0x50cd:dong4 +0x50ce:zhuan4 +0x50cf:xiang4 +0x50d0:shan4 +0x50d1:qiao2 +0x50d2:jiong3 +0x50d3:tui3 +0x50d4:zun3 +0x50d5:pu2 +0x50d6:xi1 +0x50d7:lao2 +0x50d8:chang3 +0x50d9:guang1 +0x50da:liao2 +0x50db:qi1 +0x50dc:deng4 +0x50dd:chan2 +0x50de:wei3 +0x50df:ji1 +0x50e0:fan1 +0x50e1:hui4 +0x50e2:chuan3 +0x50e3:jian4 +0x50e4:dan4 +0x50e5:jiao3 +0x50e6:jiu4 +0x50e7:seng1 +0x50e8:fen4 +0x50e9:xian4 +0x50ea:jue2 +0x50eb:e4 +0x50ec:jiao1 +0x50ed:jian4 +0x50ee:tong2 +0x50ef:lin3 +0x50f0:bo2 +0x50f1:gu4 +0x50f3:su4 +0x50f4:xian4 +0x50f5:jiang1 +0x50f6:min3 +0x50f7:ye4 +0x50f8:jin4 +0x50f9:jia4 +0x50fa:qiao4 +0x50fb:pi4 +0x50fc:feng1 +0x50fd:zhou4 +0x50fe:ai4 +0x50ff:sai4 +0x5100:yi2 +0x5101:jun4 +0x5102:nong2 +0x5103:chan2 +0x5104:yi4 +0x5105:dang1 +0x5106:jing3 +0x5107:xuan1 +0x5108:kuai4 +0x5109:jian3 +0x510a:chu4 +0x510b:dan1 +0x510c:jiao3 +0x510d:sha3 +0x510e:zai4 +0x5110:bin4 +0x5111:an4 +0x5112:ru2 +0x5113:tai2 +0x5114:chou2 +0x5115:chai2 +0x5116:lan2 +0x5117:ni3 +0x5118:jin3 +0x5119:qian4 +0x511a:meng2 +0x511b:wu3 +0x511c:ning2 +0x511d:qiong2 +0x511e:ni3 +0x511f:chang2 +0x5120:lie4 +0x5121:lei3 +0x5122:lv3 +0x5123:kuang4 +0x5124:bao4 +0x5125:du2 +0x5126:biao1 +0x5127:zan3 +0x5128:zhi2 +0x5129:si4 +0x512a:you1 +0x512b:hao2 +0x512c:chen4 +0x512d:chen4 +0x512e:li4 +0x512f:teng2 +0x5130:wei3 +0x5131:long3 +0x5132:chu3 +0x5133:chan4 +0x5134:rang2 +0x5135:shu1 +0x5136:hui4 +0x5137:li4 +0x5138:luo2 +0x5139:zan3 +0x513a:nuo2 +0x513b:tang3 +0x513c:yan3 +0x513d:lei3 +0x513e:nang4 +0x513f:er2 +0x5140:wu4 +0x5141:yun3 +0x5142:zan1 +0x5143:yuan2 +0x5144:xiong1 +0x5145:chong1 +0x5146:zhao4 +0x5147:xiong1 +0x5148:xian1 +0x5149:guang1 +0x514a:dui4 +0x514b:ke4 +0x514c:dui4 +0x514d:mian3 +0x514e:tu4 +0x514f:chang2 +0x5150:er2 +0x5151:dui4 +0x5152:er2 +0x5153:xin1 +0x5154:tu4 +0x5155:si4 +0x5156:yan3 +0x5157:yan3 +0x5158:shi3 +0x515a:dang3 +0x515b:qian1 +0x515c:dou1 +0x515d:fen1 +0x515e:mao2 +0x515f:shen1 +0x5160:dou1 +0x5162:jing1 +0x5163:li3 +0x5164:huang2 +0x5165:ru4 +0x5166:wang2 +0x5167:nei4 +0x5168:quan2 +0x5169:liang3 +0x516a:yu2 +0x516b:ba1 +0x516c:gong1 +0x516d:liu4 +0x516e:xi1 +0x5170:lan2 +0x5171:gong4 +0x5172:tian1 +0x5173:guan1 +0x5174:xing1 +0x5175:bing1 +0x5176:qi2 +0x5177:ju4 +0x5178:dian3 +0x5179:zi1 +0x517b:yang3 +0x517c:jian1 +0x517d:shou4 +0x517e:ji4 +0x517f:yi4 +0x5180:ji4 +0x5181:chan3 +0x5182:jiong1 +0x5184:ran3 +0x5185:nei4 +0x5187:mao3 +0x5188:gang1 +0x5189:ran3 +0x518a:ce4 +0x518b:jiong1 +0x518c:ce4 +0x518d:zai4 +0x518e:gua3 +0x518f:jiong3 +0x5190:mao4 +0x5191:zhou4 +0x5192:mao4 +0x5193:gou4 +0x5194:xu3 +0x5195:mian3 +0x5196:mi4 +0x5197:rong3 +0x5198:yin2 +0x5199:xie3 +0x519a:kan3 +0x519b:jun1 +0x519c:nong2 +0x519d:yi2 +0x519e:mi2 +0x519f:shi4 +0x51a0:guan1 +0x51a1:meng2 +0x51a2:zhong3 +0x51a3:ju4 +0x51a4:yuan1 +0x51a5:ming2 +0x51a6:kou4 +0x51a8:fu4 +0x51a9:xie3 +0x51aa:mi4 +0x51ab:bing1 +0x51ac:dong1 +0x51ad:tai2 +0x51ae:gang1 +0x51af:feng2 +0x51b0:bing1 +0x51b1:hu4 +0x51b2:chong1 +0x51b3:jue2 +0x51b4:hu4 +0x51b5:kuang4 +0x51b6:ye3 +0x51b7:leng3 +0x51b8:pan4 +0x51b9:fu2 +0x51ba:min3 +0x51bb:dong4 +0x51bc:xian3 +0x51bd:lie4 +0x51be:xia2 +0x51bf:jian1 +0x51c0:jing4 +0x51c1:shu4 +0x51c2:mei3 +0x51c3:tu2 +0x51c4:qi1 +0x51c5:gu4 +0x51c6:zhun3 +0x51c7:song1 +0x51c8:jing4 +0x51c9:liang2 +0x51ca:qing4 +0x51cb:diao1 +0x51cc:ling2 +0x51cd:dong4 +0x51ce:gan4 +0x51cf:jian3 +0x51d0:yin1 +0x51d1:cou4 +0x51d2:yi2 +0x51d3:li4 +0x51d4:cang1 +0x51d5:ming3 +0x51d7:cui2 +0x51d8:si1 +0x51d9:duo2 +0x51da:jin4 +0x51db:lin3 +0x51dc:lin3 +0x51dd:ning2 +0x51de:xi1 +0x51df:du2 +0x51e0:ji1 +0x51e1:fan2 +0x51e2:fan2 +0x51e3:fan2 +0x51e4:feng4 +0x51e5:ju1 +0x51e6:chu3 +0x51e8:feng1 +0x51eb:fu2 +0x51ec:feng1 +0x51ed:ping2 +0x51ee:feng1 +0x51ef:kai3 +0x51f0:huang2 +0x51f1:kai3 +0x51f2:gan1 +0x51f3:deng4 +0x51f4:ping2 +0x51f5:qu1 +0x51f6:xiong1 +0x51f7:kuai4 +0x51f8:tu1 +0x51f9:ao1 +0x51fa:chu1 +0x51fb:ji2 +0x51fc:dang4 +0x51fd:han2 +0x51fe:han2 +0x51ff:zao2 +0x5200:dao1 +0x5201:diao1 +0x5202:dao1 +0x5203:ren4 +0x5204:ren4 +0x5205:chuang1 +0x5206:fen1 +0x5207:qie1 +0x5208:yi4 +0x5209:ji1 +0x520a:kan1 +0x520b:qian4 +0x520c:cun3 +0x520d:chu2 +0x520e:wen3 +0x520f:ji1 +0x5210:dan3 +0x5211:xing2 +0x5212:hua2 +0x5213:wan2 +0x5214:jue2 +0x5215:li2 +0x5216:yue4 +0x5217:lie4 +0x5218:liu2 +0x5219:ze2 +0x521a:gang1 +0x521b:chuang4 +0x521c:fu2 +0x521d:chu1 +0x521e:qu4 +0x521f:ju1 +0x5220:shan1 +0x5221:min3 +0x5222:ling2 +0x5223:zhong1 +0x5224:pan4 +0x5225:bie2 +0x5226:jie2 +0x5227:jie2 +0x5228:bao4 +0x5229:li4 +0x522a:shan1 +0x522b:bie2 +0x522c:chan3 +0x522d:jing3 +0x522e:gua1 +0x522f:gen1 +0x5230:dao4 +0x5231:chuang4 +0x5232:kui1 +0x5233:ku1 +0x5234:duo4 +0x5235:er4 +0x5236:zhi4 +0x5237:shua1 +0x5238:quan4 +0x5239:cha4 +0x523a:ci4 +0x523b:ke4 +0x523c:jie2 +0x523d:gui4 +0x523e:ci4 +0x523f:gui4 +0x5240:kai3 +0x5241:duo4 +0x5242:ji4 +0x5243:ti4 +0x5244:jing3 +0x5245:lou2 +0x5246:gen1 +0x5247:ze2 +0x5248:yuan1 +0x5249:cuo4 +0x524a:xue1 +0x524b:ke4 +0x524c:la4 +0x524d:qian2 +0x524e:cha4 +0x524f:chuang4 +0x5250:gua3 +0x5251:jian4 +0x5252:cuo4 +0x5253:li2 +0x5254:ti1 +0x5255:fei4 +0x5256:pou1 +0x5257:chan3 +0x5258:qi2 +0x5259:chuang4 +0x525a:zi4 +0x525b:gang1 +0x525c:wan1 +0x525d:bo1 +0x525e:ji1 +0x525f:duo1 +0x5260:qing2 +0x5261:yan3 +0x5262:zhuo2 +0x5263:jian4 +0x5264:ji4 +0x5265:bo1 +0x5266:yan1 +0x5267:ju4 +0x5268:huo4 +0x5269:sheng4 +0x526a:jian3 +0x526b:duo2 +0x526c:duan1 +0x526d:wu1 +0x526e:gua3 +0x526f:fu4 +0x5270:sheng4 +0x5271:jian4 +0x5272:ge1 +0x5273:zha1 +0x5274:kai3 +0x5275:chuang4 +0x5276:juan1 +0x5277:chan3 +0x5278:tuan2 +0x5279:lu4 +0x527a:li2 +0x527b:fou2 +0x527c:shan1 +0x527d:piao4 +0x527e:kou1 +0x527f:jiao3 +0x5280:gua1 +0x5281:qiao1 +0x5282:jue2 +0x5283:hua4 +0x5284:zha2 +0x5285:zhuo4 +0x5286:lian2 +0x5287:ju4 +0x5288:pi1 +0x5289:liu2 +0x528a:gui4 +0x528b:jiao3 +0x528c:gui4 +0x528d:jian4 +0x528e:jian4 +0x528f:tang1 +0x5290:huo1 +0x5291:ji4 +0x5292:jian4 +0x5293:yi4 +0x5294:jian4 +0x5295:zhi2 +0x5296:chan2 +0x5297:cuan2 +0x5298:mo2 +0x5299:li2 +0x529a:zhu2 +0x529b:li4 +0x529c:ya1 +0x529d:quan4 +0x529e:ban4 +0x529f:gong1 +0x52a0:jia1 +0x52a1:wu4 +0x52a2:mai4 +0x52a3:lie4 +0x52a4:jin4 +0x52a5:keng1 +0x52a6:xie2 +0x52a7:zhi3 +0x52a8:dong4 +0x52a9:zhu4 +0x52aa:nu3 +0x52ab:jie2 +0x52ac:qu2 +0x52ad:shao4 +0x52ae:yi4 +0x52af:zhu1 +0x52b0:miao3 +0x52b1:li4 +0x52b2:jing4 +0x52b3:lao2 +0x52b4:lao2 +0x52b5:juan4 +0x52b6:kou3 +0x52b7:yang2 +0x52b8:wa1 +0x52b9:xiao4 +0x52ba:mou2 +0x52bb:kuang1 +0x52bc:jie2 +0x52bd:lie4 +0x52be:he2 +0x52bf:shi4 +0x52c0:ke4 +0x52c1:jin4 +0x52c2:hao2 +0x52c3:bo2 +0x52c4:min3 +0x52c5:chi4 +0x52c6:lang2 +0x52c7:yong3 +0x52c8:yong3 +0x52c9:mian3 +0x52ca:ke4 +0x52cb:xun1 +0x52cc:juan4 +0x52cd:qing2 +0x52ce:lu4 +0x52cf:pou3 +0x52d0:meng3 +0x52d1:lai4 +0x52d2:le4 +0x52d3:kai4 +0x52d4:mian3 +0x52d5:dong4 +0x52d6:xu4 +0x52d7:xu4 +0x52d8:kan1 +0x52d9:wu4 +0x52da:yi4 +0x52db:xun1 +0x52dc:weng3 +0x52dd:sheng4 +0x52de:lao2 +0x52df:mu4 +0x52e0:lu4 +0x52e1:piao4 +0x52e2:shi4 +0x52e3:ji1 +0x52e4:qin2 +0x52e5:qiang3 +0x52e6:jiao3 +0x52e7:quan4 +0x52e8:yang3 +0x52e9:yi4 +0x52ea:jue2 +0x52eb:fan2 +0x52ec:juan4 +0x52ed:tong2 +0x52ee:ju4 +0x52ef:dan1 +0x52f0:xie2 +0x52f1:mai4 +0x52f2:xun1 +0x52f3:xun1 +0x52f4:lv4 +0x52f5:li4 +0x52f6:che4 +0x52f7:rang2 +0x52f8:quan4 +0x52f9:bao1 +0x52fa:shao2 +0x52fb:yun2 +0x52fc:jiu1 +0x52fd:bao4 +0x52fe:gou1 +0x52ff:wu4 +0x5300:yun2 +0x5303:gai4 +0x5304:gai4 +0x5305:bao1 +0x5306:cong1 +0x5308:xiong1 +0x5309:peng1 +0x530a:ju2 +0x530b:tao2 +0x530c:ge2 +0x530d:pu2 +0x530e:an4 +0x530f:pao2 +0x5310:fu2 +0x5311:gong1 +0x5312:da2 +0x5313:jiu4 +0x5314:qiong1 +0x5315:bi3 +0x5316:hua4 +0x5317:bei3 +0x5318:nao3 +0x5319:chi2 +0x531a:fang1 +0x531b:jiu4 +0x531c:yi2 +0x531d:za1 +0x531e:jiang4 +0x531f:kang4 +0x5320:jiang4 +0x5321:kuang1 +0x5322:hu1 +0x5323:xia2 +0x5324:qu1 +0x5325:bian4 +0x5326:gui3 +0x5327:qie4 +0x5328:zang1 +0x5329:kuang1 +0x532a:fei3 +0x532b:hu1 +0x532c:tou2 +0x532d:gui3 +0x532e:gui4 +0x532f:hui4 +0x5330:dan1 +0x5331:gui4 +0x5332:lian2 +0x5333:lian2 +0x5334:suan3 +0x5335:du2 +0x5336:jiu4 +0x5337:qu2 +0x5338:xi3 +0x5339:pi3 +0x533a:qu1 +0x533b:yi4 +0x533c:qia4 +0x533d:yan3 +0x533e:bian3 +0x533f:ni4 +0x5340:qu1 +0x5341:shi2 +0x5342:xin4 +0x5343:qian1 +0x5344:nian4 +0x5345:sa4 +0x5346:zu2 +0x5347:sheng1 +0x5348:wu3 +0x5349:hui4 +0x534a:ban4 +0x534b:shi4 +0x534c:xi4 +0x534d:wan4 +0x534e:hua2 +0x534f:xie2 +0x5350:wan4 +0x5351:bei1 +0x5352:zu2 +0x5353:zhuo1 +0x5354:xie2 +0x5355:dan1 +0x5356:mai4 +0x5357:nan2 +0x5358:dan1 +0x5359:ji2 +0x535a:bo2 +0x535b:shuai4 +0x535c:bu3 +0x535d:kuang4 +0x535e:bian4 +0x535f:bu3 +0x5360:zhan1 +0x5361:qia3 +0x5362:lu2 +0x5363:you3 +0x5364:lu3 +0x5365:xi1 +0x5366:gua4 +0x5367:wo4 +0x5368:xie4 +0x5369:jie2 +0x536a:jie2 +0x536b:wei4 +0x536c:ang2 +0x536d:qiong2 +0x536e:zhi1 +0x536f:mao3 +0x5370:yin4 +0x5371:wei1 +0x5372:shao4 +0x5373:ji2 +0x5374:que4 +0x5375:luan3 +0x5376:shi4 +0x5377:juan4 +0x5378:xie4 +0x5379:xu4 +0x537a:jin3 +0x537b:que4 +0x537c:wu4 +0x537d:ji2 +0x537e:e4 +0x537f:qing1 +0x5380:xi1 +0x5382:chang3 +0x5383:zhan1 +0x5384:e4 +0x5385:ting1 +0x5386:li4 +0x5387:zhe2 +0x5388:han3 +0x5389:li4 +0x538a:ya3 +0x538b:ya1 +0x538c:yan4 +0x538d:she4 +0x538e:zhi3 +0x538f:zha3 +0x5390:pang2 +0x5392:he2 +0x5393:ya2 +0x5394:zhi4 +0x5395:ce4 +0x5396:pang2 +0x5397:ti2 +0x5398:li2 +0x5399:she4 +0x539a:hou4 +0x539b:ting1 +0x539c:zui1 +0x539d:cuo4 +0x539e:fei4 +0x539f:yuan2 +0x53a0:ce4 +0x53a1:yuan2 +0x53a2:xiang1 +0x53a3:yan3 +0x53a4:li4 +0x53a5:jue2 +0x53a6:sha4 +0x53a7:dian1 +0x53a8:chu2 +0x53a9:jiu4 +0x53aa:qin2 +0x53ab:ao2 +0x53ac:gui3 +0x53ad:yan4 +0x53ae:si1 +0x53af:li4 +0x53b0:chang3 +0x53b1:lan2 +0x53b2:li4 +0x53b3:yan2 +0x53b4:yan3 +0x53b5:yuan2 +0x53b6:si1 +0x53b7:gong1 +0x53b8:lin2 +0x53b9:qiu2 +0x53ba:qu4 +0x53bb:qu4 +0x53bd:lei3 +0x53be:du1 +0x53bf:xian4 +0x53c0:zhuan1 +0x53c1:san1 +0x53c2:can1 +0x53c3:can1 +0x53c4:can1 +0x53c5:can1 +0x53c6:ai4 +0x53c7:dai4 +0x53c8:you4 +0x53c9:cha1 +0x53ca:ji2 +0x53cb:you3 +0x53cc:shuang1 +0x53cd:fan3 +0x53ce:shou1 +0x53cf:guai4 +0x53d0:ba2 +0x53d1:fa1 +0x53d2:ruo4 +0x53d3:shi4 +0x53d4:shu1 +0x53d5:zhuo2 +0x53d6:qu3 +0x53d7:shou4 +0x53d8:bian4 +0x53d9:xu4 +0x53da:jia3 +0x53db:pan4 +0x53dc:sou3 +0x53dd:gao4 +0x53de:wei4 +0x53df:sou3 +0x53e0:die2 +0x53e1:rui4 +0x53e2:cong2 +0x53e3:kou3 +0x53e4:gu3 +0x53e5:ju4 +0x53e6:ling4 +0x53e7:gua3 +0x53e8:tao1 +0x53e9:kou4 +0x53ea:zhi3 +0x53eb:jiao4 +0x53ec:zhao4 +0x53ed:ba1 +0x53ee:ding1 +0x53ef:ke3 +0x53f0:tai2 +0x53f1:chi4 +0x53f2:shi3 +0x53f3:you4 +0x53f4:qiu2 +0x53f5:po3 +0x53f6:xie2 +0x53f7:hao4 +0x53f8:si1 +0x53f9:tan4 +0x53fa:chi3 +0x53fb:le4 +0x53fc:diao1 +0x53fd:ji1 +0x53ff:hong1 +0x5400:mie1 +0x5401:xu1 +0x5402:mang2 +0x5403:chi1 +0x5404:ge4 +0x5405:xuan1 +0x5406:yao1 +0x5407:zi3 +0x5408:he2 +0x5409:ji2 +0x540a:diao4 +0x540b:cun4 +0x540c:tong2 +0x540d:ming2 +0x540e:hou4 +0x540f:li4 +0x5410:tu3 +0x5411:xiang4 +0x5412:zha4 +0x5413:xia4 +0x5414:ye3 +0x5415:lv3 +0x5416:a1 +0x5417:ma5 +0x5418:ou3 +0x5419:xue1 +0x541a:yi1 +0x541b:jun1 +0x541c:chou3 +0x541d:lin4 +0x541e:tun1 +0x541f:yin2 +0x5420:fei4 +0x5421:bi3 +0x5422:qin4 +0x5423:qin4 +0x5424:jie4 +0x5425:bu4 +0x5426:fou3 +0x5427:ba5 +0x5428:dun1 +0x5429:fen1 +0x542a:e2 +0x542b:han2 +0x542c:ting1 +0x542d:hang2 +0x542e:shun3 +0x542f:qi3 +0x5430:hong2 +0x5431:zhi1 +0x5432:shen3 +0x5433:wu2 +0x5434:wu2 +0x5435:chao3 +0x5436:ne5 +0x5437:xue4 +0x5438:xi1 +0x5439:chui1 +0x543a:dou1 +0x543b:wen3 +0x543c:hou3 +0x543d:ou1 +0x543e:wu2 +0x543f:gao4 +0x5440:ya1 +0x5441:jun4 +0x5442:lv3 +0x5443:e4 +0x5444:ge2 +0x5445:mei2 +0x5446:dai1 +0x5447:qi3 +0x5448:cheng2 +0x5449:wu2 +0x544a:gao4 +0x544b:fu1 +0x544c:jiao4 +0x544d:hong1 +0x544e:chi3 +0x544f:sheng1 +0x5450:ne4 +0x5451:tun1 +0x5452:fu3 +0x5453:yi4 +0x5454:dai1 +0x5455:ou1 +0x5456:li4 +0x5457:bai4 +0x5458:yuan2 +0x5459:kuai1 +0x545b:qiang1 +0x545c:wu1 +0x545d:e4 +0x545e:shi1 +0x545f:quan3 +0x5460:pen1 +0x5461:wen3 +0x5462:ni2 +0x5464:ling2 +0x5465:ran3 +0x5466:you1 +0x5467:di3 +0x5468:zhou1 +0x5469:shi4 +0x546a:zhou4 +0x546b:tie1 +0x546c:xi4 +0x546d:yi4 +0x546e:qi4 +0x546f:ping2 +0x5470:zi3 +0x5471:gu1 +0x5472:zi1 +0x5473:wei4 +0x5474:xu1 +0x5475:he1 +0x5476:nao2 +0x5477:xia1 +0x5478:pei1 +0x5479:yi4 +0x547a:xiao1 +0x547b:shen1 +0x547c:hu1 +0x547d:ming4 +0x547e:da2 +0x547f:qu1 +0x5480:ju3 +0x5482:za1 +0x5483:tuo1 +0x5484:duo1 +0x5485:pou4 +0x5486:pao2 +0x5487:bi4 +0x5488:fu2 +0x5489:yang1 +0x548a:he2 +0x548b:zha4 +0x548c:he2 +0x548d:hai1 +0x548e:jiu4 +0x548f:yong3 +0x5490:fu4 +0x5491:que4 +0x5492:zhou4 +0x5493:wa3 +0x5494:ka3 +0x5495:gu1 +0x5496:ka1 +0x5497:zuo3 +0x5498:bu4 +0x5499:long2 +0x549a:dong1 +0x549b:ning2 +0x549d:si1 +0x549e:xian4 +0x549f:huo4 +0x54a0:qi4 +0x54a1:er4 +0x54a2:e4 +0x54a3:guang1 +0x54a4:zha4 +0x54a5:xi4 +0x54a6:yi2 +0x54a7:lie3 +0x54a8:zi1 +0x54a9:mie1 +0x54aa:mi1 +0x54ab:zhi3 +0x54ac:yao3 +0x54ad:ji1 +0x54ae:zhou4 +0x54af:ge1 +0x54b0:shuai4 +0x54b1:zan2 +0x54b2:xiao4 +0x54b3:ke2 +0x54b4:hui1 +0x54b5:kua1 +0x54b6:huai4 +0x54b7:tao2 +0x54b8:xian2 +0x54b9:e4 +0x54ba:xuan3 +0x54bb:xiu1 +0x54bc:wai1 +0x54bd:yan1 +0x54be:lao3 +0x54bf:yi1 +0x54c0:ai1 +0x54c1:pin3 +0x54c2:shen3 +0x54c3:tong2 +0x54c4:hong1 +0x54c5:xiong1 +0x54c6:duo1 +0x54c7:wa1 +0x54c8:ha1 +0x54c9:zai1 +0x54ca:yu4 +0x54cb:di4 +0x54cc:pai4 +0x54cd:xiang3 +0x54ce:ai1 +0x54cf:hen3 +0x54d0:kuang1 +0x54d1:ya3 +0x54d2:da1 +0x54d3:xiao1 +0x54d4:bi4 +0x54d5:yue3 +0x54d7:hua1 +0x54d9:kuai4 +0x54da:duo3 +0x54dc:ji4 +0x54dd:nong2 +0x54de:mou1 +0x54df:yo5 +0x54e0:hao4 +0x54e1:yuan2 +0x54e2:long4 +0x54e3:pou3 +0x54e4:mang2 +0x54e5:ge1 +0x54e6:e2 +0x54e7:chi1 +0x54e8:shao4 +0x54e9:li1 +0x54ea:na3 +0x54eb:zu2 +0x54ec:he2 +0x54ed:ku1 +0x54ee:xiao1 +0x54ef:xian4 +0x54f0:lao2 +0x54f1:bo1 +0x54f2:zhe2 +0x54f3:zha1 +0x54f4:liang4 +0x54f5:ba1 +0x54f6:mie1 +0x54f7:le4 +0x54f8:sui1 +0x54f9:fou2 +0x54fa:bu3 +0x54fb:han4 +0x54fc:heng1 +0x54fd:geng3 +0x54fe:shuo1 +0x54ff:ge3 +0x5500:you3 +0x5501:yan4 +0x5502:gu3 +0x5503:gu3 +0x5504:bai4 +0x5505:han1 +0x5506:suo1 +0x5507:chun2 +0x5508:yi4 +0x5509:ai1 +0x550a:jia2 +0x550b:tu3 +0x550c:xian2 +0x550d:huan3 +0x550e:li4 +0x550f:xi1 +0x5510:tang2 +0x5511:zuo4 +0x5512:qiu2 +0x5513:che1 +0x5514:wu2 +0x5515:zao4 +0x5516:ya3 +0x5517:dou1 +0x5518:qi3 +0x5519:di2 +0x551a:qin4 +0x551b:ma4 +0x551d:hong3 +0x551e:dou3 +0x5520:lao2 +0x5521:liang3 +0x5522:suo3 +0x5523:zao4 +0x5524:huan4 +0x5526:sha1 +0x5527:ji1 +0x5528:zuo3 +0x5529:wo1 +0x552a:feng3 +0x552b:yin2 +0x552c:hu3 +0x552d:qi1 +0x552e:shou4 +0x552f:wei2 +0x5530:shua1 +0x5531:chang4 +0x5532:er2 +0x5533:li4 +0x5534:qiang4 +0x5535:an3 +0x5536:jie4 +0x5537:yo1 +0x5538:nian4 +0x5539:yu1 +0x553a:tian3 +0x553b:lai3 +0x553c:sha4 +0x553d:xi1 +0x553e:tuo4 +0x553f:hu1 +0x5540:ai2 +0x5541:zhou1 +0x5542:nou4 +0x5543:ken3 +0x5544:zhuo2 +0x5545:zhuo2 +0x5546:shang1 +0x5547:di2 +0x5548:heng4 +0x5549:lan2 +0x554a:a5 +0x554b:xiao1 +0x554c:xiang1 +0x554d:tun1 +0x554e:wu3 +0x554f:wen4 +0x5550:cui4 +0x5551:sha4 +0x5552:hu1 +0x5553:qi3 +0x5554:qi3 +0x5555:tao2 +0x5556:dan4 +0x5557:dan4 +0x5558:ye4 +0x5559:zi3 +0x555a:bi3 +0x555b:cui4 +0x555c:chuo4 +0x555d:he2 +0x555e:ya3 +0x555f:qi3 +0x5560:zhe2 +0x5561:fei1 +0x5562:liang3 +0x5563:xian2 +0x5564:pi2 +0x5565:sha4 +0x5566:la5 +0x5567:ze2 +0x5568:qing1 +0x5569:gua4 +0x556a:pa1 +0x556b:zhe3 +0x556c:se4 +0x556d:zhuan4 +0x556e:nie4 +0x556f:guo5 +0x5570:luo1 +0x5571:yan1 +0x5572:di4 +0x5573:quan2 +0x5574:tan1 +0x5575:bo5 +0x5576:ding4 +0x5577:lang1 +0x5578:xiao4 +0x557a:tang2 +0x557b:chi4 +0x557c:ti2 +0x557d:an2 +0x557e:jiu1 +0x557f:dan4 +0x5580:ka1 +0x5581:yong2 +0x5582:wei4 +0x5583:nan2 +0x5584:shan4 +0x5585:yu4 +0x5586:zhe2 +0x5587:la3 +0x5588:jie1 +0x5589:hou2 +0x558a:han3 +0x558b:die2 +0x558c:zhou1 +0x558d:chai2 +0x558e:wai1 +0x558f:re3 +0x5590:yu4 +0x5591:yin1 +0x5592:zan2 +0x5593:yao1 +0x5594:o1 +0x5595:mian3 +0x5596:hu2 +0x5597:yun3 +0x5598:chuan3 +0x5599:hui4 +0x559a:huan4 +0x559b:huan4 +0x559c:xi3 +0x559d:he1 +0x559e:ji1 +0x559f:kui4 +0x55a0:zhong3 +0x55a1:wei3 +0x55a2:sha4 +0x55a3:xu3 +0x55a4:huang2 +0x55a5:du4 +0x55a6:nie4 +0x55a7:xuan1 +0x55a8:liang4 +0x55a9:yu4 +0x55aa:sang1 +0x55ab:chi1 +0x55ac:qiao2 +0x55ad:yan4 +0x55ae:dan1 +0x55af:pen1 +0x55b0:can1 +0x55b1:li2 +0x55b2:yo5 +0x55b3:zha1 +0x55b4:wei1 +0x55b5:miao1 +0x55b6:ying2 +0x55b7:pen1 +0x55b9:kui2 +0x55ba:xi4 +0x55bb:yu4 +0x55bc:jie2 +0x55bd:lou5 +0x55be:ku4 +0x55bf:sao4 +0x55c0:huo4 +0x55c1:ti2 +0x55c2:yao2 +0x55c3:he4 +0x55c4:a2 +0x55c5:xiu4 +0x55c6:qiang1 +0x55c7:se4 +0x55c8:yong1 +0x55c9:su4 +0x55ca:hong3 +0x55cb:xie2 +0x55cc:yi4 +0x55cd:suo1 +0x55ce:ma5 +0x55cf:cha1 +0x55d0:hai4 +0x55d1:ke4 +0x55d2:ta4 +0x55d3:sang3 +0x55d4:tian2 +0x55d5:ru4 +0x55d6:sou1 +0x55d7:wa1 +0x55d8:ji1 +0x55d9:pang3 +0x55da:wu1 +0x55db:xian2 +0x55dc:shi4 +0x55dd:ge2 +0x55de:zi1 +0x55df:jie1 +0x55e0:luo4 +0x55e1:weng1 +0x55e2:wa4 +0x55e3:si4 +0x55e4:chi1 +0x55e5:hao2 +0x55e6:suo1 +0x55e8:hai1 +0x55e9:suo3 +0x55ea:qin2 +0x55eb:nie4 +0x55ec:he1 +0x55ee:sai4 +0x55f0:ge4 +0x55f1:na2 +0x55f2:dia3 +0x55f3:ai4 +0x55f5:tong1 +0x55f6:bi4 +0x55f7:ao2 +0x55f8:ao2 +0x55f9:lian2 +0x55fa:cui1 +0x55fb:zhe1 +0x55fc:mo4 +0x55fd:sou4 +0x55fe:sou3 +0x55ff:tan3 +0x5600:di2 +0x5601:qi1 +0x5602:jiao4 +0x5603:chong1 +0x5604:jiao1 +0x5605:kai3 +0x5606:tan4 +0x5607:san1 +0x5608:cao2 +0x5609:jia1 +0x560a:ai2 +0x560b:xiao1 +0x560c:piao1 +0x560d:lou5 +0x560e:ga1 +0x560f:gu3 +0x5610:xiao1 +0x5611:hu1 +0x5612:hui4 +0x5613:guo1 +0x5614:ou1 +0x5615:xian1 +0x5616:ze2 +0x5617:chang2 +0x5618:xu1 +0x5619:po2 +0x561a:de2 +0x561b:ma5 +0x561c:ma4 +0x561d:hu2 +0x561e:lei5 +0x561f:du1 +0x5620:ga1 +0x5621:tang1 +0x5622:ye3 +0x5623:beng1 +0x5624:ying1 +0x5626:jiao4 +0x5627:mi4 +0x5628:xiao4 +0x5629:hua1 +0x562a:mai3 +0x562b:ran2 +0x562c:zuo1 +0x562d:peng1 +0x562e:lao2 +0x562f:xiao4 +0x5630:ji1 +0x5631:zhu3 +0x5632:chao2 +0x5633:kui4 +0x5634:zui3 +0x5635:xiao1 +0x5636:si1 +0x5637:hao2 +0x5638:fu3 +0x5639:liao2 +0x563a:qiao2 +0x563b:xi1 +0x563c:xiu4 +0x563d:tan1 +0x563e:tan2 +0x563f:hei1 +0x5640:xun4 +0x5641:e3 +0x5642:zun3 +0x5643:fan1 +0x5644:chi1 +0x5645:hui1 +0x5646:zan3 +0x5647:chuang2 +0x5648:cu4 +0x5649:dan4 +0x564a:yu4 +0x564b:tun1 +0x564c:cheng1 +0x564d:jiao4 +0x564e:ye1 +0x564f:xi1 +0x5650:qi4 +0x5651:hao2 +0x5652:lian2 +0x5653:xu1 +0x5654:deng1 +0x5655:hui1 +0x5656:yin2 +0x5657:pu1 +0x5658:jue1 +0x5659:qin2 +0x565a:xun2 +0x565b:nie4 +0x565c:lu1 +0x565d:si1 +0x565e:yan3 +0x565f:ying4 +0x5660:da1 +0x5661:dan1 +0x5662:o1 +0x5663:zhou4 +0x5664:jin4 +0x5665:nong2 +0x5666:yue3 +0x5667:hui4 +0x5668:qi4 +0x5669:e4 +0x566a:zao4 +0x566b:yi1 +0x566c:shi4 +0x566d:jiao4 +0x566e:yuan1 +0x566f:ai3 +0x5670:yong1 +0x5671:jue2 +0x5672:kuai4 +0x5673:yu3 +0x5674:pen1 +0x5675:dao4 +0x5676:ge2 +0x5677:xin1 +0x5678:dun1 +0x5679:dang1 +0x567b:sai5 +0x567c:pi1 +0x567d:pi3 +0x567e:yin1 +0x567f:zui3 +0x5680:ning2 +0x5681:di2 +0x5682:lan4 +0x5683:ta4 +0x5684:huo4 +0x5685:ru2 +0x5686:hao1 +0x5687:xia4 +0x5688:ya4 +0x5689:duo1 +0x568a:xi4 +0x568b:chou2 +0x568c:ji4 +0x568d:jin4 +0x568e:hao2 +0x568f:ti4 +0x5690:chang2 +0x5693:ca1 +0x5694:ti4 +0x5695:lu1 +0x5696:hui4 +0x5697:bo2 +0x5698:you1 +0x5699:nie4 +0x569a:yin2 +0x569b:hu4 +0x569c:mo4 +0x569d:huang1 +0x569e:zhe2 +0x569f:li2 +0x56a0:liu2 +0x56a2:nang2 +0x56a3:xiao1 +0x56a4:mo2 +0x56a5:yan4 +0x56a6:li4 +0x56a7:lu2 +0x56a8:long2 +0x56a9:fu2 +0x56aa:dan4 +0x56ab:chen4 +0x56ac:pin2 +0x56ad:pi3 +0x56ae:xiang4 +0x56af:huo4 +0x56b0:mo2 +0x56b1:xi4 +0x56b2:duo3 +0x56b3:ku4 +0x56b4:yan2 +0x56b5:chan2 +0x56b6:ying1 +0x56b7:rang3 +0x56b8:dian3 +0x56b9:la1 +0x56ba:ta4 +0x56bb:xiao1 +0x56bc:jiao2 +0x56bd:chuo4 +0x56be:huan1 +0x56bf:huo4 +0x56c0:zhuan4 +0x56c1:nie4 +0x56c2:xiao1 +0x56c3:ca4 +0x56c4:li2 +0x56c5:chan3 +0x56c6:chai4 +0x56c7:li4 +0x56c8:yi4 +0x56c9:luo1 +0x56ca:nang2 +0x56cb:zan4 +0x56cc:su1 +0x56cd:xi3 +0x56cf:jian1 +0x56d0:za2 +0x56d1:zhu3 +0x56d2:lan2 +0x56d3:nie4 +0x56d4:nang1 +0x56d7:wei2 +0x56d8:hui2 +0x56d9:yin1 +0x56da:qiu2 +0x56db:si4 +0x56dc:nin2 +0x56dd:jian3 +0x56de:hui2 +0x56df:xin4 +0x56e0:yin1 +0x56e1:nan1 +0x56e2:tuan2 +0x56e3:tuan2 +0x56e4:dun4 +0x56e5:kang4 +0x56e6:yuan1 +0x56e7:jiong3 +0x56e8:pian1 +0x56e9:yun4 +0x56ea:cong1 +0x56eb:hu2 +0x56ec:hui2 +0x56ed:yuan2 +0x56ee:e2 +0x56ef:guo2 +0x56f0:kun4 +0x56f1:cong1 +0x56f2:wei2 +0x56f3:tu2 +0x56f4:wei2 +0x56f5:lun2 +0x56f6:guo2 +0x56f7:qun1 +0x56f8:ri4 +0x56f9:ling2 +0x56fa:gu4 +0x56fb:guo2 +0x56fc:tai1 +0x56fd:guo2 +0x56fe:tu2 +0x56ff:you4 +0x5700:guo2 +0x5701:yin2 +0x5702:hun4 +0x5703:pu3 +0x5704:yu3 +0x5705:han2 +0x5706:yuan2 +0x5707:lun2 +0x5708:quan1 +0x5709:yu3 +0x570a:qing1 +0x570b:guo2 +0x570c:chuan2 +0x570d:wei2 +0x570e:yuan2 +0x570f:quan1 +0x5710:ku1 +0x5711:fu4 +0x5712:yuan2 +0x5713:yuan2 +0x5714:e4 +0x5716:tu2 +0x5717:tu2 +0x5718:tuan2 +0x5719:lve4 +0x571a:hui4 +0x571b:yi4 +0x571c:yuan2 +0x571d:luan2 +0x571e:luan2 +0x571f:tu3 +0x5720:ya4 +0x5721:tu3 +0x5722:ting1 +0x5723:sheng4 +0x5724:pu3 +0x5725:lu4 +0x5727:ya1 +0x5728:zai4 +0x5729:wei2 +0x572a:ge1 +0x572b:yu4 +0x572c:wu1 +0x572d:gui1 +0x572e:pi3 +0x572f:yi2 +0x5730:di4 +0x5731:qian1 +0x5732:qian1 +0x5733:zhen4 +0x5734:zhuo2 +0x5735:dang4 +0x5736:qia4 +0x5739:kuang4 +0x573a:chang2 +0x573b:qi2 +0x573c:nie4 +0x573d:mo4 +0x573e:ji2 +0x573f:jia2 +0x5740:zhi3 +0x5741:zhi3 +0x5742:ban3 +0x5743:xun1 +0x5744:tou2 +0x5745:qin3 +0x5746:fen2 +0x5747:jun1 +0x5748:keng1 +0x5749:tun2 +0x574a:fang1 +0x574b:fen4 +0x574c:ben4 +0x574d:tan1 +0x574e:kan3 +0x574f:huai4 +0x5750:zuo4 +0x5751:keng1 +0x5752:bi4 +0x5753:xing2 +0x5754:di4 +0x5755:jing1 +0x5756:ji4 +0x5757:kuai4 +0x5758:di3 +0x5759:jing1 +0x575a:jian1 +0x575b:tan2 +0x575c:li4 +0x575d:ba4 +0x575e:wu4 +0x575f:fen2 +0x5760:zhui4 +0x5761:po1 +0x5762:pan3 +0x5763:tang1 +0x5764:kun1 +0x5765:qu1 +0x5766:tan3 +0x5767:zhi1 +0x5768:tuo2 +0x5769:gan1 +0x576a:ping2 +0x576b:dian4 +0x576c:gua4 +0x576d:ni2 +0x576e:tai2 +0x576f:pi1 +0x5770:jiong1 +0x5771:yang3 +0x5772:fo2 +0x5773:ao4 +0x5774:liu4 +0x5775:qiu1 +0x5776:mu4 +0x5777:ke3 +0x5778:gou4 +0x5779:xue4 +0x577a:ba2 +0x577b:chi2 +0x577c:che4 +0x577d:ling2 +0x577e:zhu4 +0x577f:fu4 +0x5780:hu1 +0x5781:zhi4 +0x5782:chui2 +0x5783:la1 +0x5784:long3 +0x5785:long3 +0x5786:lu2 +0x5787:ao4 +0x5789:pao2 +0x578b:xing2 +0x578c:dong4 +0x578d:ji4 +0x578e:ke4 +0x578f:lu4 +0x5790:ci2 +0x5791:chi3 +0x5792:lei3 +0x5793:gai1 +0x5794:yin1 +0x5795:hou4 +0x5796:dui1 +0x5797:zhao4 +0x5798:fu2 +0x5799:guang1 +0x579a:yao2 +0x579b:duo3 +0x579c:duo3 +0x579d:gui3 +0x579e:cha2 +0x579f:yang2 +0x57a0:yin2 +0x57a1:fa2 +0x57a2:gou4 +0x57a3:yuan2 +0x57a4:die2 +0x57a5:xie2 +0x57a6:ken3 +0x57a7:jiong1 +0x57a8:shou3 +0x57a9:e4 +0x57ab:dian4 +0x57ac:hong2 +0x57ad:wu4 +0x57ae:kua3 +0x57b1:dang4 +0x57b2:kai3 +0x57b4:nao3 +0x57b5:an3 +0x57b6:xing1 +0x57b7:xian4 +0x57b8:huan4 +0x57b9:bang1 +0x57ba:pei1 +0x57bb:ba4 +0x57bc:yi4 +0x57bd:yin4 +0x57be:han4 +0x57bf:xu4 +0x57c0:chui2 +0x57c1:cen2 +0x57c2:geng3 +0x57c3:ai1 +0x57c4:peng2 +0x57c5:fang2 +0x57c6:que4 +0x57c7:yong3 +0x57c8:xun4 +0x57c9:jia2 +0x57ca:di4 +0x57cb:mai2 +0x57cc:lang4 +0x57cd:xuan4 +0x57ce:cheng2 +0x57cf:yan2 +0x57d0:jin1 +0x57d1:zhe2 +0x57d2:lei4 +0x57d3:lie4 +0x57d4:pu3 +0x57d5:cheng2 +0x57d7:bu4 +0x57d8:shi2 +0x57d9:xun1 +0x57da:guo1 +0x57db:jiong1 +0x57dc:ye3 +0x57dd:nian4 +0x57de:di3 +0x57df:yu4 +0x57e0:bu4 +0x57e1:ya4 +0x57e2:juan3 +0x57e3:sui4 +0x57e4:pi2 +0x57e5:cheng1 +0x57e6:wan3 +0x57e7:ju4 +0x57e8:lun3 +0x57e9:zheng1 +0x57ea:kong1 +0x57eb:chong3 +0x57ec:dong1 +0x57ed:dai4 +0x57ee:tan4 +0x57ef:an3 +0x57f0:cai4 +0x57f1:shu2 +0x57f2:beng3 +0x57f3:kan3 +0x57f4:zhi2 +0x57f5:duo3 +0x57f6:yi4 +0x57f7:zhi2 +0x57f8:yi4 +0x57f9:pei2 +0x57fa:ji1 +0x57fb:zhun3 +0x57fc:qi2 +0x57fd:sao4 +0x57fe:ju4 +0x57ff:ni2 +0x5800:ku1 +0x5801:ke4 +0x5802:tang2 +0x5803:kun1 +0x5804:ni4 +0x5805:jian1 +0x5806:dui1 +0x5807:jin3 +0x5808:gang1 +0x5809:yu4 +0x580a:e4 +0x580b:peng2 +0x580c:gu4 +0x580d:tu4 +0x580e:leng4 +0x5810:ya2 +0x5811:qian4 +0x5813:an4 +0x5815:duo4 +0x5816:nao3 +0x5817:tu1 +0x5818:cheng2 +0x5819:yin1 +0x581a:hun2 +0x581b:bi4 +0x581c:lian4 +0x581d:guo1 +0x581e:die2 +0x581f:zhuan4 +0x5820:hou4 +0x5821:bao3 +0x5822:bao3 +0x5823:yu2 +0x5824:di1 +0x5825:mao2 +0x5826:jie1 +0x5827:ruan2 +0x5828:e4 +0x5829:geng4 +0x582a:kan1 +0x582b:zong1 +0x582c:yu2 +0x582d:huang2 +0x582e:e4 +0x582f:yao2 +0x5830:yan4 +0x5831:bao4 +0x5832:ji2 +0x5833:mei2 +0x5834:chang2 +0x5835:du3 +0x5836:tuo2 +0x5837:yin4 +0x5838:feng2 +0x5839:zhong4 +0x583a:jie4 +0x583b:zhen1 +0x583c:feng1 +0x583d:gang1 +0x583e:chuan3 +0x583f:jian3 +0x5842:xiang4 +0x5843:huang1 +0x5844:leng2 +0x5845:duan4 +0x5847:xuan1 +0x5848:ji4 +0x5849:ji2 +0x584a:kuai4 +0x584b:ying2 +0x584c:ta1 +0x584d:cheng2 +0x584e:yong3 +0x584f:kai3 +0x5850:su4 +0x5851:su4 +0x5852:shi2 +0x5853:mi4 +0x5854:ta3 +0x5855:weng3 +0x5856:cheng2 +0x5857:tu2 +0x5858:tang2 +0x5859:que4 +0x585a:zhong3 +0x585b:li4 +0x585c:peng2 +0x585d:bang4 +0x585e:sai1 +0x585f:zang4 +0x5860:dui1 +0x5861:tian2 +0x5862:wu4 +0x5863:cheng3 +0x5864:xun1 +0x5865:ge2 +0x5866:zhen4 +0x5867:ai4 +0x5868:gong1 +0x5869:yan2 +0x586a:kan3 +0x586b:tian2 +0x586c:yuan2 +0x586d:wen1 +0x586e:xie4 +0x586f:liu4 +0x5871:lang3 +0x5872:chang2 +0x5873:peng2 +0x5874:beng4 +0x5875:chen2 +0x5876:cu4 +0x5877:lu3 +0x5878:ou3 +0x5879:qian4 +0x587a:mei2 +0x587b:mo4 +0x587c:zhuan1 +0x587d:shuang3 +0x587e:shu2 +0x587f:lou3 +0x5880:chi2 +0x5881:man4 +0x5882:biao1 +0x5883:jing4 +0x5884:qi1 +0x5885:shu4 +0x5886:di4 +0x5887:zhang1 +0x5888:kan4 +0x5889:yong1 +0x588a:dian4 +0x588b:chen3 +0x588c:zhi1 +0x588d:xi4 +0x588e:guo1 +0x588f:qiang3 +0x5890:jin4 +0x5891:di1 +0x5892:shang1 +0x5893:mu4 +0x5894:cui1 +0x5895:yan4 +0x5896:ta3 +0x5897:zeng1 +0x5898:qi2 +0x5899:qiang2 +0x589a:liang2 +0x589c:zhui4 +0x589d:qiao1 +0x589e:zeng1 +0x589f:xu1 +0x58a0:shan4 +0x58a1:shan4 +0x58a2:ba2 +0x58a3:pu1 +0x58a4:kuai4 +0x58a5:dong3 +0x58a6:fan2 +0x58a7:que4 +0x58a8:mo4 +0x58a9:dun1 +0x58aa:dun1 +0x58ab:zun1 +0x58ac:di4 +0x58ad:sheng4 +0x58ae:duo4 +0x58af:duo4 +0x58b0:tan2 +0x58b1:deng4 +0x58b2:wu3 +0x58b3:fen2 +0x58b4:huang2 +0x58b5:tan2 +0x58b6:da1 +0x58b7:ye4 +0x58ba:ao4 +0x58bb:qiang2 +0x58bc:ji1 +0x58bd:qiao1 +0x58be:ken3 +0x58bf:yi4 +0x58c0:pi2 +0x58c1:bi4 +0x58c2:dian4 +0x58c3:jiang1 +0x58c4:ye3 +0x58c5:yong1 +0x58c6:bo2 +0x58c7:tan2 +0x58c8:lan3 +0x58c9:ju4 +0x58ca:huai4 +0x58cb:dang4 +0x58cc:rang3 +0x58cd:qian4 +0x58ce:xun1 +0x58cf:lan4 +0x58d0:xi3 +0x58d1:he4 +0x58d2:ai4 +0x58d3:ya1 +0x58d4:dao3 +0x58d5:hao2 +0x58d6:ruan2 +0x58d8:lei3 +0x58d9:kuang4 +0x58da:lu2 +0x58db:yan2 +0x58dc:tan2 +0x58dd:wei2 +0x58de:huai4 +0x58df:long3 +0x58e0:long3 +0x58e1:rui4 +0x58e2:li4 +0x58e3:lin2 +0x58e4:rang3 +0x58e6:xun1 +0x58e7:yan2 +0x58e8:lei2 +0x58e9:ba4 +0x58eb:shi4 +0x58ec:ren2 +0x58ee:zhuang4 +0x58ef:zhuang4 +0x58f0:sheng1 +0x58f1:yi1 +0x58f2:mai4 +0x58f3:ke2 +0x58f4:zhu3 +0x58f5:zhuang4 +0x58f6:hu2 +0x58f7:hu2 +0x58f8:kun3 +0x58f9:yi1 +0x58fa:hu2 +0x58fb:xu4 +0x58fc:kun3 +0x58fd:shou4 +0x58fe:mang3 +0x58ff:zun1 +0x5900:shou4 +0x5901:yi1 +0x5902:zhi3 +0x5903:gu1 +0x5904:chu4 +0x5905:jiang4 +0x5906:feng2 +0x5907:bei4 +0x5909:bian4 +0x590a:sui1 +0x590b:qun1 +0x590c:ling2 +0x590d:fu4 +0x590e:zuo4 +0x590f:xia4 +0x5910:xiong4 +0x5912:nao2 +0x5913:xia4 +0x5914:kui2 +0x5915:xi1 +0x5916:wai4 +0x5917:yuan4 +0x5918:mao3 +0x5919:su4 +0x591a:duo1 +0x591b:duo1 +0x591c:ye4 +0x591d:qing2 +0x591f:gou4 +0x5920:gou4 +0x5921:qi4 +0x5922:meng4 +0x5923:meng4 +0x5924:yin2 +0x5925:huo3 +0x5926:chen4 +0x5927:da4 +0x5928:ze4 +0x5929:tian1 +0x592a:tai4 +0x592b:fu1 +0x592c:guai4 +0x592d:yao1 +0x592e:yang1 +0x592f:hang1 +0x5930:gao3 +0x5931:shi1 +0x5932:ben3 +0x5933:tai4 +0x5934:tou2 +0x5935:yan3 +0x5936:bi3 +0x5937:yi2 +0x5938:kua1 +0x5939:jia1 +0x593a:duo2 +0x593c:kuang3 +0x593d:yun4 +0x593e:jia1 +0x593f:pa1 +0x5940:en1 +0x5941:lian2 +0x5942:huan4 +0x5943:di4 +0x5944:yan3 +0x5945:pao4 +0x5946:quan3 +0x5947:qi2 +0x5948:nai4 +0x5949:feng4 +0x594a:xie2 +0x594b:fen4 +0x594c:dian3 +0x594e:kui2 +0x594f:zou4 +0x5950:huan4 +0x5951:qi4 +0x5952:kai1 +0x5953:she1 +0x5954:ben1 +0x5955:yi4 +0x5956:jiang3 +0x5957:tao4 +0x5958:zang4 +0x5959:ben3 +0x595a:xi1 +0x595b:xiang3 +0x595c:fei3 +0x595d:diao1 +0x595e:xun4 +0x595f:keng1 +0x5960:dian4 +0x5961:ao4 +0x5962:she1 +0x5963:weng3 +0x5964:pan3 +0x5965:ao4 +0x5966:wu4 +0x5967:ao4 +0x5968:jiang3 +0x5969:lian2 +0x596a:duo2 +0x596b:yun1 +0x596c:jiang3 +0x596d:shi4 +0x596e:fen4 +0x596f:huo4 +0x5970:bi4 +0x5971:lian2 +0x5972:duo3 +0x5973:nv3 +0x5974:nu2 +0x5975:ding1 +0x5976:nai3 +0x5977:qian1 +0x5978:jian1 +0x5979:ta1 +0x597a:jiu3 +0x597b:nan2 +0x597c:cha4 +0x597d:hao3 +0x597e:xian1 +0x597f:fan4 +0x5980:ji3 +0x5981:shuo4 +0x5982:ru2 +0x5983:fei1 +0x5984:wang4 +0x5985:hong2 +0x5986:zhuang1 +0x5987:fu4 +0x5988:ma1 +0x5989:dan1 +0x598a:ren4 +0x598b:fu1 +0x598c:jing4 +0x598d:yan2 +0x598e:xie4 +0x598f:wen4 +0x5990:zhong1 +0x5991:pa1 +0x5992:du4 +0x5993:ji4 +0x5994:keng1 +0x5995:zhong4 +0x5996:yao1 +0x5997:jin4 +0x5998:yun2 +0x5999:miao4 +0x599a:pei1 +0x599c:yue4 +0x599d:zhuang1 +0x599e:niu1 +0x599f:yan4 +0x59a0:na4 +0x59a1:xin1 +0x59a2:fen2 +0x59a3:bi3 +0x59a4:yu2 +0x59a5:tuo3 +0x59a6:feng1 +0x59a7:yuan2 +0x59a8:fang2 +0x59a9:wu3 +0x59aa:yu4 +0x59ab:gui1 +0x59ac:du4 +0x59ad:ba2 +0x59ae:ni1 +0x59af:zhou2 +0x59b0:zhuo2 +0x59b1:zhao1 +0x59b2:da2 +0x59b3:nai3 +0x59b4:yuan3 +0x59b5:tou3 +0x59b6:xuan2 +0x59b7:zhi2 +0x59b8:e1 +0x59b9:mei4 +0x59ba:mo4 +0x59bb:qi1 +0x59bc:bi4 +0x59bd:shen1 +0x59be:qie4 +0x59bf:e1 +0x59c0:he2 +0x59c1:xu3 +0x59c2:fa2 +0x59c3:zheng1 +0x59c4:min2 +0x59c5:ban4 +0x59c6:mu3 +0x59c7:fu1 +0x59c8:ling2 +0x59c9:zi3 +0x59ca:zi3 +0x59cb:shi3 +0x59cc:ran3 +0x59cd:shan1 +0x59ce:yang1 +0x59cf:man2 +0x59d0:jie3 +0x59d1:gu1 +0x59d2:si4 +0x59d3:xing4 +0x59d4:wei3 +0x59d5:zi1 +0x59d6:ju4 +0x59d7:shan1 +0x59d8:pin1 +0x59d9:ren4 +0x59da:yao2 +0x59db:tong3 +0x59dc:jiang1 +0x59dd:shu1 +0x59de:ji2 +0x59df:gai1 +0x59e0:shang4 +0x59e1:kuo4 +0x59e2:juan1 +0x59e3:jiao1 +0x59e4:gou4 +0x59e5:mu3 +0x59e6:jian1 +0x59e7:jian1 +0x59e8:yi2 +0x59e9:nian4 +0x59ea:zhi2 +0x59eb:ji1 +0x59ec:ji1 +0x59ed:xian4 +0x59ee:heng2 +0x59ef:guang1 +0x59f0:jun1 +0x59f1:kua1 +0x59f2:yan4 +0x59f3:ming3 +0x59f4:lie4 +0x59f5:pei4 +0x59f6:yan3 +0x59f7:you4 +0x59f8:yan2 +0x59f9:cha4 +0x59fa:shen1 +0x59fb:yin1 +0x59fc:chi3 +0x59fd:gui3 +0x59fe:quan1 +0x59ff:zi1 +0x5a00:song1 +0x5a01:wei1 +0x5a02:hong2 +0x5a03:wa2 +0x5a04:lou2 +0x5a05:ya4 +0x5a06:rao3 +0x5a07:jiao1 +0x5a08:luan2 +0x5a09:ping1 +0x5a0a:xian4 +0x5a0b:shao4 +0x5a0c:li3 +0x5a0d:cheng2 +0x5a0e:xiao4 +0x5a0f:mang2 +0x5a11:suo1 +0x5a12:wu3 +0x5a13:wei3 +0x5a14:ke4 +0x5a15:lai4 +0x5a16:chuo4 +0x5a17:ding4 +0x5a18:niang2 +0x5a19:xing2 +0x5a1a:nan2 +0x5a1b:yu2 +0x5a1c:nuo2 +0x5a1d:pei1 +0x5a1e:nei3 +0x5a1f:juan1 +0x5a20:shen1 +0x5a21:zhi4 +0x5a22:han2 +0x5a23:di4 +0x5a24:zhuang1 +0x5a25:e2 +0x5a26:pin2 +0x5a27:tui4 +0x5a28:han4 +0x5a29:mian3 +0x5a2a:wu2 +0x5a2b:yan2 +0x5a2c:wu3 +0x5a2d:xi1 +0x5a2e:yan2 +0x5a2f:yu2 +0x5a30:si4 +0x5a31:yu2 +0x5a32:wa1 +0x5a34:xian2 +0x5a35:ju1 +0x5a36:qu3 +0x5a37:shui4 +0x5a38:qi1 +0x5a39:xian2 +0x5a3a:zhui1 +0x5a3b:dong1 +0x5a3c:chang1 +0x5a3d:lu4 +0x5a3e:ai3 +0x5a3f:e1 +0x5a40:e1 +0x5a41:lou2 +0x5a42:mian2 +0x5a43:cong2 +0x5a44:pou3 +0x5a45:ju2 +0x5a46:po2 +0x5a47:cai3 +0x5a48:ding2 +0x5a49:wan3 +0x5a4a:biao3 +0x5a4b:xiao1 +0x5a4c:shu3 +0x5a4d:qi3 +0x5a4e:hui1 +0x5a4f:fu4 +0x5a50:e1 +0x5a51:wo3 +0x5a52:tan2 +0x5a53:fei1 +0x5a55:jie2 +0x5a56:tian1 +0x5a57:ni2 +0x5a58:quan2 +0x5a59:jing4 +0x5a5a:hun1 +0x5a5b:jing1 +0x5a5c:qian1 +0x5a5d:dian4 +0x5a5e:xing4 +0x5a5f:hu4 +0x5a60:wa4 +0x5a61:lai2 +0x5a62:bi4 +0x5a63:yin1 +0x5a64:zhou1 +0x5a65:chuo4 +0x5a66:fu4 +0x5a67:jing4 +0x5a68:lun2 +0x5a69:yan4 +0x5a6a:lan2 +0x5a6b:kun1 +0x5a6c:yin2 +0x5a6d:ya4 +0x5a6f:li4 +0x5a70:dian3 +0x5a71:xian2 +0x5a73:hua4 +0x5a74:ying1 +0x5a75:chan2 +0x5a76:shen3 +0x5a77:ting2 +0x5a78:dang4 +0x5a79:yao3 +0x5a7a:wu4 +0x5a7b:nan4 +0x5a7c:ruo4 +0x5a7d:jia3 +0x5a7e:tou1 +0x5a7f:xu4 +0x5a80:yu2 +0x5a81:wei1 +0x5a82:ti2 +0x5a83:rou2 +0x5a84:mei3 +0x5a85:dan1 +0x5a86:ruan3 +0x5a87:qin1 +0x5a89:wu1 +0x5a8a:qian2 +0x5a8b:chun1 +0x5a8c:mao2 +0x5a8d:fu4 +0x5a8e:jie3 +0x5a8f:duan1 +0x5a90:xi1 +0x5a91:zhong4 +0x5a92:mei2 +0x5a93:huang2 +0x5a94:mian2 +0x5a95:an1 +0x5a96:ying1 +0x5a97:xuan1 +0x5a99:wei1 +0x5a9a:mei4 +0x5a9b:yuan4 +0x5a9c:zhen1 +0x5a9d:qiu1 +0x5a9e:ti2 +0x5a9f:xie4 +0x5aa0:tuo3 +0x5aa1:lian4 +0x5aa2:mao4 +0x5aa3:ran3 +0x5aa4:si1 +0x5aa5:pian1 +0x5aa6:wei4 +0x5aa7:wa1 +0x5aa8:jiu4 +0x5aa9:hu2 +0x5aaa:ao3 +0x5aad:xu1 +0x5aae:tou1 +0x5aaf:gui1 +0x5ab0:zou1 +0x5ab1:yao2 +0x5ab2:pi4 +0x5ab3:xi2 +0x5ab4:yuan2 +0x5ab5:ying4 +0x5ab6:rong2 +0x5ab7:ru4 +0x5ab8:chi1 +0x5ab9:liu2 +0x5aba:mei3 +0x5abb:pan2 +0x5abc:ao3 +0x5abd:ma1 +0x5abe:gou4 +0x5abf:kui4 +0x5ac0:qin2 +0x5ac1:jia4 +0x5ac2:sao3 +0x5ac3:zhen1 +0x5ac4:yuan2 +0x5ac5:cha1 +0x5ac6:yong2 +0x5ac7:ming2 +0x5ac8:ying1 +0x5ac9:ji2 +0x5aca:su4 +0x5acb:niao3 +0x5acc:xian2 +0x5acd:tao1 +0x5ace:pang2 +0x5acf:lang2 +0x5ad0:nao3 +0x5ad1:bao2 +0x5ad2:ai4 +0x5ad3:pi4 +0x5ad4:pin2 +0x5ad5:yi4 +0x5ad6:piao4 +0x5ad7:yu4 +0x5ad8:lei2 +0x5ad9:xuan2 +0x5ada:man4 +0x5adb:yi1 +0x5adc:zhang1 +0x5add:kang1 +0x5ade:yong2 +0x5adf:ni4 +0x5ae0:li2 +0x5ae1:di2 +0x5ae2:gui1 +0x5ae3:yan1 +0x5ae4:jin4 +0x5ae5:zhuan1 +0x5ae6:chang2 +0x5ae7:ce4 +0x5ae8:han1 +0x5ae9:nen4 +0x5aea:lao4 +0x5aeb:mo2 +0x5aec:zhe1 +0x5aed:hu4 +0x5aee:hu4 +0x5aef:ao4 +0x5af0:nen4 +0x5af1:qiang2 +0x5af3:pie4 +0x5af4:gu1 +0x5af5:wu3 +0x5af6:jiao2 +0x5af7:tuo3 +0x5af8:zhan3 +0x5af9:mao2 +0x5afa:xian2 +0x5afb:xian2 +0x5afc:mo4 +0x5afd:liao2 +0x5afe:lian2 +0x5aff:hua4 +0x5b00:gui1 +0x5b01:deng1 +0x5b02:zhi1 +0x5b03:xu1 +0x5b05:hua2 +0x5b06:xi1 +0x5b07:hui4 +0x5b08:rao3 +0x5b09:xi1 +0x5b0a:yan4 +0x5b0b:chan2 +0x5b0c:jiao1 +0x5b0d:mei3 +0x5b0e:fan4 +0x5b0f:fan1 +0x5b10:xian1 +0x5b11:yi4 +0x5b12:wei4 +0x5b13:jiao4 +0x5b14:fu4 +0x5b15:shi4 +0x5b16:bi4 +0x5b17:shan4 +0x5b18:sui4 +0x5b19:qiang2 +0x5b1a:lian3 +0x5b1b:huan2 +0x5b1d:niao3 +0x5b1e:dong3 +0x5b1f:yi4 +0x5b20:can2 +0x5b21:ai4 +0x5b22:niang2 +0x5b23:neng2 +0x5b24:ma1 +0x5b25:tiao3 +0x5b26:chou2 +0x5b27:jin4 +0x5b28:ci2 +0x5b29:yu2 +0x5b2a:pin2 +0x5b2c:xu1 +0x5b2d:nai3 +0x5b2e:yan1 +0x5b2f:tai2 +0x5b30:ying1 +0x5b31:can2 +0x5b32:niao3 +0x5b34:ying2 +0x5b35:mian2 +0x5b37:ma1 +0x5b38:shen3 +0x5b39:xing4 +0x5b3a:ni4 +0x5b3b:du2 +0x5b3c:liu3 +0x5b3d:yuan1 +0x5b3e:lan3 +0x5b3f:yan4 +0x5b40:shuang1 +0x5b41:ling2 +0x5b42:jiao3 +0x5b43:niang2 +0x5b44:lan3 +0x5b45:xian1 +0x5b46:ying1 +0x5b47:shuang1 +0x5b48:shuai1 +0x5b49:quan2 +0x5b4a:mi3 +0x5b4b:li2 +0x5b4c:luan2 +0x5b4d:yan2 +0x5b4e:zhu3 +0x5b4f:lan3 +0x5b50:zi3 +0x5b51:jie2 +0x5b52:jue2 +0x5b53:jue2 +0x5b54:kong3 +0x5b55:yun4 +0x5b56:zi1 +0x5b57:zi4 +0x5b58:cun2 +0x5b59:sun1 +0x5b5a:fu2 +0x5b5b:bei4 +0x5b5c:zi1 +0x5b5d:xiao4 +0x5b5e:xin4 +0x5b5f:meng4 +0x5b60:si4 +0x5b61:tai1 +0x5b62:bao1 +0x5b63:ji4 +0x5b64:gu1 +0x5b65:nu2 +0x5b66:xue2 +0x5b68:zhuan3 +0x5b69:hai2 +0x5b6a:luan2 +0x5b6b:sun1 +0x5b6c:huai4 +0x5b6d:mie1 +0x5b6e:cong2 +0x5b6f:qian1 +0x5b70:shu2 +0x5b71:chan2 +0x5b72:ya1 +0x5b73:zi1 +0x5b74:ni3 +0x5b75:fu1 +0x5b76:zi1 +0x5b77:li2 +0x5b78:xue2 +0x5b79:bo4 +0x5b7a:ru2 +0x5b7b:lai2 +0x5b7c:nie4 +0x5b7d:nie4 +0x5b7e:ying1 +0x5b7f:luan2 +0x5b80:mian2 +0x5b81:ning2 +0x5b82:rong3 +0x5b83:ta1 +0x5b84:gui3 +0x5b85:zhai2 +0x5b86:qiong2 +0x5b87:yu3 +0x5b88:shou3 +0x5b89:an1 +0x5b8a:tu2 +0x5b8b:song4 +0x5b8c:wan2 +0x5b8d:rou4 +0x5b8e:yao3 +0x5b8f:hong2 +0x5b90:yi2 +0x5b91:jing3 +0x5b92:zhun1 +0x5b93:mi4 +0x5b94:zhu3 +0x5b95:dang4 +0x5b96:hong2 +0x5b97:zong1 +0x5b98:guan1 +0x5b99:zhou4 +0x5b9a:ding4 +0x5b9b:wan3 +0x5b9c:yi2 +0x5b9d:bao3 +0x5b9e:shi2 +0x5b9f:shi2 +0x5ba0:chong3 +0x5ba1:shen3 +0x5ba2:ke4 +0x5ba3:xuan1 +0x5ba4:shi4 +0x5ba5:you4 +0x5ba6:huan4 +0x5ba7:yi2 +0x5ba8:tiao3 +0x5ba9:shi3 +0x5baa:xian4 +0x5bab:gong1 +0x5bac:cheng2 +0x5bad:qun2 +0x5bae:gong1 +0x5baf:xiao1 +0x5bb0:zai3 +0x5bb1:zha4 +0x5bb2:bao3 +0x5bb3:hai4 +0x5bb4:yan4 +0x5bb5:xiao1 +0x5bb6:jia1 +0x5bb7:shen3 +0x5bb8:chen2 +0x5bb9:rong2 +0x5bba:huang3 +0x5bbb:mi4 +0x5bbc:kou4 +0x5bbd:kuan1 +0x5bbe:bin1 +0x5bbf:su4 +0x5bc0:cai4 +0x5bc1:zan3 +0x5bc2:ji4 +0x5bc3:yuan1 +0x5bc4:ji4 +0x5bc5:yin2 +0x5bc6:mi4 +0x5bc7:kou4 +0x5bc8:qing1 +0x5bc9:que4 +0x5bca:zhen1 +0x5bcb:jian3 +0x5bcc:fu4 +0x5bcd:ning2 +0x5bce:bing4 +0x5bcf:huan2 +0x5bd0:mei4 +0x5bd1:qin3 +0x5bd2:han2 +0x5bd3:yu4 +0x5bd4:shi2 +0x5bd5:ning2 +0x5bd6:jin4 +0x5bd7:ning2 +0x5bd8:zhi4 +0x5bd9:yu3 +0x5bda:bao3 +0x5bdb:kuan1 +0x5bdc:ning2 +0x5bdd:qin3 +0x5bde:mo4 +0x5bdf:cha2 +0x5be0:ju4 +0x5be1:gua3 +0x5be2:qin3 +0x5be3:hu1 +0x5be4:wu4 +0x5be5:liao2 +0x5be6:shi2 +0x5be7:ning2 +0x5be8:zhai4 +0x5be9:shen3 +0x5bea:wei3 +0x5beb:xie3 +0x5bec:kuan1 +0x5bed:hui4 +0x5bee:liao2 +0x5bef:jun4 +0x5bf0:huan2 +0x5bf1:yi4 +0x5bf2:yi2 +0x5bf3:bao3 +0x5bf4:qin4 +0x5bf5:chong3 +0x5bf6:bao3 +0x5bf7:feng1 +0x5bf8:cun4 +0x5bf9:dui4 +0x5bfa:si4 +0x5bfb:xun2 +0x5bfc:dao3 +0x5bfd:lv4 +0x5bfe:dui4 +0x5bff:shou4 +0x5c00:po3 +0x5c01:feng1 +0x5c02:zhuan1 +0x5c03:fu1 +0x5c04:she4 +0x5c05:ke4 +0x5c06:jiang1 +0x5c07:jiang1 +0x5c08:zhuan1 +0x5c09:wei4 +0x5c0a:zun1 +0x5c0b:xun2 +0x5c0c:shu4 +0x5c0d:dui4 +0x5c0e:dao3 +0x5c0f:xiao3 +0x5c10:ji1 +0x5c11:shao3 +0x5c12:er3 +0x5c13:er3 +0x5c14:er3 +0x5c15:ga3 +0x5c16:jian1 +0x5c17:shu2 +0x5c18:chen2 +0x5c19:shang4 +0x5c1a:shang4 +0x5c1c:ga2 +0x5c1d:chang2 +0x5c1e:liao4 +0x5c1f:xian3 +0x5c20:xian3 +0x5c22:wang1 +0x5c23:wang1 +0x5c24:you2 +0x5c25:liao4 +0x5c26:liao4 +0x5c27:yao2 +0x5c28:mang2 +0x5c29:wang1 +0x5c2a:wang1 +0x5c2b:wang1 +0x5c2c:ga4 +0x5c2d:yao2 +0x5c2e:duo4 +0x5c2f:kui4 +0x5c30:zhong3 +0x5c31:jiu4 +0x5c32:gan1 +0x5c33:gu3 +0x5c34:gan1 +0x5c35:tui2 +0x5c36:gan1 +0x5c37:gan1 +0x5c38:shi1 +0x5c39:yin3 +0x5c3a:chi3 +0x5c3b:kao1 +0x5c3c:ni2 +0x5c3d:jin3 +0x5c3e:wei3 +0x5c3f:niao4 +0x5c40:ju2 +0x5c41:pi4 +0x5c42:ceng2 +0x5c43:xi4 +0x5c44:bi1 +0x5c45:ju1 +0x5c46:jie4 +0x5c47:tian2 +0x5c48:qu1 +0x5c49:ti4 +0x5c4a:jie4 +0x5c4b:wu1 +0x5c4c:diao3 +0x5c4d:shi1 +0x5c4e:shi3 +0x5c4f:ping2 +0x5c50:ji1 +0x5c51:xie4 +0x5c52:chen2 +0x5c53:xi4 +0x5c54:ni2 +0x5c55:zhan3 +0x5c56:xi1 +0x5c58:man3 +0x5c59:e1 +0x5c5a:lou4 +0x5c5b:ping2 +0x5c5c:ti4 +0x5c5d:fei4 +0x5c5e:shu3 +0x5c5f:xie4 +0x5c60:tu2 +0x5c61:lv3 +0x5c62:lv3 +0x5c63:xi3 +0x5c64:ceng2 +0x5c65:lv3 +0x5c66:ju4 +0x5c67:xie4 +0x5c68:ju4 +0x5c69:jue1 +0x5c6a:liao2 +0x5c6b:jue2 +0x5c6c:shu3 +0x5c6d:xi4 +0x5c6e:che4 +0x5c6f:tun2 +0x5c70:ni4 +0x5c71:shan1 +0x5c73:xian1 +0x5c74:li4 +0x5c75:xue1 +0x5c78:long2 +0x5c79:yi4 +0x5c7a:qi3 +0x5c7b:ren4 +0x5c7c:wu4 +0x5c7d:han4 +0x5c7e:shen1 +0x5c7f:yu3 +0x5c80:chu1 +0x5c81:sui4 +0x5c82:qi3 +0x5c84:yue4 +0x5c85:ban3 +0x5c86:yao3 +0x5c87:ang2 +0x5c88:ya2 +0x5c89:wu4 +0x5c8a:jie2 +0x5c8b:e4 +0x5c8c:ji2 +0x5c8d:qian1 +0x5c8e:fen1 +0x5c8f:yuan2 +0x5c90:qi2 +0x5c91:cen2 +0x5c92:qian2 +0x5c93:qi2 +0x5c94:cha4 +0x5c95:jie4 +0x5c96:qu1 +0x5c97:gang3 +0x5c98:xian4 +0x5c99:ao4 +0x5c9a:lan2 +0x5c9b:dao3 +0x5c9c:ba1 +0x5c9d:zuo4 +0x5c9e:zuo4 +0x5c9f:yang3 +0x5ca0:ju4 +0x5ca1:gang1 +0x5ca2:ke3 +0x5ca3:gou3 +0x5ca4:xue4 +0x5ca5:bei1 +0x5ca6:li4 +0x5ca7:tiao2 +0x5ca8:ju1 +0x5ca9:yan2 +0x5caa:fu2 +0x5cab:xiu4 +0x5cac:jia3 +0x5cad:ling2 +0x5cae:tuo2 +0x5caf:pei1 +0x5cb0:you3 +0x5cb1:dai4 +0x5cb2:kuang4 +0x5cb3:yue4 +0x5cb4:qu1 +0x5cb5:hu4 +0x5cb6:po4 +0x5cb7:min2 +0x5cb8:an4 +0x5cb9:tiao2 +0x5cba:ling2 +0x5cbb:chi2 +0x5cbd:dong1 +0x5cbf:kui1 +0x5cc0:xiu4 +0x5cc1:mao3 +0x5cc2:tong2 +0x5cc3:xue2 +0x5cc4:yi4 +0x5cc6:he1 +0x5cc7:ke1 +0x5cc8:luo4 +0x5cc9:e1 +0x5cca:fu4 +0x5ccb:xun2 +0x5ccc:die2 +0x5ccd:lu4 +0x5cce:an1 +0x5ccf:er3 +0x5cd0:gai1 +0x5cd1:quan2 +0x5cd2:tong2 +0x5cd3:yi2 +0x5cd4:mu3 +0x5cd5:shi2 +0x5cd6:an1 +0x5cd7:wei2 +0x5cd8:hu1 +0x5cd9:zhi4 +0x5cda:mi4 +0x5cdb:li3 +0x5cdc:ji1 +0x5cdd:tong2 +0x5cde:wei2 +0x5cdf:you4 +0x5ce1:xia2 +0x5ce2:li3 +0x5ce3:yao2 +0x5ce4:jiao4 +0x5ce5:zheng1 +0x5ce6:luan2 +0x5ce7:jiao1 +0x5ce8:e2 +0x5ce9:e2 +0x5cea:yu4 +0x5ceb:ye2 +0x5cec:bu1 +0x5ced:qiao4 +0x5cee:qun1 +0x5cef:feng1 +0x5cf0:feng1 +0x5cf1:nao2 +0x5cf2:li3 +0x5cf3:you2 +0x5cf4:xian4 +0x5cf5:hong2 +0x5cf6:dao3 +0x5cf7:shen1 +0x5cf8:cheng2 +0x5cf9:tu2 +0x5cfa:geng3 +0x5cfb:jun4 +0x5cfc:hao4 +0x5cfd:xia2 +0x5cfe:yin1 +0x5cff:yu3 +0x5d00:lang4 +0x5d01:kan3 +0x5d02:lao2 +0x5d03:lai2 +0x5d04:xian3 +0x5d05:que4 +0x5d06:kong1 +0x5d07:chong2 +0x5d08:chong2 +0x5d09:ta4 +0x5d0b:hua2 +0x5d0c:ju1 +0x5d0d:lai2 +0x5d0e:qi2 +0x5d0f:min2 +0x5d10:kun1 +0x5d11:kun1 +0x5d12:zu2 +0x5d13:gu4 +0x5d14:cui1 +0x5d15:ya2 +0x5d16:ya2 +0x5d17:gang3 +0x5d18:lun2 +0x5d19:lun2 +0x5d1a:leng2 +0x5d1b:jue2 +0x5d1c:duo1 +0x5d1d:zheng1 +0x5d1e:guo1 +0x5d1f:yin2 +0x5d20:dong1 +0x5d21:han2 +0x5d22:zheng1 +0x5d23:wei3 +0x5d24:yao2 +0x5d25:pi3 +0x5d26:yan1 +0x5d27:song1 +0x5d28:jie2 +0x5d29:beng1 +0x5d2a:zu2 +0x5d2b:jue2 +0x5d2c:dong1 +0x5d2d:zhan3 +0x5d2e:gu4 +0x5d2f:yin2 +0x5d31:ze2 +0x5d32:huang2 +0x5d33:yu2 +0x5d34:wei1 +0x5d35:yang2 +0x5d36:feng1 +0x5d37:qiu2 +0x5d38:dun4 +0x5d39:ti2 +0x5d3a:yi3 +0x5d3b:zhi4 +0x5d3c:shi4 +0x5d3d:zai3 +0x5d3e:yao3 +0x5d3f:e4 +0x5d40:zhu4 +0x5d41:kan1 +0x5d42:lv4 +0x5d43:yan3 +0x5d44:mei3 +0x5d45:gan1 +0x5d46:ji1 +0x5d47:ji1 +0x5d48:huan3 +0x5d49:ting2 +0x5d4a:sheng4 +0x5d4b:mei2 +0x5d4c:qian4 +0x5d4d:wu4 +0x5d4e:yu2 +0x5d4f:zong1 +0x5d50:lan2 +0x5d51:jue2 +0x5d52:yan2 +0x5d53:yan2 +0x5d54:wei3 +0x5d55:zong1 +0x5d56:cha2 +0x5d57:sui4 +0x5d58:rong2 +0x5d5a:qin1 +0x5d5b:yu2 +0x5d5d:lou3 +0x5d5e:tu2 +0x5d5f:dui1 +0x5d60:xi1 +0x5d61:weng1 +0x5d62:cang1 +0x5d63:dang1 +0x5d64:hong2 +0x5d65:jie2 +0x5d66:ai2 +0x5d67:liu2 +0x5d68:wu3 +0x5d69:song1 +0x5d6a:qiao1 +0x5d6b:zi1 +0x5d6c:wei2 +0x5d6d:beng1 +0x5d6e:dian1 +0x5d6f:cuo2 +0x5d70:qian3 +0x5d71:yong3 +0x5d72:nie4 +0x5d73:cuo2 +0x5d74:ji2 +0x5d77:song3 +0x5d78:zong1 +0x5d79:jiang4 +0x5d7a:liao2 +0x5d7c:chan3 +0x5d7d:die2 +0x5d7e:cen1 +0x5d7f:ding3 +0x5d80:tu1 +0x5d81:lou3 +0x5d82:zhang4 +0x5d83:zhan3 +0x5d84:zhan3 +0x5d85:ao2 +0x5d86:cao2 +0x5d87:qu1 +0x5d88:qiang1 +0x5d89:zui1 +0x5d8a:zui3 +0x5d8b:dao3 +0x5d8c:dao3 +0x5d8d:xi2 +0x5d8e:yu4 +0x5d8f:bo2 +0x5d90:long2 +0x5d91:xiang3 +0x5d92:ceng2 +0x5d93:bo1 +0x5d94:qin1 +0x5d95:jiao1 +0x5d96:yan3 +0x5d97:lao2 +0x5d98:zhan4 +0x5d99:lin2 +0x5d9a:liao2 +0x5d9b:liao2 +0x5d9c:jin1 +0x5d9d:deng4 +0x5d9e:duo4 +0x5d9f:zun1 +0x5da0:jiao4 +0x5da1:gui4 +0x5da2:yao2 +0x5da3:qiao2 +0x5da4:yao2 +0x5da5:jue2 +0x5da6:zhan1 +0x5da7:yi4 +0x5da8:xue2 +0x5da9:nao2 +0x5daa:ye4 +0x5dab:ye4 +0x5dac:yi2 +0x5dad:e4 +0x5dae:xian3 +0x5daf:ji2 +0x5db0:xie4 +0x5db1:ke3 +0x5db2:xi1 +0x5db3:di4 +0x5db4:ao4 +0x5db5:zui3 +0x5db7:yi2 +0x5db8:rong2 +0x5db9:dao3 +0x5dba:ling3 +0x5dbb:za2 +0x5dbc:yu3 +0x5dbd:yue4 +0x5dbe:yin3 +0x5dc0:jie1 +0x5dc1:li4 +0x5dc2:sui3 +0x5dc3:long2 +0x5dc4:long2 +0x5dc5:dian1 +0x5dc6:ying2 +0x5dc7:xi1 +0x5dc8:ju2 +0x5dc9:chan2 +0x5dca:ying3 +0x5dcb:kui1 +0x5dcc:yan2 +0x5dcd:wei1 +0x5dce:nao2 +0x5dcf:quan2 +0x5dd0:chao3 +0x5dd1:cuan2 +0x5dd2:luan2 +0x5dd3:dian1 +0x5dd4:dian1 +0x5dd6:yan2 +0x5dd7:yan2 +0x5dd8:yan3 +0x5dd9:nao2 +0x5dda:yan3 +0x5ddb:chuan1 +0x5ddc:gui4 +0x5ddd:chuan1 +0x5dde:zhou1 +0x5ddf:huang1 +0x5de0:jing1 +0x5de1:xun2 +0x5de2:chao2 +0x5de3:chao2 +0x5de4:lie1 +0x5de5:gong1 +0x5de6:zuo3 +0x5de7:qiao3 +0x5de8:ju4 +0x5de9:gong3 +0x5deb:wu1 +0x5dee:cha4 +0x5def:qiu2 +0x5df0:qiu2 +0x5df1:ji3 +0x5df2:yi3 +0x5df3:si4 +0x5df4:ba1 +0x5df5:zhi1 +0x5df6:zhao1 +0x5df7:xiang4 +0x5df8:yi2 +0x5df9:jin3 +0x5dfa:xun4 +0x5dfb:juan4 +0x5dfd:xun4 +0x5dfe:jin1 +0x5dff:fu2 +0x5e00:za1 +0x5e01:bi4 +0x5e02:shi4 +0x5e03:bu4 +0x5e04:ding1 +0x5e05:shuai4 +0x5e06:fan1 +0x5e07:nie4 +0x5e08:shi1 +0x5e09:fen1 +0x5e0a:pa4 +0x5e0b:zhi3 +0x5e0c:xi1 +0x5e0d:hu4 +0x5e0e:dan4 +0x5e0f:wei2 +0x5e10:zhang4 +0x5e11:tang3 +0x5e12:dai4 +0x5e13:ma4 +0x5e14:pei4 +0x5e15:pa4 +0x5e16:tie1 +0x5e17:fu2 +0x5e18:lian2 +0x5e19:zhi4 +0x5e1a:zhou3 +0x5e1b:bo2 +0x5e1c:zhi4 +0x5e1d:di4 +0x5e1e:mo4 +0x5e1f:yi4 +0x5e20:yi4 +0x5e21:ping2 +0x5e22:qia4 +0x5e23:juan4 +0x5e24:ru2 +0x5e25:shuai4 +0x5e26:dai4 +0x5e27:zheng4 +0x5e28:shui4 +0x5e29:qiao4 +0x5e2a:zhen1 +0x5e2b:shi1 +0x5e2c:qun2 +0x5e2d:xi2 +0x5e2e:bang1 +0x5e2f:dai4 +0x5e30:gui1 +0x5e31:chou2 +0x5e32:ping2 +0x5e33:zhang4 +0x5e34:sha1 +0x5e35:wan1 +0x5e36:dai4 +0x5e37:wei2 +0x5e38:chang2 +0x5e39:sha4 +0x5e3a:qi2 +0x5e3b:ze2 +0x5e3c:guo2 +0x5e3d:mao4 +0x5e3e:du3 +0x5e3f:hou2 +0x5e40:zheng4 +0x5e41:xu1 +0x5e42:mi4 +0x5e43:wei2 +0x5e44:wo4 +0x5e45:fu2 +0x5e46:yi4 +0x5e47:bang1 +0x5e48:ping2 +0x5e4a:gong1 +0x5e4b:pan2 +0x5e4c:huang3 +0x5e4d:dao1 +0x5e4e:mi4 +0x5e4f:jia1 +0x5e50:teng2 +0x5e51:hui1 +0x5e52:zhong1 +0x5e53:shan1 +0x5e54:man4 +0x5e55:mu4 +0x5e56:biao1 +0x5e57:guo2 +0x5e58:ze2 +0x5e59:mu4 +0x5e5a:bang1 +0x5e5b:zhang4 +0x5e5c:jiong3 +0x5e5d:chan3 +0x5e5e:fu2 +0x5e5f:zhi4 +0x5e60:hu1 +0x5e61:fan1 +0x5e62:chuang2 +0x5e63:bi4 +0x5e66:mi4 +0x5e67:qiao1 +0x5e68:chan1 +0x5e69:fen2 +0x5e6a:meng2 +0x5e6b:bang1 +0x5e6c:chou2 +0x5e6d:mie4 +0x5e6e:chu2 +0x5e6f:jie2 +0x5e70:xian3 +0x5e71:lan2 +0x5e72:gan1 +0x5e73:ping2 +0x5e74:nian2 +0x5e75:qian1 +0x5e76:bing4 +0x5e77:bing4 +0x5e78:xing4 +0x5e79:gan4 +0x5e7a:yao1 +0x5e7b:huan4 +0x5e7c:you4 +0x5e7d:you1 +0x5e7e:ji3 +0x5e7f:guang3 +0x5e80:pi3 +0x5e81:ting1 +0x5e82:ze4 +0x5e83:guang3 +0x5e84:zhuang1 +0x5e85:mo5 +0x5e86:qing4 +0x5e87:bi4 +0x5e88:qin2 +0x5e89:dun4 +0x5e8a:chuang2 +0x5e8b:gui3 +0x5e8c:ya3 +0x5e8d:bai4 +0x5e8e:jie4 +0x5e8f:xu4 +0x5e90:lu2 +0x5e91:wu3 +0x5e93:ku4 +0x5e94:ying4 +0x5e95:di3 +0x5e96:pao2 +0x5e97:dian4 +0x5e98:ya1 +0x5e99:miao4 +0x5e9a:geng1 +0x5e9b:ci1 +0x5e9c:fu3 +0x5e9d:tong2 +0x5e9e:pang2 +0x5e9f:fei4 +0x5ea0:xiang2 +0x5ea1:yi3 +0x5ea2:zhi4 +0x5ea3:tiao1 +0x5ea4:zhi4 +0x5ea5:xiu1 +0x5ea6:du4 +0x5ea7:zuo4 +0x5ea8:xiao1 +0x5ea9:tu2 +0x5eaa:gui3 +0x5eab:ku4 +0x5eac:pang2 +0x5ead:ting2 +0x5eae:you3 +0x5eaf:bu1 +0x5eb0:ding1 +0x5eb1:cheng3 +0x5eb2:lai2 +0x5eb3:bei1 +0x5eb4:ji2 +0x5eb5:an1 +0x5eb6:shu4 +0x5eb7:kang1 +0x5eb8:yong1 +0x5eb9:tuo3 +0x5eba:song1 +0x5ebb:shu4 +0x5ebc:qing3 +0x5ebd:yu4 +0x5ebe:yu3 +0x5ebf:miao4 +0x5ec0:sou1 +0x5ec1:ce4 +0x5ec2:xiang1 +0x5ec3:fei4 +0x5ec4:jiu4 +0x5ec5:he2 +0x5ec6:hui4 +0x5ec7:liu4 +0x5ec8:sha4 +0x5ec9:lian2 +0x5eca:lang2 +0x5ecb:sou1 +0x5ecc:zhi4 +0x5ecd:pou3 +0x5ece:qing3 +0x5ecf:jiu4 +0x5ed0:jiu4 +0x5ed1:jin3 +0x5ed2:ao2 +0x5ed3:kuo4 +0x5ed4:lou2 +0x5ed5:yin4 +0x5ed6:liao4 +0x5ed7:dai4 +0x5ed8:lu4 +0x5ed9:yi4 +0x5eda:chu2 +0x5edb:chan2 +0x5edc:tu1 +0x5edd:si1 +0x5ede:xin1 +0x5edf:miao4 +0x5ee0:chang3 +0x5ee1:wu3 +0x5ee2:fei4 +0x5ee3:guang3 +0x5ee5:kuai4 +0x5ee6:bi4 +0x5ee7:qiang2 +0x5ee8:xie4 +0x5ee9:lin3 +0x5eea:lin3 +0x5eeb:liao2 +0x5eec:lu2 +0x5eee:ying2 +0x5eef:xian1 +0x5ef0:ting1 +0x5ef1:yong1 +0x5ef2:li2 +0x5ef3:ting1 +0x5ef4:yin3 +0x5ef5:xun2 +0x5ef6:yan2 +0x5ef7:ting2 +0x5ef8:di2 +0x5ef9:po4 +0x5efa:jian4 +0x5efb:hui2 +0x5efc:nai3 +0x5efd:hui2 +0x5efe:gong3 +0x5eff:nian4 +0x5f00:kai1 +0x5f01:bian4 +0x5f02:yi4 +0x5f03:qi4 +0x5f04:nong4 +0x5f05:fen2 +0x5f06:ju3 +0x5f07:yan3 +0x5f08:yi4 +0x5f09:zang4 +0x5f0a:bi4 +0x5f0b:yi4 +0x5f0c:yi1 +0x5f0d:er4 +0x5f0e:san1 +0x5f0f:shi4 +0x5f10:er4 +0x5f11:shi4 +0x5f12:shi4 +0x5f13:gong1 +0x5f14:diao4 +0x5f15:yin3 +0x5f16:hu4 +0x5f17:fu2 +0x5f18:hong2 +0x5f19:wu1 +0x5f1a:tui2 +0x5f1b:chi2 +0x5f1c:jiang4 +0x5f1d:ba4 +0x5f1e:shen3 +0x5f1f:di4 +0x5f20:zhang1 +0x5f21:jue2 +0x5f22:tao1 +0x5f23:fu3 +0x5f24:di3 +0x5f25:mi2 +0x5f26:xian2 +0x5f27:hu2 +0x5f28:chao1 +0x5f29:nu3 +0x5f2a:jing4 +0x5f2b:zhen3 +0x5f2c:yi2 +0x5f2d:mi3 +0x5f2e:quan1 +0x5f2f:wan1 +0x5f30:shao1 +0x5f31:ruo4 +0x5f32:xuan1 +0x5f33:jing4 +0x5f34:dun1 +0x5f35:zhang1 +0x5f36:jiang4 +0x5f37:qiang2 +0x5f38:peng2 +0x5f39:dan4 +0x5f3a:qiang2 +0x5f3b:bi4 +0x5f3c:bi4 +0x5f3d:she4 +0x5f3e:dan4 +0x5f3f:jian3 +0x5f40:gou4 +0x5f42:fa1 +0x5f43:bi4 +0x5f44:kou1 +0x5f46:bie4 +0x5f47:xiao1 +0x5f48:dan4 +0x5f49:kuo4 +0x5f4a:qiang2 +0x5f4b:hong2 +0x5f4c:mi2 +0x5f4d:kuo4 +0x5f4e:wan1 +0x5f4f:jue2 +0x5f50:ji4 +0x5f51:ji4 +0x5f52:gui1 +0x5f53:dang1 +0x5f54:lu4 +0x5f55:lu4 +0x5f56:tuan4 +0x5f57:hui4 +0x5f58:zhi4 +0x5f59:hui4 +0x5f5a:hui4 +0x5f5b:yi2 +0x5f5c:yi2 +0x5f5d:yi2 +0x5f5e:yi2 +0x5f5f:huo4 +0x5f60:huo4 +0x5f61:shan1 +0x5f62:xing2 +0x5f63:wen2 +0x5f64:tong2 +0x5f65:yan4 +0x5f66:yan4 +0x5f67:yu4 +0x5f68:chi1 +0x5f69:cai3 +0x5f6a:biao1 +0x5f6b:diao1 +0x5f6c:bin1 +0x5f6d:peng2 +0x5f6e:yong3 +0x5f6f:piao1 +0x5f70:zhang1 +0x5f71:ying3 +0x5f72:chi1 +0x5f73:chi4 +0x5f74:zhuo2 +0x5f75:tuo3 +0x5f76:ji2 +0x5f77:pang2 +0x5f78:zhong1 +0x5f79:yi4 +0x5f7a:wang2 +0x5f7b:che4 +0x5f7c:bi3 +0x5f7d:chi2 +0x5f7e:ling3 +0x5f7f:fu2 +0x5f80:wang3 +0x5f81:zheng1 +0x5f82:cu2 +0x5f83:wang3 +0x5f84:jing4 +0x5f85:dai4 +0x5f86:xi1 +0x5f87:xun4 +0x5f88:hen3 +0x5f89:yang2 +0x5f8a:huai2 +0x5f8b:lv4 +0x5f8c:hou4 +0x5f8d:wa1 +0x5f8e:cheng3 +0x5f8f:zhi4 +0x5f90:xu2 +0x5f91:jing4 +0x5f92:tu2 +0x5f93:cong2 +0x5f95:lai2 +0x5f96:cong2 +0x5f97:de2 +0x5f98:pai2 +0x5f99:xi3 +0x5f9b:qi4 +0x5f9c:chang2 +0x5f9d:zhi4 +0x5f9e:cong2 +0x5f9f:zhou1 +0x5fa0:lai2 +0x5fa1:yu4 +0x5fa2:xie4 +0x5fa3:jie4 +0x5fa4:jian4 +0x5fa5:chi2 +0x5fa6:jia3 +0x5fa7:bian4 +0x5fa8:huang2 +0x5fa9:fu4 +0x5faa:xun2 +0x5fab:wei3 +0x5fac:pang2 +0x5fad:yao2 +0x5fae:wei1 +0x5faf:xi1 +0x5fb0:zheng1 +0x5fb1:piao4 +0x5fb2:chi2 +0x5fb3:de2 +0x5fb4:zheng1 +0x5fb5:zheng1 +0x5fb6:bie4 +0x5fb7:de2 +0x5fb8:chong1 +0x5fb9:che4 +0x5fba:jiao3 +0x5fbb:wei4 +0x5fbc:jiao4 +0x5fbd:hui1 +0x5fbe:mei2 +0x5fbf:long4 +0x5fc0:xiang1 +0x5fc1:bao4 +0x5fc2:qu2 +0x5fc3:xin1 +0x5fc5:bi4 +0x5fc6:yi4 +0x5fc7:le4 +0x5fc8:ren2 +0x5fc9:dao1 +0x5fca:ding4 +0x5fcb:gai3 +0x5fcc:ji4 +0x5fcd:ren3 +0x5fce:ren2 +0x5fcf:chan4 +0x5fd0:tan3 +0x5fd1:te4 +0x5fd2:te4 +0x5fd3:gan1 +0x5fd4:qi4 +0x5fd5:shi4 +0x5fd6:cun3 +0x5fd7:zhi4 +0x5fd8:wang4 +0x5fd9:mang2 +0x5fda:xi1 +0x5fdb:fan2 +0x5fdc:ying1 +0x5fdd:tian3 +0x5fde:min2 +0x5fdf:min2 +0x5fe0:zhong1 +0x5fe1:chong1 +0x5fe2:wu4 +0x5fe3:ji2 +0x5fe4:wu3 +0x5fe5:xi4 +0x5fe6:ye4 +0x5fe7:you1 +0x5fe8:wan4 +0x5fe9:cong1 +0x5fea:zhong1 +0x5feb:kuai4 +0x5fec:yu4 +0x5fed:bian4 +0x5fee:zhi4 +0x5fef:qi2 +0x5ff0:cui4 +0x5ff1:chen2 +0x5ff2:tai4 +0x5ff3:tun2 +0x5ff4:qian2 +0x5ff5:nian4 +0x5ff6:hun2 +0x5ff7:xiong1 +0x5ff8:niu3 +0x5ff9:wang3 +0x5ffa:xian1 +0x5ffb:xin1 +0x5ffc:kang1 +0x5ffd:hu1 +0x5ffe:kai4 +0x5fff:fen4 +0x6000:huai2 +0x6001:tai4 +0x6002:song3 +0x6003:wu3 +0x6004:ou4 +0x6005:chang4 +0x6006:chuang4 +0x6007:ju4 +0x6008:yi4 +0x6009:bao3 +0x600a:chao1 +0x600b:min2 +0x600c:pei1 +0x600d:zuo4 +0x600e:zen3 +0x600f:yang4 +0x6010:kou4 +0x6011:ban4 +0x6012:nu4 +0x6013:nao2 +0x6014:zheng1 +0x6015:pa4 +0x6016:bu4 +0x6017:tie1 +0x6018:gu4 +0x6019:hu4 +0x601a:ju4 +0x601b:da2 +0x601c:lian2 +0x601d:si1 +0x601e:chou1 +0x601f:di4 +0x6020:dai4 +0x6021:yi2 +0x6022:tu2 +0x6023:you2 +0x6024:fu1 +0x6025:ji2 +0x6026:peng1 +0x6027:xing4 +0x6028:yuan4 +0x6029:ni2 +0x602a:guai4 +0x602b:fu2 +0x602c:xi4 +0x602d:bi4 +0x602e:you1 +0x602f:qie4 +0x6030:xuan4 +0x6031:cong1 +0x6032:bing3 +0x6033:huang3 +0x6034:xu4 +0x6035:chu4 +0x6036:pi1 +0x6037:xi1 +0x6038:xi1 +0x6039:tan1 +0x603b:zong3 +0x603c:dui4 +0x603f:yi4 +0x6040:chi3 +0x6041:ren4 +0x6042:xun2 +0x6043:shi4 +0x6044:xi4 +0x6045:lao3 +0x6046:heng2 +0x6047:kuang1 +0x6048:mu2 +0x6049:zhi3 +0x604a:xie2 +0x604b:lian4 +0x604c:tiao1 +0x604d:huang3 +0x604e:die2 +0x604f:hao3 +0x6050:kong3 +0x6051:gui3 +0x6052:heng2 +0x6053:xi1 +0x6054:xiao4 +0x6055:shu4 +0x6057:kua3 +0x6058:qiu1 +0x6059:yang4 +0x605a:hui4 +0x605b:hui2 +0x605c:chi4 +0x605d:jia2 +0x605e:yi2 +0x605f:xiong1 +0x6060:guai4 +0x6061:lin4 +0x6062:hui1 +0x6063:zi4 +0x6064:xu4 +0x6065:chi3 +0x6066:xiang4 +0x6067:nv4 +0x6068:hen4 +0x6069:en1 +0x606a:ke4 +0x606b:tong1 +0x606c:tian2 +0x606d:gong1 +0x606e:quan2 +0x606f:xi1 +0x6070:qia4 +0x6071:yue4 +0x6072:peng1 +0x6073:ken3 +0x6074:de2 +0x6075:hui4 +0x6076:e4 +0x6078:tong4 +0x6079:yan4 +0x607a:kai3 +0x607b:ce4 +0x607c:nao3 +0x607d:yun4 +0x607e:mang2 +0x607f:yong3 +0x6080:yong3 +0x6081:yuan1 +0x6082:pi1 +0x6083:kun3 +0x6084:qiao3 +0x6085:yue4 +0x6086:yu4 +0x6087:yu4 +0x6088:jie4 +0x6089:xi1 +0x608a:zhe2 +0x608b:lin4 +0x608c:ti4 +0x608d:han4 +0x608e:hao4 +0x608f:qie4 +0x6090:ti4 +0x6091:bu4 +0x6092:yi4 +0x6093:qian4 +0x6094:hui3 +0x6095:xi1 +0x6096:bei4 +0x6097:man2 +0x6098:yi1 +0x6099:heng1 +0x609a:song3 +0x609b:quan1 +0x609c:cheng3 +0x609d:kui1 +0x609e:wu4 +0x609f:wu4 +0x60a0:you1 +0x60a1:li2 +0x60a2:liang4 +0x60a3:huan4 +0x60a4:cong1 +0x60a5:yi4 +0x60a6:yue4 +0x60a7:li4 +0x60a8:nin2 +0x60a9:nao3 +0x60aa:e4 +0x60ab:que4 +0x60ac:xuan2 +0x60ad:qian1 +0x60ae:wu4 +0x60af:min3 +0x60b0:cong2 +0x60b1:fei3 +0x60b2:bei1 +0x60b3:duo2 +0x60b4:cui4 +0x60b5:chang4 +0x60b6:men4 +0x60b7:li4 +0x60b8:ji4 +0x60b9:guan4 +0x60ba:guan4 +0x60bb:xing4 +0x60bc:dao4 +0x60bd:qi1 +0x60be:kong1 +0x60bf:tian3 +0x60c0:lun2 +0x60c1:xi1 +0x60c2:kan3 +0x60c3:kun1 +0x60c4:ni4 +0x60c5:qing2 +0x60c6:chou2 +0x60c7:dun1 +0x60c8:guo3 +0x60c9:chan1 +0x60ca:liang2 +0x60cb:wan3 +0x60cc:yuan1 +0x60cd:jin1 +0x60ce:ji4 +0x60cf:lin2 +0x60d0:yu4 +0x60d1:huo4 +0x60d2:he2 +0x60d3:quan2 +0x60d4:tan2 +0x60d5:ti4 +0x60d6:ti4 +0x60d7:nie1 +0x60d8:wang3 +0x60d9:chuo4 +0x60da:hu1 +0x60db:hun1 +0x60dc:xi1 +0x60dd:chang3 +0x60de:xin1 +0x60df:wei2 +0x60e0:hui4 +0x60e1:e4 +0x60e2:rui3 +0x60e3:zong3 +0x60e4:jian1 +0x60e5:yong3 +0x60e6:dian4 +0x60e7:ju4 +0x60e8:can3 +0x60e9:cheng2 +0x60ea:de2 +0x60eb:bei4 +0x60ec:qie4 +0x60ed:can2 +0x60ee:dan4 +0x60ef:guan4 +0x60f0:duo4 +0x60f1:nao3 +0x60f2:yun4 +0x60f3:xiang3 +0x60f4:zhui4 +0x60f5:die4 +0x60f6:huang2 +0x60f7:chun3 +0x60f8:qiong2 +0x60f9:re3 +0x60fa:xing1 +0x60fb:ce4 +0x60fc:bian3 +0x60fd:hun1 +0x60fe:zong1 +0x60ff:ti2 +0x6100:qiao3 +0x6101:chou2 +0x6102:bei4 +0x6103:xuan1 +0x6104:wei1 +0x6105:ge2 +0x6106:qian1 +0x6107:wei3 +0x6108:yu4 +0x6109:yu2 +0x610a:bi4 +0x610b:xuan1 +0x610c:huan4 +0x610d:min3 +0x610e:bi4 +0x610f:yi4 +0x6110:mian3 +0x6111:yong3 +0x6112:kai4 +0x6113:dang4 +0x6114:yin1 +0x6115:e4 +0x6116:chen2 +0x6117:mou4 +0x6118:ke4 +0x6119:ke4 +0x611a:yu2 +0x611b:ai4 +0x611c:qie4 +0x611d:yan3 +0x611e:nuo4 +0x611f:gan3 +0x6120:yun4 +0x6121:zong3 +0x6122:sai1 +0x6123:leng4 +0x6124:fen4 +0x6126:kui4 +0x6127:kui4 +0x6128:que4 +0x6129:gong1 +0x612a:yun2 +0x612b:su4 +0x612c:su4 +0x612d:qi2 +0x612e:yao2 +0x612f:song3 +0x6130:huang3 +0x6131:ji2 +0x6132:gu3 +0x6133:ju4 +0x6134:chuang4 +0x6135:ni4 +0x6136:xie2 +0x6137:kai3 +0x6138:zheng3 +0x6139:yong3 +0x613a:cao3 +0x613b:sun4 +0x613c:shen4 +0x613d:bo2 +0x613e:kai4 +0x613f:yuan4 +0x6140:xie2 +0x6141:hun4 +0x6142:yong3 +0x6143:yang3 +0x6144:li4 +0x6145:sao1 +0x6146:tao1 +0x6147:yin1 +0x6148:ci2 +0x6149:xu4 +0x614a:qian4 +0x614b:tai4 +0x614c:huang1 +0x614d:yun4 +0x614e:shen4 +0x614f:ming3 +0x6151:she4 +0x6152:cong2 +0x6153:piao4 +0x6154:mo4 +0x6155:mu4 +0x6156:guo2 +0x6157:chi4 +0x6158:can3 +0x6159:can2 +0x615a:can2 +0x615b:cui2 +0x615c:min3 +0x615d:te4 +0x615e:zhang1 +0x615f:tong4 +0x6160:ao4 +0x6161:shuang3 +0x6162:man4 +0x6163:guan4 +0x6164:que4 +0x6165:zao4 +0x6166:jiu4 +0x6167:hui4 +0x6168:kai3 +0x6169:lian2 +0x616a:ou4 +0x616b:song3 +0x616c:jin3 +0x616d:yin4 +0x616e:lv4 +0x616f:shang1 +0x6170:wei4 +0x6171:tuan2 +0x6172:man2 +0x6173:qian1 +0x6174:she4 +0x6175:yong1 +0x6176:qing4 +0x6177:kang1 +0x6178:di4 +0x6179:zhi2 +0x617a:lou2 +0x617b:juan4 +0x617c:qi1 +0x617d:qi1 +0x617e:yu4 +0x617f:ping2 +0x6180:liao2 +0x6181:cong1 +0x6182:you1 +0x6183:chong1 +0x6184:zhi4 +0x6185:tong4 +0x6186:cheng1 +0x6187:qi4 +0x6188:qu1 +0x6189:peng2 +0x618a:bei4 +0x618b:bie1 +0x618c:chun2 +0x618d:jiao1 +0x618e:zeng1 +0x618f:chi4 +0x6190:lian2 +0x6191:ping2 +0x6192:kui4 +0x6193:hui4 +0x6194:qiao2 +0x6195:cheng2 +0x6196:yin4 +0x6197:yin4 +0x6198:xi3 +0x6199:xi3 +0x619a:dan4 +0x619b:tan2 +0x619c:duo3 +0x619d:dui4 +0x619e:dui4 +0x619f:su4 +0x61a0:jue2 +0x61a1:ce4 +0x61a2:xiao1 +0x61a3:fan2 +0x61a4:fen4 +0x61a5:lao2 +0x61a6:lao4 +0x61a7:chong1 +0x61a8:han1 +0x61a9:qi4 +0x61aa:xian2 +0x61ab:min3 +0x61ac:jing3 +0x61ad:liao3 +0x61ae:wu3 +0x61af:can3 +0x61b0:jue2 +0x61b1:cu4 +0x61b2:xian4 +0x61b3:tan3 +0x61b4:sheng2 +0x61b5:pi1 +0x61b6:yi4 +0x61b7:chu3 +0x61b8:xian1 +0x61b9:nao2 +0x61ba:dan4 +0x61bb:tan3 +0x61bc:jing3 +0x61bd:song1 +0x61be:han4 +0x61bf:jiao1 +0x61c0:wai4 +0x61c1:huan2 +0x61c2:dong3 +0x61c3:qin2 +0x61c4:qin2 +0x61c5:qu2 +0x61c6:cao3 +0x61c7:ken3 +0x61c8:xie4 +0x61c9:ying1 +0x61ca:ao4 +0x61cb:mao4 +0x61cc:yi4 +0x61cd:lin3 +0x61ce:se4 +0x61cf:jun4 +0x61d0:huai2 +0x61d1:men4 +0x61d2:lan3 +0x61d3:ai4 +0x61d4:lin3 +0x61d5:yan1 +0x61d6:gua1 +0x61d7:xia4 +0x61d8:chi4 +0x61d9:yu3 +0x61da:yin4 +0x61db:dai1 +0x61dc:meng4 +0x61dd:ai4 +0x61de:meng2 +0x61df:dui4 +0x61e0:qi2 +0x61e1:mo3 +0x61e2:lan2 +0x61e3:men4 +0x61e4:chou2 +0x61e5:zhi4 +0x61e6:nuo4 +0x61e7:nuo4 +0x61e8:yan1 +0x61e9:yang3 +0x61ea:bo2 +0x61eb:zhi2 +0x61ec:kuang4 +0x61ed:kuang4 +0x61ee:you3 +0x61ef:fu1 +0x61f0:liu2 +0x61f1:mie4 +0x61f2:cheng2 +0x61f4:chan4 +0x61f5:meng3 +0x61f6:lan3 +0x61f7:huai2 +0x61f8:xuan2 +0x61f9:rang4 +0x61fa:chan4 +0x61fb:ji4 +0x61fc:ju4 +0x61fd:huan1 +0x61fe:she4 +0x61ff:yi4 +0x6200:lian4 +0x6201:nan3 +0x6202:mi2 +0x6203:tang3 +0x6204:jue2 +0x6205:gang4 +0x6206:gang4 +0x6207:gang4 +0x6208:ge1 +0x6209:yue4 +0x620a:wu4 +0x620b:jian1 +0x620c:xu1 +0x620d:shu4 +0x620e:rong2 +0x620f:xi4 +0x6210:cheng2 +0x6211:wo3 +0x6212:jie4 +0x6213:ge1 +0x6214:jian1 +0x6215:qiang1 +0x6216:huo4 +0x6217:qiang1 +0x6218:zhan4 +0x6219:dong4 +0x621a:qi1 +0x621b:jia2 +0x621c:die2 +0x621d:zei2 +0x621e:jia2 +0x621f:ji3 +0x6220:shi4 +0x6221:kan1 +0x6222:ji2 +0x6223:kui2 +0x6224:gai4 +0x6225:deng3 +0x6226:zhan4 +0x6227:chuang1 +0x6228:ge1 +0x6229:jian3 +0x622a:jie2 +0x622b:yu4 +0x622c:jian3 +0x622d:yan3 +0x622e:lu4 +0x622f:xi4 +0x6230:zhan4 +0x6231:xi4 +0x6232:xi4 +0x6233:chuo1 +0x6234:dai4 +0x6235:qu2 +0x6236:hu4 +0x6237:hu4 +0x6238:hu4 +0x6239:e4 +0x623a:shi4 +0x623b:li4 +0x623c:mao3 +0x623d:hu4 +0x623e:li4 +0x623f:fang2 +0x6240:suo3 +0x6241:bian3 +0x6242:dian4 +0x6243:jiong1 +0x6244:shang3 +0x6245:yi2 +0x6246:yi3 +0x6247:shan4 +0x6248:hu4 +0x6249:fei1 +0x624a:yan3 +0x624b:shou3 +0x624d:cai2 +0x624e:zha1 +0x624f:qiu2 +0x6250:le4 +0x6251:pu1 +0x6252:ba1 +0x6253:da3 +0x6254:reng1 +0x6255:fu2 +0x6257:zai4 +0x6258:tuo1 +0x6259:zhang4 +0x625a:diao1 +0x625b:kang2 +0x625c:yu1 +0x625d:ku1 +0x625e:han4 +0x625f:shen1 +0x6260:cha1 +0x6261:yi3 +0x6262:gu3 +0x6263:kou4 +0x6264:wu4 +0x6265:tuo1 +0x6266:qian1 +0x6267:zhi2 +0x6268:ren4 +0x6269:kuo4 +0x626a:men2 +0x626b:sao3 +0x626c:yang2 +0x626d:niu3 +0x626e:ban4 +0x626f:che3 +0x6270:rao3 +0x6271:xi1 +0x6272:qian2 +0x6273:ban1 +0x6274:jia2 +0x6275:yu2 +0x6276:fu2 +0x6277:ao4 +0x6278:xi1 +0x6279:pi1 +0x627a:zhi3 +0x627b:zi4 +0x627c:e4 +0x627d:dun4 +0x627e:zhao3 +0x627f:cheng2 +0x6280:ji4 +0x6281:yan3 +0x6282:kuang2 +0x6283:bian4 +0x6284:chao1 +0x6285:ju1 +0x6286:wen4 +0x6287:hu2 +0x6288:yue4 +0x6289:jue2 +0x628a:ba3 +0x628b:qin4 +0x628c:zhen3 +0x628d:zheng3 +0x628e:yun3 +0x628f:wan2 +0x6290:nu4 +0x6291:yi4 +0x6292:shu1 +0x6293:zhua1 +0x6294:pou2 +0x6295:tou2 +0x6296:dou3 +0x6297:kang4 +0x6298:zhe2 +0x6299:pou2 +0x629a:fu3 +0x629b:pao1 +0x629c:ba2 +0x629d:ao3 +0x629e:ze2 +0x629f:tuan2 +0x62a0:kou1 +0x62a1:lun2 +0x62a2:qiang3 +0x62a4:hu4 +0x62a5:bao4 +0x62a6:bing3 +0x62a7:zhi3 +0x62a8:peng1 +0x62a9:tan1 +0x62aa:pu1 +0x62ab:pi1 +0x62ac:tai2 +0x62ad:yao3 +0x62ae:zhen3 +0x62af:zha1 +0x62b0:yang3 +0x62b1:bao4 +0x62b2:he1 +0x62b3:ni3 +0x62b4:yi4 +0x62b5:di3 +0x62b6:chi4 +0x62b7:pi1 +0x62b8:za1 +0x62b9:mo3 +0x62ba:mei4 +0x62bb:shen4 +0x62bc:ya1 +0x62bd:chou1 +0x62be:qu1 +0x62bf:min3 +0x62c0:chu4 +0x62c1:jia1 +0x62c2:fu2 +0x62c3:zhan3 +0x62c4:zhu3 +0x62c5:dan4 +0x62c6:chai1 +0x62c7:mu3 +0x62c8:nian2 +0x62c9:la1 +0x62ca:fu3 +0x62cb:pao1 +0x62cc:ban4 +0x62cd:pai1 +0x62ce:ling1 +0x62cf:na2 +0x62d0:guai3 +0x62d1:qian2 +0x62d2:ju4 +0x62d3:tuo4 +0x62d4:ba2 +0x62d5:tuo1 +0x62d6:tuo1 +0x62d7:ao3 +0x62d8:ju1 +0x62d9:zhuo2 +0x62da:pan4 +0x62db:zhao1 +0x62dc:bai4 +0x62dd:bai4 +0x62de:di3 +0x62df:ni3 +0x62e0:ju4 +0x62e1:kuo4 +0x62e2:long3 +0x62e3:jian3 +0x62e5:yong3 +0x62e6:lan2 +0x62e7:ning2 +0x62e8:bo1 +0x62e9:ze2 +0x62ea:qian1 +0x62eb:hen2 +0x62ec:kuo4 +0x62ed:shi4 +0x62ee:jie2 +0x62ef:zheng3 +0x62f0:nin3 +0x62f1:gong3 +0x62f2:gong3 +0x62f3:quan2 +0x62f4:shuan1 +0x62f5:cun2 +0x62f6:zan3 +0x62f7:kao3 +0x62f8:chi3 +0x62f9:xie2 +0x62fa:ce4 +0x62fb:hui1 +0x62fc:pin1 +0x62fd:ye4 +0x62fe:shi2 +0x62ff:na2 +0x6300:bo4 +0x6301:chi2 +0x6302:gua4 +0x6303:zhi4 +0x6304:kuo4 +0x6305:duo3 +0x6306:duo3 +0x6307:zhi3 +0x6308:qie4 +0x6309:an4 +0x630a:nong4 +0x630b:zhen4 +0x630c:ge2 +0x630d:jiao4 +0x630e:ku1 +0x630f:dong4 +0x6310:ru2 +0x6311:tiao1 +0x6312:lie4 +0x6313:zha1 +0x6314:lv3 +0x6315:die2 +0x6316:wa1 +0x6317:jue2 +0x6319:ju3 +0x631a:zhi4 +0x631b:luan2 +0x631c:ya4 +0x631d:zhua1 +0x631e:ta4 +0x631f:xie2 +0x6320:nao2 +0x6321:dang3 +0x6322:jiao3 +0x6323:zheng1 +0x6324:ji3 +0x6325:hui1 +0x6326:xun2 +0x6328:ai1 +0x6329:tuo1 +0x632a:nuo2 +0x632b:cuo4 +0x632c:bo2 +0x632d:geng3 +0x632e:ti3 +0x632f:zhen4 +0x6330:cheng2 +0x6331:suo1 +0x6332:suo1 +0x6333:keng1 +0x6334:mei3 +0x6335:long4 +0x6336:ju2 +0x6337:peng2 +0x6338:jian3 +0x6339:yi4 +0x633a:ting3 +0x633b:shan1 +0x633c:nuo4 +0x633d:wan3 +0x633e:xie2 +0x633f:cha1 +0x6340:feng1 +0x6341:jiao3 +0x6342:wu3 +0x6343:jun4 +0x6344:jiu4 +0x6345:tong3 +0x6346:kun3 +0x6347:huo4 +0x6348:tu2 +0x6349:zhuo1 +0x634a:pou2 +0x634b:le4 +0x634c:ba1 +0x634d:han4 +0x634e:shao1 +0x634f:nie1 +0x6350:juan1 +0x6351:ze2 +0x6352:song3 +0x6353:ye2 +0x6354:jue2 +0x6355:bu3 +0x6356:huan2 +0x6357:bu4 +0x6358:zun4 +0x6359:yi4 +0x635a:zhai1 +0x635b:lv3 +0x635c:sou1 +0x635d:tuo1 +0x635e:lao1 +0x635f:sun3 +0x6360:bang1 +0x6361:jian3 +0x6362:huan4 +0x6363:dao3 +0x6365:wan4 +0x6366:qin2 +0x6367:peng3 +0x6368:she3 +0x6369:lie4 +0x636a:min2 +0x636b:men2 +0x636c:fu3 +0x636d:bai3 +0x636e:ju4 +0x636f:dao3 +0x6370:wo3 +0x6371:ai2 +0x6372:juan3 +0x6373:yue4 +0x6374:zong3 +0x6375:chen3 +0x6376:chui2 +0x6377:jie2 +0x6378:tu1 +0x6379:ben4 +0x637a:na4 +0x637b:nian3 +0x637c:nuo2 +0x637d:zu2 +0x637e:wo4 +0x637f:xi1 +0x6380:xian1 +0x6381:cheng2 +0x6382:dian1 +0x6383:sao3 +0x6384:lun1 +0x6385:qing4 +0x6386:gang1 +0x6387:duo2 +0x6388:shou4 +0x6389:diao4 +0x638a:pou2 +0x638b:di3 +0x638c:zhang3 +0x638d:gun3 +0x638e:ji3 +0x638f:tao1 +0x6390:qia1 +0x6391:qi2 +0x6392:pai2 +0x6393:shu2 +0x6394:qian1 +0x6395:ling4 +0x6396:ye4 +0x6397:ya4 +0x6398:jue2 +0x6399:zheng1 +0x639a:liang3 +0x639b:gua4 +0x639c:yi3 +0x639d:huo4 +0x639e:shan4 +0x639f:zheng3 +0x63a0:lve4 +0x63a1:cai3 +0x63a2:tan4 +0x63a3:che4 +0x63a4:bing1 +0x63a5:jie1 +0x63a6:ti4 +0x63a7:kong4 +0x63a8:tui1 +0x63a9:yan3 +0x63aa:cuo4 +0x63ab:zou1 +0x63ac:ju2 +0x63ad:tian4 +0x63ae:qian2 +0x63af:ken4 +0x63b0:bai1 +0x63b1:shou3 +0x63b2:jie1 +0x63b3:lu3 +0x63b4:guo2 +0x63b7:zhi2 +0x63b8:dan3 +0x63ba:xian1 +0x63bb:sao1 +0x63bc:guan4 +0x63bd:peng4 +0x63be:yuan4 +0x63bf:nuo4 +0x63c0:jian3 +0x63c1:zhen1 +0x63c2:jiu1 +0x63c3:jian1 +0x63c4:yu2 +0x63c5:yan2 +0x63c6:kui2 +0x63c7:nan3 +0x63c8:hong1 +0x63c9:rou2 +0x63ca:pi4 +0x63cb:wei1 +0x63cc:sai1 +0x63cd:zou4 +0x63ce:xuan1 +0x63cf:miao2 +0x63d0:ti2 +0x63d1:nie1 +0x63d2:cha1 +0x63d3:shi4 +0x63d4:zong3 +0x63d5:zhen4 +0x63d6:yi1 +0x63d7:shun3 +0x63d8:heng2 +0x63d9:bian4 +0x63da:yang2 +0x63db:huan4 +0x63dc:yan3 +0x63dd:zuan4 +0x63de:an3 +0x63df:xu1 +0x63e0:ya4 +0x63e1:wo4 +0x63e2:ke4 +0x63e3:chuai3 +0x63e4:ji2 +0x63e5:ti4 +0x63e6:la2 +0x63e7:la4 +0x63e8:cheng2 +0x63e9:kai1 +0x63ea:jiu1 +0x63eb:jiu1 +0x63ec:tu2 +0x63ed:jie1 +0x63ee:hui1 +0x63ef:geng1 +0x63f0:chong4 +0x63f1:shuo4 +0x63f2:she2 +0x63f3:xie4 +0x63f4:yuan2 +0x63f5:qian2 +0x63f6:ye2 +0x63f7:cha1 +0x63f8:zha1 +0x63f9:bei1 +0x63fa:yao2 +0x63fd:lan3 +0x63fe:wen4 +0x63ff:qin4 +0x6400:chan1 +0x6401:ge1 +0x6402:lou3 +0x6403:zong3 +0x6404:geng1 +0x6405:jiao3 +0x6406:gou4 +0x6407:qin4 +0x6408:yong3 +0x6409:que4 +0x640a:chou1 +0x640b:chi3 +0x640c:zhan3 +0x640d:sun3 +0x640e:sun1 +0x640f:bo2 +0x6410:chu4 +0x6411:rong3 +0x6412:beng4 +0x6413:cuo1 +0x6414:sao1 +0x6415:ke4 +0x6416:yao2 +0x6417:dao3 +0x6418:zhi1 +0x6419:nu4 +0x641a:xie2 +0x641b:jian1 +0x641c:sou1 +0x641d:qiu3 +0x641e:gao3 +0x641f:xian3 +0x6420:shuo4 +0x6421:sang3 +0x6422:jin4 +0x6423:mie4 +0x6424:e4 +0x6425:chui2 +0x6426:nuo4 +0x6427:shan1 +0x6428:ta4 +0x6429:jie2 +0x642a:tang2 +0x642b:pan2 +0x642c:ban1 +0x642d:da1 +0x642e:li4 +0x642f:tao1 +0x6430:hu2 +0x6431:zhi4 +0x6432:wa1 +0x6433:xia2 +0x6434:qian1 +0x6435:wen4 +0x6436:qiang3 +0x6437:tian2 +0x6438:zhen1 +0x6439:e4 +0x643a:xi1 +0x643b:nuo4 +0x643c:quan2 +0x643d:cha2 +0x643e:zha4 +0x643f:ge2 +0x6440:wu3 +0x6441:en4 +0x6442:she4 +0x6443:kang2 +0x6444:she4 +0x6445:shu1 +0x6446:bai3 +0x6447:yao2 +0x6448:bin4 +0x6449:sou1 +0x644a:tan1 +0x644b:sa4 +0x644c:chan3 +0x644d:suo1 +0x644e:liao2 +0x644f:chong1 +0x6450:chuang1 +0x6451:guo2 +0x6452:bing4 +0x6453:feng2 +0x6454:shuai1 +0x6455:di4 +0x6456:qi4 +0x6458:zhai1 +0x6459:lian3 +0x645a:tang2 +0x645b:chi1 +0x645c:guan4 +0x645d:lu4 +0x645e:luo4 +0x645f:lou3 +0x6460:zong3 +0x6461:gai4 +0x6462:hu4 +0x6463:zha1 +0x6464:chuang3 +0x6465:tang4 +0x6466:hua4 +0x6467:cui1 +0x6468:nai2 +0x6469:mo2 +0x646a:jiang1 +0x646b:gui1 +0x646c:ying4 +0x646d:zhi2 +0x646e:ao2 +0x646f:zhi4 +0x6470:nie4 +0x6471:man2 +0x6472:shan4 +0x6473:kou1 +0x6474:shu1 +0x6475:suo3 +0x6476:tuan2 +0x6477:jiao3 +0x6478:mo1 +0x6479:mo2 +0x647a:zhe2 +0x647b:shan3 +0x647c:keng1 +0x647d:piao1 +0x647e:jiang4 +0x647f:yin1 +0x6480:gou4 +0x6481:qian1 +0x6482:liao4 +0x6483:ji2 +0x6484:ying1 +0x6485:jue1 +0x6486:pie1 +0x6487:pie1 +0x6488:lao1 +0x6489:dun1 +0x648a:xian4 +0x648b:ruan2 +0x648c:kui4 +0x648d:zan3 +0x648e:yi4 +0x648f:xun2 +0x6490:cheng1 +0x6491:cheng1 +0x6492:sa1 +0x6493:nao2 +0x6494:heng4 +0x6495:si1 +0x6496:qian3 +0x6497:huang2 +0x6498:da1 +0x6499:zun3 +0x649a:nian3 +0x649b:lin3 +0x649c:zheng3 +0x649d:hui1 +0x649e:zhuang4 +0x649f:jiao3 +0x64a0:ji3 +0x64a1:cao1 +0x64a2:dan3 +0x64a3:dan3 +0x64a4:che4 +0x64a5:bo1 +0x64a6:che3 +0x64a7:jue2 +0x64a8:xiao1 +0x64a9:liao1 +0x64aa:ben4 +0x64ab:fu3 +0x64ac:qiao4 +0x64ad:bo1 +0x64ae:cuo1 +0x64af:zhuo2 +0x64b0:zhuan4 +0x64b1:tuo3 +0x64b2:pu1 +0x64b3:qin4 +0x64b4:dun1 +0x64b5:nian3 +0x64b7:xie2 +0x64b8:lu3 +0x64b9:jiao3 +0x64ba:cuan1 +0x64bb:ta4 +0x64bc:han4 +0x64bd:qiao4 +0x64be:zhua1 +0x64bf:jian3 +0x64c0:gan3 +0x64c1:yong1 +0x64c2:lei2 +0x64c3:kuo3 +0x64c4:lu3 +0x64c5:shan4 +0x64c6:zhuo2 +0x64c7:ze2 +0x64c8:pu1 +0x64c9:chuo4 +0x64ca:ji1 +0x64cb:dang3 +0x64cc:suo3 +0x64cd:cao1 +0x64ce:qing2 +0x64cf:jing4 +0x64d0:huan4 +0x64d1:jie1 +0x64d2:qin2 +0x64d3:kuai3 +0x64d4:dan1 +0x64d5:xi1 +0x64d6:ge3 +0x64d7:pi4 +0x64d8:bo4 +0x64d9:ao4 +0x64da:ju4 +0x64db:ye4 +0x64de:sou3 +0x64df:mi2 +0x64e0:ji3 +0x64e1:tai2 +0x64e2:zhuo2 +0x64e3:dao3 +0x64e4:xing3 +0x64e5:lan3 +0x64e6:ca1 +0x64e7:ju3 +0x64e8:ye2 +0x64e9:ru3 +0x64ea:ye4 +0x64eb:ye4 +0x64ec:ni3 +0x64ed:wo4 +0x64ee:ji2 +0x64ef:bin4 +0x64f0:ning2 +0x64f1:ge1 +0x64f2:zhi4 +0x64f3:jie2 +0x64f4:kuo4 +0x64f5:mo2 +0x64f6:jian4 +0x64f7:xie2 +0x64f8:lie4 +0x64f9:tan1 +0x64fa:bai3 +0x64fb:sou3 +0x64fc:lu3 +0x64fd:lve4 +0x64fe:rao3 +0x64ff:zhi2 +0x6500:pan1 +0x6501:yang3 +0x6502:lei4 +0x6503:sa4 +0x6504:shu1 +0x6505:zan3 +0x6506:nian3 +0x6507:xian3 +0x6508:jun4 +0x6509:huo4 +0x650a:li4 +0x650b:la4 +0x650c:han4 +0x650d:ying2 +0x650e:lu2 +0x650f:long3 +0x6510:qian1 +0x6511:qian1 +0x6512:zan3 +0x6513:qian1 +0x6514:lan2 +0x6515:san1 +0x6516:ying1 +0x6517:mei2 +0x6518:rang4 +0x6519:chan1 +0x651b:cuan1 +0x651c:xie2 +0x651d:she4 +0x651e:luo3 +0x651f:jun4 +0x6520:mi2 +0x6521:li2 +0x6522:zan3 +0x6523:luan2 +0x6524:tan1 +0x6525:zuan4 +0x6526:li4 +0x6527:dian1 +0x6528:wa1 +0x6529:dang3 +0x652a:jiao3 +0x652b:jue2 +0x652c:lan3 +0x652d:li4 +0x652e:nang3 +0x652f:zhi1 +0x6530:gui4 +0x6531:gui3 +0x6532:qi1 +0x6533:xin2 +0x6534:pu1 +0x6535:sui1 +0x6536:shou1 +0x6537:kao3 +0x6538:you1 +0x6539:gai3 +0x653a:yi3 +0x653b:gong1 +0x653c:gan1 +0x653d:ban1 +0x653e:fang4 +0x653f:zheng4 +0x6540:bo2 +0x6541:dian1 +0x6542:kou4 +0x6543:min3 +0x6544:wu4 +0x6545:gu4 +0x6546:he2 +0x6547:ce4 +0x6548:xiao4 +0x6549:mi3 +0x654a:chu4 +0x654b:ge2 +0x654c:di2 +0x654d:xu4 +0x654e:jiao4 +0x654f:min3 +0x6550:chen2 +0x6551:jiu4 +0x6552:zhen4 +0x6553:duo2 +0x6554:yu3 +0x6555:chi4 +0x6556:ao2 +0x6557:bai4 +0x6558:xu4 +0x6559:jiao4 +0x655a:duo2 +0x655b:lian4 +0x655c:nie4 +0x655d:bi4 +0x655e:chang3 +0x655f:dian3 +0x6560:duo2 +0x6561:yi4 +0x6562:gan3 +0x6563:san4 +0x6564:ke3 +0x6565:yan4 +0x6566:dun1 +0x6567:qi3 +0x6568:dou3 +0x6569:xiao4 +0x656a:duo2 +0x656b:jiao4 +0x656c:jing4 +0x656d:yang2 +0x656e:xia2 +0x656f:min2 +0x6570:shu4 +0x6571:ai2 +0x6572:qiao1 +0x6573:ai2 +0x6574:zheng3 +0x6575:di2 +0x6576:zhen4 +0x6577:fu1 +0x6578:shu4 +0x6579:liao2 +0x657a:qu1 +0x657b:xiong4 +0x657c:xi3 +0x657d:jiao3 +0x657f:jiao3 +0x6580:zhuo2 +0x6581:yi4 +0x6582:lian3 +0x6583:bi4 +0x6584:li4 +0x6585:xiao4 +0x6586:xiao4 +0x6587:wen2 +0x6588:xue2 +0x6589:qi2 +0x658a:qi2 +0x658b:zhai1 +0x658c:bin1 +0x658d:jue2 +0x658e:zhai1 +0x6590:fei3 +0x6591:ban1 +0x6592:ban1 +0x6593:lan2 +0x6594:yu3 +0x6595:lan2 +0x6596:wei3 +0x6597:dou3 +0x6598:sheng1 +0x6599:liao4 +0x659a:jia3 +0x659b:hu2 +0x659c:xie2 +0x659d:jia3 +0x659e:yu3 +0x659f:zhen1 +0x65a0:jiao4 +0x65a1:wo4 +0x65a2:tou3 +0x65a3:chu4 +0x65a4:jin1 +0x65a5:chi4 +0x65a6:yin2 +0x65a7:fu3 +0x65a8:qiang1 +0x65a9:zhan3 +0x65aa:qu2 +0x65ab:zhuo2 +0x65ac:zhan3 +0x65ad:duan4 +0x65ae:zhuo2 +0x65af:si1 +0x65b0:xin1 +0x65b1:zhuo2 +0x65b2:zhuo2 +0x65b3:qin2 +0x65b4:lin2 +0x65b5:zhuo2 +0x65b6:chu4 +0x65b7:duan4 +0x65b8:zhu3 +0x65b9:fang1 +0x65ba:xie4 +0x65bb:hang2 +0x65bc:yu2 +0x65bd:shi1 +0x65be:pei4 +0x65bf:you2 +0x65c1:pang2 +0x65c2:qi2 +0x65c3:zhan1 +0x65c4:mao2 +0x65c5:lv3 +0x65c6:pei4 +0x65c7:pi1 +0x65c8:liu2 +0x65c9:fu1 +0x65ca:fang3 +0x65cb:xuan2 +0x65cc:jing1 +0x65cd:jing1 +0x65ce:ni3 +0x65cf:zu2 +0x65d0:zhao4 +0x65d1:yi3 +0x65d2:liu2 +0x65d3:shao1 +0x65d4:jian4 +0x65d6:yi3 +0x65d7:qi2 +0x65d8:zhi4 +0x65d9:fan1 +0x65da:piao1 +0x65db:fan1 +0x65dc:zhan1 +0x65dd:guai4 +0x65de:sui4 +0x65df:yu2 +0x65e0:wu2 +0x65e1:ji4 +0x65e2:ji4 +0x65e3:ji4 +0x65e4:huo4 +0x65e5:ri4 +0x65e6:dan4 +0x65e7:jiu4 +0x65e8:zhi3 +0x65e9:zao3 +0x65ea:xie2 +0x65eb:tiao1 +0x65ec:xun2 +0x65ed:xu4 +0x65ee:xu4 +0x65ef:xu4 +0x65f0:gan4 +0x65f1:han4 +0x65f2:tai2 +0x65f3:di4 +0x65f4:xu1 +0x65f5:chan3 +0x65f6:shi2 +0x65f7:kuang4 +0x65f8:yang2 +0x65f9:shi2 +0x65fa:wang4 +0x65fb:min2 +0x65fc:min2 +0x65fd:tun1 +0x65fe:chun1 +0x65ff:wu3 +0x6600:yun2 +0x6601:bei4 +0x6602:ang2 +0x6603:ze4 +0x6604:ban3 +0x6605:jie2 +0x6606:kun1 +0x6607:sheng1 +0x6608:hu4 +0x6609:fang3 +0x660a:hao4 +0x660b:gui4 +0x660c:chang1 +0x660d:xuan1 +0x660e:ming2 +0x660f:hun1 +0x6610:fen1 +0x6611:qin3 +0x6612:hu1 +0x6613:yi4 +0x6614:xi1 +0x6615:xin1 +0x6616:yan2 +0x6617:ze4 +0x6618:fang3 +0x6619:tan2 +0x661a:shen4 +0x661b:ju4 +0x661c:yang2 +0x661d:zan3 +0x661e:bing3 +0x661f:xing1 +0x6620:ying4 +0x6621:xuan4 +0x6622:pei3 +0x6623:zhen3 +0x6624:ling1 +0x6625:chun1 +0x6626:hao4 +0x6627:mei4 +0x6628:zuo2 +0x6629:mo4 +0x662a:bian4 +0x662b:xu3 +0x662c:hun1 +0x662d:zhao1 +0x662e:zong4 +0x662f:shi4 +0x6630:shi4 +0x6631:yu4 +0x6632:fei4 +0x6633:die2 +0x6634:mao3 +0x6635:ni4 +0x6636:chang3 +0x6637:wen1 +0x6638:dong1 +0x6639:ai3 +0x663a:bing3 +0x663b:ang2 +0x663c:zhou4 +0x663d:long2 +0x663e:xian3 +0x663f:kuang4 +0x6640:tiao3 +0x6641:chao2 +0x6642:shi2 +0x6643:huang3 +0x6644:huang3 +0x6645:xuan1 +0x6646:kui2 +0x6647:xu1 +0x6648:jiao3 +0x6649:jin4 +0x664a:zhi3 +0x664b:jin4 +0x664c:shang3 +0x664d:tong2 +0x664e:hong3 +0x664f:yan4 +0x6650:gai1 +0x6651:xiang3 +0x6652:shai4 +0x6653:xiao3 +0x6654:ye1 +0x6655:yun1 +0x6656:hui1 +0x6657:han2 +0x6658:han4 +0x6659:jun4 +0x665a:wan3 +0x665b:xian4 +0x665c:kun1 +0x665d:zhou4 +0x665e:xi1 +0x665f:sheng4 +0x6660:sheng2 +0x6661:bu1 +0x6662:zhe2 +0x6663:zhe1 +0x6664:wu4 +0x6665:han4 +0x6666:hui4 +0x6667:hao4 +0x6668:chen2 +0x6669:wan3 +0x666a:tian3 +0x666b:zhuo2 +0x666c:zui4 +0x666d:zhou3 +0x666e:pu3 +0x666f:jing3 +0x6670:xi1 +0x6671:shan3 +0x6672:yi3 +0x6673:xi4 +0x6674:qing2 +0x6675:qi3 +0x6676:jing1 +0x6677:gui3 +0x6678:zhen3 +0x6679:yi4 +0x667a:zhi4 +0x667b:an3 +0x667c:wan3 +0x667d:lin2 +0x667e:liang4 +0x667f:chang1 +0x6680:wang3 +0x6681:xiao3 +0x6682:zan4 +0x6684:xuan1 +0x6685:xuan3 +0x6686:yi2 +0x6687:xia2 +0x6688:yun1 +0x6689:hui1 +0x668a:fu3 +0x668b:min3 +0x668c:kui2 +0x668d:he4 +0x668e:ying4 +0x668f:du3 +0x6690:wei3 +0x6691:shu3 +0x6692:qing2 +0x6693:mao4 +0x6694:nan2 +0x6695:jian3 +0x6696:nuan3 +0x6697:an4 +0x6698:yang2 +0x6699:chun1 +0x669a:yao2 +0x669b:suo3 +0x669c:jin4 +0x669d:ming2 +0x669e:jiao3 +0x669f:kai3 +0x66a0:gao3 +0x66a1:weng3 +0x66a2:chang4 +0x66a3:qi4 +0x66a4:hao4 +0x66a5:yan4 +0x66a6:li4 +0x66a7:ai4 +0x66a8:ji4 +0x66a9:gui4 +0x66aa:men3 +0x66ab:zan4 +0x66ac:xie4 +0x66ad:hao4 +0x66ae:mu4 +0x66af:mo4 +0x66b0:cong1 +0x66b1:ni4 +0x66b2:zhang1 +0x66b3:hui4 +0x66b4:bao4 +0x66b5:han4 +0x66b6:xuan2 +0x66b7:chuan2 +0x66b8:liao2 +0x66b9:xian1 +0x66ba:dan4 +0x66bb:jing3 +0x66bc:pie1 +0x66bd:lin2 +0x66be:tun1 +0x66bf:xi3 +0x66c0:yi4 +0x66c1:ji4 +0x66c2:huang4 +0x66c3:tai4 +0x66c4:ye4 +0x66c5:ye4 +0x66c6:li4 +0x66c7:tan2 +0x66c8:tong2 +0x66c9:xiao3 +0x66ca:fei4 +0x66cb:qin3 +0x66cc:zhao4 +0x66cd:hao4 +0x66ce:yi4 +0x66cf:xiang4 +0x66d0:xing1 +0x66d1:sen1 +0x66d2:jiao3 +0x66d3:bao4 +0x66d4:jing4 +0x66d5:yan4 +0x66d6:ai4 +0x66d7:ye4 +0x66d8:ru2 +0x66d9:shu4 +0x66da:meng2 +0x66db:xun1 +0x66dc:yao4 +0x66dd:pu4 +0x66de:li4 +0x66df:chen2 +0x66e0:kuang4 +0x66e1:die2 +0x66e3:yan4 +0x66e4:huo4 +0x66e5:lu2 +0x66e6:xi1 +0x66e7:rong2 +0x66e8:long2 +0x66e9:nang3 +0x66ea:luo3 +0x66eb:luan2 +0x66ec:shai4 +0x66ed:tang3 +0x66ee:yan3 +0x66ef:chu2 +0x66f0:yue1 +0x66f1:yue1 +0x66f2:qu1 +0x66f3:ye4 +0x66f4:geng4 +0x66f5:ye4 +0x66f6:hu1 +0x66f7:he2 +0x66f8:shu1 +0x66f9:cao2 +0x66fa:cao2 +0x66fc:man4 +0x66fd:ceng1 +0x66fe:ceng2 +0x66ff:ti4 +0x6700:zui4 +0x6701:can3 +0x6702:xu4 +0x6703:hui4 +0x6704:yin4 +0x6705:qie4 +0x6706:fen1 +0x6707:pi2 +0x6708:yue4 +0x6709:you3 +0x670a:ruan3 +0x670b:peng2 +0x670c:ban1 +0x670d:fu2 +0x670e:ling2 +0x670f:fei3 +0x6710:qu2 +0x6712:nv4 +0x6713:tiao4 +0x6714:shuo4 +0x6715:zhen4 +0x6716:lang3 +0x6717:lang3 +0x6718:juan1 +0x6719:ming2 +0x671a:huang1 +0x671b:wang4 +0x671c:tun1 +0x671d:zhao1 +0x671e:ji1 +0x671f:qi1 +0x6720:ying1 +0x6721:zong1 +0x6722:wang4 +0x6723:tong2 +0x6724:lang3 +0x6726:meng2 +0x6727:long2 +0x6728:mu4 +0x6729:deng3 +0x672a:wei4 +0x672b:mo4 +0x672c:ben3 +0x672d:zha2 +0x672e:shu4 +0x672f:zhu2 +0x6731:zhu1 +0x6732:ren2 +0x6733:ba1 +0x6734:po4 +0x6735:duo3 +0x6736:duo3 +0x6737:dao1 +0x6738:li4 +0x6739:qiu2 +0x673a:ji1 +0x673b:jiu1 +0x673c:bi3 +0x673d:xiu3 +0x673e:ting2 +0x673f:ci4 +0x6740:sha1 +0x6742:za2 +0x6743:quan2 +0x6744:qian1 +0x6745:yu2 +0x6746:gan1 +0x6747:wu1 +0x6748:cha1 +0x6749:shan1 +0x674a:xun2 +0x674b:fan1 +0x674c:wu4 +0x674d:zi3 +0x674e:li3 +0x674f:xing4 +0x6750:cai2 +0x6751:cun1 +0x6752:ren4 +0x6753:shao2 +0x6754:tuo1 +0x6755:di4 +0x6756:zhang4 +0x6757:mang2 +0x6758:chi4 +0x6759:yi4 +0x675a:gu3 +0x675b:gong1 +0x675c:du4 +0x675d:yi2 +0x675e:qi3 +0x675f:shu4 +0x6760:gang1 +0x6761:tiao2 +0x6765:lai2 +0x6767:mang2 +0x6768:yang2 +0x6769:ma4 +0x676a:miao3 +0x676b:si4 +0x676c:yuan2 +0x676d:hang2 +0x676e:fei4 +0x676f:bei1 +0x6770:jie2 +0x6771:dong1 +0x6772:gao3 +0x6773:yao3 +0x6774:xian1 +0x6775:chu3 +0x6776:chun1 +0x6777:pa2 +0x6778:shu1 +0x6779:hua4 +0x677a:xin1 +0x677b:chou3 +0x677c:zhu4 +0x677d:chou3 +0x677e:song1 +0x677f:ban3 +0x6780:song1 +0x6781:ji2 +0x6782:yue4 +0x6783:jin4 +0x6784:gou1 +0x6785:ji1 +0x6786:mao2 +0x6787:pi2 +0x6788:bi4 +0x6789:wang3 +0x678a:ang4 +0x678b:fang1 +0x678c:fen2 +0x678d:yi4 +0x678e:fu2 +0x678f:nan2 +0x6790:xi1 +0x6791:hu4 +0x6792:ya2 +0x6793:dou3 +0x6794:xun2 +0x6795:zhen3 +0x6796:yao1 +0x6797:lin2 +0x6798:rui4 +0x6799:e3 +0x679a:mei2 +0x679b:zhao4 +0x679c:guo3 +0x679d:zhi1 +0x679e:cong1 +0x679f:yun4 +0x67a1:dou3 +0x67a2:shu1 +0x67a3:zao3 +0x67a5:li4 +0x67a7:jian4 +0x67a8:cheng2 +0x67aa:qiang1 +0x67ab:feng1 +0x67ac:nan2 +0x67ad:xiao1 +0x67ae:xian1 +0x67af:ku1 +0x67b0:ping2 +0x67b1:yi2 +0x67b2:xi3 +0x67b3:zhi1 +0x67b4:guai3 +0x67b5:xiao1 +0x67b6:jia4 +0x67b7:jia1 +0x67b8:ju3 +0x67b9:fu1 +0x67ba:mo4 +0x67bb:yi4 +0x67bc:ye4 +0x67bd:ye4 +0x67be:shi4 +0x67bf:nie4 +0x67c0:bi3 +0x67c1:duo4 +0x67c2:yi2 +0x67c3:ling2 +0x67c4:bing3 +0x67c5:ni3 +0x67c6:la1 +0x67c7:he2 +0x67c8:pan2 +0x67c9:fan2 +0x67ca:zhong1 +0x67cb:dai4 +0x67cc:ci2 +0x67cd:yang1 +0x67ce:fu1 +0x67cf:bai3 +0x67d0:mou3 +0x67d1:gan1 +0x67d2:qi1 +0x67d3:ran3 +0x67d4:rou2 +0x67d5:mao4 +0x67d6:zhao1 +0x67d7:song1 +0x67d8:zhe4 +0x67d9:xia2 +0x67da:you4 +0x67db:shen1 +0x67dc:gui4 +0x67dd:tuo4 +0x67de:zuo4 +0x67df:nan2 +0x67e0:ning2 +0x67e1:yong3 +0x67e2:di3 +0x67e3:zhi2 +0x67e4:zha1 +0x67e5:cha2 +0x67e6:dan4 +0x67e7:gu1 +0x67e9:jiu4 +0x67ea:ao1 +0x67eb:fu2 +0x67ec:jian3 +0x67ed:bo1 +0x67ee:duo4 +0x67ef:ke1 +0x67f0:nai4 +0x67f1:zhu4 +0x67f2:bi4 +0x67f3:liu3 +0x67f4:chai2 +0x67f5:zha4 +0x67f6:si4 +0x67f7:zhu4 +0x67f8:pei1 +0x67f9:shi4 +0x67fa:guai3 +0x67fb:cha2 +0x67fc:yao3 +0x67fd:jue2 +0x67fe:jiu4 +0x67ff:shi4 +0x6800:zhi1 +0x6801:liu3 +0x6802:mei2 +0x6804:rong2 +0x6805:zha4 +0x6807:biao1 +0x6808:zhan4 +0x6809:jie2 +0x680a:long2 +0x680b:dong4 +0x680c:lu2 +0x680e:li4 +0x680f:lan2 +0x6810:yong3 +0x6811:shu4 +0x6812:xun2 +0x6813:shuan1 +0x6814:qi4 +0x6815:zhen1 +0x6816:qi1 +0x6817:li4 +0x6818:yi3 +0x6819:xiang2 +0x681a:zhen4 +0x681b:li4 +0x681c:su4 +0x681d:gua1 +0x681e:kan1 +0x681f:bing1 +0x6820:ren3 +0x6821:xiao4 +0x6822:bo2 +0x6823:ren3 +0x6824:bing4 +0x6825:zi1 +0x6826:chou2 +0x6827:yi4 +0x6828:jie2 +0x6829:xu3 +0x682a:zhu1 +0x682b:jian4 +0x682c:zui4 +0x682d:er2 +0x682e:er3 +0x682f:you3 +0x6830:fa2 +0x6831:gong3 +0x6832:kao3 +0x6833:lao3 +0x6834:zhan1 +0x6835:li4 +0x6837:yang2 +0x6838:he2 +0x6839:gen1 +0x683a:zhi3 +0x683b:shi4 +0x683c:ge2 +0x683d:zai1 +0x683e:luan2 +0x683f:fu2 +0x6840:jie2 +0x6841:heng2 +0x6842:gui4 +0x6843:tao2 +0x6844:guang4 +0x6845:wei2 +0x6846:kuang4 +0x6847:ru2 +0x6848:an4 +0x6849:an1 +0x684a:juan4 +0x684b:yi2 +0x684c:zhuo1 +0x684d:ku1 +0x684e:zhi4 +0x684f:qiong2 +0x6850:tong2 +0x6851:sang1 +0x6852:sang1 +0x6853:huan2 +0x6854:jie2 +0x6855:jiu4 +0x6856:xue4 +0x6857:duo4 +0x6858:zhui4 +0x6859:yu2 +0x685a:zan3 +0x685c:ying1 +0x685f:zhan4 +0x6860:ya2 +0x6861:nao2 +0x6862:zhen1 +0x6863:dang3 +0x6864:qi1 +0x6865:qiao2 +0x6866:hua4 +0x6867:kuai4 +0x6868:jiang3 +0x6869:zhuang1 +0x686a:xun2 +0x686b:suo1 +0x686c:sha1 +0x686d:zhen1 +0x686e:bei1 +0x686f:ting1 +0x6870:gua1 +0x6871:jing4 +0x6872:bo2 +0x6873:ben4 +0x6874:fu2 +0x6875:rui3 +0x6876:tong3 +0x6877:jue2 +0x6878:xi1 +0x6879:lang2 +0x687a:liu3 +0x687b:feng1 +0x687c:qi1 +0x687d:wen3 +0x687e:jun1 +0x687f:gan3 +0x6880:cu4 +0x6881:liang2 +0x6882:qiu2 +0x6883:ting3 +0x6884:you3 +0x6885:mei2 +0x6886:bang1 +0x6887:long4 +0x6888:peng1 +0x6889:zhuang1 +0x688a:di4 +0x688b:xuan1 +0x688c:tu2 +0x688d:zao4 +0x688e:ao1 +0x688f:gu4 +0x6890:bi4 +0x6891:di2 +0x6892:han2 +0x6893:zi3 +0x6894:zhi1 +0x6895:ren4 +0x6896:bei4 +0x6897:geng3 +0x6898:jian4 +0x6899:huan4 +0x689a:wan3 +0x689b:nuo2 +0x689c:jia2 +0x689d:tiao2 +0x689e:ji4 +0x689f:xiao1 +0x68a0:lv3 +0x68a1:hun2 +0x68a2:shao1 +0x68a3:cen2 +0x68a4:fen2 +0x68a5:song1 +0x68a6:meng4 +0x68a7:wu2 +0x68a8:li2 +0x68a9:li2 +0x68aa:dou4 +0x68ab:cen1 +0x68ac:ying3 +0x68ad:suo1 +0x68ae:ju2 +0x68af:ti1 +0x68b0:xie4 +0x68b1:kun3 +0x68b2:zhuo2 +0x68b3:shu1 +0x68b4:chan1 +0x68b5:fan4 +0x68b6:wei3 +0x68b7:jing4 +0x68b8:li2 +0x68b9:bing1 +0x68bc:tao2 +0x68bd:zhi4 +0x68be:lai2 +0x68bf:lian2 +0x68c0:jian3 +0x68c1:zhuo2 +0x68c2:ling2 +0x68c3:li2 +0x68c4:qi4 +0x68c5:bing4 +0x68c6:zhun1 +0x68c7:cong1 +0x68c8:qian4 +0x68c9:mian2 +0x68ca:qi2 +0x68cb:qi2 +0x68cc:cai3 +0x68cd:gun4 +0x68ce:chan2 +0x68cf:te4 +0x68d0:fei3 +0x68d1:pai2 +0x68d2:bang4 +0x68d3:pou3 +0x68d4:hun1 +0x68d5:zong1 +0x68d6:cheng2 +0x68d7:zao3 +0x68d8:ji2 +0x68d9:li4 +0x68da:peng2 +0x68db:yu4 +0x68dc:yu4 +0x68dd:gu4 +0x68de:hun2 +0x68df:dong4 +0x68e0:tang2 +0x68e1:gang1 +0x68e2:wang3 +0x68e3:di4 +0x68e4:xi2 +0x68e5:fan2 +0x68e6:cheng1 +0x68e7:zhan4 +0x68e8:qi3 +0x68e9:yuan1 +0x68ea:yan3 +0x68eb:yu4 +0x68ec:quan1 +0x68ed:yi4 +0x68ee:sen1 +0x68ef:ren3 +0x68f0:chui2 +0x68f1:leng2 +0x68f2:qi1 +0x68f3:zhuo2 +0x68f4:fu2 +0x68f5:ke1 +0x68f6:lai2 +0x68f7:zou1 +0x68f8:zou1 +0x68f9:zhuo1 +0x68fa:guan1 +0x68fb:fen2 +0x68fc:fen2 +0x68fd:chen1 +0x68fe:qiong2 +0x68ff:nie4 +0x6900:wan3 +0x6901:guo3 +0x6902:lu4 +0x6903:hao2 +0x6904:jie1 +0x6905:yi3 +0x6906:chou2 +0x6907:ju3 +0x6908:ju2 +0x6909:cheng2 +0x690a:zuo2 +0x690b:liang2 +0x690c:qiang1 +0x690d:zhi2 +0x690e:zhui1 +0x690f:ya1 +0x6910:ju1 +0x6911:bei1 +0x6912:jiao1 +0x6913:zhuo2 +0x6914:zi1 +0x6915:bin1 +0x6916:peng2 +0x6917:ding4 +0x6918:chu3 +0x691c:jian3 +0x691d:gui1 +0x691e:xi4 +0x691f:du2 +0x6920:qian4 +0x6924:luo2 +0x6925:zhi1 +0x692a:peng4 +0x692b:zhan3 +0x692d:tuo3 +0x692e:sen1 +0x692f:duo2 +0x6930:ye2 +0x6931:fou4 +0x6932:wei3 +0x6933:wei1 +0x6934:duan4 +0x6935:jia3 +0x6936:zong1 +0x6937:jian1 +0x6938:yi2 +0x6939:shen4 +0x693a:xi2 +0x693b:yan4 +0x693c:yan3 +0x693d:chuan2 +0x693e:zhan4 +0x693f:chun1 +0x6940:yu3 +0x6941:he2 +0x6942:zha1 +0x6943:wo4 +0x6944:pian2 +0x6945:bi4 +0x6946:yao1 +0x6947:huo4 +0x6948:xu1 +0x6949:ruo4 +0x694a:yang2 +0x694b:la4 +0x694c:yan2 +0x694d:ben3 +0x694e:hun2 +0x694f:kui2 +0x6950:jie4 +0x6951:kui2 +0x6952:si1 +0x6953:feng1 +0x6954:xie1 +0x6955:tuo3 +0x6956:zhi4 +0x6957:jian4 +0x6958:mu4 +0x6959:mao4 +0x695a:chu3 +0x695b:hu4 +0x695c:hu2 +0x695d:lian4 +0x695e:leng2 +0x695f:ting2 +0x6960:nan2 +0x6961:yu2 +0x6962:you2 +0x6963:mei2 +0x6964:song3 +0x6965:xuan4 +0x6966:xuan4 +0x6967:ying1 +0x6968:zhen1 +0x6969:pian2 +0x696a:ye4 +0x696b:ji2 +0x696c:jie2 +0x696d:ye4 +0x696e:chu3 +0x696f:shun3 +0x6970:yu2 +0x6971:cou4 +0x6972:wei1 +0x6973:mei2 +0x6974:di4 +0x6975:ji2 +0x6976:jie2 +0x6977:kai3 +0x6978:qiu1 +0x6979:ying2 +0x697a:rou2 +0x697b:heng2 +0x697c:lou2 +0x697d:le4 +0x6980:pin3 +0x6982:gai4 +0x6983:tan2 +0x6984:lan3 +0x6985:yun2 +0x6986:yu2 +0x6987:chen4 +0x6988:lv2 +0x6989:ju3 +0x698d:xie4 +0x698e:jia3 +0x698f:yi4 +0x6990:zhan3 +0x6991:fu4 +0x6992:nai4 +0x6993:mi4 +0x6994:lang2 +0x6995:rong2 +0x6996:gu3 +0x6997:jian4 +0x6998:ju3 +0x6999:ta3 +0x699a:yao3 +0x699b:zhen1 +0x699c:bang3 +0x699d:sha1 +0x699e:yuan2 +0x699f:zi3 +0x69a0:ming2 +0x69a1:su4 +0x69a2:jia4 +0x69a3:yao2 +0x69a4:jie2 +0x69a5:huang3 +0x69a6:gan4 +0x69a7:fei3 +0x69a8:zha4 +0x69a9:qian2 +0x69aa:ma4 +0x69ab:sun3 +0x69ac:yuan2 +0x69ad:xie4 +0x69ae:rong2 +0x69af:shi2 +0x69b0:zhi1 +0x69b1:cui1 +0x69b2:yun2 +0x69b3:ting2 +0x69b4:liu2 +0x69b5:rong2 +0x69b6:tang2 +0x69b7:que4 +0x69b8:zhai1 +0x69b9:si1 +0x69ba:sheng4 +0x69bb:ta4 +0x69bc:ke4 +0x69bd:xi1 +0x69be:gu4 +0x69bf:qi1 +0x69c0:kao3 +0x69c1:gao3 +0x69c2:sun1 +0x69c3:pan2 +0x69c4:tao1 +0x69c5:ge2 +0x69c6:xun2 +0x69c7:dian1 +0x69c8:nou4 +0x69c9:ji2 +0x69ca:shuo4 +0x69cb:gou4 +0x69cc:chui2 +0x69cd:qiang1 +0x69ce:cha2 +0x69cf:qian3 +0x69d0:huai2 +0x69d1:mei2 +0x69d2:xu4 +0x69d3:gang4 +0x69d4:gao1 +0x69d5:zhuo2 +0x69d6:tuo4 +0x69d8:yang4 +0x69d9:dian1 +0x69da:jia3 +0x69db:jian4 +0x69dc:zui4 +0x69df:bin1 +0x69e0:zhu1 +0x69e2:xi2 +0x69e3:qi3 +0x69e4:lian2 +0x69e5:hui4 +0x69e6:yong2 +0x69e7:qian4 +0x69e8:guo3 +0x69e9:gai4 +0x69ea:gai4 +0x69eb:tuan2 +0x69ec:hua4 +0x69ed:cu4 +0x69ee:sen1 +0x69ef:cui1 +0x69f0:beng4 +0x69f1:you3 +0x69f2:hu2 +0x69f3:jiang3 +0x69f4:hu4 +0x69f5:huan4 +0x69f6:kui4 +0x69f7:yi4 +0x69f8:nie4 +0x69f9:gao1 +0x69fa:kang1 +0x69fb:gui1 +0x69fc:gui1 +0x69fd:cao2 +0x69fe:man2 +0x69ff:jin3 +0x6a00:di4 +0x6a01:zhuang1 +0x6a02:le4 +0x6a03:lang2 +0x6a04:chen2 +0x6a05:cong1 +0x6a06:li2 +0x6a07:xiu1 +0x6a08:qing2 +0x6a09:shuang3 +0x6a0a:fan2 +0x6a0b:tong1 +0x6a0c:guan4 +0x6a0d:ji1 +0x6a0e:suo1 +0x6a0f:lei3 +0x6a10:lu3 +0x6a11:liang2 +0x6a12:mi4 +0x6a13:lou2 +0x6a14:chao2 +0x6a15:su4 +0x6a16:ke1 +0x6a17:chu1 +0x6a18:tang2 +0x6a19:biao1 +0x6a1a:lu4 +0x6a1b:jiu1 +0x6a1c:shu4 +0x6a1d:zha1 +0x6a1e:shu1 +0x6a1f:zhang1 +0x6a20:men2 +0x6a21:mo2 +0x6a22:niao3 +0x6a23:yang4 +0x6a24:tiao2 +0x6a25:peng2 +0x6a26:zhu4 +0x6a27:sha1 +0x6a28:xi1 +0x6a29:quan2 +0x6a2a:heng2 +0x6a2b:jian1 +0x6a2c:cong1 +0x6a2f:qiang2 +0x6a31:ying1 +0x6a32:er4 +0x6a33:xin2 +0x6a34:zhi2 +0x6a35:qiao2 +0x6a36:zui1 +0x6a37:cong1 +0x6a38:pu2 +0x6a39:shu4 +0x6a3a:hua4 +0x6a3b:kui4 +0x6a3c:zhen1 +0x6a3d:zun1 +0x6a3e:yue4 +0x6a3f:zhan3 +0x6a40:xi1 +0x6a41:xun2 +0x6a42:dian4 +0x6a43:fa1 +0x6a44:gan3 +0x6a45:mo2 +0x6a46:wu3 +0x6a47:qiao1 +0x6a48:nao2 +0x6a49:lin4 +0x6a4a:liu2 +0x6a4b:qiao2 +0x6a4c:xian4 +0x6a4d:run4 +0x6a4e:fan2 +0x6a4f:zhan3 +0x6a50:tuo2 +0x6a51:lao3 +0x6a52:yun2 +0x6a53:shun4 +0x6a54:tui2 +0x6a55:cheng1 +0x6a56:tang2 +0x6a57:meng2 +0x6a58:ju2 +0x6a59:cheng2 +0x6a5a:su4 +0x6a5b:jue2 +0x6a5c:jue2 +0x6a5d:tan1 +0x6a5e:hui4 +0x6a5f:ji1 +0x6a60:nuo3 +0x6a61:xiang4 +0x6a62:tuo3 +0x6a63:ning3 +0x6a64:rui3 +0x6a65:zhu1 +0x6a66:chuang2 +0x6a67:zeng1 +0x6a68:fen2 +0x6a69:qiong2 +0x6a6a:ran3 +0x6a6b:heng2 +0x6a6c:cen2 +0x6a6d:gu1 +0x6a6e:liu3 +0x6a6f:lao4 +0x6a70:gao1 +0x6a71:chu2 +0x6a76:ji2 +0x6a77:dou1 +0x6a79:lu3 +0x6a7c:yuan2 +0x6a7d:ta4 +0x6a7e:shu1 +0x6a7f:jiang1 +0x6a80:tan2 +0x6a81:lin3 +0x6a82:nong2 +0x6a83:yin3 +0x6a84:xi2 +0x6a85:sui4 +0x6a86:shan1 +0x6a87:zui4 +0x6a88:xuan2 +0x6a89:cheng1 +0x6a8a:gan4 +0x6a8b:ju1 +0x6a8c:zui4 +0x6a8d:yi4 +0x6a8e:qin2 +0x6a8f:pu3 +0x6a90:yan2 +0x6a91:lei2 +0x6a92:feng1 +0x6a93:hui3 +0x6a94:dang4 +0x6a95:ji4 +0x6a96:sui4 +0x6a97:bo4 +0x6a98:bi4 +0x6a99:ding3 +0x6a9a:chu3 +0x6a9b:zhua1 +0x6a9c:gui4 +0x6a9d:ji2 +0x6a9e:jie3 +0x6a9f:jia3 +0x6aa0:qing2 +0x6aa1:zhe4 +0x6aa2:jian3 +0x6aa3:qiang2 +0x6aa4:dao4 +0x6aa5:yi3 +0x6aa6:biao3 +0x6aa7:song1 +0x6aa8:she1 +0x6aa9:lin3 +0x6aab:cha2 +0x6aac:meng2 +0x6aad:yin2 +0x6aae:tao2 +0x6aaf:tai2 +0x6ab0:mian2 +0x6ab1:qi2 +0x6ab3:bin1 +0x6ab4:huo4 +0x6ab5:ji4 +0x6ab6:qian1 +0x6ab7:mi2 +0x6ab8:ning2 +0x6ab9:yi1 +0x6aba:gao3 +0x6abb:jian4 +0x6abc:yin4 +0x6abd:er2 +0x6abe:qing3 +0x6abf:yan3 +0x6ac0:qi2 +0x6ac1:mi4 +0x6ac2:zhao4 +0x6ac3:gui4 +0x6ac4:chun1 +0x6ac5:ji1 +0x6ac6:kui2 +0x6ac7:po2 +0x6ac8:deng4 +0x6ac9:chu2 +0x6acb:mian2 +0x6acc:you1 +0x6acd:zhi4 +0x6ace:guang4 +0x6acf:qian1 +0x6ad0:lei3 +0x6ad1:lei3 +0x6ad2:sa4 +0x6ad3:lu3 +0x6ad4:li4 +0x6ad5:cuan2 +0x6ad6:lv2 +0x6ad7:mie4 +0x6ad8:hui4 +0x6ad9:ou1 +0x6ada:lv2 +0x6adb:jie2 +0x6adc:gao1 +0x6add:du2 +0x6ade:yuan2 +0x6adf:li4 +0x6ae0:fei4 +0x6ae1:zhuo2 +0x6ae2:sou3 +0x6ae3:lian2 +0x6ae5:chu2 +0x6ae7:zhu1 +0x6ae8:lu2 +0x6ae9:yan2 +0x6aea:li4 +0x6aeb:zhu1 +0x6aec:chen4 +0x6aed:jie2 +0x6aee:e4 +0x6aef:su1 +0x6af0:huai2 +0x6af1:nie4 +0x6af2:yu4 +0x6af3:long2 +0x6af4:lai4 +0x6af6:xian3 +0x6af8:ju3 +0x6af9:xiao1 +0x6afa:ling2 +0x6afb:ying1 +0x6afc:jian1 +0x6afd:yin3 +0x6afe:you2 +0x6aff:ying2 +0x6b00:xiang1 +0x6b01:nong2 +0x6b02:bo2 +0x6b03:chan2 +0x6b04:lan2 +0x6b05:ju3 +0x6b06:shuang1 +0x6b07:she4 +0x6b08:wei2 +0x6b09:cong4 +0x6b0a:quan2 +0x6b0b:qu2 +0x6b0e:yu4 +0x6b0f:luo2 +0x6b10:li3 +0x6b11:zan4 +0x6b12:luan2 +0x6b13:dang3 +0x6b14:jue2 +0x6b16:lan3 +0x6b17:lan2 +0x6b18:zhu3 +0x6b19:lei2 +0x6b1a:li3 +0x6b1b:ba4 +0x6b1c:nang2 +0x6b1d:yu4 +0x6b1e:ling2 +0x6b20:qian4 +0x6b21:ci4 +0x6b22:huan1 +0x6b23:xin1 +0x6b24:yu2 +0x6b25:yu4 +0x6b26:qian1 +0x6b27:ou1 +0x6b28:xu1 +0x6b29:chao1 +0x6b2a:chu4 +0x6b2b:chi1 +0x6b2c:kai4 +0x6b2d:yi4 +0x6b2e:jue2 +0x6b2f:xi2 +0x6b30:xu1 +0x6b31:xia4 +0x6b32:yu4 +0x6b33:kuai4 +0x6b34:lang2 +0x6b35:kuan3 +0x6b36:shuo4 +0x6b37:xi1 +0x6b38:ai3 +0x6b39:yi1 +0x6b3a:qi1 +0x6b3b:xu1 +0x6b3c:chi3 +0x6b3d:qin1 +0x6b3e:kuan3 +0x6b3f:kan3 +0x6b40:kuan3 +0x6b41:kan3 +0x6b42:chuan2 +0x6b43:sha4 +0x6b45:yin1 +0x6b46:xin1 +0x6b47:xie1 +0x6b48:yu2 +0x6b49:qian4 +0x6b4a:xiao1 +0x6b4b:yi2 +0x6b4c:ge1 +0x6b4d:wu1 +0x6b4e:tan4 +0x6b4f:jin4 +0x6b50:ou1 +0x6b51:hu1 +0x6b52:ti4 +0x6b53:huan1 +0x6b54:xu1 +0x6b55:pen1 +0x6b56:xi1 +0x6b57:xiao4 +0x6b58:xu1 +0x6b59:xi1 +0x6b5b:han1 +0x6b5c:chu4 +0x6b5d:yi4 +0x6b5e:kan3 +0x6b5f:yu2 +0x6b60:chuo4 +0x6b61:huan1 +0x6b62:zhi3 +0x6b63:zheng4 +0x6b64:ci3 +0x6b65:bu4 +0x6b66:wu3 +0x6b67:qi2 +0x6b68:bu4 +0x6b69:bu4 +0x6b6a:wai1 +0x6b6b:ju4 +0x6b6c:qian2 +0x6b6d:chi2 +0x6b6e:se4 +0x6b6f:chi3 +0x6b70:se4 +0x6b71:zhong3 +0x6b72:sui4 +0x6b73:sui4 +0x6b74:li4 +0x6b75:cuo4 +0x6b76:yu2 +0x6b77:li4 +0x6b78:gui1 +0x6b79:dai3 +0x6b7a:dai3 +0x6b7b:si3 +0x6b7c:jian1 +0x6b7d:zhe2 +0x6b7e:mo4 +0x6b7f:mo4 +0x6b80:yao3 +0x6b81:mo4 +0x6b82:cu2 +0x6b83:yang1 +0x6b84:tian3 +0x6b85:sheng1 +0x6b86:dai4 +0x6b87:shang1 +0x6b88:xu4 +0x6b89:xun4 +0x6b8a:shu1 +0x6b8b:can2 +0x6b8c:jue2 +0x6b8d:piao3 +0x6b8e:qia4 +0x6b8f:qiu4 +0x6b90:su4 +0x6b91:qing2 +0x6b92:yun3 +0x6b93:lian4 +0x6b94:yi4 +0x6b95:fou3 +0x6b96:zhi2 +0x6b97:ye4 +0x6b98:can2 +0x6b99:hun1 +0x6b9a:dan1 +0x6b9b:ji2 +0x6b9c:ye4 +0x6b9e:yun3 +0x6b9f:wen1 +0x6ba0:chou4 +0x6ba1:bin4 +0x6ba2:ti4 +0x6ba3:jin4 +0x6ba4:shang1 +0x6ba5:yin2 +0x6ba6:diao1 +0x6ba7:cu4 +0x6ba8:hui4 +0x6ba9:cuan4 +0x6baa:yi4 +0x6bab:dan1 +0x6bac:du4 +0x6bad:jiang1 +0x6bae:lian4 +0x6baf:bin4 +0x6bb0:du2 +0x6bb2:jian1 +0x6bb3:shu1 +0x6bb4:ou1 +0x6bb5:duan4 +0x6bb6:zhu4 +0x6bb7:yin1 +0x6bb8:qing4 +0x6bb9:yi4 +0x6bba:sha1 +0x6bbb:que4 +0x6bbc:ke2 +0x6bbd:yao2 +0x6bbe:jun4 +0x6bbf:dian4 +0x6bc0:hui3 +0x6bc1:hui3 +0x6bc2:gu3 +0x6bc3:que4 +0x6bc4:ji1 +0x6bc5:yi4 +0x6bc6:ou1 +0x6bc7:hui3 +0x6bc8:duan4 +0x6bc9:yi1 +0x6bca:xiao1 +0x6bcb:wu2 +0x6bcc:guan4 +0x6bcd:mu3 +0x6bce:mei3 +0x6bcf:mei3 +0x6bd0:ai3 +0x6bd1:zuo3 +0x6bd2:du2 +0x6bd3:yu4 +0x6bd4:bi3 +0x6bd5:bi4 +0x6bd6:bi4 +0x6bd7:pi2 +0x6bd8:pi2 +0x6bd9:bi4 +0x6bda:chan2 +0x6bdb:mao2 +0x6bde:pu2 +0x6be0:jia1 +0x6be1:zhan1 +0x6be2:sai1 +0x6be3:mu4 +0x6be4:tuo4 +0x6be5:xun2 +0x6be6:er4 +0x6be7:rong2 +0x6be8:xian3 +0x6be9:ju2 +0x6bea:mu2 +0x6beb:hao2 +0x6bec:qiu2 +0x6bed:dou4 +0x6bef:tan3 +0x6bf0:pei2 +0x6bf1:ju2 +0x6bf2:duo2 +0x6bf3:cui4 +0x6bf4:bi1 +0x6bf5:san1 +0x6bf7:mao4 +0x6bf8:sui1 +0x6bf9:shu1 +0x6bfa:yu1 +0x6bfb:tuo4 +0x6bfc:he2 +0x6bfd:jian4 +0x6bfe:ta4 +0x6bff:san1 +0x6c00:lv2 +0x6c01:mu2 +0x6c02:mao2 +0x6c03:tong2 +0x6c04:rong3 +0x6c05:chang3 +0x6c06:pu3 +0x6c07:luo2 +0x6c08:zhan1 +0x6c09:sao4 +0x6c0a:zhan1 +0x6c0b:meng2 +0x6c0c:luo2 +0x6c0d:qu2 +0x6c0e:die2 +0x6c0f:shi4 +0x6c10:di3 +0x6c11:min2 +0x6c12:jue2 +0x6c13:mang2 +0x6c14:qi4 +0x6c15:pie1 +0x6c16:nai3 +0x6c17:qi4 +0x6c18:dao1 +0x6c19:xian1 +0x6c1a:chuan1 +0x6c1b:fen1 +0x6c1c:ri4 +0x6c1d:nei4 +0x6c1f:fu2 +0x6c20:shen1 +0x6c21:dong1 +0x6c22:qing1 +0x6c23:qi4 +0x6c24:yin1 +0x6c25:xi1 +0x6c26:hai4 +0x6c27:yang3 +0x6c28:an1 +0x6c29:ya4 +0x6c2a:ke4 +0x6c2b:qing1 +0x6c2c:ya4 +0x6c2d:dong1 +0x6c2e:dan4 +0x6c2f:lv4 +0x6c30:qing1 +0x6c31:yang3 +0x6c32:yun1 +0x6c33:yun1 +0x6c34:shui3 +0x6c36:zheng3 +0x6c37:bing1 +0x6c38:yong3 +0x6c39:dang4 +0x6c3b:le4 +0x6c3c:ni4 +0x6c3d:tun3 +0x6c3e:fan4 +0x6c3f:gui3 +0x6c40:ting1 +0x6c41:zhi1 +0x6c42:qiu2 +0x6c43:bin1 +0x6c44:ze4 +0x6c45:mian3 +0x6c46:cuan1 +0x6c47:hui4 +0x6c48:diao1 +0x6c49:han4 +0x6c4a:cha4 +0x6c4b:zhuo2 +0x6c4c:chuan4 +0x6c4d:wan2 +0x6c4e:fan4 +0x6c4f:dai4 +0x6c50:xi4 +0x6c51:tuo1 +0x6c52:mang2 +0x6c53:qiu2 +0x6c54:qi4 +0x6c55:shan4 +0x6c56:pai4 +0x6c57:han4 +0x6c58:qian1 +0x6c59:wu1 +0x6c5a:wu1 +0x6c5b:xun4 +0x6c5c:si4 +0x6c5d:ru3 +0x6c5e:gong3 +0x6c5f:jiang1 +0x6c60:chi2 +0x6c61:wu1 +0x6c64:tang1 +0x6c65:zhi1 +0x6c66:chi2 +0x6c67:qian1 +0x6c68:mi4 +0x6c69:gu3 +0x6c6a:wang1 +0x6c6b:qing4 +0x6c6c:jing3 +0x6c6d:rui4 +0x6c6e:jun1 +0x6c6f:hong2 +0x6c70:tai4 +0x6c71:quan3 +0x6c72:ji2 +0x6c73:bian4 +0x6c74:bian4 +0x6c75:gan4 +0x6c76:wen4 +0x6c77:zhong1 +0x6c78:fang1 +0x6c79:xiong1 +0x6c7a:jue2 +0x6c7b:hang3 +0x6c7d:qi4 +0x6c7e:fen2 +0x6c7f:xu4 +0x6c80:xu4 +0x6c81:qin4 +0x6c82:yi2 +0x6c83:wo4 +0x6c84:yun2 +0x6c85:yuan2 +0x6c86:hang2 +0x6c87:yan3 +0x6c88:chen2 +0x6c89:chen2 +0x6c8a:dan4 +0x6c8b:you2 +0x6c8c:dun4 +0x6c8d:hu4 +0x6c8e:huo4 +0x6c8f:qi1 +0x6c90:mu4 +0x6c91:rou2 +0x6c92:mei2 +0x6c93:ta4 +0x6c94:mian3 +0x6c95:wu4 +0x6c96:chong1 +0x6c97:tian1 +0x6c98:bi3 +0x6c99:sha1 +0x6c9a:zhi3 +0x6c9b:pei4 +0x6c9c:pan4 +0x6c9d:zhui3 +0x6c9e:za1 +0x6c9f:gou1 +0x6ca0:liu2 +0x6ca1:mei2 +0x6ca2:ze2 +0x6ca3:feng1 +0x6ca4:ou4 +0x6ca5:li4 +0x6ca6:lun2 +0x6ca7:cang1 +0x6ca8:feng2 +0x6ca9:wei2 +0x6caa:hu4 +0x6cab:mo4 +0x6cac:mei4 +0x6cad:shu4 +0x6cae:ju1 +0x6caf:zan3 +0x6cb0:tuo1 +0x6cb1:tuo2 +0x6cb2:tuo2 +0x6cb3:he2 +0x6cb4:li4 +0x6cb5:mi3 +0x6cb6:yi2 +0x6cb7:fa1 +0x6cb8:fei4 +0x6cb9:you2 +0x6cba:tian2 +0x6cbb:zhi4 +0x6cbc:zhao3 +0x6cbd:gu1 +0x6cbe:zhan1 +0x6cbf:yan2 +0x6cc0:si1 +0x6cc1:kuang4 +0x6cc2:jiong3 +0x6cc3:ju4 +0x6cc4:xie4 +0x6cc5:qiu2 +0x6cc6:yi1 +0x6cc7:jia1 +0x6cc8:zhong1 +0x6cc9:quan2 +0x6cca:bo2 +0x6ccb:hui4 +0x6ccc:mi4 +0x6ccd:ben1 +0x6cce:zhuo2 +0x6ccf:chu4 +0x6cd0:le4 +0x6cd1:you3 +0x6cd2:gu1 +0x6cd3:hong2 +0x6cd4:gan1 +0x6cd5:fa3 +0x6cd6:mao3 +0x6cd7:si4 +0x6cd8:hu1 +0x6cd9:ping2 +0x6cda:ci3 +0x6cdb:fan4 +0x6cdc:chi2 +0x6cdd:su4 +0x6cde:ning4 +0x6cdf:cheng1 +0x6ce0:ling2 +0x6ce1:pao4 +0x6ce2:bo1 +0x6ce3:qi4 +0x6ce4:si4 +0x6ce5:ni2 +0x6ce6:ju2 +0x6ce7:yue4 +0x6ce8:zhu4 +0x6ce9:sheng1 +0x6cea:lei4 +0x6ceb:xuan4 +0x6cec:xue4 +0x6ced:fu1 +0x6cee:pan4 +0x6cef:min3 +0x6cf0:tai4 +0x6cf1:yang1 +0x6cf2:ji3 +0x6cf3:yong3 +0x6cf4:guan4 +0x6cf5:beng4 +0x6cf6:xue2 +0x6cf7:long2 +0x6cf8:lu2 +0x6cfa:bo2 +0x6cfb:xie4 +0x6cfc:po1 +0x6cfd:ze2 +0x6cfe:jing1 +0x6cff:yin2 +0x6d00:zhou1 +0x6d01:ji2 +0x6d02:yi4 +0x6d03:hui1 +0x6d04:hui2 +0x6d05:zui3 +0x6d06:cheng2 +0x6d07:yin1 +0x6d08:wei2 +0x6d09:hou4 +0x6d0a:jian4 +0x6d0b:yang2 +0x6d0c:lie4 +0x6d0d:si4 +0x6d0e:ji4 +0x6d0f:er2 +0x6d10:xing2 +0x6d11:fu2 +0x6d12:sa3 +0x6d13:suo3 +0x6d14:zhi3 +0x6d15:yin1 +0x6d16:wu2 +0x6d17:xi3 +0x6d18:kao3 +0x6d19:zhu1 +0x6d1a:jiang4 +0x6d1b:luo4 +0x6d1d:an4 +0x6d1e:dong4 +0x6d1f:yi2 +0x6d20:mou2 +0x6d21:lei3 +0x6d22:yi1 +0x6d23:mi3 +0x6d24:quan2 +0x6d25:jin1 +0x6d26:mo4 +0x6d27:wei3 +0x6d28:xiao2 +0x6d29:xie4 +0x6d2a:hong2 +0x6d2b:xu4 +0x6d2c:shuo4 +0x6d2d:kuang1 +0x6d2e:tao2 +0x6d2f:qie4 +0x6d30:ju4 +0x6d31:er3 +0x6d32:zhou1 +0x6d33:ru4 +0x6d34:ping2 +0x6d35:xun2 +0x6d36:xiong1 +0x6d37:zhi4 +0x6d38:guang1 +0x6d39:huan2 +0x6d3a:ming2 +0x6d3b:huo2 +0x6d3c:wa1 +0x6d3d:qia4 +0x6d3e:pai4 +0x6d3f:wu1 +0x6d40:qu3 +0x6d41:liu2 +0x6d42:yi4 +0x6d43:jia2 +0x6d44:jing4 +0x6d45:qian3 +0x6d46:jiang1 +0x6d47:jiao1 +0x6d48:cheng2 +0x6d49:shi1 +0x6d4a:zhuo2 +0x6d4b:ce4 +0x6d4d:kuai4 +0x6d4e:ji4 +0x6d4f:liu2 +0x6d50:chan3 +0x6d51:hun2 +0x6d52:hu3 +0x6d53:nong2 +0x6d54:xun2 +0x6d55:jin4 +0x6d56:lie4 +0x6d57:qiu2 +0x6d58:wei3 +0x6d59:zhe4 +0x6d5a:jun4 +0x6d5b:han4 +0x6d5c:bang1 +0x6d5d:mang2 +0x6d5e:zhuo2 +0x6d5f:you2 +0x6d60:xi1 +0x6d61:bo2 +0x6d62:dou4 +0x6d63:wan3 +0x6d64:hong2 +0x6d65:yi4 +0x6d66:pu3 +0x6d67:ying3 +0x6d68:lan3 +0x6d69:hao4 +0x6d6a:lang4 +0x6d6b:han3 +0x6d6c:li3 +0x6d6d:geng1 +0x6d6e:fu2 +0x6d6f:wu2 +0x6d70:lian4 +0x6d71:chun2 +0x6d72:feng2 +0x6d73:yi4 +0x6d74:yu4 +0x6d75:tong2 +0x6d76:lao2 +0x6d77:hai3 +0x6d78:jin4 +0x6d79:jia2 +0x6d7a:chong1 +0x6d7b:weng3 +0x6d7c:mei3 +0x6d7d:sui1 +0x6d7e:cheng1 +0x6d7f:pei4 +0x6d80:xian4 +0x6d81:shen4 +0x6d82:tu2 +0x6d83:kun4 +0x6d84:pin1 +0x6d85:nie4 +0x6d86:han4 +0x6d87:jing1 +0x6d88:xiao1 +0x6d89:she4 +0x6d8a:nian3 +0x6d8b:tu1 +0x6d8c:yong3 +0x6d8d:xiao4 +0x6d8e:xian2 +0x6d8f:ting3 +0x6d90:e2 +0x6d91:su4 +0x6d92:tun1 +0x6d93:juan1 +0x6d94:cen2 +0x6d95:ti4 +0x6d96:li4 +0x6d97:shui4 +0x6d98:si4 +0x6d99:lei4 +0x6d9a:shui4 +0x6d9b:tao1 +0x6d9c:du2 +0x6d9d:lao4 +0x6d9e:lai2 +0x6d9f:lian2 +0x6da0:wei2 +0x6da1:wo1 +0x6da2:yun2 +0x6da3:huan4 +0x6da4:di2 +0x6da6:run4 +0x6da7:jian4 +0x6da8:zhang3 +0x6da9:se4 +0x6daa:fu2 +0x6dab:guan4 +0x6dac:xing4 +0x6dad:shou4 +0x6dae:shuan4 +0x6daf:ya2 +0x6db0:chuo4 +0x6db1:zhang4 +0x6db2:ye4 +0x6db3:kong1 +0x6db4:wo4 +0x6db5:han2 +0x6db6:tuo1 +0x6db7:dong1 +0x6db8:he2 +0x6db9:wo1 +0x6dba:ju1 +0x6dbb:gan4 +0x6dbc:liang2 +0x6dbd:hun1 +0x6dbe:ta4 +0x6dbf:zhuo1 +0x6dc0:dian4 +0x6dc1:qie4 +0x6dc2:de2 +0x6dc3:juan4 +0x6dc4:zi1 +0x6dc5:xi1 +0x6dc6:yao2 +0x6dc7:qi2 +0x6dc8:gu3 +0x6dc9:guo3 +0x6dca:han4 +0x6dcb:lin2 +0x6dcc:tang3 +0x6dcd:zhou1 +0x6dce:peng3 +0x6dcf:hao4 +0x6dd0:chang1 +0x6dd1:shu2 +0x6dd2:qi1 +0x6dd3:fang1 +0x6dd4:chi4 +0x6dd5:lu4 +0x6dd6:nao4 +0x6dd7:ju2 +0x6dd8:tao2 +0x6dd9:cong2 +0x6dda:lei4 +0x6ddb:zhi4 +0x6ddc:peng2 +0x6ddd:fei2 +0x6dde:song1 +0x6ddf:tian3 +0x6de0:pi4 +0x6de1:dan4 +0x6de2:yu4 +0x6de3:ni2 +0x6de4:yu1 +0x6de5:lu4 +0x6de6:gan4 +0x6de7:mi4 +0x6de8:jing4 +0x6de9:ling2 +0x6dea:lun2 +0x6deb:yin2 +0x6dec:cui4 +0x6ded:qu2 +0x6dee:huai2 +0x6def:yu4 +0x6df0:nian3 +0x6df1:shen1 +0x6df2:piao2 +0x6df3:chun2 +0x6df4:wa4 +0x6df5:yuan1 +0x6df6:lai2 +0x6df7:hun4 +0x6df8:qing1 +0x6df9:yan1 +0x6dfa:qian3 +0x6dfb:tian1 +0x6dfc:miao3 +0x6dfd:zhi3 +0x6dfe:yin3 +0x6dff:mi4 +0x6e00:ben1 +0x6e01:yuan1 +0x6e02:wen4 +0x6e03:re4 +0x6e04:fei1 +0x6e05:qing1 +0x6e06:yuan1 +0x6e07:ke3 +0x6e08:ji4 +0x6e09:she4 +0x6e0a:yuan1 +0x6e0c:lu4 +0x6e0d:zi4 +0x6e0e:du2 +0x6e10:jian4 +0x6e11:min3 +0x6e12:pi4 +0x6e14:yu2 +0x6e15:yuan1 +0x6e16:shen3 +0x6e17:shen4 +0x6e18:rou2 +0x6e19:huan4 +0x6e1a:zhu3 +0x6e1b:jian3 +0x6e1c:nuan3 +0x6e1d:yu2 +0x6e1e:qiu2 +0x6e1f:ting2 +0x6e20:qu2 +0x6e21:du4 +0x6e22:feng2 +0x6e23:zha1 +0x6e24:bo2 +0x6e25:wo4 +0x6e26:wo1 +0x6e27:di4 +0x6e28:wei1 +0x6e29:wen1 +0x6e2a:ru2 +0x6e2b:xie4 +0x6e2c:ce4 +0x6e2d:wei4 +0x6e2e:ge1 +0x6e2f:gang3 +0x6e30:yan3 +0x6e31:hong2 +0x6e32:xuan4 +0x6e33:mi3 +0x6e34:ke3 +0x6e35:mao2 +0x6e36:ying1 +0x6e37:yan3 +0x6e38:you2 +0x6e39:hong1 +0x6e3a:miao3 +0x6e3b:xing3 +0x6e3c:mei3 +0x6e3d:zai1 +0x6e3e:hun2 +0x6e3f:nai4 +0x6e40:kui2 +0x6e41:shi2 +0x6e42:e4 +0x6e43:pai4 +0x6e44:mei2 +0x6e45:lian4 +0x6e46:qi4 +0x6e47:qi4 +0x6e48:mei2 +0x6e49:tian2 +0x6e4a:cou4 +0x6e4b:wei2 +0x6e4c:can1 +0x6e4d:tuan1 +0x6e4e:mian3 +0x6e4f:hui4 +0x6e50:mo4 +0x6e51:xu3 +0x6e52:ji2 +0x6e53:pen2 +0x6e54:jian1 +0x6e55:jian3 +0x6e56:hu2 +0x6e57:feng4 +0x6e58:xiang1 +0x6e59:yi4 +0x6e5a:yin4 +0x6e5b:zhan4 +0x6e5c:shi2 +0x6e5d:jie1 +0x6e5e:cheng2 +0x6e5f:huang2 +0x6e60:tan4 +0x6e61:yu2 +0x6e62:bi4 +0x6e63:min3 +0x6e64:shi1 +0x6e65:tu2 +0x6e66:sheng1 +0x6e67:yong3 +0x6e68:qu4 +0x6e69:zhong4 +0x6e6b:jiao3 +0x6e6c:jiao3 +0x6e6e:yin1 +0x6e6f:tang1 +0x6e70:long2 +0x6e71:huo4 +0x6e72:yuan2 +0x6e73:nan3 +0x6e74:ban4 +0x6e75:you3 +0x6e76:quan2 +0x6e77:chui2 +0x6e78:liang4 +0x6e79:chan2 +0x6e7a:yan2 +0x6e7b:chun2 +0x6e7c:nie4 +0x6e7d:zi1 +0x6e7e:wan1 +0x6e7f:shi1 +0x6e80:man3 +0x6e81:ying2 +0x6e83:kui4 +0x6e85:jian4 +0x6e86:xu4 +0x6e87:lv3 +0x6e88:gui1 +0x6e89:gai4 +0x6e8c:po1 +0x6e8d:jin4 +0x6e8e:gui4 +0x6e8f:tang2 +0x6e90:yuan2 +0x6e91:suo3 +0x6e92:yuan2 +0x6e93:lian2 +0x6e94:yao3 +0x6e95:meng4 +0x6e96:zhun3 +0x6e97:sheng2 +0x6e98:ke4 +0x6e99:tai4 +0x6e9a:da2 +0x6e9b:wa1 +0x6e9c:liu1 +0x6e9d:gou1 +0x6e9e:sao1 +0x6e9f:ming2 +0x6ea0:zha4 +0x6ea1:shi2 +0x6ea2:yi4 +0x6ea3:lun2 +0x6ea4:ma3 +0x6ea5:pu3 +0x6ea6:wei2 +0x6ea7:li4 +0x6ea8:cai2 +0x6ea9:wu4 +0x6eaa:xi1 +0x6eab:wen1 +0x6eac:qiang1 +0x6ead:ze2 +0x6eae:shi1 +0x6eaf:su4 +0x6eb0:yi1 +0x6eb1:zhen1 +0x6eb2:sou1 +0x6eb3:yun2 +0x6eb4:xiu4 +0x6eb5:yin1 +0x6eb6:rong2 +0x6eb7:hun4 +0x6eb8:su4 +0x6eb9:su4 +0x6eba:ni4 +0x6ebb:ta4 +0x6ebc:shi1 +0x6ebd:ru4 +0x6ebe:wei1 +0x6ebf:pan4 +0x6ec0:chu4 +0x6ec1:chu2 +0x6ec2:pang1 +0x6ec3:weng3 +0x6ec4:cang1 +0x6ec5:mie4 +0x6ec6:he2 +0x6ec7:dian1 +0x6ec8:hao4 +0x6ec9:huang3 +0x6eca:xi4 +0x6ecb:zi1 +0x6ecc:di2 +0x6ecd:zhi3 +0x6ece:xing2 +0x6ecf:fu3 +0x6ed0:jie2 +0x6ed1:hua2 +0x6ed2:ge1 +0x6ed3:zi3 +0x6ed4:tao1 +0x6ed5:teng2 +0x6ed6:sui1 +0x6ed7:bi3 +0x6ed8:jiao4 +0x6ed9:hui4 +0x6eda:gun3 +0x6edb:yin2 +0x6edc:gao1 +0x6edd:long2 +0x6ede:zhi4 +0x6edf:yan4 +0x6ee0:she4 +0x6ee1:man3 +0x6ee2:ying4 +0x6ee3:chun2 +0x6ee4:lv4 +0x6ee5:lan4 +0x6ee6:luan2 +0x6ee8:bin1 +0x6ee9:tan1 +0x6eea:yu4 +0x6eeb:sou3 +0x6eec:hu4 +0x6eed:bi4 +0x6eee:biao1 +0x6eef:zhi4 +0x6ef0:jiang3 +0x6ef1:kou4 +0x6ef2:shen4 +0x6ef3:shang1 +0x6ef4:di1 +0x6ef5:mi4 +0x6ef6:ao2 +0x6ef7:lu3 +0x6ef8:hu3 +0x6ef9:hu1 +0x6efa:you2 +0x6efb:chan3 +0x6efc:fan4 +0x6efd:yong2 +0x6efe:gun3 +0x6eff:man3 +0x6f00:qing4 +0x6f01:yu2 +0x6f02:piao1 +0x6f03:ji2 +0x6f04:ya2 +0x6f05:jiao3 +0x6f06:qi1 +0x6f07:xi3 +0x6f08:ji4 +0x6f09:lu4 +0x6f0a:lv3 +0x6f0b:long2 +0x6f0c:jin3 +0x6f0d:guo2 +0x6f0e:cong2 +0x6f0f:lou4 +0x6f10:zhi2 +0x6f11:gai4 +0x6f12:qiang2 +0x6f13:li2 +0x6f14:yan3 +0x6f15:cao2 +0x6f16:jiao4 +0x6f17:cong1 +0x6f18:chun2 +0x6f19:tuan2 +0x6f1a:ou4 +0x6f1b:teng2 +0x6f1c:ye3 +0x6f1d:xi2 +0x6f1e:mi4 +0x6f1f:tang2 +0x6f20:mo4 +0x6f21:shang1 +0x6f22:han4 +0x6f23:lian2 +0x6f24:lan3 +0x6f25:wa1 +0x6f26:li2 +0x6f27:qian2 +0x6f28:feng2 +0x6f29:xuan2 +0x6f2a:yi1 +0x6f2b:man4 +0x6f2c:zi4 +0x6f2d:mang3 +0x6f2e:kang1 +0x6f2f:ta4 +0x6f30:peng1 +0x6f31:shu4 +0x6f32:zhang3 +0x6f33:zhang1 +0x6f34:chong2 +0x6f35:xu4 +0x6f36:huan4 +0x6f37:kuo4 +0x6f38:jian4 +0x6f39:yan1 +0x6f3a:chuang3 +0x6f3b:liao2 +0x6f3c:cui3 +0x6f3d:ti2 +0x6f3e:yang4 +0x6f3f:jiang1 +0x6f40:cong2 +0x6f41:ying3 +0x6f42:hong2 +0x6f43:xun2 +0x6f44:shu4 +0x6f45:guan4 +0x6f46:ying2 +0x6f47:xiao1 +0x6f4a:xu4 +0x6f4b:lian4 +0x6f4c:zhi4 +0x6f4d:wei2 +0x6f4e:pi4 +0x6f4f:jue2 +0x6f50:jiao4 +0x6f51:po1 +0x6f52:dang4 +0x6f53:hui4 +0x6f54:jie2 +0x6f55:wu3 +0x6f56:pa2 +0x6f57:ji2 +0x6f58:pan1 +0x6f59:gui2 +0x6f5a:xiao1 +0x6f5b:qian2 +0x6f5c:qian2 +0x6f5d:xi1 +0x6f5e:lu4 +0x6f5f:xi4 +0x6f60:sun4 +0x6f61:dun4 +0x6f62:huang2 +0x6f63:min3 +0x6f64:run4 +0x6f65:su4 +0x6f66:lao3 +0x6f67:zhen1 +0x6f68:zhong1 +0x6f69:yi4 +0x6f6a:di2 +0x6f6b:wan1 +0x6f6c:dan4 +0x6f6d:tan2 +0x6f6e:chao2 +0x6f6f:xun2 +0x6f70:kui4 +0x6f72:shao4 +0x6f73:tu2 +0x6f74:zhu1 +0x6f75:san4 +0x6f76:hei1 +0x6f77:bi3 +0x6f78:shan1 +0x6f79:chan2 +0x6f7a:chan2 +0x6f7b:shu3 +0x6f7c:tong2 +0x6f7d:pu3 +0x6f7e:lin2 +0x6f7f:wei2 +0x6f80:se4 +0x6f81:se4 +0x6f82:cheng2 +0x6f83:jiong4 +0x6f84:cheng2 +0x6f85:hua4 +0x6f86:jiao1 +0x6f87:lao4 +0x6f88:che4 +0x6f89:gan3 +0x6f8a:cun1 +0x6f8b:heng4 +0x6f8c:si1 +0x6f8d:shu4 +0x6f8e:peng2 +0x6f8f:han4 +0x6f90:yun2 +0x6f91:liu4 +0x6f92:hong4 +0x6f93:fu2 +0x6f94:hao4 +0x6f95:he2 +0x6f96:xian1 +0x6f97:jian4 +0x6f98:shan1 +0x6f99:xi4 +0x6f9c:lan2 +0x6f9e:yu2 +0x6f9f:lin3 +0x6fa0:mian3 +0x6fa1:zao3 +0x6fa2:dang1 +0x6fa3:huan3 +0x6fa4:ze2 +0x6fa5:xie4 +0x6fa6:yu4 +0x6fa7:li3 +0x6fa8:shi4 +0x6fa9:xue2 +0x6faa:ling2 +0x6fab:man4 +0x6fac:zi1 +0x6fad:yong1 +0x6fae:kuai4 +0x6faf:can4 +0x6fb0:lian4 +0x6fb1:dian4 +0x6fb2:ye4 +0x6fb3:ao4 +0x6fb4:huan2 +0x6fb5:zhen1 +0x6fb6:chan2 +0x6fb7:man4 +0x6fb8:dan3 +0x6fb9:dan4 +0x6fba:yi4 +0x6fbb:sui4 +0x6fbc:pi4 +0x6fbd:ju4 +0x6fbe:ta4 +0x6fbf:qin2 +0x6fc0:ji1 +0x6fc1:zhuo2 +0x6fc2:lian2 +0x6fc3:nong2 +0x6fc4:guo1 +0x6fc5:jin4 +0x6fc6:fen2 +0x6fc7:se4 +0x6fc8:ji2 +0x6fc9:sui1 +0x6fca:hui4 +0x6fcb:chu3 +0x6fcc:ta4 +0x6fcd:song1 +0x6fce:ding3 +0x6fd0:zhu3 +0x6fd1:lai4 +0x6fd2:bin1 +0x6fd3:lian2 +0x6fd4:mi3 +0x6fd5:shi1 +0x6fd6:shu4 +0x6fd7:mi4 +0x6fd8:ning4 +0x6fd9:ying2 +0x6fda:ying2 +0x6fdb:meng2 +0x6fdc:jin4 +0x6fdd:qi2 +0x6fde:pi4 +0x6fdf:ji4 +0x6fe0:hao2 +0x6fe1:ru2 +0x6fe2:zui3 +0x6fe3:wo4 +0x6fe4:tao1 +0x6fe5:yin4 +0x6fe6:yin3 +0x6fe7:dui4 +0x6fe8:ci2 +0x6fe9:huo4 +0x6fea:jing4 +0x6feb:lan4 +0x6fec:jun4 +0x6fed:ai4 +0x6fee:pu2 +0x6fef:zhuo2 +0x6ff0:wei2 +0x6ff1:bin1 +0x6ff2:gu3 +0x6ff3:qian2 +0x6ff4:xing2 +0x6ff6:kuo4 +0x6ff7:fei4 +0x6ffa:jian4 +0x6ffb:wei3 +0x6ffc:luo4 +0x6ffd:zan4 +0x6ffe:lv4 +0x6fff:li4 +0x7000:you1 +0x7001:yang4 +0x7002:lu3 +0x7003:si4 +0x7004:jie2 +0x7005:ying4 +0x7006:du2 +0x7007:wang3 +0x7008:hui1 +0x7009:xie4 +0x700a:pan2 +0x700b:shen3 +0x700c:biao1 +0x700d:chan2 +0x700e:mo4 +0x700f:liu2 +0x7010:jian1 +0x7011:pu4 +0x7012:se4 +0x7013:cheng2 +0x7014:gu3 +0x7015:bin1 +0x7016:huo4 +0x7017:xian4 +0x7018:lu2 +0x7019:qin1 +0x701a:han4 +0x701b:ying2 +0x701c:yong1 +0x701d:li4 +0x701e:jing4 +0x701f:xiao1 +0x7020:ying2 +0x7021:sui3 +0x7022:wei2 +0x7023:xie4 +0x7024:huai2 +0x7025:hao4 +0x7026:zhu1 +0x7027:long2 +0x7028:lai4 +0x7029:dui4 +0x702a:fan2 +0x702b:hu2 +0x702c:lai4 +0x702f:ying2 +0x7030:mi2 +0x7031:ji4 +0x7032:lian4 +0x7033:jian4 +0x7034:ying3 +0x7035:fen4 +0x7036:lin2 +0x7037:yi4 +0x7038:jian1 +0x7039:yue4 +0x703a:chan2 +0x703b:dai4 +0x703c:rang2 +0x703d:jian3 +0x703e:lan2 +0x703f:fan2 +0x7040:shuang4 +0x7041:yuan1 +0x7042:zhuo2 +0x7043:feng1 +0x7044:she4 +0x7045:lei3 +0x7046:lan2 +0x7047:cong2 +0x7048:qu2 +0x7049:yong1 +0x704a:qian2 +0x704b:fa3 +0x704c:guan4 +0x704d:que4 +0x704e:yan4 +0x704f:hao4 +0x7051:sa3 +0x7052:zan4 +0x7053:luan2 +0x7054:yan4 +0x7055:li2 +0x7056:mi3 +0x7057:shan4 +0x7058:tan1 +0x7059:dang3 +0x705a:jiao3 +0x705b:chan3 +0x705d:hao4 +0x705e:ba4 +0x705f:zhu2 +0x7060:lan3 +0x7061:lan2 +0x7062:nang3 +0x7063:wan1 +0x7064:luan2 +0x7065:xun2 +0x7066:xian3 +0x7067:yan4 +0x7068:gan3 +0x7069:yan4 +0x706a:yu4 +0x706b:huo3 +0x706c:biao1 +0x706d:mie4 +0x706e:guang1 +0x706f:deng1 +0x7070:hui1 +0x7071:xiao1 +0x7072:xiao1 +0x7074:hong2 +0x7075:ling2 +0x7076:zao4 +0x7077:zhuan4 +0x7078:jiu3 +0x7079:zha4 +0x707a:xie4 +0x707b:chi4 +0x707c:zhuo2 +0x707d:zai1 +0x707e:zai1 +0x707f:can4 +0x7080:yang2 +0x7081:qi4 +0x7082:zhong1 +0x7083:fen2 +0x7084:niu3 +0x7085:jiong3 +0x7086:wen2 +0x7087:po4 +0x7088:yi4 +0x7089:lu2 +0x708a:chui1 +0x708b:pi1 +0x708c:kai4 +0x708d:pan4 +0x708e:yan2 +0x708f:kai4 +0x7090:pang4 +0x7091:mu4 +0x7092:chao3 +0x7093:liao4 +0x7094:gui4 +0x7095:kang4 +0x7096:tun2 +0x7097:guang1 +0x7098:xin1 +0x7099:zhi4 +0x709b:guang1 +0x709c:wei3 +0x709d:qiang4 +0x709f:da2 +0x70a0:xia2 +0x70a1:zheng1 +0x70a2:zhu2 +0x70a3:ke3 +0x70a4:zhao4 +0x70a5:fu2 +0x70a6:ba2 +0x70a7:duo4 +0x70a8:duo4 +0x70a9:ling4 +0x70aa:zhuo2 +0x70ab:xuan4 +0x70ac:ju4 +0x70ad:tan4 +0x70ae:pao4 +0x70af:jiong3 +0x70b0:pao2 +0x70b1:tai2 +0x70b2:tai2 +0x70b3:bing3 +0x70b4:yang3 +0x70b5:tong1 +0x70b6:han1 +0x70b7:zhu4 +0x70b8:zha4 +0x70b9:dian3 +0x70ba:wei4 +0x70bb:shi2 +0x70bc:lian4 +0x70bd:chi4 +0x70be:huang3 +0x70c0:hu1 +0x70c1:shuo4 +0x70c2:lan4 +0x70c3:jing3 +0x70c4:jiao3 +0x70c5:xu4 +0x70c6:xing2 +0x70c7:quan4 +0x70c8:lie4 +0x70c9:huan4 +0x70ca:yang2 +0x70cb:xiao1 +0x70cc:xiu1 +0x70cd:xian3 +0x70ce:yin2 +0x70cf:wu1 +0x70d0:zhou1 +0x70d1:yao2 +0x70d2:shi4 +0x70d3:wei1 +0x70d4:tong2 +0x70d5:xue4 +0x70d6:zai1 +0x70d7:kai4 +0x70d8:hong1 +0x70d9:luo4 +0x70da:xia2 +0x70db:zhu2 +0x70dc:xuan3 +0x70dd:zheng1 +0x70de:po4 +0x70df:yan1 +0x70e0:hui3 +0x70e1:guang1 +0x70e2:zhe4 +0x70e3:hui1 +0x70e4:kao3 +0x70e6:fan2 +0x70e7:shao1 +0x70e8:ye4 +0x70e9:hui4 +0x70eb:tang4 +0x70ec:jin4 +0x70ed:re4 +0x70ef:xi1 +0x70f0:fu2 +0x70f1:jiong3 +0x70f2:che4 +0x70f3:pu3 +0x70f4:jing3 +0x70f5:zhuo2 +0x70f6:ting3 +0x70f7:wan2 +0x70f8:hai3 +0x70f9:peng1 +0x70fa:lang3 +0x70fb:shan1 +0x70fc:hu1 +0x70fd:feng1 +0x70fe:chi4 +0x70ff:rong2 +0x7100:hu2 +0x7102:shu2 +0x7103:he4 +0x7104:xun1 +0x7105:ku4 +0x7106:jue2 +0x7107:xiao1 +0x7108:xi1 +0x7109:yan1 +0x710a:han4 +0x710b:zhuang4 +0x710c:jun4 +0x710d:di4 +0x710e:xie4 +0x710f:ji2 +0x7110:wu4 +0x7113:han2 +0x7114:yan4 +0x7115:huan4 +0x7116:men4 +0x7117:ju2 +0x7118:chou2 +0x7119:bei4 +0x711a:fen2 +0x711b:lin4 +0x711c:kun1 +0x711d:hun4 +0x711e:tun1 +0x711f:xi2 +0x7120:cui4 +0x7121:wu2 +0x7122:hong1 +0x7123:ju4 +0x7124:fu3 +0x7125:wo4 +0x7126:jiao1 +0x7127:cong1 +0x7128:feng4 +0x7129:ping1 +0x712a:qiong1 +0x712b:ruo4 +0x712c:xi2 +0x712d:qiong2 +0x712e:xin4 +0x712f:zhuo2 +0x7130:yan4 +0x7131:yan4 +0x7132:yi4 +0x7133:jue2 +0x7134:yu4 +0x7135:gang4 +0x7136:ran2 +0x7137:pi2 +0x7138:gu3 +0x713a:sheng1 +0x713b:chang4 +0x713c:shao1 +0x713f:geng1 +0x7141:chen2 +0x7142:he4 +0x7143:kui3 +0x7144:zhong1 +0x7145:duan4 +0x7146:xia1 +0x7147:hui1 +0x7148:feng4 +0x7149:lian4 +0x714a:xuan1 +0x714b:xing1 +0x714c:huang2 +0x714d:jiao3 +0x714e:jian1 +0x714f:bi4 +0x7150:ying1 +0x7151:zhu3 +0x7152:wei3 +0x7153:tuan1 +0x7154:tian4 +0x7155:xi1 +0x7156:nuan3 +0x7157:nuan3 +0x7158:chan2 +0x7159:yan1 +0x715a:jiong3 +0x715b:jiong3 +0x715c:yu4 +0x715d:mei4 +0x715e:sha1 +0x715f:wei4 +0x7160:ye4 +0x7161:xin4 +0x7162:qiong2 +0x7163:rou3 +0x7164:mei2 +0x7165:huan4 +0x7166:xu3 +0x7167:zhao4 +0x7168:wei1 +0x7169:fan2 +0x716a:qiu2 +0x716b:sui4 +0x716c:yang2 +0x716d:lie4 +0x716e:zhu3 +0x7170:gao4 +0x7171:gua1 +0x7172:bao1 +0x7173:hu2 +0x7174:yun1 +0x7175:xia1 +0x7178:bian1 +0x7179:gou4 +0x717a:tui4 +0x717b:tang2 +0x717c:chao3 +0x717d:shan1 +0x717e:en1 +0x717f:bo2 +0x7180:huang3 +0x7181:xie2 +0x7182:xi4 +0x7183:wu4 +0x7184:xi2 +0x7185:yun4 +0x7186:he2 +0x7187:he4 +0x7188:xi1 +0x7189:yun2 +0x718a:xiong2 +0x718b:nai2 +0x718c:shan4 +0x718e:yao4 +0x718f:xun1 +0x7190:mi4 +0x7191:lian2 +0x7192:ying2 +0x7193:wu3 +0x7194:rong2 +0x7197:qiang4 +0x7198:liu1 +0x7199:xi1 +0x719a:bi4 +0x719b:biao1 +0x719c:zong3 +0x719d:lu4 +0x719e:jian1 +0x719f:shu2 +0x71a0:yi4 +0x71a1:lou2 +0x71a2:feng1 +0x71a3:sui1 +0x71a4:yi4 +0x71a5:tong1 +0x71a6:jue2 +0x71a7:zong1 +0x71a8:yun4 +0x71a9:hu4 +0x71aa:yi2 +0x71ab:zhi4 +0x71ac:ao2 +0x71ad:wei4 +0x71ae:liao2 +0x71af:han4 +0x71b0:ou1 +0x71b1:re4 +0x71b2:jiong3 +0x71b3:man4 +0x71b5:shang1 +0x71b6:cuan4 +0x71b7:zeng1 +0x71b8:jian1 +0x71b9:xi1 +0x71ba:xi1 +0x71bb:xi1 +0x71bc:yi4 +0x71bd:xiao4 +0x71be:chi4 +0x71bf:huang2 +0x71c0:chan3 +0x71c1:ye4 +0x71c2:qian2 +0x71c3:ran2 +0x71c4:yan4 +0x71c5:xian2 +0x71c6:qiao2 +0x71c7:zun4 +0x71c8:deng1 +0x71c9:dun4 +0x71ca:shen1 +0x71cb:jiao1 +0x71cc:fen2 +0x71cd:si1 +0x71ce:liao3 +0x71cf:yu4 +0x71d0:lin2 +0x71d1:tong2 +0x71d2:shao1 +0x71d3:fen1 +0x71d4:fan2 +0x71d5:yan4 +0x71d6:xun2 +0x71d7:lan4 +0x71d8:mei3 +0x71d9:tang4 +0x71da:yi1 +0x71db:jing3 +0x71dc:men4 +0x71df:ying2 +0x71e0:yu4 +0x71e1:yi4 +0x71e2:xue2 +0x71e3:lan2 +0x71e4:tai4 +0x71e5:zao4 +0x71e6:can4 +0x71e7:sui4 +0x71e8:xi1 +0x71e9:que4 +0x71ea:cong1 +0x71eb:lian2 +0x71ec:hui3 +0x71ed:zhu2 +0x71ee:xie4 +0x71ef:ling2 +0x71f0:wei1 +0x71f1:yi4 +0x71f2:xie2 +0x71f3:zhao4 +0x71f4:hui4 +0x71f7:lan2 +0x71f8:ru2 +0x71f9:xian3 +0x71fa:kao3 +0x71fb:xun1 +0x71fc:jin4 +0x71fd:chou2 +0x71fe:dao4 +0x71ff:yao4 +0x7200:he4 +0x7201:lan4 +0x7202:biao1 +0x7203:rong2 +0x7204:li4 +0x7205:mo4 +0x7206:bao4 +0x7207:ruo4 +0x7208:lv2 +0x7209:la4 +0x720a:ao2 +0x720b:xun4 +0x720c:kuang4 +0x720d:shuo4 +0x720f:li4 +0x7210:lu2 +0x7211:jue2 +0x7212:liao4 +0x7213:yan4 +0x7214:xi1 +0x7215:xie4 +0x7216:long2 +0x7217:ye4 +0x7219:rang3 +0x721a:yue4 +0x721b:lan4 +0x721c:cong2 +0x721d:jue2 +0x721e:tong2 +0x721f:guan4 +0x7221:che4 +0x7222:mi2 +0x7223:tang3 +0x7224:lan4 +0x7225:zhu2 +0x7227:ling2 +0x7228:cuan4 +0x7229:yu4 +0x722a:zhua3 +0x722c:pa2 +0x722d:zheng1 +0x722e:pao2 +0x722f:cheng1 +0x7230:yuan2 +0x7231:ai4 +0x7232:wei4 +0x7234:jue2 +0x7235:jue2 +0x7236:fu4 +0x7237:ye2 +0x7238:ba4 +0x7239:die1 +0x723a:ye2 +0x723b:yao2 +0x723c:zu3 +0x723d:shuang3 +0x723e:er3 +0x723f:qiang2 +0x7240:chuang2 +0x7241:ge1 +0x7242:zang1 +0x7243:die2 +0x7244:qiang1 +0x7245:yong2 +0x7246:qiang2 +0x7247:pian4 +0x7248:ban3 +0x7249:pan4 +0x724a:shao2 +0x724b:jian1 +0x724c:pai2 +0x724d:du2 +0x724e:chuang1 +0x724f:tou2 +0x7250:zha2 +0x7251:bian1 +0x7252:die2 +0x7253:bang3 +0x7254:bo2 +0x7255:chuang1 +0x7256:you3 +0x7258:du2 +0x7259:ya2 +0x725a:cheng4 +0x725b:niu2 +0x725d:pin4 +0x725e:jiu1 +0x725f:mou2 +0x7260:tuo2 +0x7261:mu3 +0x7262:lao2 +0x7263:ren4 +0x7264:mang2 +0x7265:fang1 +0x7266:mao2 +0x7267:mu4 +0x7268:gang1 +0x7269:wu4 +0x726a:yan4 +0x726b:ge1 +0x726c:bei4 +0x726d:si4 +0x726e:jian4 +0x726f:gu3 +0x7270:you4 +0x7271:ge1 +0x7272:sheng1 +0x7273:mu3 +0x7274:di3 +0x7275:qian1 +0x7276:quan4 +0x7277:quan2 +0x7278:zi4 +0x7279:te4 +0x727a:xi1 +0x727b:mang2 +0x727c:keng1 +0x727d:qian1 +0x727e:wu2 +0x727f:gu4 +0x7280:xi1 +0x7281:li2 +0x7282:li2 +0x7283:pou3 +0x7284:ji1 +0x7285:gang1 +0x7286:zhi2 +0x7287:ben1 +0x7288:quan2 +0x7289:run2 +0x728a:du2 +0x728b:ju4 +0x728c:jia1 +0x728d:jian1 +0x728e:feng1 +0x728f:pian1 +0x7290:ke1 +0x7291:ju2 +0x7292:kao4 +0x7293:chu2 +0x7294:xi4 +0x7295:bei4 +0x7296:luo4 +0x7297:jie4 +0x7298:ma2 +0x7299:san1 +0x729a:wei4 +0x729b:li2 +0x729c:dun1 +0x729d:tong2 +0x729f:jiang4 +0x72a1:li4 +0x72a2:du2 +0x72a3:lie4 +0x72a4:pi2 +0x72a5:piao3 +0x72a6:bao4 +0x72a7:xi1 +0x72a8:chou1 +0x72a9:wei4 +0x72aa:kui2 +0x72ab:chou1 +0x72ac:quan3 +0x72ae:ba2 +0x72af:fan4 +0x72b0:qiu2 +0x72b1:ji3 +0x72b2:cai2 +0x72b3:chuo2 +0x72b4:an4 +0x72b5:ge1 +0x72b6:zhuang4 +0x72b7:guang3 +0x72b8:ma4 +0x72b9:you2 +0x72ba:kang4 +0x72bb:bo2 +0x72bc:hou3 +0x72bd:ya2 +0x72be:yin2 +0x72bf:huan1 +0x72c0:zhuang4 +0x72c1:yun3 +0x72c2:kuang2 +0x72c3:niu3 +0x72c4:di2 +0x72c5:qing1 +0x72c6:zhong4 +0x72c7:mu4 +0x72c8:bei4 +0x72c9:pi1 +0x72ca:ju2 +0x72cb:ni2 +0x72cc:sheng1 +0x72cd:pao2 +0x72ce:xia2 +0x72cf:tuo2 +0x72d0:hu2 +0x72d1:ling2 +0x72d2:fei4 +0x72d3:pi1 +0x72d4:ni3 +0x72d5:ao3 +0x72d6:you4 +0x72d7:gou3 +0x72d8:yue4 +0x72d9:ju1 +0x72da:dan4 +0x72db:po4 +0x72dc:gu3 +0x72dd:xian3 +0x72de:ning2 +0x72df:huan2 +0x72e0:hen3 +0x72e1:jiao3 +0x72e2:he2 +0x72e3:zhao4 +0x72e4:ji2 +0x72e5:xun4 +0x72e6:shan1 +0x72e7:ta4 +0x72e8:rong2 +0x72e9:shou4 +0x72ea:tong1 +0x72eb:lao3 +0x72ec:du2 +0x72ed:xia2 +0x72ee:shi1 +0x72ef:hua2 +0x72f0:zheng1 +0x72f1:yu4 +0x72f2:sun1 +0x72f3:yu2 +0x72f4:bi4 +0x72f5:mang2 +0x72f6:xi3 +0x72f7:juan4 +0x72f8:li2 +0x72f9:xia2 +0x72fa:yin2 +0x72fb:suan1 +0x72fc:lang2 +0x72fd:bei4 +0x72fe:zhi4 +0x72ff:yan2 +0x7300:sha1 +0x7301:li4 +0x7302:han4 +0x7303:xian3 +0x7304:jing1 +0x7305:pai2 +0x7306:fei1 +0x7307:yao2 +0x7308:ba4 +0x7309:qi2 +0x730a:ni2 +0x730b:biao1 +0x730c:yin4 +0x730d:lai2 +0x730e:xi2 +0x730f:jian1 +0x7310:qiang1 +0x7311:kun1 +0x7312:yan1 +0x7313:guo3 +0x7314:zong4 +0x7315:mi2 +0x7316:chang1 +0x7317:yi1 +0x7318:zhi4 +0x7319:zheng1 +0x731a:ya2 +0x731b:meng3 +0x731c:cai1 +0x731d:cu4 +0x731e:she4 +0x7321:luo2 +0x7322:hu2 +0x7323:zong1 +0x7324:ji4 +0x7325:wei3 +0x7326:feng1 +0x7327:wo1 +0x7328:yuan2 +0x7329:xing1 +0x732a:zhu1 +0x732b:mao1 +0x732c:wei4 +0x732d:yuan2 +0x732e:xian4 +0x732f:tuan1 +0x7330:ya4 +0x7331:nao2 +0x7332:xie1 +0x7333:jia1 +0x7334:hou2 +0x7335:bian1 +0x7336:you2 +0x7337:you2 +0x7338:mei2 +0x7339:zha1 +0x733a:yao2 +0x733b:sun1 +0x733c:bo2 +0x733d:ming2 +0x733e:hua2 +0x733f:yuan2 +0x7340:sou1 +0x7341:ma4 +0x7342:yuan2 +0x7343:dai1 +0x7344:yu4 +0x7345:shi1 +0x7346:hao2 +0x7348:yi4 +0x7349:zhen1 +0x734a:chuang4 +0x734b:hao2 +0x734c:man4 +0x734d:jing4 +0x734e:jiang3 +0x734f:mu2 +0x7350:zhang1 +0x7351:chan2 +0x7352:ao2 +0x7353:ao2 +0x7354:hao2 +0x7355:cui1 +0x7356:fen2 +0x7357:jue2 +0x7358:bi4 +0x7359:bi4 +0x735a:huang2 +0x735b:pu2 +0x735c:lin2 +0x735d:yu4 +0x735e:tong2 +0x735f:yao4 +0x7360:liao2 +0x7361:shuo4 +0x7362:xiao1 +0x7365:xi2 +0x7366:ge2 +0x7367:juan4 +0x7368:du2 +0x7369:hui4 +0x736a:kuai4 +0x736b:xian3 +0x736c:xie4 +0x736d:ta4 +0x736e:xian3 +0x736f:xun1 +0x7370:ning2 +0x7371:pin2 +0x7372:huo4 +0x7373:nou4 +0x7374:meng2 +0x7375:lie4 +0x7376:nao2 +0x7377:guang3 +0x7378:shou4 +0x7379:lu2 +0x737a:ta3 +0x737b:xian4 +0x737c:mi2 +0x737d:rang2 +0x737e:huan1 +0x737f:nao2 +0x7380:luo2 +0x7381:xian3 +0x7382:qi2 +0x7383:jue2 +0x7384:xuan2 +0x7385:miao4 +0x7386:zi1 +0x7387:lv4 +0x7388:lu2 +0x7389:yu4 +0x738a:su4 +0x738b:wang2 +0x738c:qiu2 +0x738d:ga3 +0x738e:ding1 +0x738f:le4 +0x7390:ba1 +0x7391:ji1 +0x7392:hong2 +0x7393:di4 +0x7394:chuan4 +0x7395:gan1 +0x7396:jiu3 +0x7397:yu2 +0x7398:ji3 +0x7399:yu2 +0x739a:yang2 +0x739b:ma3 +0x739c:gong1 +0x739d:wu3 +0x739e:fu1 +0x739f:min2 +0x73a0:jie4 +0x73a1:ya4 +0x73a2:bin1 +0x73a3:bian4 +0x73a4:bang4 +0x73a5:yue4 +0x73a6:jue2 +0x73a7:yun3 +0x73a8:jue2 +0x73a9:wan2 +0x73aa:jian1 +0x73ab:mei2 +0x73ac:dan3 +0x73ad:pi2 +0x73ae:wei3 +0x73af:huan2 +0x73b0:xian4 +0x73b1:qiang1 +0x73b2:ling2 +0x73b3:dai4 +0x73b4:yi4 +0x73b5:an2 +0x73b6:ping2 +0x73b7:dian4 +0x73b8:fu2 +0x73b9:xuan2 +0x73ba:xi3 +0x73bb:bo1 +0x73bc:ci3 +0x73bd:gou3 +0x73be:jia3 +0x73bf:shao2 +0x73c0:po4 +0x73c1:ci2 +0x73c2:ke1 +0x73c3:ran3 +0x73c4:sheng1 +0x73c5:shen1 +0x73c6:yi2 +0x73c7:zu3 +0x73c8:jia1 +0x73c9:min2 +0x73ca:shan1 +0x73cb:liu3 +0x73cc:bi4 +0x73cd:zhen1 +0x73ce:zhen1 +0x73cf:jue2 +0x73d0:fa4 +0x73d1:long2 +0x73d2:jin1 +0x73d3:jiao4 +0x73d4:jian4 +0x73d5:li4 +0x73d6:guang1 +0x73d7:xian1 +0x73d8:zhou1 +0x73d9:gong3 +0x73da:yan1 +0x73db:xiu4 +0x73dc:yang2 +0x73dd:xu3 +0x73de:luo4 +0x73df:su4 +0x73e0:zhu1 +0x73e1:qin2 +0x73e2:ken4 +0x73e3:xun2 +0x73e4:bao3 +0x73e5:er3 +0x73e6:xiang4 +0x73e7:yao2 +0x73e8:xia2 +0x73e9:heng2 +0x73ea:gui1 +0x73eb:chong1 +0x73ec:xu4 +0x73ed:ban1 +0x73ee:pei4 +0x73f0:dang1 +0x73f2:hun2 +0x73f3:wen2 +0x73f4:e2 +0x73f5:cheng2 +0x73f6:di4 +0x73f7:wu3 +0x73f8:wu2 +0x73f9:cheng2 +0x73fa:jun4 +0x73fb:mei2 +0x73fc:bei4 +0x73fd:ting3 +0x73fe:xian4 +0x73ff:chuo4 +0x7400:han2 +0x7401:xuan2 +0x7402:yan2 +0x7403:qiu2 +0x7404:quan3 +0x7405:lang2 +0x7406:li3 +0x7407:xiu4 +0x7408:fu2 +0x7409:liu2 +0x740a:ye2 +0x740b:xi1 +0x740c:ling2 +0x740d:li4 +0x740e:jin4 +0x740f:lian2 +0x7410:suo3 +0x7413:wan2 +0x7414:dian4 +0x7415:pin2 +0x7416:zhan3 +0x7417:cui4 +0x7418:min2 +0x7419:yu4 +0x741a:ju1 +0x741b:chen1 +0x741c:lai2 +0x741d:wen2 +0x741e:sheng4 +0x741f:wei2 +0x7420:dian3 +0x7421:chu4 +0x7422:zhuo2 +0x7423:pei3 +0x7424:cheng1 +0x7425:hu3 +0x7426:qi2 +0x7427:e4 +0x7428:kun1 +0x7429:chang1 +0x742a:qi2 +0x742b:beng3 +0x742c:wan3 +0x742d:lu4 +0x742e:cong2 +0x742f:guan3 +0x7430:yan3 +0x7431:diao1 +0x7432:bei4 +0x7433:lin2 +0x7434:qin2 +0x7435:pi2 +0x7436:pa2 +0x7437:que4 +0x7438:zhuo2 +0x7439:qin2 +0x743a:fa4 +0x743c:qiong2 +0x743d:du3 +0x743e:jie4 +0x743f:hun2 +0x7440:yu3 +0x7441:mao4 +0x7442:mei2 +0x7444:xuan1 +0x7445:ti2 +0x7446:xing1 +0x7447:dai4 +0x7448:rou2 +0x7449:min2 +0x744a:zhen1 +0x744b:wei3 +0x744c:ruan3 +0x744d:huan4 +0x744e:jie1 +0x744f:chuan1 +0x7450:jian3 +0x7451:zhuan4 +0x7452:yang2 +0x7453:lian4 +0x7454:quan2 +0x7455:xia2 +0x7456:duan4 +0x7457:yuan4 +0x7458:ye2 +0x7459:nao3 +0x745a:hu2 +0x745b:ying1 +0x745c:yu2 +0x745d:huang2 +0x745e:rui4 +0x745f:se4 +0x7460:liu2 +0x7462:rong2 +0x7463:suo3 +0x7464:yao2 +0x7465:wen1 +0x7466:wu1 +0x7467:jin1 +0x7468:jin4 +0x7469:ying2 +0x746a:ma3 +0x746b:tao1 +0x746c:liu2 +0x746d:tang2 +0x746e:li4 +0x746f:lang2 +0x7470:gui1 +0x7471:tian4 +0x7472:qiang1 +0x7473:cuo3 +0x7474:jue2 +0x7475:zhao3 +0x7476:yao2 +0x7477:ai4 +0x7478:bin1 +0x7479:tu2 +0x747a:chang2 +0x747b:kun1 +0x747c:zhuan1 +0x747d:cong1 +0x747e:jin3 +0x747f:yi1 +0x7480:cui3 +0x7481:cong1 +0x7482:qi2 +0x7483:li2 +0x7484:ying3 +0x7485:suo3 +0x7486:qiu2 +0x7487:xuan2 +0x7488:ao2 +0x7489:lian2 +0x748a:men2 +0x748b:zhang1 +0x748c:yin2 +0x748e:ying1 +0x748f:zhi4 +0x7490:lu4 +0x7491:wu2 +0x7492:deng1 +0x7494:zeng1 +0x7495:xun2 +0x7496:qu2 +0x7497:dang4 +0x7498:lin2 +0x7499:liao2 +0x749a:qiong2 +0x749b:su4 +0x749c:huang2 +0x749d:gui1 +0x749e:pu2 +0x749f:jing3 +0x74a0:fan2 +0x74a1:jin4 +0x74a2:liu2 +0x74a3:ji1 +0x74a5:jing3 +0x74a6:ai4 +0x74a7:bi4 +0x74a8:can4 +0x74a9:qu2 +0x74aa:zao3 +0x74ab:dang1 +0x74ac:jiao3 +0x74ad:gun4 +0x74ae:tan3 +0x74af:hui4 +0x74b0:huan2 +0x74b1:se4 +0x74b2:sui4 +0x74b3:tian2 +0x74b5:yu2 +0x74b6:jin4 +0x74b7:lu2 +0x74b8:bin1 +0x74b9:shou4 +0x74ba:wen4 +0x74bb:zui3 +0x74bc:lan2 +0x74bd:xi3 +0x74be:ji4 +0x74bf:xuan2 +0x74c0:ruan3 +0x74c1:huo4 +0x74c2:gai4 +0x74c3:lei2 +0x74c4:du2 +0x74c5:li4 +0x74c6:zhi2 +0x74c7:rou2 +0x74c8:li2 +0x74c9:zan4 +0x74ca:qiong2 +0x74cb:zhe2 +0x74cc:gui1 +0x74cd:sui4 +0x74ce:la4 +0x74cf:long2 +0x74d0:lu2 +0x74d1:li4 +0x74d2:zan4 +0x74d3:lan4 +0x74d4:ying1 +0x74d5:mi2 +0x74d6:xiang1 +0x74d7:xi1 +0x74d8:guan4 +0x74d9:dao4 +0x74da:zan4 +0x74db:huan2 +0x74dc:gua1 +0x74dd:bo2 +0x74de:die2 +0x74df:bao2 +0x74e0:hu4 +0x74e1:zhi2 +0x74e2:piao2 +0x74e3:ban4 +0x74e4:rang2 +0x74e5:li4 +0x74e6:wa3 +0x74e8:jiang1 +0x74ea:fan3 +0x74eb:pen2 +0x74ec:fang3 +0x74ed:dan3 +0x74ee:weng4 +0x74ef:ou1 +0x74f3:hu2 +0x74f4:ling2 +0x74f5:yi2 +0x74f6:ping2 +0x74f7:ci2 +0x74f9:juan4 +0x74fa:chang2 +0x74fb:chi1 +0x74fd:dang4 +0x74fe:meng3 +0x74ff:pou3 +0x7500:zhui4 +0x7501:ping2 +0x7502:bian1 +0x7503:zhou4 +0x7504:zhen1 +0x7506:ci2 +0x7507:ying1 +0x7508:qi4 +0x7509:xian2 +0x750a:lou3 +0x750b:di4 +0x750c:ou1 +0x750d:meng2 +0x750e:zhuan1 +0x750f:peng4 +0x7510:lin2 +0x7511:zeng4 +0x7512:wu3 +0x7513:pi4 +0x7514:dan1 +0x7515:weng4 +0x7516:ying1 +0x7517:yan3 +0x7518:gan1 +0x7519:dai4 +0x751a:shen2 +0x751b:tian2 +0x751c:tian2 +0x751d:han1 +0x751e:chang2 +0x751f:sheng1 +0x7520:qing2 +0x7521:shen1 +0x7522:chan3 +0x7523:chan3 +0x7524:rui2 +0x7525:sheng1 +0x7526:su1 +0x7527:sen1 +0x7528:yong4 +0x7529:shuai3 +0x752a:lu4 +0x752b:fu3 +0x752c:yong3 +0x752d:beng2 +0x752e:feng4 +0x752f:ning2 +0x7530:tian2 +0x7531:you2 +0x7532:jia3 +0x7533:shen1 +0x7534:zha2 +0x7535:dian4 +0x7536:fu2 +0x7537:nan2 +0x7538:dian4 +0x7539:ping2 +0x753a:ting3 +0x753b:hua4 +0x753c:ting3 +0x753d:quan3 +0x753e:zi1 +0x753f:meng2 +0x7540:bi4 +0x7541:qi2 +0x7542:liu4 +0x7543:xun2 +0x7544:liu2 +0x7545:chang4 +0x7546:mu3 +0x7547:yun2 +0x7548:fan4 +0x7549:fu2 +0x754a:geng1 +0x754b:tian2 +0x754c:jie4 +0x754d:jie4 +0x754e:quan3 +0x754f:wei4 +0x7550:fu2 +0x7551:tian2 +0x7552:mu3 +0x7554:pan4 +0x7555:jiang1 +0x7556:wa1 +0x7557:da2 +0x7558:nan2 +0x7559:liu2 +0x755a:ben3 +0x755b:zhen3 +0x755c:chu4 +0x755d:mu3 +0x755e:mu3 +0x755f:ce4 +0x7561:gai1 +0x7562:bi4 +0x7563:da2 +0x7564:zhi4 +0x7565:lve4 +0x7566:qi2 +0x7567:lve4 +0x7568:pan1 +0x756a:fan1 +0x756b:hua4 +0x756c:yu2 +0x756d:yu2 +0x756e:mu3 +0x756f:jun4 +0x7570:yi4 +0x7571:liu2 +0x7572:yu2 +0x7573:die2 +0x7574:chou2 +0x7575:hua4 +0x7576:dang1 +0x7577:chuo4 +0x7578:ji1 +0x7579:wan3 +0x757a:jiang1 +0x757b:sheng2 +0x757c:chang4 +0x757d:tuan3 +0x757e:lei2 +0x757f:ji1 +0x7580:cha1 +0x7581:liu2 +0x7583:tuan3 +0x7584:lin2 +0x7585:jiang1 +0x7586:jiang1 +0x7587:chou2 +0x7588:bo4 +0x7589:die2 +0x758a:die2 +0x758b:pi3 +0x758c:nie4 +0x758d:dan4 +0x758e:shu1 +0x758f:shu1 +0x7590:zhi4 +0x7591:yi2 +0x7592:chuang2 +0x7593:nai3 +0x7594:ding1 +0x7595:bi3 +0x7596:jie2 +0x7597:liao2 +0x7598:gang1 +0x7599:ge1 +0x759a:jiu4 +0x759b:zhou3 +0x759c:xia4 +0x759d:shan4 +0x759e:xu1 +0x759f:nve4 +0x75a0:li4 +0x75a1:yang2 +0x75a2:chen4 +0x75a3:you2 +0x75a4:ba1 +0x75a5:jie4 +0x75a6:jue2 +0x75a7:zhi1 +0x75a8:xia1 +0x75a9:cui4 +0x75aa:bi4 +0x75ab:yi4 +0x75ac:li4 +0x75ad:zong4 +0x75ae:chuang1 +0x75af:feng1 +0x75b0:zhu4 +0x75b1:pao4 +0x75b2:pi2 +0x75b3:gan1 +0x75b4:ke1 +0x75b5:ci1 +0x75b6:xie4 +0x75b7:qi2 +0x75b8:dan3 +0x75b9:zhen3 +0x75ba:fa2 +0x75bb:zhi3 +0x75bc:teng2 +0x75bd:ju1 +0x75be:ji2 +0x75bf:fei4 +0x75c0:qu2 +0x75c1:dian4 +0x75c2:jia1 +0x75c3:xian2 +0x75c4:zha4 +0x75c5:bing4 +0x75c6:ni4 +0x75c7:zheng4 +0x75c8:yong1 +0x75c9:jing4 +0x75ca:quan2 +0x75cb:chong2 +0x75cc:tong1 +0x75cd:yi2 +0x75ce:kai1 +0x75cf:wei3 +0x75d0:hui2 +0x75d1:duo3 +0x75d2:yang3 +0x75d3:chi4 +0x75d4:zhi4 +0x75d5:hen2 +0x75d6:ya3 +0x75d7:mei4 +0x75d8:dou4 +0x75d9:jing4 +0x75da:xiao1 +0x75db:tong4 +0x75dc:tu1 +0x75dd:mang2 +0x75de:pi3 +0x75df:xiao1 +0x75e0:suan1 +0x75e1:pu1 +0x75e2:li4 +0x75e3:zhi4 +0x75e4:cuo2 +0x75e5:duo2 +0x75e6:wu4 +0x75e7:sha1 +0x75e8:lao2 +0x75e9:shou4 +0x75ea:huan4 +0x75eb:xian2 +0x75ec:yi4 +0x75ed:peng2 +0x75ee:zhang4 +0x75ef:guan3 +0x75f0:tan2 +0x75f1:fei4 +0x75f2:ma2 +0x75f3:lin2 +0x75f4:chi1 +0x75f5:ji4 +0x75f6:dian3 +0x75f7:an1 +0x75f8:chi4 +0x75f9:bi4 +0x75fa:bi4 +0x75fb:min2 +0x75fc:gu4 +0x75fd:dui1 +0x75fe:e1 +0x75ff:wei3 +0x7600:yu1 +0x7601:cui4 +0x7602:ya3 +0x7603:zhu2 +0x7604:cu4 +0x7605:dan4 +0x7606:shen4 +0x7607:zhong3 +0x7608:ji4 +0x7609:yu4 +0x760a:hou2 +0x760b:feng1 +0x760c:la4 +0x760d:yang2 +0x760e:shen4 +0x760f:tu2 +0x7610:yu3 +0x7611:gua1 +0x7612:wen2 +0x7613:huan4 +0x7614:ku4 +0x7615:jia3 +0x7616:yin1 +0x7617:yi4 +0x7618:lv2 +0x7619:sao1 +0x761a:jue2 +0x761b:chi4 +0x761c:xi2 +0x761d:guan1 +0x761e:yi4 +0x761f:wen1 +0x7620:ji2 +0x7621:chuang1 +0x7622:ban1 +0x7623:lei3 +0x7624:liu2 +0x7625:chai4 +0x7626:shou4 +0x7627:nve4 +0x7628:dian1 +0x7629:da5 +0x762a:pie1 +0x762b:tan1 +0x762c:zhang4 +0x762d:biao1 +0x762e:shen4 +0x762f:cu4 +0x7630:luo3 +0x7631:yi4 +0x7632:zong4 +0x7633:chou1 +0x7634:zhang4 +0x7635:zhai4 +0x7636:sou4 +0x7637:suo3 +0x7638:que2 +0x7639:diao4 +0x763a:lou4 +0x763b:lv2 +0x763c:mo4 +0x763d:jin4 +0x763e:yin3 +0x763f:ying3 +0x7640:huang2 +0x7641:fu2 +0x7642:liao2 +0x7643:long2 +0x7644:qiao2 +0x7645:liu2 +0x7646:lao2 +0x7647:xian2 +0x7648:fei4 +0x7649:dan4 +0x764a:yin4 +0x764b:he4 +0x764c:ai2 +0x764d:ban1 +0x764e:xian2 +0x764f:guan1 +0x7650:guai4 +0x7651:nong2 +0x7652:yu4 +0x7653:wei2 +0x7654:yi4 +0x7655:yong1 +0x7656:pi3 +0x7657:lei3 +0x7658:li4 +0x7659:shu3 +0x765a:dan4 +0x765b:lin3 +0x765c:dian4 +0x765d:lin3 +0x765e:lai4 +0x765f:bie3 +0x7660:ji4 +0x7661:chi1 +0x7662:yang3 +0x7663:xian3 +0x7664:jie2 +0x7665:zheng1 +0x7667:li4 +0x7668:huo4 +0x7669:lai4 +0x766b:dian1 +0x766c:xuan3 +0x766d:ying3 +0x766e:yin3 +0x766f:qu2 +0x7670:yong1 +0x7671:tan1 +0x7672:dian1 +0x7673:luo3 +0x7674:luan2 +0x7675:luan2 +0x7676:bo1 +0x7678:gui3 +0x7679:po1 +0x767a:fa1 +0x767b:deng1 +0x767c:fa1 +0x767d:bai2 +0x767e:bai3 +0x767f:qie2 +0x7680:bi1 +0x7681:zao4 +0x7682:zao4 +0x7683:mao4 +0x7684:de5 +0x7685:pa1 +0x7686:jie1 +0x7687:huang2 +0x7688:gui1 +0x7689:ci3 +0x768a:ling2 +0x768b:gao1 +0x768c:mo4 +0x768d:ji2 +0x768e:jiao3 +0x768f:peng3 +0x7690:gao1 +0x7691:ai2 +0x7692:e2 +0x7693:hao4 +0x7694:han4 +0x7695:bi1 +0x7696:wan3 +0x7697:chou2 +0x7698:qian4 +0x7699:xi1 +0x769a:ai2 +0x769b:jiong3 +0x769c:hao4 +0x769d:huang3 +0x769e:hao4 +0x769f:ze2 +0x76a0:cui3 +0x76a1:hao4 +0x76a2:xiao3 +0x76a3:ye4 +0x76a4:po2 +0x76a5:hao4 +0x76a6:jiao3 +0x76a7:ai4 +0x76a8:xing1 +0x76a9:huang4 +0x76aa:li4 +0x76ab:piao3 +0x76ac:he4 +0x76ad:jiao4 +0x76ae:pi2 +0x76af:gan3 +0x76b0:pao4 +0x76b1:zhou4 +0x76b2:jun1 +0x76b3:qiu2 +0x76b4:cun1 +0x76b5:que4 +0x76b6:zha1 +0x76b7:gu3 +0x76b8:jun1 +0x76b9:jun1 +0x76ba:zhou4 +0x76bb:zha1 +0x76bc:gu3 +0x76bd:zhan3 +0x76be:du2 +0x76bf:min3 +0x76c0:qi3 +0x76c1:ying2 +0x76c2:yu2 +0x76c3:bei1 +0x76c4:zhao1 +0x76c5:zhong1 +0x76c6:pen2 +0x76c7:he2 +0x76c8:ying2 +0x76c9:he2 +0x76ca:yi4 +0x76cb:bo1 +0x76cc:wan3 +0x76cd:he2 +0x76ce:ang4 +0x76cf:zhan3 +0x76d0:yan2 +0x76d1:jian1 +0x76d2:he2 +0x76d3:yu1 +0x76d4:kui1 +0x76d5:fan4 +0x76d6:gai4 +0x76d7:dao4 +0x76d8:pan2 +0x76d9:fu3 +0x76da:qiu2 +0x76db:sheng4 +0x76dc:dao4 +0x76dd:lu4 +0x76de:zhan3 +0x76df:meng2 +0x76e0:li3 +0x76e1:jin4 +0x76e2:xu4 +0x76e3:jian1 +0x76e4:pan2 +0x76e5:guan4 +0x76e6:an1 +0x76e7:lu2 +0x76e8:shu3 +0x76e9:zhou1 +0x76ea:dang4 +0x76eb:an1 +0x76ec:gu3 +0x76ed:li4 +0x76ee:mu4 +0x76ef:ding1 +0x76f0:gan3 +0x76f1:xu1 +0x76f2:mang2 +0x76f3:mang2 +0x76f4:zhi2 +0x76f5:qi4 +0x76f6:ruan3 +0x76f7:tian2 +0x76f8:xiang1 +0x76f9:dun3 +0x76fa:xin1 +0x76fb:xi4 +0x76fc:pan4 +0x76fd:feng1 +0x76fe:dun4 +0x76ff:min2 +0x7700:ming2 +0x7701:sheng3 +0x7702:shi4 +0x7703:yun2 +0x7704:mian3 +0x7705:pan1 +0x7706:fang3 +0x7707:miao3 +0x7708:dan1 +0x7709:mei2 +0x770a:mao4 +0x770b:kan4 +0x770c:xian4 +0x770d:ou1 +0x770e:shi4 +0x770f:yang1 +0x7710:zheng1 +0x7711:yao3 +0x7712:shen4 +0x7713:huo4 +0x7714:da4 +0x7715:zhen3 +0x7716:kuang4 +0x7717:ju1 +0x7718:shen4 +0x7719:chi4 +0x771a:sheng3 +0x771b:mei4 +0x771c:mo4 +0x771d:zhu4 +0x771e:zhen1 +0x771f:zhen1 +0x7720:mian2 +0x7721:di1 +0x7722:yuan1 +0x7723:die2 +0x7724:yi2 +0x7725:zi4 +0x7726:zi4 +0x7727:chao3 +0x7728:zha3 +0x7729:xuan4 +0x772a:bing3 +0x772b:mi3 +0x772c:long2 +0x772d:sui1 +0x772e:dong4 +0x772f:mi3 +0x7730:die2 +0x7731:yi2 +0x7732:er4 +0x7733:ming3 +0x7734:xuan4 +0x7735:chi1 +0x7736:kuang4 +0x7737:juan4 +0x7738:mou2 +0x7739:zhen4 +0x773a:tiao4 +0x773b:yang2 +0x773c:yan3 +0x773d:mo4 +0x773e:zhong4 +0x773f:mai4 +0x7740:zhao2 +0x7741:zheng1 +0x7742:mei2 +0x7743:jun4 +0x7744:shao4 +0x7745:han4 +0x7746:huan3 +0x7747:di4 +0x7748:cheng3 +0x7749:cuo1 +0x774a:juan4 +0x774b:e2 +0x774c:wan3 +0x774d:xian4 +0x774e:xi1 +0x774f:kun4 +0x7750:lai4 +0x7751:jian3 +0x7752:shan3 +0x7753:tian3 +0x7754:hun3 +0x7755:wan3 +0x7756:ling2 +0x7757:shi4 +0x7758:qiong2 +0x7759:lie4 +0x775a:yai2 +0x775b:jing1 +0x775c:zheng1 +0x775d:li2 +0x775e:lai4 +0x775f:sui4 +0x7760:juan4 +0x7761:shui4 +0x7762:sui1 +0x7763:du1 +0x7764:bi4 +0x7765:bi4 +0x7766:mu4 +0x7767:hun1 +0x7768:ni4 +0x7769:lu4 +0x776a:yi4 +0x776b:jie2 +0x776c:cai3 +0x776d:zhou3 +0x776e:yu2 +0x776f:hun1 +0x7770:ma4 +0x7771:xia4 +0x7772:xing3 +0x7773:xi1 +0x7774:gun4 +0x7776:chun3 +0x7777:jian1 +0x7778:mei4 +0x7779:du3 +0x777a:hou2 +0x777b:xuan1 +0x777c:ti4 +0x777d:kui2 +0x777e:gao1 +0x777f:rui4 +0x7780:mao4 +0x7781:xu4 +0x7782:fa1 +0x7783:wen1 +0x7784:miao2 +0x7785:chou3 +0x7786:kui4 +0x7787:mi1 +0x7788:weng3 +0x7789:kou4 +0x778a:dang4 +0x778b:chen1 +0x778c:ke1 +0x778d:sou3 +0x778e:xia1 +0x778f:qiong2 +0x7790:mao4 +0x7791:ming2 +0x7792:man2 +0x7793:shui4 +0x7794:ze2 +0x7795:zhang4 +0x7796:yi4 +0x7797:diao1 +0x7798:ou1 +0x7799:mo4 +0x779a:shun4 +0x779b:cong1 +0x779c:lou1 +0x779d:chi1 +0x779e:man2 +0x779f:piao3 +0x77a0:cheng1 +0x77a1:ji4 +0x77a2:meng2 +0x77a4:run2 +0x77a5:pie1 +0x77a6:xi1 +0x77a7:qiao2 +0x77a8:pu2 +0x77a9:zhu3 +0x77aa:deng4 +0x77ab:shen3 +0x77ac:shun4 +0x77ad:liao3 +0x77ae:che4 +0x77af:xian2 +0x77b0:kan4 +0x77b1:ye4 +0x77b2:xu4 +0x77b3:tong2 +0x77b4:mou2 +0x77b5:lin2 +0x77b6:kui4 +0x77b7:xian2 +0x77b8:ye4 +0x77b9:ai4 +0x77ba:hui4 +0x77bb:zhan1 +0x77bc:jian3 +0x77bd:gu3 +0x77be:zhao4 +0x77bf:ju4 +0x77c0:wei2 +0x77c1:chou3 +0x77c2:sao4 +0x77c3:ning3 +0x77c4:xun1 +0x77c5:yao4 +0x77c6:huo4 +0x77c7:meng2 +0x77c8:mian2 +0x77c9:bin1 +0x77ca:mian2 +0x77cb:li4 +0x77cc:kuang4 +0x77cd:jue2 +0x77ce:xuan1 +0x77cf:mian2 +0x77d0:huo4 +0x77d1:lu2 +0x77d2:meng2 +0x77d3:long2 +0x77d4:guan4 +0x77d5:man3 +0x77d6:xi3 +0x77d7:chu4 +0x77d8:tang3 +0x77d9:kan4 +0x77da:zhu3 +0x77db:mao2 +0x77dc:jin1 +0x77dd:lin2 +0x77de:yu4 +0x77df:shuo4 +0x77e0:ce4 +0x77e1:jue2 +0x77e2:shi3 +0x77e3:yi3 +0x77e4:shen3 +0x77e5:zhi1 +0x77e6:hou2 +0x77e7:shen3 +0x77e8:ying3 +0x77e9:ju3 +0x77ea:zhou1 +0x77eb:jiao3 +0x77ec:cuo2 +0x77ed:duan3 +0x77ee:ai3 +0x77ef:jiao3 +0x77f0:zeng1 +0x77f1:huo4 +0x77f2:bai3 +0x77f3:shi2 +0x77f4:ding4 +0x77f5:qi4 +0x77f6:ji1 +0x77f7:zi3 +0x77f8:gan1 +0x77f9:wu4 +0x77fa:tuo1 +0x77fb:ku4 +0x77fc:qiang1 +0x77fd:xi4 +0x77fe:fan2 +0x77ff:kuang4 +0x7800:dang4 +0x7801:ma3 +0x7802:sha1 +0x7803:dan1 +0x7804:jue2 +0x7805:li4 +0x7806:fu1 +0x7807:min2 +0x7808:nuo3 +0x7809:huo4 +0x780a:kang4 +0x780b:zhi3 +0x780c:qi4 +0x780d:kan3 +0x780e:jie4 +0x780f:fen1 +0x7810:e4 +0x7811:ya4 +0x7812:pi1 +0x7813:zhe2 +0x7814:yan2 +0x7815:sui4 +0x7816:zhuan1 +0x7817:che1 +0x7818:dun4 +0x7819:pan1 +0x781a:yan4 +0x781c:feng1 +0x781d:fa2 +0x781e:mo4 +0x781f:zha4 +0x7820:qu1 +0x7821:yu4 +0x7822:luo3 +0x7823:tuo2 +0x7824:tuo2 +0x7825:di3 +0x7826:zhai4 +0x7827:zhen1 +0x7828:ai4 +0x7829:fei4 +0x782a:mu3 +0x782b:zhu3 +0x782c:li4 +0x782d:bian1 +0x782e:nu3 +0x782f:ping1 +0x7830:peng1 +0x7831:ling2 +0x7832:pao4 +0x7833:le4 +0x7834:po4 +0x7835:bo1 +0x7836:po4 +0x7837:shen1 +0x7838:za2 +0x7839:nuo3 +0x783a:li4 +0x783b:long2 +0x783c:tong2 +0x783e:li4 +0x7840:chu3 +0x7841:keng1 +0x7842:quan2 +0x7843:zhu1 +0x7844:kuang1 +0x7845:gui1 +0x7846:e4 +0x7847:nao2 +0x7848:jia2 +0x7849:lu4 +0x784a:wei3 +0x784b:ai4 +0x784c:luo4 +0x784d:ken4 +0x784e:xing2 +0x784f:yan2 +0x7850:tong2 +0x7851:peng1 +0x7852:xi1 +0x7854:hong2 +0x7855:shuo4 +0x7856:xia2 +0x7857:qiao1 +0x7859:wei4 +0x785a:qiao2 +0x785c:keng1 +0x785d:xiao1 +0x785e:que4 +0x785f:chan4 +0x7860:lang3 +0x7861:hong2 +0x7862:yu2 +0x7863:xiao1 +0x7864:xia2 +0x7865:mang3 +0x7866:long4 +0x7867:yong3 +0x7868:che1 +0x7869:che4 +0x786a:e2 +0x786b:liu2 +0x786c:ying4 +0x786d:mang2 +0x786e:que4 +0x786f:yan4 +0x7870:sha1 +0x7871:kun3 +0x7872:yu4 +0x7875:lu3 +0x7876:chen3 +0x7877:jian3 +0x7878:nve4 +0x7879:song1 +0x787a:zhuo2 +0x787b:keng1 +0x787c:peng2 +0x787d:yan3 +0x787e:zhui4 +0x787f:kong1 +0x7880:ceng2 +0x7881:qi2 +0x7882:zong4 +0x7883:qing4 +0x7884:lin2 +0x7885:jun1 +0x7886:bo1 +0x7887:ding4 +0x7888:min2 +0x7889:diao1 +0x788a:jian1 +0x788b:he4 +0x788c:lu4 +0x788d:ai4 +0x788e:sui4 +0x788f:que4 +0x7890:ling2 +0x7891:bei1 +0x7892:yin2 +0x7893:dui4 +0x7894:wu3 +0x7895:qi2 +0x7896:lun4 +0x7897:wan3 +0x7898:dian3 +0x7899:gang1 +0x789a:bei4 +0x789b:qi4 +0x789c:chen3 +0x789d:ruan3 +0x789e:yan2 +0x789f:die2 +0x78a0:ding4 +0x78a1:du2 +0x78a2:tuo2 +0x78a3:jie2 +0x78a4:ying1 +0x78a5:bian3 +0x78a6:ke4 +0x78a7:bi4 +0x78a8:wei1 +0x78a9:shuo4 +0x78aa:zhen1 +0x78ab:duan4 +0x78ac:xia2 +0x78ad:dang4 +0x78ae:ti2 +0x78af:nao3 +0x78b0:peng4 +0x78b1:jian3 +0x78b2:di4 +0x78b3:tan4 +0x78b4:cha2 +0x78b6:qi4 +0x78b8:feng1 +0x78b9:xuan4 +0x78ba:que4 +0x78bb:que4 +0x78bc:ma3 +0x78bd:gong1 +0x78be:nian3 +0x78bf:su4 +0x78c0:e2 +0x78c1:ci2 +0x78c2:liu4 +0x78c3:si1 +0x78c4:tang2 +0x78c5:bang4 +0x78c6:hua2 +0x78c7:pi1 +0x78c8:wei3 +0x78c9:sang3 +0x78ca:lei3 +0x78cb:cuo1 +0x78cc:zhen1 +0x78cd:xia2 +0x78ce:qi1 +0x78cf:lian2 +0x78d0:pan2 +0x78d1:wei4 +0x78d2:yun3 +0x78d3:dui1 +0x78d4:zhe2 +0x78d5:ke1 +0x78d6:la1 +0x78d8:qing4 +0x78d9:gun3 +0x78da:zhuan1 +0x78db:chan2 +0x78dc:qi4 +0x78dd:ao2 +0x78de:peng1 +0x78df:lu4 +0x78e0:lu3 +0x78e1:kan4 +0x78e2:qiang3 +0x78e3:chen3 +0x78e4:yin3 +0x78e5:lei3 +0x78e6:biao1 +0x78e7:qi4 +0x78e8:mo2 +0x78e9:qi1 +0x78ea:cui1 +0x78eb:zong1 +0x78ec:qing4 +0x78ed:chuo4 +0x78ef:ji1 +0x78f0:shan4 +0x78f1:lao2 +0x78f2:qu2 +0x78f3:zeng1 +0x78f4:deng4 +0x78f5:jian4 +0x78f6:xi4 +0x78f7:lin2 +0x78f8:ding4 +0x78f9:dian4 +0x78fa:huang2 +0x78fb:pan2 +0x78fc:za2 +0x78fd:qiao1 +0x78fe:di1 +0x78ff:li4 +0x7901:jiao1 +0x7903:zhang3 +0x7904:qiao2 +0x7905:dun1 +0x7906:xian3 +0x7907:yu4 +0x7908:zhui4 +0x7909:he2 +0x790a:huo4 +0x790b:zhai2 +0x790c:lei4 +0x790d:ke3 +0x790e:chu3 +0x790f:ji2 +0x7910:que4 +0x7911:dang4 +0x7912:yi3 +0x7913:jiang1 +0x7914:pi4 +0x7915:pi1 +0x7916:yu4 +0x7917:pin1 +0x7918:qi4 +0x7919:ai4 +0x791a:kai4 +0x791b:jian1 +0x791c:yu4 +0x791d:ruan3 +0x791e:meng2 +0x791f:pao4 +0x7920:ci2 +0x7921:bo2 +0x7923:mie4 +0x7924:ca3 +0x7925:xian2 +0x7926:kuang4 +0x7927:lei4 +0x7928:lei3 +0x7929:zhi4 +0x792a:li4 +0x792b:li4 +0x792c:fan2 +0x792d:que4 +0x792e:pao4 +0x792f:ying1 +0x7930:li4 +0x7931:long2 +0x7932:long2 +0x7933:mo4 +0x7934:bo2 +0x7935:shuang1 +0x7936:guan4 +0x7937:lan2 +0x7938:zan3 +0x7939:yan2 +0x793a:shi4 +0x793b:shi4 +0x793c:li3 +0x793d:reng2 +0x793e:she4 +0x793f:yue4 +0x7940:si4 +0x7941:qi2 +0x7942:ta1 +0x7943:ma4 +0x7944:xie4 +0x7945:yao1 +0x7946:xian1 +0x7947:qi2 +0x7948:qi2 +0x7949:zhi3 +0x794a:beng1 +0x794b:dui4 +0x794c:zhong4 +0x794e:yi1 +0x794f:shi2 +0x7950:you4 +0x7951:zhi4 +0x7952:tiao2 +0x7953:fu2 +0x7954:fu4 +0x7955:mi4 +0x7956:zu3 +0x7957:zhi1 +0x7958:suan4 +0x7959:mei4 +0x795a:zuo4 +0x795b:qu1 +0x795c:hu4 +0x795d:zhu4 +0x795e:shen2 +0x795f:sui4 +0x7960:ci2 +0x7961:chai2 +0x7962:mi2 +0x7963:lv3 +0x7964:yu3 +0x7965:xiang2 +0x7966:wu2 +0x7967:tiao1 +0x7968:piao4 +0x7969:zhu1 +0x796a:gui3 +0x796b:xia2 +0x796c:zhi1 +0x796d:ji4 +0x796e:gao4 +0x796f:zhen1 +0x7970:gao4 +0x7971:shui4 +0x7972:jin1 +0x7973:chen3 +0x7974:gai1 +0x7975:kun3 +0x7976:di4 +0x7977:dao3 +0x7978:huo4 +0x7979:tao2 +0x797a:qi2 +0x797b:gu4 +0x797c:guan4 +0x797d:zui4 +0x797e:ling2 +0x797f:lu4 +0x7980:bing3 +0x7981:jin4 +0x7982:dao3 +0x7983:zhi2 +0x7984:lu4 +0x7985:shan4 +0x7986:bei1 +0x7987:zhe3 +0x7988:hui1 +0x7989:you3 +0x798a:xi4 +0x798b:yin1 +0x798c:zi1 +0x798d:huo4 +0x798e:zhen1 +0x798f:fu2 +0x7990:yuan4 +0x7991:wu2 +0x7992:xian3 +0x7993:yang2 +0x7994:ti2 +0x7995:yi1 +0x7996:mei2 +0x7997:si1 +0x7998:di4 +0x799a:zhuo2 +0x799b:zhen1 +0x799c:yong3 +0x799d:ji2 +0x799e:gao4 +0x799f:tang2 +0x79a0:si1 +0x79a1:ma4 +0x79a2:ta1 +0x79a4:xuan1 +0x79a5:qi2 +0x79a6:yu4 +0x79a7:xi3 +0x79a8:ji1 +0x79a9:si4 +0x79aa:chan2 +0x79ab:tan3 +0x79ac:kuai4 +0x79ad:sui4 +0x79ae:li3 +0x79af:nong2 +0x79b0:ni3 +0x79b1:dao3 +0x79b2:li4 +0x79b3:rang2 +0x79b4:yue4 +0x79b5:ti2 +0x79b6:zan3 +0x79b7:lei4 +0x79b8:rou2 +0x79b9:yu3 +0x79ba:yu2 +0x79bb:li2 +0x79bc:xie4 +0x79bd:qin2 +0x79be:he2 +0x79bf:tu1 +0x79c0:xiu4 +0x79c1:si1 +0x79c2:ren2 +0x79c3:tu1 +0x79c4:zi3 +0x79c5:cha2 +0x79c6:gan3 +0x79c7:yi4 +0x79c8:xian1 +0x79c9:bing3 +0x79ca:nian2 +0x79cb:qiu1 +0x79cc:qiu1 +0x79cd:zhong3 +0x79ce:fen2 +0x79cf:hao4 +0x79d0:yun2 +0x79d1:ke1 +0x79d2:miao3 +0x79d3:zhi1 +0x79d4:geng1 +0x79d5:bi3 +0x79d6:zhi1 +0x79d7:yu4 +0x79d8:mi4 +0x79d9:ku4 +0x79da:ban4 +0x79db:pi1 +0x79dc:ni2 +0x79dd:li4 +0x79de:you2 +0x79df:zu1 +0x79e0:pi1 +0x79e1:ba2 +0x79e2:ling2 +0x79e3:mo4 +0x79e4:cheng4 +0x79e5:nian2 +0x79e6:qin2 +0x79e7:yang1 +0x79e8:zuo2 +0x79e9:zhi4 +0x79ea:zhi1 +0x79eb:shu2 +0x79ec:ju4 +0x79ed:zi3 +0x79ee:huo2 +0x79ef:ji1 +0x79f0:cheng1 +0x79f1:tong2 +0x79f2:zhi4 +0x79f3:huo2 +0x79f4:he2 +0x79f5:yin1 +0x79f6:zi1 +0x79f7:zhi2 +0x79f8:jie1 +0x79f9:ren3 +0x79fa:du4 +0x79fb:yi2 +0x79fc:zhu1 +0x79fd:hui4 +0x79fe:nong2 +0x79ff:fu3 +0x7a00:xi1 +0x7a01:kao3 +0x7a02:lang2 +0x7a03:fu1 +0x7a04:ze4 +0x7a05:shui4 +0x7a06:lv3 +0x7a07:kun3 +0x7a08:gan3 +0x7a09:geng1 +0x7a0a:ti2 +0x7a0b:cheng2 +0x7a0c:tu2 +0x7a0d:shao1 +0x7a0e:shui4 +0x7a0f:ya4 +0x7a10:lun3 +0x7a11:lu4 +0x7a12:gu4 +0x7a13:zuo2 +0x7a14:ren3 +0x7a15:zhun4 +0x7a16:bang4 +0x7a17:bai4 +0x7a18:ji1 +0x7a19:zhi2 +0x7a1a:zhi4 +0x7a1b:kun3 +0x7a1c:leng2 +0x7a1d:peng2 +0x7a1e:ke1 +0x7a1f:bing3 +0x7a20:chou2 +0x7a21:zu2 +0x7a22:yu4 +0x7a23:su1 +0x7a24:lve4 +0x7a26:yi1 +0x7a27:xi4 +0x7a28:bian1 +0x7a29:ji4 +0x7a2a:fu4 +0x7a2b:bi1 +0x7a2c:nuo4 +0x7a2d:jie1 +0x7a2e:zhong3 +0x7a2f:zong1 +0x7a30:xu1 +0x7a31:cheng1 +0x7a32:dao4 +0x7a33:wen3 +0x7a34:lian2 +0x7a35:zi1 +0x7a36:yu4 +0x7a37:ji4 +0x7a38:xu4 +0x7a39:zhen3 +0x7a3a:zhi4 +0x7a3b:dao4 +0x7a3c:jia4 +0x7a3d:ji1 +0x7a3e:gao3 +0x7a3f:gao3 +0x7a40:gu3 +0x7a41:rong2 +0x7a42:sui4 +0x7a44:ji4 +0x7a45:kang1 +0x7a46:mu4 +0x7a47:shan1 +0x7a48:men2 +0x7a49:zhi4 +0x7a4a:ji4 +0x7a4b:lu4 +0x7a4c:su1 +0x7a4d:ji1 +0x7a4e:ying3 +0x7a4f:wen3 +0x7a50:qiu1 +0x7a51:se4 +0x7a53:yi4 +0x7a54:huang2 +0x7a55:qie4 +0x7a56:ji3 +0x7a57:sui4 +0x7a58:xiao1 +0x7a59:pu2 +0x7a5a:jiao1 +0x7a5b:zhuo1 +0x7a5c:tong2 +0x7a5e:lv3 +0x7a5f:sui4 +0x7a60:nong2 +0x7a61:se4 +0x7a62:hui4 +0x7a63:rang2 +0x7a64:nuo4 +0x7a65:yu4 +0x7a67:ji4 +0x7a68:tui2 +0x7a69:wen3 +0x7a6a:cheng1 +0x7a6b:huo4 +0x7a6c:gong3 +0x7a6d:lv3 +0x7a6e:biao1 +0x7a70:rang2 +0x7a71:zhuo1 +0x7a72:li2 +0x7a73:zan4 +0x7a74:xue2 +0x7a75:wa1 +0x7a76:jiu1 +0x7a77:qiong2 +0x7a78:xi4 +0x7a79:qiong2 +0x7a7a:kong1 +0x7a7b:yu1 +0x7a7c:sen1 +0x7a7d:jing3 +0x7a7e:yao4 +0x7a7f:chuan1 +0x7a80:zhun1 +0x7a81:tu1 +0x7a82:lao2 +0x7a83:qie4 +0x7a84:zhai3 +0x7a85:yao3 +0x7a86:bian3 +0x7a87:bao2 +0x7a88:yao3 +0x7a89:bing3 +0x7a8a:wa1 +0x7a8b:zhu2 +0x7a8c:jiao4 +0x7a8d:qiao4 +0x7a8e:diao4 +0x7a8f:wu1 +0x7a90:gui1 +0x7a91:yao2 +0x7a92:zhi4 +0x7a93:chuang1 +0x7a94:yao3 +0x7a95:tiao3 +0x7a96:jiao4 +0x7a97:chuang1 +0x7a98:jiong3 +0x7a99:xiao1 +0x7a9a:cheng2 +0x7a9b:kou4 +0x7a9c:cuan4 +0x7a9d:wo1 +0x7a9e:dan4 +0x7a9f:ku1 +0x7aa0:ke1 +0x7aa1:zhui4 +0x7aa2:xu4 +0x7aa3:su4 +0x7aa5:kui1 +0x7aa6:dou4 +0x7aa8:yin4 +0x7aa9:wo1 +0x7aaa:wa1 +0x7aab:ya4 +0x7aac:yu2 +0x7aad:ju4 +0x7aae:qiong2 +0x7aaf:yao2 +0x7ab0:yao2 +0x7ab1:tiao4 +0x7ab2:chao2 +0x7ab3:yu3 +0x7ab4:tian2 +0x7ab5:diao4 +0x7ab6:ju4 +0x7ab7:liao2 +0x7ab8:xi1 +0x7ab9:wu4 +0x7aba:kui1 +0x7abb:chuang1 +0x7abc:zhao1 +0x7abe:kuan3 +0x7abf:long2 +0x7ac0:cheng1 +0x7ac1:cui4 +0x7ac2:piao2 +0x7ac3:zao4 +0x7ac4:cuan4 +0x7ac5:qiao4 +0x7ac6:qiong2 +0x7ac7:dou4 +0x7ac8:zao4 +0x7ac9:long3 +0x7aca:qie4 +0x7acb:li4 +0x7acc:chu4 +0x7ace:fou4 +0x7ad0:chu4 +0x7ad1:hong2 +0x7ad2:qi2 +0x7ad6:shu4 +0x7ad7:miao4 +0x7ad8:ju3 +0x7ad9:zhan4 +0x7ada:zhu4 +0x7adb:ling2 +0x7adc:long2 +0x7add:bing4 +0x7ade:jing4 +0x7adf:jing4 +0x7ae0:zhang1 +0x7ae2:si4 +0x7ae3:jun4 +0x7ae4:hong2 +0x7ae5:tong2 +0x7ae6:song3 +0x7ae7:jing4 +0x7ae8:diao4 +0x7ae9:yi4 +0x7aea:shu4 +0x7aeb:jing4 +0x7aec:qu3 +0x7aed:jie2 +0x7aee:ping2 +0x7aef:duan1 +0x7af0:shao2 +0x7af1:zhuan3 +0x7af2:ceng2 +0x7af3:deng1 +0x7af4:cui1 +0x7af5:huai1 +0x7af6:jing4 +0x7af7:kan4 +0x7af8:jing4 +0x7af9:zhu2 +0x7afa:zhu2 +0x7afb:le4 +0x7afc:peng2 +0x7afd:yu2 +0x7afe:chi2 +0x7aff:gan1 +0x7b00:mang2 +0x7b01:zhu2 +0x7b03:du3 +0x7b04:ji1 +0x7b05:xiao2 +0x7b06:ba1 +0x7b07:suan4 +0x7b08:ji2 +0x7b09:zhen3 +0x7b0a:zhao4 +0x7b0b:sun3 +0x7b0c:ya2 +0x7b0d:zhui4 +0x7b0e:yuan2 +0x7b0f:hu4 +0x7b10:gang1 +0x7b11:xiao4 +0x7b12:cen2 +0x7b13:pi2 +0x7b14:bi3 +0x7b15:jian3 +0x7b16:yi3 +0x7b17:dong1 +0x7b18:shan1 +0x7b19:sheng1 +0x7b1a:xia2 +0x7b1b:di2 +0x7b1c:zhu2 +0x7b1d:na4 +0x7b1e:chi1 +0x7b1f:gu1 +0x7b20:li4 +0x7b21:qie4 +0x7b22:min3 +0x7b23:bao1 +0x7b24:tiao2 +0x7b25:si4 +0x7b26:fu2 +0x7b27:ce4 +0x7b28:ben4 +0x7b29:pei4 +0x7b2a:da2 +0x7b2b:zi3 +0x7b2c:di4 +0x7b2d:ling2 +0x7b2e:ze2 +0x7b2f:nu2 +0x7b30:fu2 +0x7b31:gou3 +0x7b32:fan2 +0x7b33:jia1 +0x7b34:ge3 +0x7b35:fan4 +0x7b36:shi3 +0x7b37:mao3 +0x7b38:po3 +0x7b3a:jian1 +0x7b3b:qiong2 +0x7b3c:long2 +0x7b3e:bian1 +0x7b3f:luo4 +0x7b40:gui4 +0x7b41:qu3 +0x7b42:chi2 +0x7b43:yin1 +0x7b44:yao4 +0x7b45:xian3 +0x7b46:bi3 +0x7b47:qiong2 +0x7b48:gua1 +0x7b49:deng3 +0x7b4a:jiao3 +0x7b4b:jin1 +0x7b4c:quan2 +0x7b4d:sun3 +0x7b4e:ru2 +0x7b4f:fa2 +0x7b50:kuang1 +0x7b51:zhu2 +0x7b52:tong3 +0x7b53:ji1 +0x7b54:da2 +0x7b55:xing2 +0x7b56:ce4 +0x7b57:zhong4 +0x7b58:kou4 +0x7b59:lai2 +0x7b5a:bi4 +0x7b5b:shai1 +0x7b5c:dang1 +0x7b5d:zheng1 +0x7b5e:ce4 +0x7b5f:fu1 +0x7b60:yun2 +0x7b61:tu2 +0x7b62:pa2 +0x7b63:li4 +0x7b64:lang2 +0x7b65:ju3 +0x7b66:guan3 +0x7b67:jian3 +0x7b68:han2 +0x7b69:tong3 +0x7b6a:xia2 +0x7b6b:zhi4 +0x7b6c:cheng2 +0x7b6d:suan4 +0x7b6e:shi4 +0x7b6f:zhu4 +0x7b70:zuo2 +0x7b71:xiao3 +0x7b72:shao1 +0x7b73:ting2 +0x7b74:ce4 +0x7b75:yan2 +0x7b76:gao3 +0x7b77:kuai4 +0x7b78:gan1 +0x7b79:chou2 +0x7b7b:gang4 +0x7b7c:yun2 +0x7b7e:qian1 +0x7b7f:xiao3 +0x7b80:jian3 +0x7b81:pu2 +0x7b82:lai2 +0x7b83:zou1 +0x7b84:bi4 +0x7b85:bi4 +0x7b86:bi4 +0x7b87:ge4 +0x7b88:chi2 +0x7b89:guai3 +0x7b8a:yu1 +0x7b8b:jian1 +0x7b8c:zhao4 +0x7b8d:gu1 +0x7b8e:chi2 +0x7b8f:zheng1 +0x7b90:jing1 +0x7b91:sha4 +0x7b92:zhou3 +0x7b93:lu4 +0x7b94:bo2 +0x7b95:ji1 +0x7b96:lin2 +0x7b97:suan4 +0x7b98:jun4 +0x7b99:fu2 +0x7b9a:zha2 +0x7b9b:gu1 +0x7b9c:kong1 +0x7b9d:qian2 +0x7b9e:quan1 +0x7b9f:jun4 +0x7ba0:chui2 +0x7ba1:guan3 +0x7ba2:yuan1 +0x7ba3:ce4 +0x7ba4:ju2 +0x7ba5:bo3 +0x7ba6:ze2 +0x7ba7:qie4 +0x7ba8:tuo4 +0x7ba9:luo2 +0x7baa:dan1 +0x7bab:xiao1 +0x7bac:ruo4 +0x7bad:jian4 +0x7baf:bian1 +0x7bb0:sun3 +0x7bb1:xiang1 +0x7bb2:xian3 +0x7bb3:ping2 +0x7bb4:zhen1 +0x7bb5:sheng3 +0x7bb6:hu2 +0x7bb7:shi1 +0x7bb8:zhu4 +0x7bb9:yue1 +0x7bba:chun3 +0x7bbb:lv4 +0x7bbc:wu1 +0x7bbd:dong3 +0x7bbe:shuo4 +0x7bbf:ji2 +0x7bc0:jie2 +0x7bc1:huang2 +0x7bc2:xing1 +0x7bc3:mei2 +0x7bc4:fan4 +0x7bc5:chui2 +0x7bc6:zhuan4 +0x7bc7:pian1 +0x7bc8:feng1 +0x7bc9:zhu2 +0x7bca:hong2 +0x7bcb:qie4 +0x7bcc:hou2 +0x7bcd:qiu1 +0x7bce:miao3 +0x7bcf:qian4 +0x7bd1:kui4 +0x7bd3:lou3 +0x7bd4:yun2 +0x7bd5:he2 +0x7bd6:tang2 +0x7bd7:yue4 +0x7bd8:chou1 +0x7bd9:gao1 +0x7bda:fei3 +0x7bdb:ruo4 +0x7bdc:zheng1 +0x7bdd:gou1 +0x7bde:nie4 +0x7bdf:qian4 +0x7be0:xiao3 +0x7be1:cuan4 +0x7be2:gong1 +0x7be3:pang2 +0x7be4:du3 +0x7be5:li4 +0x7be6:bi4 +0x7be7:zhuo2 +0x7be8:chu2 +0x7be9:shai1 +0x7bea:chi2 +0x7beb:zhu2 +0x7bec:qiang1 +0x7bed:long2 +0x7bee:lan2 +0x7bef:jian1 +0x7bf0:bu4 +0x7bf1:li2 +0x7bf2:hui4 +0x7bf3:bi4 +0x7bf4:di2 +0x7bf5:cong1 +0x7bf6:yan1 +0x7bf7:peng2 +0x7bf8:sen1 +0x7bf9:zhuan4 +0x7bfa:pai2 +0x7bfb:piao4 +0x7bfc:dou1 +0x7bfd:yu3 +0x7bfe:mie4 +0x7bff:zhuan1 +0x7c00:ze2 +0x7c01:xi3 +0x7c02:guo2 +0x7c03:yi2 +0x7c04:hu4 +0x7c05:chan3 +0x7c06:kou4 +0x7c07:cu4 +0x7c08:ping2 +0x7c09:chou4 +0x7c0a:ji1 +0x7c0b:gui3 +0x7c0c:su4 +0x7c0d:lou3 +0x7c0e:zha4 +0x7c0f:lu4 +0x7c10:nian3 +0x7c11:suo1 +0x7c12:cuan4 +0x7c14:suo1 +0x7c15:le4 +0x7c16:duan4 +0x7c18:xiao1 +0x7c19:bo2 +0x7c1a:mi4 +0x7c1b:si1 +0x7c1c:dang4 +0x7c1d:liao2 +0x7c1e:dan1 +0x7c1f:dian4 +0x7c20:fu3 +0x7c21:jian3 +0x7c22:min3 +0x7c23:kui4 +0x7c24:dai4 +0x7c25:jiao1 +0x7c26:deng1 +0x7c27:huang2 +0x7c28:sun3 +0x7c29:lao2 +0x7c2a:zan1 +0x7c2b:xiao1 +0x7c2c:lu4 +0x7c2d:shi4 +0x7c2e:zan1 +0x7c30:pai2 +0x7c32:pai2 +0x7c33:gan4 +0x7c34:ju4 +0x7c35:du4 +0x7c36:lu4 +0x7c37:yan2 +0x7c38:bo4 +0x7c39:dang1 +0x7c3a:sai4 +0x7c3b:ke1 +0x7c3c:long2 +0x7c3d:qian1 +0x7c3e:lian2 +0x7c3f:bu4 +0x7c40:zhou4 +0x7c41:lai4 +0x7c43:lan2 +0x7c44:kui4 +0x7c45:yu2 +0x7c46:yue4 +0x7c47:hao2 +0x7c48:zhen1 +0x7c49:tai2 +0x7c4a:ti4 +0x7c4b:mi2 +0x7c4c:chou2 +0x7c4d:ji2 +0x7c50:teng2 +0x7c51:zhuan4 +0x7c52:zhou4 +0x7c53:fan1 +0x7c54:sou3 +0x7c55:zhou4 +0x7c57:zhuo2 +0x7c58:teng2 +0x7c59:lu4 +0x7c5a:lu2 +0x7c5b:jian1 +0x7c5c:tuo4 +0x7c5d:ying2 +0x7c5e:yu4 +0x7c5f:lai4 +0x7c60:long2 +0x7c62:lian2 +0x7c63:lan2 +0x7c64:qian1 +0x7c65:yue4 +0x7c66:zhong1 +0x7c67:qu2 +0x7c68:lian2 +0x7c69:bian1 +0x7c6a:duan4 +0x7c6b:zuan3 +0x7c6c:li2 +0x7c6d:si1 +0x7c6e:luo2 +0x7c6f:ying2 +0x7c70:yue4 +0x7c71:zhuo2 +0x7c72:yu4 +0x7c73:mi3 +0x7c74:di2 +0x7c75:fan2 +0x7c76:shen1 +0x7c77:zhe2 +0x7c78:shen1 +0x7c79:nv3 +0x7c7a:xie2 +0x7c7b:lei4 +0x7c7c:xian1 +0x7c7d:zi3 +0x7c7e:ni2 +0x7c7f:cun4 +0x7c81:qian1 +0x7c83:bi3 +0x7c84:ban3 +0x7c85:wu4 +0x7c86:sha1 +0x7c87:kang1 +0x7c88:rou3 +0x7c89:fen3 +0x7c8a:bi4 +0x7c8b:cui4 +0x7c8d:li2 +0x7c8e:chi3 +0x7c91:ba1 +0x7c92:li4 +0x7c93:gan1 +0x7c94:ju4 +0x7c95:po4 +0x7c96:mo4 +0x7c97:cu1 +0x7c98:nian2 +0x7c99:zhou4 +0x7c9a:li2 +0x7c9b:su4 +0x7c9c:tiao4 +0x7c9d:li4 +0x7c9e:xi1 +0x7c9f:su4 +0x7ca0:hong2 +0x7ca1:tong2 +0x7ca2:zi1 +0x7ca3:ce4 +0x7ca4:yue4 +0x7ca5:zhou1 +0x7ca6:lin4 +0x7ca7:zhuang1 +0x7ca8:bai3 +0x7caa:fen4 +0x7cae:liang2 +0x7caf:xian4 +0x7cb0:fu2 +0x7cb1:liang2 +0x7cb2:can4 +0x7cb3:geng1 +0x7cb4:li3 +0x7cb5:yue4 +0x7cb6:lu4 +0x7cb7:ju2 +0x7cb8:qi2 +0x7cb9:cui4 +0x7cba:bai4 +0x7cbb:zhang1 +0x7cbc:lin2 +0x7cbd:zong4 +0x7cbe:jing1 +0x7cbf:guo3 +0x7cc1:san1 +0x7cc2:san3 +0x7cc3:tang2 +0x7cc4:bian1 +0x7cc5:rou3 +0x7cc6:mian4 +0x7cc7:hou2 +0x7cc8:xu3 +0x7cc9:zong4 +0x7cca:hu2 +0x7ccb:jian4 +0x7ccc:zan2 +0x7ccd:ci2 +0x7cce:li2 +0x7ccf:xie4 +0x7cd0:fu1 +0x7cd1:ni4 +0x7cd2:bei4 +0x7cd3:gu3 +0x7cd4:xiu3 +0x7cd5:gao1 +0x7cd6:tang2 +0x7cd7:qiu3 +0x7cd9:cao1 +0x7cda:zhuang1 +0x7cdb:tang2 +0x7cdc:mi2 +0x7cdd:san3 +0x7cde:fen4 +0x7cdf:zao1 +0x7ce0:kang1 +0x7ce1:jiang4 +0x7ce2:mo2 +0x7ce3:san3 +0x7ce4:san3 +0x7ce5:nuo4 +0x7ce6:xi1 +0x7ce7:liang2 +0x7ce8:jiang4 +0x7ce9:kuai4 +0x7cea:bo2 +0x7ceb:huan2 +0x7ced:zong4 +0x7cee:xian4 +0x7cef:nuo4 +0x7cf0:tuan2 +0x7cf1:nie4 +0x7cf2:li4 +0x7cf3:zuo4 +0x7cf4:di2 +0x7cf5:nie4 +0x7cf6:tiao4 +0x7cf7:lan2 +0x7cf8:mi4 +0x7cf9:si1 +0x7cfa:jiu1 +0x7cfb:xi4 +0x7cfc:gong1 +0x7cfd:zheng3 +0x7cfe:jiu1 +0x7cff:you4 +0x7d00:ji4 +0x7d01:cha4 +0x7d02:zhou4 +0x7d03:xun2 +0x7d04:yue1 +0x7d05:hong2 +0x7d06:yu1 +0x7d07:he2 +0x7d08:wan2 +0x7d09:ren4 +0x7d0a:wen4 +0x7d0b:wen2 +0x7d0c:qiu2 +0x7d0d:na4 +0x7d0e:zi1 +0x7d0f:tou3 +0x7d10:niu3 +0x7d11:fou2 +0x7d12:jie4 +0x7d13:shu1 +0x7d14:chun2 +0x7d15:pi1 +0x7d16:yin3 +0x7d17:sha1 +0x7d18:hong2 +0x7d19:zhi3 +0x7d1a:ji2 +0x7d1b:fen1 +0x7d1c:yun2 +0x7d1d:ren4 +0x7d1e:dan3 +0x7d1f:jin1 +0x7d20:su4 +0x7d21:fang3 +0x7d22:suo3 +0x7d23:cui4 +0x7d24:jiu3 +0x7d25:zha2 +0x7d27:jin3 +0x7d28:fu4 +0x7d29:zhi4 +0x7d2a:ci3 +0x7d2b:zi3 +0x7d2c:chou2 +0x7d2d:hong2 +0x7d2e:za1 +0x7d2f:lei4 +0x7d30:xi4 +0x7d31:fu2 +0x7d32:xie4 +0x7d33:shen1 +0x7d34:bei4 +0x7d35:zhu4 +0x7d36:qu3 +0x7d37:ling2 +0x7d38:zhu4 +0x7d39:shao4 +0x7d3a:gan4 +0x7d3b:yang1 +0x7d3c:fu2 +0x7d3d:tuo2 +0x7d3e:zhen3 +0x7d3f:dai4 +0x7d40:chu4 +0x7d41:shi1 +0x7d42:zhong1 +0x7d43:xian2 +0x7d44:zu3 +0x7d45:jiong3 +0x7d46:ban4 +0x7d47:ju4 +0x7d48:mo4 +0x7d49:shu4 +0x7d4a:zui4 +0x7d4c:jing1 +0x7d4d:ren2 +0x7d4e:heng4 +0x7d4f:xie4 +0x7d50:jie2 +0x7d51:zhu1 +0x7d52:chou2 +0x7d53:gua4 +0x7d54:bai3 +0x7d55:jue2 +0x7d56:kuang4 +0x7d57:hu2 +0x7d58:ci4 +0x7d59:geng1 +0x7d5a:geng1 +0x7d5b:tao1 +0x7d5c:xie2 +0x7d5d:ku4 +0x7d5e:jiao3 +0x7d5f:quan1 +0x7d60:gai3 +0x7d61:luo4 +0x7d62:xuan4 +0x7d63:bing1 +0x7d64:xian4 +0x7d65:fu2 +0x7d66:gei3 +0x7d67:tong2 +0x7d68:rong2 +0x7d69:tiao4 +0x7d6a:yin1 +0x7d6b:lei3 +0x7d6c:xie4 +0x7d6d:quan4 +0x7d6e:xu4 +0x7d6f:gai1 +0x7d70:die2 +0x7d71:tong3 +0x7d72:si1 +0x7d73:jiang4 +0x7d74:xiang2 +0x7d75:hui4 +0x7d76:jue2 +0x7d77:zhi2 +0x7d78:jian3 +0x7d79:juan4 +0x7d7a:chi1 +0x7d7b:mian3 +0x7d7c:zhen3 +0x7d7d:lv3 +0x7d7e:cheng2 +0x7d7f:qiu2 +0x7d80:shu1 +0x7d81:bang3 +0x7d82:tong3 +0x7d83:xiao1 +0x7d84:wan4 +0x7d85:qin1 +0x7d86:geng3 +0x7d87:xiu3 +0x7d88:ti2 +0x7d89:xiu4 +0x7d8a:xie2 +0x7d8b:hong2 +0x7d8c:xi4 +0x7d8d:fu2 +0x7d8e:ting1 +0x7d8f:sui1 +0x7d90:dui4 +0x7d91:kun3 +0x7d92:fu1 +0x7d93:jing1 +0x7d94:hu4 +0x7d95:zhi1 +0x7d96:yan2 +0x7d97:jiong3 +0x7d98:feng2 +0x7d99:ji4 +0x7d9c:zong1 +0x7d9d:lin2 +0x7d9e:duo3 +0x7d9f:li4 +0x7da0:lv4 +0x7da1:liang2 +0x7da2:chou2 +0x7da3:quan3 +0x7da4:shao4 +0x7da5:qi4 +0x7da6:qi2 +0x7da7:zhun3 +0x7da8:qi2 +0x7da9:wan3 +0x7daa:qian4 +0x7dab:xian4 +0x7dac:shou4 +0x7dad:wei2 +0x7dae:qi3 +0x7daf:tao2 +0x7db0:wan3 +0x7db1:gang1 +0x7db2:wang3 +0x7db3:beng1 +0x7db4:zhui4 +0x7db5:cai3 +0x7db6:guo3 +0x7db7:cui4 +0x7db8:lun2 +0x7db9:liu3 +0x7dba:qi3 +0x7dbb:zhan4 +0x7dbc:bei1 +0x7dbd:chuo4 +0x7dbe:ling2 +0x7dbf:mian2 +0x7dc0:qi1 +0x7dc1:qie4 +0x7dc2:tan1 +0x7dc3:zong1 +0x7dc4:gun3 +0x7dc5:zou1 +0x7dc6:yi4 +0x7dc7:zi1 +0x7dc8:xing4 +0x7dc9:liang3 +0x7dca:jin3 +0x7dcb:fei1 +0x7dcc:rui2 +0x7dcd:min2 +0x7dce:yu4 +0x7dcf:zong3 +0x7dd0:fan2 +0x7dd1:lv4 +0x7dd2:xu4 +0x7dd3:ying1 +0x7dd4:zhang4 +0x7dd6:xu4 +0x7dd7:xiang1 +0x7dd8:jian1 +0x7dd9:ke4 +0x7dda:xian4 +0x7ddb:ruan3 +0x7ddc:mian2 +0x7ddd:ji1 +0x7dde:duan4 +0x7ddf:zhong4 +0x7de0:di4 +0x7de1:min2 +0x7de2:miao2 +0x7de3:yuan2 +0x7de4:xie4 +0x7de5:bao3 +0x7de6:si1 +0x7de7:qiu1 +0x7de8:bian1 +0x7de9:huan3 +0x7dea:geng1 +0x7deb:cong1 +0x7dec:mian3 +0x7ded:wei4 +0x7dee:fu4 +0x7def:wei3 +0x7df0:yu2 +0x7df1:gou1 +0x7df2:miao3 +0x7df3:xie2 +0x7df4:lian4 +0x7df5:zong1 +0x7df6:bian4 +0x7df7:yun4 +0x7df8:yin1 +0x7df9:ti2 +0x7dfa:gua1 +0x7dfb:zhi4 +0x7dfc:yun1 +0x7dfd:cheng1 +0x7dfe:chan2 +0x7dff:dai4 +0x7e00:xia2 +0x7e01:yuan2 +0x7e02:zong3 +0x7e03:xu1 +0x7e06:geng1 +0x7e08:ying2 +0x7e09:jin4 +0x7e0a:yi4 +0x7e0b:zhui4 +0x7e0c:ni4 +0x7e0d:bang1 +0x7e0e:gu3 +0x7e0f:pan2 +0x7e10:zhou4 +0x7e11:jian1 +0x7e12:cuo3 +0x7e13:quan3 +0x7e14:shuang3 +0x7e15:yun1 +0x7e16:xia2 +0x7e17:cui1 +0x7e18:xi1 +0x7e19:rong2 +0x7e1a:tao1 +0x7e1b:fu2 +0x7e1c:yun2 +0x7e1d:chen1 +0x7e1e:gao3 +0x7e1f:ru4 +0x7e20:hu2 +0x7e21:zai3 +0x7e22:teng2 +0x7e23:xian4 +0x7e24:su4 +0x7e25:zhen3 +0x7e26:zong4 +0x7e27:tao1 +0x7e29:cai4 +0x7e2a:bi4 +0x7e2b:feng2 +0x7e2c:cu4 +0x7e2d:li2 +0x7e2e:suo1 +0x7e2f:yin3 +0x7e30:xi3 +0x7e31:zong4 +0x7e32:lei2 +0x7e33:zhuan4 +0x7e34:qian1 +0x7e35:man4 +0x7e36:zhi2 +0x7e37:lv3 +0x7e38:mo4 +0x7e39:piao3 +0x7e3a:lian2 +0x7e3b:mi2 +0x7e3c:xuan4 +0x7e3d:zong3 +0x7e3e:ji1 +0x7e3f:shan1 +0x7e40:sui4 +0x7e41:fan2 +0x7e42:shuai4 +0x7e43:beng1 +0x7e44:yi1 +0x7e45:sao1 +0x7e46:mou2 +0x7e47:yao2 +0x7e48:qiang3 +0x7e49:hun2 +0x7e4b:xi4 +0x7e4d:xiu4 +0x7e4e:ran2 +0x7e4f:xuan4 +0x7e50:sui4 +0x7e51:qiao1 +0x7e52:zeng1 +0x7e53:zuo3 +0x7e54:zhi1 +0x7e55:shan4 +0x7e56:san3 +0x7e57:lin2 +0x7e58:yu4 +0x7e59:fan1 +0x7e5a:liao2 +0x7e5b:chuo4 +0x7e5c:zun1 +0x7e5d:jian4 +0x7e5e:rao4 +0x7e5f:chan3 +0x7e60:rui3 +0x7e61:xiu4 +0x7e62:hui4 +0x7e63:hua4 +0x7e64:zuan3 +0x7e65:xi1 +0x7e66:qiang3 +0x7e68:da2 +0x7e69:sheng2 +0x7e6a:hui4 +0x7e6b:xi4 +0x7e6c:se4 +0x7e6d:jian3 +0x7e6e:jiang1 +0x7e6f:huan2 +0x7e70:zao3 +0x7e71:cong1 +0x7e72:jie4 +0x7e73:jiao3 +0x7e74:bo4 +0x7e75:chan2 +0x7e76:yi4 +0x7e77:nao2 +0x7e78:sui4 +0x7e79:yi4 +0x7e7a:shai3 +0x7e7b:xu1 +0x7e7c:ji4 +0x7e7d:bin1 +0x7e7e:qian3 +0x7e7f:lan2 +0x7e80:pu2 +0x7e81:xun1 +0x7e82:zuan3 +0x7e83:qi2 +0x7e84:peng2 +0x7e85:li4 +0x7e86:mo4 +0x7e87:lei4 +0x7e88:xie2 +0x7e89:zuan3 +0x7e8a:kuang4 +0x7e8b:you1 +0x7e8c:xu4 +0x7e8d:lei2 +0x7e8e:xian1 +0x7e8f:chan2 +0x7e91:lu2 +0x7e92:chan2 +0x7e93:ying1 +0x7e94:cai2 +0x7e95:xiang1 +0x7e96:xian1 +0x7e97:zui1 +0x7e98:zuan3 +0x7e99:luo4 +0x7e9a:xi3 +0x7e9b:dao4 +0x7e9c:lan4 +0x7e9d:lei2 +0x7e9e:lian4 +0x7e9f:si1 +0x7ea0:jiu1 +0x7ea1:yu1 +0x7ea2:hong2 +0x7ea3:zhou4 +0x7ea4:xian1 +0x7ea5:he2 +0x7ea6:yue1 +0x7ea7:ji2 +0x7ea8:wan2 +0x7ea9:kuang4 +0x7eaa:ji4 +0x7eab:ren4 +0x7eac:wei3 +0x7ead:yun2 +0x7eae:hong2 +0x7eaf:chun2 +0x7eb0:pi2 +0x7eb1:sha1 +0x7eb2:gang1 +0x7eb3:na4 +0x7eb4:ren2 +0x7eb5:zong4 +0x7eb6:lun2 +0x7eb7:fen1 +0x7eb8:zhi3 +0x7eb9:wen2 +0x7eba:fang3 +0x7ebb:zhu4 +0x7ebc:yin3 +0x7ebd:niu3 +0x7ebe:shu1 +0x7ebf:xian4 +0x7ec0:gan4 +0x7ec1:xie4 +0x7ec2:fu2 +0x7ec3:lian4 +0x7ec4:zu3 +0x7ec5:shen1 +0x7ec6:xi4 +0x7ec7:zhi1 +0x7ec8:zhong1 +0x7ec9:zhou4 +0x7eca:ban4 +0x7ecb:fu2 +0x7ecc:zhuo2 +0x7ecd:shao4 +0x7ece:yi4 +0x7ecf:jing1 +0x7ed0:dai4 +0x7ed1:bang3 +0x7ed2:rong2 +0x7ed3:jie2 +0x7ed4:ku4 +0x7ed5:rao4 +0x7ed6:die2 +0x7ed7:heng4 +0x7ed8:hui4 +0x7ed9:gei3 +0x7eda:xuan4 +0x7edb:jiang4 +0x7edc:luo4 +0x7edd:jue2 +0x7ede:jiao3 +0x7edf:tong3 +0x7ee0:geng3 +0x7ee1:xiao1 +0x7ee2:juan4 +0x7ee3:xiu4 +0x7ee4:xi4 +0x7ee5:sui1 +0x7ee6:tao1 +0x7ee7:ji4 +0x7ee8:ti2 +0x7ee9:ji1 +0x7eea:xu4 +0x7eeb:ling2 +0x7eec:ying1 +0x7eed:xu4 +0x7eee:qi3 +0x7eef:fei1 +0x7ef0:chuo4 +0x7ef1:zhang3 +0x7ef2:gun3 +0x7ef3:sheng2 +0x7ef4:wei2 +0x7ef5:mian2 +0x7ef6:shou4 +0x7ef7:beng1 +0x7ef8:chou2 +0x7ef9:tao2 +0x7efa:liu3 +0x7efb:quan3 +0x7efc:zong4 +0x7efd:zhan4 +0x7efe:wan3 +0x7eff:lv4 +0x7f00:zhui4 +0x7f01:zi1 +0x7f02:ke4 +0x7f03:xiang1 +0x7f04:jian1 +0x7f05:mian3 +0x7f06:lan4 +0x7f07:ti2 +0x7f08:miao3 +0x7f09:qi4 +0x7f0a:yun1 +0x7f0b:hui4 +0x7f0c:si1 +0x7f0d:duo3 +0x7f0e:duan4 +0x7f0f:bian4 +0x7f10:xian4 +0x7f11:gou1 +0x7f12:zhui4 +0x7f13:huan3 +0x7f14:di4 +0x7f15:lv3 +0x7f16:bian1 +0x7f17:min2 +0x7f18:yuan2 +0x7f19:jin4 +0x7f1a:fu2 +0x7f1b:ru4 +0x7f1c:zhen1 +0x7f1d:feng2 +0x7f1e:shuai1 +0x7f1f:gao3 +0x7f20:chan2 +0x7f21:li2 +0x7f22:yi4 +0x7f23:jian1 +0x7f24:bin1 +0x7f25:piao3 +0x7f26:man4 +0x7f27:lei2 +0x7f28:ying1 +0x7f29:suo1 +0x7f2a:mou2 +0x7f2b:sao1 +0x7f2c:xie2 +0x7f2d:liao2 +0x7f2e:shan4 +0x7f2f:zeng1 +0x7f30:jiang1 +0x7f31:qian3 +0x7f32:zao3 +0x7f33:huan2 +0x7f34:jiao3 +0x7f35:zuan3 +0x7f36:fou3 +0x7f37:xie4 +0x7f38:gang1 +0x7f39:fou3 +0x7f3a:que1 +0x7f3b:fou3 +0x7f3d:bo1 +0x7f3e:ping2 +0x7f3f:hou4 +0x7f41:gang1 +0x7f42:ying1 +0x7f43:ying1 +0x7f44:qing4 +0x7f45:xia4 +0x7f46:guan4 +0x7f47:zun1 +0x7f48:tan2 +0x7f4a:qi4 +0x7f4b:weng4 +0x7f4c:ying1 +0x7f4d:lei2 +0x7f4e:tan2 +0x7f4f:lu2 +0x7f50:guan4 +0x7f51:wang3 +0x7f52:wang3 +0x7f53:gang1 +0x7f54:wang3 +0x7f55:han3 +0x7f57:luo1 +0x7f58:fu2 +0x7f59:mi2 +0x7f5a:fa2 +0x7f5b:gu1 +0x7f5c:zhu3 +0x7f5d:ju1 +0x7f5e:mao2 +0x7f5f:gu3 +0x7f60:min2 +0x7f61:gang1 +0x7f62:ba4 +0x7f63:gua4 +0x7f64:ti2 +0x7f65:juan4 +0x7f66:fu2 +0x7f67:lin2 +0x7f68:yan3 +0x7f69:zhao4 +0x7f6a:zui4 +0x7f6b:gua4 +0x7f6c:zhuo2 +0x7f6d:yu4 +0x7f6e:zhi4 +0x7f6f:an3 +0x7f70:fa2 +0x7f71:nan3 +0x7f72:shu3 +0x7f73:si1 +0x7f74:pi2 +0x7f75:ma4 +0x7f76:liu3 +0x7f77:ba4 +0x7f78:fa2 +0x7f79:li2 +0x7f7a:chao1 +0x7f7b:wei4 +0x7f7c:bi4 +0x7f7d:ji4 +0x7f7e:zeng1 +0x7f7f:tong2 +0x7f80:liu3 +0x7f81:ji1 +0x7f82:juan4 +0x7f83:mi4 +0x7f84:zhao4 +0x7f85:luo2 +0x7f86:pi2 +0x7f87:ji1 +0x7f88:ji1 +0x7f89:luan2 +0x7f8a:yang2 +0x7f8b:mi3 +0x7f8c:qiang1 +0x7f8d:ta4 +0x7f8e:mei3 +0x7f8f:yang2 +0x7f90:you3 +0x7f91:you3 +0x7f92:fen2 +0x7f93:ba1 +0x7f94:gao1 +0x7f95:yang4 +0x7f96:gu3 +0x7f97:qiang1 +0x7f98:zang1 +0x7f99:gao1 +0x7f9a:ling2 +0x7f9b:yi4 +0x7f9c:zhu4 +0x7f9d:di1 +0x7f9e:xiu1 +0x7f9f:qian1 +0x7fa0:yi2 +0x7fa1:xian4 +0x7fa2:rong2 +0x7fa3:qun2 +0x7fa4:qun2 +0x7fa5:qiang3 +0x7fa6:huan2 +0x7fa7:suo1 +0x7fa8:xian4 +0x7fa9:yi4 +0x7fab:qiang1 +0x7fac:xian2 +0x7fad:yu2 +0x7fae:geng1 +0x7faf:jie2 +0x7fb0:tang1 +0x7fb1:yuan2 +0x7fb2:xi1 +0x7fb3:fan2 +0x7fb4:shan1 +0x7fb5:fen3 +0x7fb6:shan1 +0x7fb7:lian3 +0x7fb8:lei2 +0x7fb9:geng1 +0x7fba:nou2 +0x7fbb:qiang4 +0x7fbc:chan4 +0x7fbd:yu3 +0x7fbe:gong4 +0x7fbf:yi4 +0x7fc0:chong1 +0x7fc1:weng1 +0x7fc2:fen1 +0x7fc3:hong2 +0x7fc4:chi4 +0x7fc5:chi4 +0x7fc6:cui4 +0x7fc7:fu2 +0x7fc8:xia2 +0x7fc9:pen3 +0x7fca:yi4 +0x7fcb:la1 +0x7fcc:yi4 +0x7fcd:pi1 +0x7fce:ling2 +0x7fcf:liu4 +0x7fd0:zhi4 +0x7fd1:qu2 +0x7fd2:xi2 +0x7fd3:xie2 +0x7fd4:xiang2 +0x7fd5:xi4 +0x7fd6:xi4 +0x7fd7:qi2 +0x7fd8:qiao2 +0x7fd9:hui4 +0x7fda:hui1 +0x7fdb:xiao1 +0x7fdc:se4 +0x7fdd:hong2 +0x7fde:jiang1 +0x7fdf:di2 +0x7fe0:cui4 +0x7fe1:fei3 +0x7fe2:tao1 +0x7fe3:sha4 +0x7fe4:chi4 +0x7fe5:zhu4 +0x7fe6:jian3 +0x7fe7:xuan1 +0x7fe8:shi4 +0x7fe9:pian1 +0x7fea:zong1 +0x7feb:wan4 +0x7fec:hui1 +0x7fed:hou2 +0x7fee:he2 +0x7fef:he4 +0x7ff0:han4 +0x7ff1:ao2 +0x7ff2:piao1 +0x7ff3:yi4 +0x7ff4:lian2 +0x7ff5:qu2 +0x7ff7:lin2 +0x7ff8:pen3 +0x7ff9:qiao2 +0x7ffa:ao2 +0x7ffb:fan1 +0x7ffc:yi4 +0x7ffd:hui4 +0x7ffe:xuan1 +0x7fff:dao4 +0x8000:yao4 +0x8001:lao3 +0x8003:kao3 +0x8004:mao4 +0x8005:zhe3 +0x8006:qi2 +0x8007:gou3 +0x8008:gou3 +0x8009:gou3 +0x800a:die4 +0x800b:die4 +0x800c:er2 +0x800d:shua3 +0x800e:ruan3 +0x800f:er2 +0x8010:nai4 +0x8011:zhuan1 +0x8012:lei3 +0x8013:ting1 +0x8014:zi3 +0x8015:geng1 +0x8016:chao4 +0x8017:hao4 +0x8018:yun2 +0x8019:ba4 +0x801a:pi1 +0x801b:chi2 +0x801c:si4 +0x801d:chu2 +0x801e:jia1 +0x801f:ju4 +0x8020:he2 +0x8021:chu2 +0x8022:lao4 +0x8023:lun3 +0x8024:ji2 +0x8025:tang3 +0x8026:ou3 +0x8027:lou2 +0x8028:nou4 +0x8029:jiang3 +0x802a:pang3 +0x802b:ze2 +0x802c:lou2 +0x802d:ji1 +0x802e:lao4 +0x802f:huo4 +0x8030:you1 +0x8031:mo4 +0x8032:huai2 +0x8033:er3 +0x8034:zhe2 +0x8035:ting1 +0x8036:ye2 +0x8037:da1 +0x8038:song3 +0x8039:qin2 +0x803a:yun2 +0x803b:chi3 +0x803c:dan1 +0x803d:dan1 +0x803e:hong2 +0x803f:geng3 +0x8040:zhi2 +0x8042:nie4 +0x8043:dan1 +0x8044:zhen3 +0x8045:che4 +0x8046:ling2 +0x8047:zheng1 +0x8048:you3 +0x8049:wa1 +0x804a:liao2 +0x804b:long2 +0x804c:zhi2 +0x804d:ning2 +0x804e:tiao1 +0x804f:er2 +0x8050:ya4 +0x8051:die2 +0x8052:gua1 +0x8054:lian2 +0x8055:hao4 +0x8056:sheng4 +0x8057:lie4 +0x8058:pin4 +0x8059:jing1 +0x805a:ju4 +0x805b:bi4 +0x805c:di3 +0x805d:guo2 +0x805e:wen2 +0x805f:xu4 +0x8060:ping2 +0x8061:cong1 +0x8064:ting2 +0x8065:yu3 +0x8066:cong1 +0x8067:kui2 +0x8069:kui4 +0x806a:cong1 +0x806b:lian2 +0x806c:weng3 +0x806d:kui4 +0x806e:lian2 +0x806f:lian2 +0x8070:cong1 +0x8071:ao2 +0x8072:sheng1 +0x8073:song3 +0x8074:ting1 +0x8075:kui4 +0x8076:nie4 +0x8077:zhi2 +0x8078:dan1 +0x8079:ning2 +0x807b:ji1 +0x807c:ting1 +0x807d:ting1 +0x807e:long2 +0x807f:yu4 +0x8080:yu4 +0x8081:zhao4 +0x8082:si4 +0x8083:su4 +0x8084:yi4 +0x8085:su4 +0x8086:si4 +0x8087:zhao4 +0x8088:zhao4 +0x8089:rou4 +0x808a:yi4 +0x808b:lei4 +0x808c:ji1 +0x808d:qiu2 +0x808e:ken3 +0x808f:cao4 +0x8090:ge1 +0x8091:di4 +0x8092:huan2 +0x8093:huang1 +0x8094:yi3 +0x8095:ren4 +0x8096:xiao4 +0x8097:ru3 +0x8098:zhou3 +0x8099:yuan1 +0x809a:du4 +0x809b:gang1 +0x809c:rong2 +0x809d:gan1 +0x809e:cha1 +0x809f:wo4 +0x80a0:chang2 +0x80a1:gu3 +0x80a2:zhi1 +0x80a3:han2 +0x80a4:fu1 +0x80a5:fei2 +0x80a6:fen2 +0x80a7:pei1 +0x80a8:pang4 +0x80a9:jian1 +0x80aa:fang2 +0x80ab:zhun1 +0x80ac:you2 +0x80ad:na4 +0x80ae:hang2 +0x80af:ken3 +0x80b0:ran2 +0x80b1:gong1 +0x80b2:yu4 +0x80b3:wen3 +0x80b4:yao2 +0x80b5:jin4 +0x80b6:pi2 +0x80b7:qian1 +0x80b8:xi4 +0x80b9:xi1 +0x80ba:fei4 +0x80bb:ken3 +0x80bc:jing3 +0x80bd:tai4 +0x80be:shen4 +0x80bf:zhong3 +0x80c0:zhang4 +0x80c1:xie2 +0x80c2:shen1 +0x80c3:wei4 +0x80c4:zhou4 +0x80c5:die2 +0x80c6:dan3 +0x80c7:fei4 +0x80c8:ba2 +0x80c9:bo2 +0x80ca:qu2 +0x80cb:tian2 +0x80cc:bei4 +0x80cd:gua1 +0x80ce:tai1 +0x80cf:zi3 +0x80d0:ku1 +0x80d1:zhi1 +0x80d2:ni4 +0x80d3:ping2 +0x80d4:zi4 +0x80d5:fu4 +0x80d6:pang4 +0x80d7:zhen1 +0x80d8:xian2 +0x80d9:zuo4 +0x80da:pei1 +0x80db:jia3 +0x80dc:sheng4 +0x80dd:zhi1 +0x80de:bao1 +0x80df:mu3 +0x80e0:qu1 +0x80e1:hu2 +0x80e2:ke1 +0x80e3:yi3 +0x80e4:yin4 +0x80e5:xu1 +0x80e6:yang1 +0x80e7:long2 +0x80e8:dong4 +0x80e9:ka3 +0x80ea:lu2 +0x80eb:jing4 +0x80ec:nu3 +0x80ed:yan1 +0x80ee:pang2 +0x80ef:kua4 +0x80f0:yi2 +0x80f1:guang1 +0x80f2:hai3 +0x80f3:ge1 +0x80f4:dong4 +0x80f5:zhi4 +0x80f6:xiao2 +0x80f7:xiong1 +0x80f8:xiong1 +0x80f9:er2 +0x80fa:e4 +0x80fb:xing2 +0x80fc:pian2 +0x80fd:neng2 +0x80fe:zi4 +0x8100:cheng2 +0x8101:tiao4 +0x8102:zhi1 +0x8103:cui4 +0x8104:mei2 +0x8105:xie2 +0x8106:cui4 +0x8107:xie2 +0x8108:mai4 +0x8109:mai4 +0x810a:ji2 +0x810d:kuai4 +0x810e:sa4 +0x810f:zang1 +0x8110:qi2 +0x8111:nao3 +0x8112:mi3 +0x8113:nong2 +0x8114:luan2 +0x8115:wan3 +0x8116:bo2 +0x8117:wen3 +0x8118:guan3 +0x8119:qiu2 +0x811a:jiao3 +0x811b:jing4 +0x811c:rou2 +0x811d:heng1 +0x811e:cuo3 +0x811f:lie4 +0x8120:shan1 +0x8121:ting3 +0x8122:mei2 +0x8123:chun2 +0x8124:shen4 +0x8125:qian3 +0x8126:te4 +0x8127:zui1 +0x8128:cu4 +0x8129:xiu1 +0x812a:xin4 +0x812b:tuo1 +0x812c:pao1 +0x812d:cheng2 +0x812e:nei3 +0x812f:fu3 +0x8130:dou4 +0x8131:tuo1 +0x8132:niao4 +0x8134:pi3 +0x8135:gu3 +0x8136:gua1 +0x8137:li4 +0x8138:lian3 +0x8139:zhang4 +0x813a:cui4 +0x813b:jie2 +0x813c:liang3 +0x813d:zhou1 +0x813e:pi2 +0x813f:biao1 +0x8140:lun2 +0x8141:pian2 +0x8142:guo4 +0x8143:kui4 +0x8144:chui2 +0x8145:dan4 +0x8146:tian3 +0x8147:nei3 +0x8148:jing1 +0x8149:jie1 +0x814a:la4 +0x814b:yi4 +0x814c:yan1 +0x814d:ren3 +0x814e:shen4 +0x814f:chuo4 +0x8150:fu3 +0x8151:fu3 +0x8152:ju1 +0x8153:fei2 +0x8154:qiang1 +0x8155:wan4 +0x8156:dong4 +0x8157:pi2 +0x8158:guo2 +0x8159:zong1 +0x815a:ding4 +0x815b:wu1 +0x815c:mei2 +0x815d:ruan3 +0x815e:zhuan4 +0x815f:zhi4 +0x8160:cou4 +0x8161:gua1 +0x8162:ou3 +0x8163:di4 +0x8164:an1 +0x8165:xing1 +0x8166:nao3 +0x8167:yu2 +0x8168:chuan3 +0x8169:nan3 +0x816a:yun4 +0x816b:zhong3 +0x816c:rou2 +0x816d:e4 +0x816e:sai1 +0x816f:tu2 +0x8170:yao1 +0x8171:jian4 +0x8172:wei3 +0x8173:jiao3 +0x8174:yu2 +0x8175:jia1 +0x8176:duan4 +0x8177:bi4 +0x8178:chang2 +0x8179:fu4 +0x817a:xian4 +0x817b:ni4 +0x817c:mian3 +0x817d:wa4 +0x817e:teng2 +0x817f:tui3 +0x8180:bang3 +0x8181:qian1 +0x8182:lv3 +0x8183:wa4 +0x8184:sou4 +0x8185:tang2 +0x8186:su4 +0x8187:zhui4 +0x8188:ge2 +0x8189:yi4 +0x818a:bo2 +0x818b:liao2 +0x818c:ji2 +0x818d:pi2 +0x818e:xie2 +0x818f:gao1 +0x8190:lv3 +0x8191:bin4 +0x8193:chang2 +0x8194:lu4 +0x8195:guo2 +0x8196:pang1 +0x8197:chuai2 +0x8198:piao3 +0x8199:jiang3 +0x819a:fu1 +0x819b:tang2 +0x819c:mo4 +0x819d:xi1 +0x819e:zhuan1 +0x819f:lv4 +0x81a0:jiao1 +0x81a1:ying4 +0x81a2:lv2 +0x81a3:zhi4 +0x81a5:chun1 +0x81a6:lian3 +0x81a7:tong2 +0x81a8:peng2 +0x81a9:ni4 +0x81aa:zha4 +0x81ab:liao2 +0x81ac:cui4 +0x81ad:gui1 +0x81ae:xiao1 +0x81af:teng1 +0x81b0:fan2 +0x81b1:zhi2 +0x81b2:jiao1 +0x81b3:shan4 +0x81b4:hu1 +0x81b5:cui4 +0x81b6:run4 +0x81b7:xiang1 +0x81b8:sui3 +0x81b9:fen4 +0x81ba:ying1 +0x81bb:dan4 +0x81bc:zhua1 +0x81bd:dan3 +0x81be:kuai4 +0x81bf:nong2 +0x81c0:tun2 +0x81c1:lian2 +0x81c2:bi4 +0x81c3:yong3 +0x81c4:jue2 +0x81c5:chu4 +0x81c6:yi4 +0x81c7:juan3 +0x81c8:la4 +0x81c9:lian3 +0x81ca:sao1 +0x81cb:tun2 +0x81cc:gu3 +0x81cd:qi2 +0x81ce:cui4 +0x81cf:bin4 +0x81d0:xun1 +0x81d1:ru2 +0x81d2:huo4 +0x81d3:zang4 +0x81d4:xian4 +0x81d5:biao1 +0x81d6:xing4 +0x81d7:kuan1 +0x81d8:la4 +0x81d9:yan1 +0x81da:lu2 +0x81db:huo4 +0x81dc:zang1 +0x81dd:luo3 +0x81de:qu2 +0x81df:zang4 +0x81e0:luan2 +0x81e1:ni2 +0x81e2:zang1 +0x81e3:chen2 +0x81e4:qian1 +0x81e5:wo4 +0x81e6:guang4 +0x81e7:zang1 +0x81e8:lin2 +0x81e9:guang4 +0x81ea:zi4 +0x81eb:jiao3 +0x81ec:nie4 +0x81ed:chou4 +0x81ee:ji4 +0x81ef:gao1 +0x81f0:chou4 +0x81f1:mian2 +0x81f2:nie4 +0x81f3:zhi4 +0x81f4:zhi4 +0x81f5:ge2 +0x81f6:jian4 +0x81f7:die2 +0x81f8:zhi4 +0x81f9:xiu1 +0x81fa:tai2 +0x81fb:zhen1 +0x81fc:jiu4 +0x81fd:xian4 +0x81fe:yu2 +0x81ff:cha1 +0x8200:yao3 +0x8201:yu2 +0x8202:chong1 +0x8203:xi4 +0x8204:xi4 +0x8205:jiu4 +0x8206:yu2 +0x8207:yu3 +0x8208:xing1 +0x8209:ju3 +0x820a:jiu4 +0x820b:xin4 +0x820c:she2 +0x820d:she4 +0x820f:jiu3 +0x8210:shi4 +0x8211:tan1 +0x8212:shu1 +0x8213:shi4 +0x8214:tian3 +0x8215:dan4 +0x8216:pu4 +0x8217:pu4 +0x8218:guan3 +0x8219:hua4 +0x821a:tan1 +0x821b:chuan3 +0x821c:shun4 +0x821d:xia2 +0x821e:wu3 +0x821f:zhou1 +0x8220:dao1 +0x8221:gang1 +0x8222:shan1 +0x8223:yi3 +0x8225:pa1 +0x8226:tai4 +0x8227:fan2 +0x8228:ban3 +0x8229:chuan2 +0x822a:hang2 +0x822b:fang3 +0x822c:ban1 +0x822d:que4 +0x822f:zhong1 +0x8230:jian4 +0x8231:cang1 +0x8232:ling2 +0x8233:zhu2 +0x8234:ze2 +0x8235:duo4 +0x8236:bo2 +0x8237:xian2 +0x8238:ge3 +0x8239:chuan2 +0x823a:xia2 +0x823b:lu3 +0x823c:hong2 +0x823d:pang2 +0x823e:xi1 +0x8240:fu2 +0x8241:zao4 +0x8242:feng2 +0x8243:li2 +0x8244:shao1 +0x8245:yu2 +0x8246:lang2 +0x8247:ting3 +0x8249:wei3 +0x824a:bo2 +0x824b:meng3 +0x824c:nian4 +0x824d:ju1 +0x824e:huang2 +0x824f:shou3 +0x8250:zong1 +0x8251:bian4 +0x8252:mao4 +0x8253:die2 +0x8255:bang4 +0x8256:cha1 +0x8257:yi4 +0x8258:sao1 +0x8259:cang1 +0x825a:cao2 +0x825b:lou2 +0x825c:dai4 +0x825e:yao4 +0x825f:tong2 +0x8261:dang1 +0x8262:tan2 +0x8263:lu3 +0x8264:yi3 +0x8265:jie4 +0x8266:jian4 +0x8267:huo4 +0x8268:meng2 +0x8269:qi2 +0x826a:lu3 +0x826b:lu2 +0x826c:chan2 +0x826d:shuang1 +0x826e:gen4 +0x826f:liang2 +0x8270:jian1 +0x8271:jian1 +0x8272:se4 +0x8273:yan4 +0x8274:fu2 +0x8275:ping2 +0x8276:yan4 +0x8277:yan4 +0x8278:cao3 +0x827a:yi4 +0x827b:le4 +0x827c:ting1 +0x827d:qiu2 +0x827e:ai4 +0x827f:nai3 +0x8280:tiao2 +0x8281:jiao1 +0x8282:jie2 +0x8283:peng2 +0x8284:wan2 +0x8285:yi4 +0x8286:chai1 +0x8287:mian2 +0x8288:mie1 +0x8289:gan1 +0x828a:qian1 +0x828b:yu4 +0x828c:yu4 +0x828d:shao2 +0x828e:qiong1 +0x828f:tu3 +0x8290:xia4 +0x8291:qi3 +0x8292:mang2 +0x8293:zi3 +0x8294:hui3 +0x8295:sui1 +0x8296:zhi4 +0x8297:xiang1 +0x8298:pi2 +0x8299:fu2 +0x829a:tun2 +0x829b:wei3 +0x829c:wu2 +0x829d:zhi1 +0x829e:qi3 +0x829f:shan1 +0x82a0:wen2 +0x82a1:qian4 +0x82a2:ren2 +0x82a3:fu2 +0x82a4:kou1 +0x82a5:jie4 +0x82a6:lu2 +0x82a7:xu4 +0x82a8:ji2 +0x82a9:qin2 +0x82aa:qi2 +0x82ab:yuan2 +0x82ac:fen1 +0x82ad:ba1 +0x82ae:rui4 +0x82af:xin1 +0x82b0:ji4 +0x82b1:hua1 +0x82b2:hua1 +0x82b3:fang1 +0x82b4:wu4 +0x82b5:jue2 +0x82b6:gou1 +0x82b7:zhi3 +0x82b8:yun2 +0x82b9:qin2 +0x82ba:ao3 +0x82bb:chu2 +0x82bc:mao4 +0x82bd:ya2 +0x82be:fei4 +0x82bf:reng4 +0x82c0:hang2 +0x82c1:cong1 +0x82c2:yin2 +0x82c3:you3 +0x82c4:bian4 +0x82c5:yi4 +0x82c7:wei3 +0x82c8:li4 +0x82c9:pi3 +0x82ca:e4 +0x82cb:xian4 +0x82cc:chang2 +0x82cd:cang1 +0x82ce:meng2 +0x82cf:su1 +0x82d0:yi2 +0x82d1:yuan4 +0x82d2:ran3 +0x82d3:ling2 +0x82d4:tai2 +0x82d5:tiao2 +0x82d6:di3 +0x82d7:miao2 +0x82d8:qiong3 +0x82d9:li4 +0x82da:yong4 +0x82db:ke1 +0x82dc:mu4 +0x82dd:pei4 +0x82de:bao1 +0x82df:gou3 +0x82e0:min2 +0x82e1:yi3 +0x82e2:yi3 +0x82e3:ju4 +0x82e4:pi1 +0x82e5:ruo4 +0x82e6:ku3 +0x82e7:zhu4 +0x82e8:ni3 +0x82e9:bo2 +0x82ea:bing3 +0x82eb:shan1 +0x82ec:qiu2 +0x82ed:yao3 +0x82ee:xian1 +0x82ef:ben3 +0x82f0:hong2 +0x82f1:ying1 +0x82f2:zha3 +0x82f3:dong1 +0x82f4:ju1 +0x82f5:die2 +0x82f6:nie2 +0x82f7:gan1 +0x82f8:hu1 +0x82f9:ping2 +0x82fa:mei2 +0x82fb:fu2 +0x82fc:sheng1 +0x82fd:gu1 +0x82fe:bi4 +0x82ff:wei4 +0x8300:fu2 +0x8301:zhuo2 +0x8302:mao4 +0x8303:fan4 +0x8304:qie2 +0x8305:mao2 +0x8306:mao3 +0x8307:ba2 +0x8308:zi3 +0x8309:mo4 +0x830a:zi1 +0x830b:di3 +0x830c:chi2 +0x830d:ji4 +0x830e:jing1 +0x830f:long2 +0x8311:niao3 +0x8313:xue2 +0x8314:ying2 +0x8315:qiong2 +0x8316:ge2 +0x8317:ming2 +0x8318:li4 +0x8319:rong2 +0x831a:yin4 +0x831b:gen4 +0x831c:qian4 +0x831d:chai3 +0x831e:chen2 +0x831f:yu4 +0x8320:xiu1 +0x8321:zi4 +0x8322:lie4 +0x8323:wu2 +0x8324:ji4 +0x8325:gui1 +0x8326:ce4 +0x8327:chong2 +0x8328:ci2 +0x8329:gou3 +0x832a:guang1 +0x832b:mang2 +0x832c:chi2 +0x832d:jiao1 +0x832e:jiao1 +0x832f:fu2 +0x8330:yu2 +0x8331:zhu1 +0x8332:zi1 +0x8333:jiang1 +0x8334:hui2 +0x8335:yin1 +0x8336:cha2 +0x8337:fa2 +0x8338:rong2 +0x8339:ru2 +0x833a:chong1 +0x833b:mang3 +0x833c:tong2 +0x833d:zhong4 +0x833f:zhu2 +0x8340:xun2 +0x8341:huan2 +0x8342:kua1 +0x8343:quan2 +0x8344:gai1 +0x8345:da1 +0x8346:jing1 +0x8347:xing4 +0x8348:chuan3 +0x8349:cao3 +0x834a:jing1 +0x834b:er2 +0x834c:an4 +0x834d:shou1 +0x834e:chi2 +0x834f:ren3 +0x8350:jian4 +0x8351:ti2 +0x8352:huang1 +0x8353:ping2 +0x8354:li4 +0x8355:jin1 +0x8356:lao3 +0x8357:shu4 +0x8358:zhuang1 +0x8359:da2 +0x835a:jia2 +0x835b:rao2 +0x835c:bi4 +0x835d:ze2 +0x835e:qiao2 +0x835f:hui4 +0x8360:qi2 +0x8361:dang4 +0x8363:rong2 +0x8364:hun1 +0x8365:ying2 +0x8366:luo4 +0x8367:ying2 +0x8368:xun2 +0x8369:jin4 +0x836a:sun1 +0x836b:yin4 +0x836c:mai3 +0x836d:hong2 +0x836e:zhou4 +0x836f:yao4 +0x8370:du4 +0x8371:wei3 +0x8372:chu4 +0x8373:dou4 +0x8374:fu1 +0x8375:ren3 +0x8376:yin2 +0x8377:he2 +0x8378:bi2 +0x8379:bu4 +0x837a:yun2 +0x837b:di2 +0x837c:tu2 +0x837d:sui1 +0x837e:sui1 +0x837f:cheng2 +0x8380:chen2 +0x8381:wu2 +0x8382:bie2 +0x8383:xi1 +0x8384:geng3 +0x8385:li4 +0x8386:fu3 +0x8387:zhu4 +0x8388:mo4 +0x8389:li4 +0x838a:zhuang1 +0x838b:ji2 +0x838c:duo2 +0x838d:qiu2 +0x838e:sha1 +0x838f:suo1 +0x8390:chen2 +0x8391:feng1 +0x8392:ju3 +0x8393:mei2 +0x8394:meng2 +0x8395:xing4 +0x8396:jing1 +0x8397:che1 +0x8398:shen1 +0x8399:jun1 +0x839a:yan2 +0x839b:ting2 +0x839c:diao4 +0x839d:cuo4 +0x839e:guan1 +0x839f:han4 +0x83a0:you3 +0x83a1:cuo4 +0x83a2:jia2 +0x83a3:wang2 +0x83a4:you2 +0x83a5:niu3 +0x83a6:shao1 +0x83a7:xian4 +0x83a8:lang2 +0x83a9:fu2 +0x83aa:e2 +0x83ab:mo4 +0x83ac:wen4 +0x83ad:jie2 +0x83ae:nan2 +0x83af:mu4 +0x83b0:kan3 +0x83b1:lai2 +0x83b2:lian2 +0x83b3:shi2 +0x83b4:wo1 +0x83b6:lian3 +0x83b7:huo4 +0x83b8:you2 +0x83b9:ying2 +0x83ba:ying1 +0x83bc:chun2 +0x83bd:mang3 +0x83be:mang3 +0x83bf:ci4 +0x83c0:wan3 +0x83c1:jing1 +0x83c2:di1 +0x83c3:qu2 +0x83c4:dong1 +0x83c5:jian1 +0x83c6:zou1 +0x83c7:gu1 +0x83c8:la1 +0x83c9:lu4 +0x83ca:ju2 +0x83cb:wei4 +0x83cc:jun1 +0x83cd:nie4 +0x83ce:kun1 +0x83cf:he2 +0x83d0:pu2 +0x83d1:zi1 +0x83d2:gao3 +0x83d3:guo3 +0x83d4:fu2 +0x83d5:lun2 +0x83d6:chang1 +0x83d7:chou2 +0x83d8:song1 +0x83d9:chui2 +0x83da:zhan4 +0x83db:men2 +0x83dc:cai4 +0x83dd:ba2 +0x83de:li2 +0x83df:tu4 +0x83e0:bo1 +0x83e1:han4 +0x83e2:bao4 +0x83e3:qin4 +0x83e4:juan3 +0x83e5:xi1 +0x83e6:qin2 +0x83e7:di3 +0x83e8:jie1 +0x83e9:pu2 +0x83ea:dang4 +0x83eb:jin3 +0x83ec:zhao3 +0x83ed:tai2 +0x83ee:geng1 +0x83ef:hua2 +0x83f0:gu1 +0x83f1:ling2 +0x83f2:fei1 +0x83f3:jin1 +0x83f4:an1 +0x83f5:wang3 +0x83f6:beng3 +0x83f7:zhou3 +0x83f8:yan1 +0x83f9:ju1 +0x83fa:jian1 +0x83fb:lin3 +0x83fc:tan3 +0x83fd:shu2 +0x83fe:tian2 +0x83ff:dao4 +0x8400:hu3 +0x8401:qi2 +0x8402:he2 +0x8403:cui4 +0x8404:tao2 +0x8405:chun1 +0x8406:pi4 +0x8407:chang2 +0x8408:huan2 +0x8409:fei2 +0x840a:lai2 +0x840b:qi1 +0x840c:meng2 +0x840d:ping2 +0x840e:wei1 +0x840f:dan4 +0x8410:sha4 +0x8411:huan2 +0x8412:yan3 +0x8413:yi2 +0x8414:tiao2 +0x8415:qi2 +0x8416:wan3 +0x8417:ce4 +0x8418:nai4 +0x841a:tuo4 +0x841b:jiu1 +0x841c:tie1 +0x841d:luo2 +0x8420:meng2 +0x8424:ying2 +0x8425:ying2 +0x8426:ying2 +0x8427:xiao1 +0x8428:sa4 +0x8429:qiu1 +0x842a:ke1 +0x842b:xiang4 +0x842c:wan4 +0x842d:yu3 +0x842e:yu4 +0x842f:fu4 +0x8430:lian4 +0x8431:xuan1 +0x8432:yuan2 +0x8433:nan2 +0x8434:ze2 +0x8435:wo1 +0x8436:chun3 +0x8437:xiao1 +0x8438:yu2 +0x8439:pian1 +0x843a:mao4 +0x843b:an1 +0x843c:e4 +0x843d:luo4 +0x843e:ying2 +0x843f:huo2 +0x8440:gua1 +0x8441:jiang1 +0x8442:mian3 +0x8443:zuo2 +0x8444:zuo4 +0x8445:ju1 +0x8446:bao3 +0x8447:rou2 +0x8448:xi3 +0x8449:ye4 +0x844a:an1 +0x844b:qu2 +0x844c:jian1 +0x844d:fu2 +0x844e:lv4 +0x844f:jing1 +0x8450:pen2 +0x8451:feng1 +0x8452:hong2 +0x8453:hong2 +0x8454:hou2 +0x8455:yan2 +0x8456:tu2 +0x8457:zhu4 +0x8458:zi1 +0x8459:xiang1 +0x845a:shen4 +0x845b:ge2 +0x845c:jie2 +0x845d:jing4 +0x845e:mi3 +0x845f:huang2 +0x8460:shen1 +0x8461:pu2 +0x8462:gai4 +0x8463:dong3 +0x8464:zhou4 +0x8465:qian2 +0x8466:wei3 +0x8467:bo2 +0x8468:wei1 +0x8469:pa1 +0x846a:ji4 +0x846b:hu2 +0x846c:zang4 +0x846d:jia1 +0x846e:duan4 +0x846f:yao4 +0x8470:jun4 +0x8471:cong1 +0x8472:quan2 +0x8473:wei1 +0x8474:zhen1 +0x8475:kui2 +0x8476:ting2 +0x8477:hun1 +0x8478:xi3 +0x8479:shi1 +0x847a:qi4 +0x847b:lan2 +0x847c:zong1 +0x847d:yao1 +0x847e:yuan1 +0x847f:mei2 +0x8480:yun1 +0x8481:shu4 +0x8482:di4 +0x8483:zhuan4 +0x8484:guan1 +0x8486:xue1 +0x8487:chan3 +0x8488:kai3 +0x8489:kui4 +0x848b:jiang3 +0x848c:lou2 +0x848d:wei2 +0x848e:pai4 +0x8490:sou1 +0x8491:yin1 +0x8492:shi1 +0x8493:chun2 +0x8494:shi2 +0x8495:yun1 +0x8496:zhen1 +0x8497:lang4 +0x8498:nu2 +0x8499:meng2 +0x849a:he2 +0x849b:que1 +0x849c:suan4 +0x849d:yuan2 +0x849e:li4 +0x849f:ju3 +0x84a0:xi2 +0x84a1:bang4 +0x84a2:chu2 +0x84a3:xu2 +0x84a4:tu2 +0x84a5:liu2 +0x84a6:wo4 +0x84a7:zhen1 +0x84a8:qian4 +0x84a9:zu1 +0x84aa:po4 +0x84ab:cuo1 +0x84ac:yuan1 +0x84ad:chu2 +0x84ae:yu4 +0x84af:kuai3 +0x84b0:pan2 +0x84b1:pu2 +0x84b2:pu2 +0x84b3:na4 +0x84b4:shuo4 +0x84b5:xi1 +0x84b6:fen2 +0x84b7:yun2 +0x84b8:zheng1 +0x84b9:jian1 +0x84ba:ji2 +0x84bb:ruo4 +0x84bc:cang1 +0x84bd:en1 +0x84be:mi2 +0x84bf:hao1 +0x84c0:sun1 +0x84c1:zhen1 +0x84c2:ming2 +0x84c3:huo4 +0x84c4:xu4 +0x84c5:liu2 +0x84c6:xi2 +0x84c7:gu3 +0x84c8:lang2 +0x84c9:rong2 +0x84ca:weng3 +0x84cb:gai4 +0x84cc:cuo4 +0x84cd:shi1 +0x84ce:tang2 +0x84cf:luo3 +0x84d0:ru4 +0x84d1:suo1 +0x84d2:xian1 +0x84d3:bei4 +0x84d4:yao3 +0x84d5:gui4 +0x84d6:bi4 +0x84d7:zong3 +0x84d8:gun3 +0x84da:xiu1 +0x84db:ce4 +0x84dd:lan2 +0x84df:ji4 +0x84e0:li2 +0x84e1:can1 +0x84e2:lang2 +0x84e3:yu4 +0x84e5:ying4 +0x84e6:mo4 +0x84e7:diao4 +0x84e8:tiao1 +0x84e9:mao4 +0x84ea:tong1 +0x84eb:zhu2 +0x84ec:peng2 +0x84ed:an1 +0x84ee:lian2 +0x84ef:cong1 +0x84f0:xi3 +0x84f1:ping2 +0x84f2:qiu1 +0x84f3:jin4 +0x84f4:chun2 +0x84f5:jie2 +0x84f6:wei3 +0x84f7:tui1 +0x84f8:cao2 +0x84f9:yu3 +0x84fa:yi4 +0x84fb:ji2 +0x84fc:liao3 +0x84fd:bi4 +0x84fe:lu3 +0x84ff:su4 +0x8500:bu4 +0x8501:zhang1 +0x8502:luo2 +0x8503:jiang4 +0x8504:man4 +0x8505:yan2 +0x8506:ling2 +0x8507:ji4 +0x8508:piao3 +0x8509:gun3 +0x850a:han3 +0x850b:di2 +0x850c:su4 +0x850d:lu4 +0x850e:she4 +0x850f:shang1 +0x8510:di2 +0x8511:mie4 +0x8512:xun1 +0x8513:man4 +0x8514:bo5 +0x8515:di4 +0x8516:cuo2 +0x8517:zhe4 +0x8518:sen1 +0x8519:xuan4 +0x851a:wei4 +0x851b:hu2 +0x851c:ao2 +0x851d:mi3 +0x851e:lou2 +0x851f:cu4 +0x8520:zhong1 +0x8521:cai4 +0x8522:po2 +0x8523:jiang3 +0x8524:mi4 +0x8525:cong1 +0x8526:niao3 +0x8527:hui4 +0x8528:jun4 +0x8529:yin2 +0x852a:jian4 +0x852b:yan1 +0x852c:shu1 +0x852d:yin4 +0x852e:kui4 +0x852f:chen2 +0x8530:hu4 +0x8531:sha1 +0x8532:kou4 +0x8533:qian4 +0x8534:ma2 +0x8535:zang1 +0x8537:qiang2 +0x8538:dou1 +0x8539:lian4 +0x853a:lin4 +0x853b:kou4 +0x853c:ai3 +0x853d:bi4 +0x853e:li2 +0x853f:wei2 +0x8540:ji2 +0x8541:xun2 +0x8542:sheng4 +0x8543:fan2 +0x8544:meng2 +0x8545:ou3 +0x8546:chan3 +0x8547:dian3 +0x8548:xun4 +0x8549:jiao1 +0x854a:rui3 +0x854b:rui3 +0x854c:lei3 +0x854d:yu2 +0x854e:qiao2 +0x854f:chu2 +0x8550:hua2 +0x8551:jian1 +0x8552:mai3 +0x8553:yun2 +0x8554:bao1 +0x8555:you2 +0x8556:qu2 +0x8557:lu4 +0x8558:rao2 +0x8559:hui4 +0x855a:e4 +0x855b:teng2 +0x855c:fei3 +0x855d:jue2 +0x855e:zui4 +0x855f:fa4 +0x8560:ru2 +0x8561:fen2 +0x8562:kui4 +0x8563:shun4 +0x8564:rui2 +0x8565:ya3 +0x8566:xu1 +0x8567:fu4 +0x8568:jue2 +0x8569:dang4 +0x856a:wu2 +0x856b:tong2 +0x856c:si1 +0x856d:xiao1 +0x856e:xi4 +0x856f:long2 +0x8570:yun4 +0x8572:qi2 +0x8573:jian1 +0x8574:yun4 +0x8575:sun1 +0x8576:ling2 +0x8577:yu4 +0x8578:xia2 +0x8579:yong1 +0x857a:ji2 +0x857b:hong4 +0x857c:si4 +0x857d:nong2 +0x857e:lei3 +0x857f:xuan1 +0x8580:yun4 +0x8581:yu4 +0x8582:xi2 +0x8583:hao4 +0x8584:bo2 +0x8585:hao1 +0x8586:ai4 +0x8587:wei2 +0x8588:hui4 +0x8589:wei4 +0x858a:ji4 +0x858b:ci1 +0x858c:xiang1 +0x858d:luan4 +0x858e:mie4 +0x858f:yi4 +0x8590:leng2 +0x8591:jiang1 +0x8592:can4 +0x8593:shen1 +0x8594:qiang2 +0x8595:lian2 +0x8596:ke1 +0x8597:yuan2 +0x8598:da2 +0x8599:ti4 +0x859a:tang2 +0x859b:xue1 +0x859c:bi4 +0x859d:zhan2 +0x859e:sun1 +0x859f:lian3 +0x85a0:fan2 +0x85a1:ding3 +0x85a2:jie1 +0x85a3:gu3 +0x85a4:xie4 +0x85a5:shu3 +0x85a6:jian4 +0x85a7:kao3 +0x85a8:hong1 +0x85a9:sa4 +0x85aa:xin1 +0x85ab:xun1 +0x85ac:yao4 +0x85ae:sou3 +0x85af:shu3 +0x85b0:xun1 +0x85b1:dui4 +0x85b2:pin2 +0x85b3:wei3 +0x85b4:neng2 +0x85b5:chou2 +0x85b6:mai2 +0x85b7:ru2 +0x85b8:piao1 +0x85b9:tai2 +0x85ba:ci2 +0x85bb:zao3 +0x85bc:chen2 +0x85bd:zhen1 +0x85be:er3 +0x85bf:ni3 +0x85c0:ying2 +0x85c1:gao3 +0x85c2:cong4 +0x85c3:xiao1 +0x85c4:qi2 +0x85c5:fa2 +0x85c6:jian3 +0x85c7:xu4 +0x85c8:kui1 +0x85c9:jie4 +0x85ca:bian3 +0x85cb:diao4 +0x85cc:mi4 +0x85cd:lan2 +0x85ce:jin4 +0x85cf:cang2 +0x85d0:miao3 +0x85d1:qiong2 +0x85d2:qie4 +0x85d3:xian3 +0x85d5:ou3 +0x85d6:xian2 +0x85d7:su4 +0x85d8:lv2 +0x85d9:yi4 +0x85da:xu4 +0x85db:xie3 +0x85dc:li2 +0x85dd:yi4 +0x85de:la3 +0x85df:lei3 +0x85e0:xiao4 +0x85e1:di2 +0x85e2:zhi3 +0x85e3:bei1 +0x85e4:teng2 +0x85e5:yao4 +0x85e6:mo4 +0x85e7:huan3 +0x85e8:biao1 +0x85e9:fan2 +0x85ea:sou3 +0x85eb:tan2 +0x85ec:tui1 +0x85ed:qiong2 +0x85ee:qiao2 +0x85ef:wei4 +0x85f0:liu2 +0x85f1:hui4 +0x85f3:gao3 +0x85f4:yun4 +0x85f6:li4 +0x85f7:shu3 +0x85f8:chu2 +0x85f9:ai3 +0x85fa:lin4 +0x85fb:zao3 +0x85fc:xuan1 +0x85fd:chen4 +0x85fe:lai4 +0x85ff:huo4 +0x8600:tuo4 +0x8601:wu4 +0x8602:rui3 +0x8603:rui3 +0x8604:qi2 +0x8605:heng2 +0x8606:lu2 +0x8607:su1 +0x8608:tui2 +0x8609:mang2 +0x860a:yun4 +0x860b:pin2 +0x860c:yu3 +0x860d:xun1 +0x860e:ji4 +0x860f:jiong1 +0x8610:xian1 +0x8611:mo2 +0x8613:su1 +0x8614:jiong1 +0x8616:nie4 +0x8617:bo4 +0x8618:rang2 +0x8619:yi4 +0x861a:xian3 +0x861b:yu2 +0x861c:ju2 +0x861d:lian4 +0x861e:lian4 +0x861f:yin3 +0x8620:qiang2 +0x8621:ying1 +0x8622:long2 +0x8623:tong4 +0x8624:wei3 +0x8625:yue4 +0x8626:ling2 +0x8627:qu2 +0x8628:yao2 +0x8629:fan2 +0x862a:mi2 +0x862b:lan2 +0x862c:kui1 +0x862d:lan2 +0x862e:ji4 +0x862f:dang4 +0x8631:lei4 +0x8632:lei2 +0x8633:hua3 +0x8634:feng1 +0x8635:zhi2 +0x8636:wei4 +0x8637:kui2 +0x8638:zhan4 +0x8639:huai4 +0x863a:li2 +0x863b:ji4 +0x863c:mi2 +0x863d:lei3 +0x863e:huai4 +0x863f:luo2 +0x8640:ji1 +0x8641:kui2 +0x8642:lu4 +0x8643:jian1 +0x8646:lei2 +0x8647:quan3 +0x8648:xiao1 +0x8649:yi4 +0x864a:luan2 +0x864b:men2 +0x864c:bie1 +0x864d:hu1 +0x864e:hu3 +0x864f:lu3 +0x8650:nve4 +0x8651:lv4 +0x8652:si1 +0x8653:xiao1 +0x8654:qian2 +0x8655:chu4 +0x8656:hu1 +0x8657:xu1 +0x8658:cuo2 +0x8659:fu2 +0x865a:xu1 +0x865b:xu1 +0x865c:lu3 +0x865d:hu3 +0x865e:yu2 +0x865f:hao4 +0x8660:jiao3 +0x8661:ju4 +0x8662:guo2 +0x8663:bao4 +0x8664:yan2 +0x8665:zhan4 +0x8666:zhan4 +0x8667:kui1 +0x8668:ban1 +0x8669:xi4 +0x866a:shu2 +0x866b:chong2 +0x866c:qiu2 +0x866d:diao1 +0x866e:ji1 +0x866f:qiu2 +0x8670:cheng2 +0x8671:shi1 +0x8673:di4 +0x8674:zhe2 +0x8675:she2 +0x8676:yu1 +0x8677:gan1 +0x8678:zi3 +0x8679:hong2 +0x867a:hui3 +0x867b:meng2 +0x867c:ge4 +0x867d:sui1 +0x867e:xia1 +0x867f:chai4 +0x8680:shi2 +0x8681:yi3 +0x8682:ma3 +0x8683:xiang4 +0x8684:fang1 +0x8685:e4 +0x8686:pa1 +0x8687:chi3 +0x8688:qian1 +0x8689:wen2 +0x868a:wen2 +0x868b:rui4 +0x868c:bang4 +0x868d:bi3 +0x868e:yue4 +0x868f:yue4 +0x8690:jun1 +0x8691:qi2 +0x8692:tong2 +0x8693:yin3 +0x8694:qi2 +0x8695:can2 +0x8696:yuan2 +0x8697:jue2 +0x8698:hui2 +0x8699:qin2 +0x869a:qi2 +0x869b:zhong4 +0x869c:ya2 +0x869d:ci4 +0x869e:mu4 +0x869f:wang2 +0x86a0:fen2 +0x86a1:fen2 +0x86a2:hang2 +0x86a3:gong1 +0x86a4:zao3 +0x86a5:fu3 +0x86a6:ran2 +0x86a7:jie4 +0x86a8:fu2 +0x86a9:chi1 +0x86aa:dou3 +0x86ab:piao2 +0x86ac:xian4 +0x86ad:ni2 +0x86ae:te4 +0x86af:qiu1 +0x86b0:you2 +0x86b1:zha4 +0x86b2:ping2 +0x86b3:chi2 +0x86b4:you3 +0x86b5:he2 +0x86b6:han1 +0x86b7:ju4 +0x86b8:li4 +0x86b9:fu4 +0x86ba:ran2 +0x86bb:zha2 +0x86bc:gou3 +0x86bd:pi2 +0x86be:bo3 +0x86bf:xian2 +0x86c0:zhu4 +0x86c1:diao1 +0x86c2:bie3 +0x86c3:bing3 +0x86c4:gu1 +0x86c5:ran2 +0x86c6:qu1 +0x86c7:she2 +0x86c8:tie4 +0x86c9:ling2 +0x86ca:gu3 +0x86cb:dan4 +0x86cc:gu3 +0x86cd:ying2 +0x86ce:li4 +0x86cf:cheng1 +0x86d0:qu1 +0x86d1:mou2 +0x86d2:ge2 +0x86d3:ci4 +0x86d4:hui2 +0x86d5:hui2 +0x86d6:mang2 +0x86d7:fu4 +0x86d8:yang2 +0x86d9:wa1 +0x86da:lie4 +0x86db:zhu1 +0x86dc:yi1 +0x86dd:xian2 +0x86de:kuo4 +0x86df:jiao1 +0x86e0:li4 +0x86e1:yi4 +0x86e2:ping2 +0x86e3:jie2 +0x86e4:ha2 +0x86e5:she2 +0x86e6:yi2 +0x86e7:wang3 +0x86e8:mo4 +0x86e9:qiong2 +0x86ea:qie4 +0x86eb:gui3 +0x86ec:gong3 +0x86ed:zhi4 +0x86ee:man2 +0x86f0:zhi2 +0x86f1:jia2 +0x86f2:rao2 +0x86f3:si1 +0x86f4:qi2 +0x86f5:xing1 +0x86f6:lie4 +0x86f7:qiu2 +0x86f8:shao1 +0x86f9:yong3 +0x86fa:jia2 +0x86fb:tui4 +0x86fc:che1 +0x86fd:bai4 +0x86fe:e2 +0x86ff:han4 +0x8700:shu3 +0x8701:xuan2 +0x8702:feng1 +0x8703:shen4 +0x8704:zhen4 +0x8705:fu3 +0x8706:xian4 +0x8707:zhe2 +0x8708:wu2 +0x8709:fu2 +0x870a:li2 +0x870b:lang2 +0x870c:bi4 +0x870d:chu2 +0x870e:yuan1 +0x870f:you3 +0x8710:jie2 +0x8711:dan4 +0x8712:yan2 +0x8713:ting2 +0x8714:dian4 +0x8715:shui4 +0x8716:hui2 +0x8717:gua1 +0x8718:zhi1 +0x8719:song1 +0x871a:fei1 +0x871b:ju1 +0x871c:mi4 +0x871d:qi2 +0x871e:qi2 +0x871f:yu4 +0x8720:jun3 +0x8721:la4 +0x8722:meng3 +0x8723:qiang1 +0x8724:si1 +0x8725:xi1 +0x8726:lun2 +0x8727:li4 +0x8728:die2 +0x8729:tiao2 +0x872a:tao1 +0x872b:kun1 +0x872c:gan1 +0x872d:han4 +0x872e:yu4 +0x872f:bang4 +0x8730:fei2 +0x8731:pi2 +0x8732:wei3 +0x8733:dun1 +0x8734:yi4 +0x8735:yuan1 +0x8736:su4 +0x8737:quan2 +0x8738:qian3 +0x8739:rui4 +0x873a:ni2 +0x873b:qing1 +0x873c:wei4 +0x873d:liang3 +0x873e:guo3 +0x873f:wan1 +0x8740:dong1 +0x8741:e4 +0x8742:ban3 +0x8743:di4 +0x8744:wang3 +0x8745:can2 +0x8746:yang3 +0x8747:ying2 +0x8748:guo1 +0x8749:chan2 +0x874b:la4 +0x874c:ke1 +0x874d:ji2 +0x874e:he2 +0x874f:ting2 +0x8750:mai4 +0x8751:xu1 +0x8752:mian2 +0x8753:yu2 +0x8754:jie1 +0x8755:shi2 +0x8756:xuan1 +0x8757:huang2 +0x8758:yan3 +0x8759:bian1 +0x875a:rou2 +0x875b:wei1 +0x875c:fu4 +0x875d:yuan2 +0x875e:mei4 +0x875f:wei4 +0x8760:fu2 +0x8761:ruan3 +0x8762:xie2 +0x8763:you2 +0x8764:qiu2 +0x8765:mao2 +0x8766:xia1 +0x8767:ying1 +0x8768:shi1 +0x8769:chong2 +0x876a:tang1 +0x876b:zhu1 +0x876c:zong1 +0x876d:ti2 +0x876e:fu4 +0x876f:yuan2 +0x8770:hui3 +0x8771:meng2 +0x8772:la4 +0x8773:du2 +0x8774:hu2 +0x8775:qiu1 +0x8776:die2 +0x8777:li4 +0x8778:gua1 +0x8779:yun1 +0x877a:ju3 +0x877b:nan3 +0x877c:lou2 +0x877d:qun3 +0x877e:rong2 +0x877f:ying2 +0x8780:jiang1 +0x8782:lang2 +0x8783:pang2 +0x8784:si1 +0x8785:xi1 +0x8786:ci4 +0x8787:xi1 +0x8788:yuan2 +0x8789:weng1 +0x878a:lian2 +0x878b:sou1 +0x878c:ban1 +0x878d:rong2 +0x878e:rong2 +0x878f:ji2 +0x8790:wu1 +0x8791:qiu4 +0x8792:han4 +0x8793:qin2 +0x8794:yi2 +0x8795:bi1 +0x8796:hua2 +0x8797:tang2 +0x8798:yi3 +0x8799:du4 +0x879a:nai4 +0x879b:he2 +0x879c:hu2 +0x879d:hui4 +0x879e:ma3 +0x879f:ming2 +0x87a0:yi4 +0x87a1:wen2 +0x87a2:ying2 +0x87a3:teng2 +0x87a4:yu3 +0x87a5:cang1 +0x87a8:man3 +0x87aa:shang1 +0x87ab:shi4 +0x87ac:cao2 +0x87ad:chi1 +0x87ae:di4 +0x87af:ao2 +0x87b0:lu4 +0x87b1:wei4 +0x87b2:zhi4 +0x87b3:tang2 +0x87b4:chen2 +0x87b5:piao1 +0x87b6:qu2 +0x87b7:pi2 +0x87b8:yu2 +0x87b9:jian4 +0x87ba:luo2 +0x87bb:lou2 +0x87bc:qin3 +0x87bd:zhong1 +0x87be:yin3 +0x87bf:jiang1 +0x87c0:shuai4 +0x87c1:wen2 +0x87c2:jiao1 +0x87c3:wan4 +0x87c4:zhe2 +0x87c5:zhe4 +0x87c6:ma2 +0x87c7:ma2 +0x87c8:guo1 +0x87c9:liu2 +0x87ca:mao2 +0x87cb:xi1 +0x87cc:cong1 +0x87cd:li2 +0x87ce:man3 +0x87cf:xiao1 +0x87d1:zhang1 +0x87d2:mang3 +0x87d3:xiang4 +0x87d4:mo4 +0x87d5:zui1 +0x87d6:si1 +0x87d7:qiu1 +0x87d8:te4 +0x87d9:zhi2 +0x87da:peng2 +0x87db:peng2 +0x87dc:jiao3 +0x87dd:qu2 +0x87de:bie2 +0x87df:liao2 +0x87e0:pan2 +0x87e1:gui3 +0x87e2:xi3 +0x87e3:ji3 +0x87e4:zhuan1 +0x87e5:huang2 +0x87e6:fei4 +0x87e7:lao2 +0x87e8:jue2 +0x87e9:jue2 +0x87ea:hui4 +0x87eb:yin2 +0x87ec:chan2 +0x87ed:jiao1 +0x87ee:shan4 +0x87ef:rao2 +0x87f0:xiao1 +0x87f1:mou2 +0x87f2:chong2 +0x87f3:xun2 +0x87f4:si1 +0x87f6:cheng1 +0x87f7:dang1 +0x87f8:li3 +0x87f9:xie4 +0x87fa:shan4 +0x87fb:yi3 +0x87fc:jing3 +0x87fd:da2 +0x87fe:chan2 +0x87ff:qi4 +0x8800:ci1 +0x8801:xiang4 +0x8802:she4 +0x8803:luo3 +0x8804:qin2 +0x8805:ying2 +0x8806:chai4 +0x8807:li4 +0x8808:ze2 +0x8809:xuan1 +0x880a:lian2 +0x880b:zhu2 +0x880c:ze2 +0x880d:xie1 +0x880e:mang3 +0x880f:xie4 +0x8810:qi2 +0x8811:rong2 +0x8812:jian3 +0x8813:meng3 +0x8814:hao2 +0x8815:ru2 +0x8816:huo4 +0x8817:zhuo2 +0x8818:jie2 +0x8819:bin1 +0x881a:he4 +0x881b:mie4 +0x881c:fan2 +0x881d:lei2 +0x881e:jie2 +0x881f:la4 +0x8820:mi4 +0x8821:li3 +0x8822:chun3 +0x8823:li4 +0x8824:qiu1 +0x8825:nie4 +0x8826:lu2 +0x8827:du4 +0x8828:xiao1 +0x8829:zhu1 +0x882a:long2 +0x882b:li4 +0x882c:long2 +0x882d:feng1 +0x882e:ye1 +0x882f:beng4 +0x8830:shang4 +0x8831:gu3 +0x8832:juan1 +0x8833:ying1 +0x8835:xi1 +0x8836:can2 +0x8837:qu2 +0x8838:quan2 +0x8839:du4 +0x883a:can2 +0x883b:man2 +0x883c:jue2 +0x883d:jie2 +0x883e:zhu2 +0x883f:zha2 +0x8840:xie3 +0x8841:huang1 +0x8842:niu4 +0x8843:pei1 +0x8844:nv4 +0x8845:xin4 +0x8846:zhong4 +0x8847:mo4 +0x8848:er4 +0x8849:ke4 +0x884a:mie4 +0x884b:xi4 +0x884c:xing2 +0x884d:yan3 +0x884e:kan4 +0x884f:yuan4 +0x8851:ling2 +0x8852:xuan4 +0x8853:shu4 +0x8854:xian2 +0x8855:tong4 +0x8856:long4 +0x8857:jie1 +0x8858:xian2 +0x8859:ya2 +0x885a:hu2 +0x885b:wei4 +0x885c:dao4 +0x885d:chong1 +0x885e:wei4 +0x885f:dao4 +0x8860:zhun1 +0x8861:heng2 +0x8862:qu2 +0x8863:yi1 +0x8865:bu3 +0x8866:gan3 +0x8867:yu2 +0x8868:biao3 +0x8869:cha4 +0x886a:yi3 +0x886b:shan1 +0x886c:chen4 +0x886d:fu1 +0x886e:gun3 +0x886f:fen1 +0x8870:shuai1 +0x8871:jie2 +0x8872:na4 +0x8873:zhong1 +0x8874:dan3 +0x8875:ri4 +0x8876:zhong4 +0x8877:zhong1 +0x8878:xie4 +0x8879:qi2 +0x887a:xie2 +0x887b:ran2 +0x887c:zhi1 +0x887d:ren4 +0x887e:qin1 +0x887f:jin1 +0x8880:jun1 +0x8881:yuan2 +0x8882:mei4 +0x8883:chai4 +0x8884:ao3 +0x8885:niao3 +0x8886:hui1 +0x8887:ran2 +0x8888:jia1 +0x8889:tuo2 +0x888a:ling3 +0x888b:dai4 +0x888c:bao4 +0x888d:pao2 +0x888e:yao4 +0x888f:zuo4 +0x8890:bi4 +0x8891:shao4 +0x8892:tan3 +0x8893:ju3 +0x8894:he4 +0x8895:shu4 +0x8896:xiu4 +0x8897:zhen3 +0x8898:yi2 +0x8899:pa4 +0x889a:bo1 +0x889b:di1 +0x889c:wa4 +0x889d:fu4 +0x889e:gun3 +0x889f:zhi4 +0x88a0:zhi4 +0x88a1:ran2 +0x88a2:pan4 +0x88a3:yi4 +0x88a4:mao4 +0x88a6:na4 +0x88a7:kou1 +0x88a8:xian4 +0x88a9:chan1 +0x88aa:qu1 +0x88ab:bei4 +0x88ac:gun3 +0x88ad:xi2 +0x88af:bo2 +0x88b1:fu2 +0x88b2:yi2 +0x88b3:chi3 +0x88b4:ku4 +0x88b5:ren4 +0x88b6:jiang4 +0x88b7:jia2 +0x88b8:cun2 +0x88b9:mo4 +0x88ba:jie2 +0x88bb:er2 +0x88bc:luo4 +0x88bd:ru2 +0x88be:zhu1 +0x88bf:gui1 +0x88c0:yin1 +0x88c1:cai2 +0x88c2:lie4 +0x88c5:zhuang1 +0x88c6:dang1 +0x88c8:kun1 +0x88c9:ken4 +0x88ca:niao3 +0x88cb:shu4 +0x88cc:jia2 +0x88cd:kun3 +0x88ce:cheng2 +0x88cf:li3 +0x88d0:juan1 +0x88d1:shen1 +0x88d2:pou2 +0x88d3:ge2 +0x88d4:yi4 +0x88d5:yu4 +0x88d6:zhen3 +0x88d7:liu2 +0x88d8:qiu2 +0x88d9:qun2 +0x88da:ji4 +0x88db:yi4 +0x88dc:bu3 +0x88dd:zhuang1 +0x88de:shui4 +0x88df:sha1 +0x88e0:qun2 +0x88e1:li3 +0x88e2:lian2 +0x88e3:lian4 +0x88e4:ku4 +0x88e5:jian3 +0x88e6:fou2 +0x88e7:chan1 +0x88e8:bi4 +0x88e9:gun1 +0x88ea:tao2 +0x88eb:yuan4 +0x88ec:ling2 +0x88ed:chi3 +0x88ee:chang1 +0x88ef:chou2 +0x88f0:duo2 +0x88f1:biao3 +0x88f2:liang3 +0x88f3:chang2 +0x88f4:pei2 +0x88f5:pei2 +0x88f6:fei1 +0x88f7:yuan1 +0x88f8:luo3 +0x88f9:guo3 +0x88fa:yan3 +0x88fb:du3 +0x88fc:xi2 +0x88fd:zhi4 +0x88fe:ju1 +0x88ff:qi3 +0x8900:ji4 +0x8901:zhi2 +0x8902:gua4 +0x8903:ken4 +0x8905:ti4 +0x8906:ti2 +0x8907:fu4 +0x8908:chong2 +0x8909:xie1 +0x890a:bian3 +0x890b:die2 +0x890c:kun1 +0x890d:duan1 +0x890e:xiu4 +0x890f:xiu4 +0x8910:he2 +0x8911:yuan4 +0x8912:bao1 +0x8913:bao3 +0x8914:fu4 +0x8915:yu2 +0x8916:tuan4 +0x8917:yan3 +0x8918:hui1 +0x8919:bei4 +0x891a:chu3 +0x891b:lv3 +0x891e:yun3 +0x891f:da2 +0x8920:gou1 +0x8921:da1 +0x8922:huai2 +0x8923:rong2 +0x8924:yuan4 +0x8925:ru4 +0x8926:nai4 +0x8927:jiong3 +0x8928:suo3 +0x8929:ban1 +0x892a:tun4 +0x892b:chi3 +0x892c:sang3 +0x892d:niao3 +0x892e:ying1 +0x892f:jie4 +0x8930:qian1 +0x8931:huai2 +0x8932:ku4 +0x8933:lian2 +0x8934:bao3 +0x8935:li2 +0x8936:zhe2 +0x8937:shi1 +0x8938:lv3 +0x8939:yi4 +0x893a:die2 +0x893b:xie4 +0x893c:xian1 +0x893d:wei4 +0x893e:biao3 +0x893f:cao2 +0x8940:ji1 +0x8941:jiang3 +0x8942:sen1 +0x8943:bao1 +0x8944:xiang1 +0x8946:pu2 +0x8947:jian3 +0x8948:zhuan4 +0x8949:jian4 +0x894a:zui4 +0x894b:ji2 +0x894c:dan1 +0x894d:za2 +0x894e:fan2 +0x894f:bo2 +0x8950:xiang4 +0x8951:xin2 +0x8952:bie2 +0x8953:rao2 +0x8954:man3 +0x8955:lan2 +0x8956:ao3 +0x8957:duo2 +0x8958:gui4 +0x8959:cao4 +0x895a:sui4 +0x895b:nong2 +0x895c:chan1 +0x895d:lian4 +0x895e:bi4 +0x895f:jin1 +0x8960:dang1 +0x8961:shu2 +0x8962:tan3 +0x8963:bi4 +0x8964:lan2 +0x8965:pu2 +0x8966:ru2 +0x8967:zhi3 +0x8969:shu3 +0x896a:wa4 +0x896b:shi4 +0x896c:bai3 +0x896d:xie2 +0x896e:bo2 +0x896f:chen4 +0x8970:lai4 +0x8971:long2 +0x8972:xi2 +0x8973:xian1 +0x8974:lan2 +0x8975:zhe2 +0x8976:dai4 +0x8978:zan4 +0x8979:shi1 +0x897a:jian3 +0x897b:pan4 +0x897c:yi4 +0x897e:ya4 +0x897f:xi1 +0x8980:xi1 +0x8981:yao4 +0x8982:feng3 +0x8983:tan2 +0x8985:biao4 +0x8986:fu4 +0x8987:ba4 +0x8988:he2 +0x8989:ji1 +0x898a:ji1 +0x898b:jian4 +0x898c:guan1 +0x898d:bian4 +0x898e:yan4 +0x898f:gui1 +0x8990:jue2 +0x8991:pian3 +0x8992:mao2 +0x8993:mi4 +0x8994:mi4 +0x8995:mie4 +0x8996:shi4 +0x8997:si1 +0x8998:zhan1 +0x8999:luo2 +0x899a:jue2 +0x899b:mi4 +0x899c:tiao4 +0x899d:lian2 +0x899e:yao4 +0x899f:zhi4 +0x89a0:jun1 +0x89a1:xi2 +0x89a2:shan3 +0x89a3:wei1 +0x89a4:xi4 +0x89a5:tian3 +0x89a6:yu2 +0x89a7:lan3 +0x89a8:e4 +0x89a9:du3 +0x89aa:qin1 +0x89ab:pang3 +0x89ac:ji4 +0x89ad:ming2 +0x89ae:ying2 +0x89af:gou4 +0x89b0:qu4 +0x89b1:zhan4 +0x89b2:jin3 +0x89b3:guan1 +0x89b4:deng1 +0x89b5:jian4 +0x89b6:luo2 +0x89b7:qu4 +0x89b8:jian4 +0x89b9:wei2 +0x89ba:jue2 +0x89bb:qu4 +0x89bc:luo2 +0x89bd:lan3 +0x89be:shen3 +0x89bf:di2 +0x89c0:guan1 +0x89c1:jian4 +0x89c2:guan1 +0x89c3:yan4 +0x89c4:gui1 +0x89c5:mi4 +0x89c6:shi4 +0x89c7:zhan1 +0x89c8:lan3 +0x89c9:jue2 +0x89ca:ji4 +0x89cb:xi2 +0x89cc:di2 +0x89cd:tian3 +0x89ce:yu2 +0x89cf:gou4 +0x89d0:jin3 +0x89d1:qu4 +0x89d2:jiao3 +0x89d3:jiu1 +0x89d4:jin1 +0x89d5:cu1 +0x89d6:jue2 +0x89d7:zhi4 +0x89d8:chao4 +0x89d9:ji2 +0x89da:gu1 +0x89db:dan4 +0x89dc:zi1 +0x89dd:di3 +0x89de:shang1 +0x89df:hua4 +0x89e0:quan2 +0x89e1:ge2 +0x89e2:chi4 +0x89e3:jie3 +0x89e4:gui3 +0x89e5:gong1 +0x89e6:chu4 +0x89e7:jie3 +0x89e8:hun4 +0x89e9:qiu2 +0x89ea:xing1 +0x89eb:su4 +0x89ec:ni2 +0x89ed:ji1 +0x89ee:lu4 +0x89ef:zhi4 +0x89f0:zha1 +0x89f1:bi4 +0x89f2:xing1 +0x89f3:hu2 +0x89f4:shang1 +0x89f5:gong1 +0x89f6:zhi4 +0x89f7:xue2 +0x89f8:chu4 +0x89f9:xi1 +0x89fa:yi2 +0x89fb:lu4 +0x89fc:jue2 +0x89fd:xi1 +0x89fe:yan4 +0x89ff:xi1 +0x8a00:yan2 +0x8a02:ding4 +0x8a03:fu4 +0x8a04:qiu2 +0x8a05:qiu2 +0x8a06:jiao4 +0x8a07:hong1 +0x8a08:ji4 +0x8a09:fan4 +0x8a0a:xun4 +0x8a0b:diao4 +0x8a0c:hong2 +0x8a0d:cha4 +0x8a0e:tao3 +0x8a0f:xu1 +0x8a10:jie2 +0x8a11:yi2 +0x8a12:ren4 +0x8a13:xun4 +0x8a14:yin2 +0x8a15:shan4 +0x8a16:qi4 +0x8a17:tuo1 +0x8a18:ji4 +0x8a19:xun4 +0x8a1a:yin2 +0x8a1b:e2 +0x8a1c:fen1 +0x8a1d:ya4 +0x8a1e:yao1 +0x8a1f:song4 +0x8a20:shen3 +0x8a21:yin2 +0x8a22:xin1 +0x8a23:jue2 +0x8a24:xiao2 +0x8a25:ne4 +0x8a26:chen2 +0x8a27:you2 +0x8a28:zhi3 +0x8a29:xiong1 +0x8a2a:fang3 +0x8a2b:xin4 +0x8a2c:chao1 +0x8a2d:she4 +0x8a2e:xian1 +0x8a2f:sha3 +0x8a30:tun2 +0x8a31:xu3 +0x8a32:yi4 +0x8a33:yi4 +0x8a34:su4 +0x8a35:chi1 +0x8a36:he1 +0x8a37:shen1 +0x8a38:he2 +0x8a39:xu4 +0x8a3a:zhen3 +0x8a3b:zhu4 +0x8a3c:zheng4 +0x8a3d:gou4 +0x8a3e:zi3 +0x8a3f:zi3 +0x8a40:zhan1 +0x8a41:gu3 +0x8a42:fu4 +0x8a43:quan3 +0x8a44:die2 +0x8a45:ling2 +0x8a46:di3 +0x8a47:yang4 +0x8a48:li4 +0x8a49:nao2 +0x8a4a:pan4 +0x8a4b:zhou4 +0x8a4c:gan4 +0x8a4d:yi4 +0x8a4e:ju4 +0x8a4f:ao4 +0x8a50:zha4 +0x8a51:tuo2 +0x8a52:yi2 +0x8a53:qu3 +0x8a54:zhao4 +0x8a55:ping2 +0x8a56:bi4 +0x8a57:xiong4 +0x8a58:qu1 +0x8a59:ba2 +0x8a5a:da2 +0x8a5b:zu3 +0x8a5c:tao1 +0x8a5d:zhu3 +0x8a5e:ci2 +0x8a5f:zhe2 +0x8a60:yong3 +0x8a61:xu3 +0x8a62:xun2 +0x8a63:yi4 +0x8a64:huang3 +0x8a65:he2 +0x8a66:shi4 +0x8a67:cha2 +0x8a68:jiao1 +0x8a69:shi1 +0x8a6a:hen3 +0x8a6b:cha4 +0x8a6c:gou4 +0x8a6d:gui3 +0x8a6e:quan2 +0x8a6f:hui4 +0x8a70:jie2 +0x8a71:hua4 +0x8a72:gai1 +0x8a73:xiang2 +0x8a74:wei1 +0x8a75:shen1 +0x8a76:chou2 +0x8a77:tong2 +0x8a78:mi2 +0x8a79:zhan1 +0x8a7a:ming4 +0x8a7b:e4 +0x8a7c:hui1 +0x8a7d:yan2 +0x8a7e:xiong1 +0x8a7f:gua4 +0x8a80:er4 +0x8a81:beng3 +0x8a82:tiao3 +0x8a83:chi3 +0x8a84:lei3 +0x8a85:zhu1 +0x8a86:kuang1 +0x8a87:kua1 +0x8a88:wu2 +0x8a89:yu4 +0x8a8a:teng2 +0x8a8b:ji4 +0x8a8c:zhi4 +0x8a8d:ren4 +0x8a8e:su4 +0x8a8f:lang3 +0x8a90:e2 +0x8a91:kuang2 +0x8a92:e4 +0x8a93:shi4 +0x8a94:ting3 +0x8a95:dan4 +0x8a96:bo2 +0x8a97:chan2 +0x8a98:you4 +0x8a99:heng2 +0x8a9a:qiao4 +0x8a9b:qin1 +0x8a9c:shua4 +0x8a9d:an1 +0x8a9e:yu3 +0x8a9f:xiao4 +0x8aa0:cheng2 +0x8aa1:jie4 +0x8aa2:xian4 +0x8aa3:wu1 +0x8aa4:wu4 +0x8aa5:gao4 +0x8aa6:song4 +0x8aa7:pu3 +0x8aa8:hui4 +0x8aa9:jing4 +0x8aaa:shuo1 +0x8aab:zhen4 +0x8aac:shuo1 +0x8aad:du2 +0x8aaf:chang4 +0x8ab0:shui2 +0x8ab1:jie2 +0x8ab2:ke4 +0x8ab3:qu1 +0x8ab4:cong2 +0x8ab5:xiao2 +0x8ab6:sui4 +0x8ab7:wang3 +0x8ab8:xuan2 +0x8ab9:fei3 +0x8aba:chi1 +0x8abb:ta4 +0x8abc:yi4 +0x8abd:na2 +0x8abe:yin2 +0x8abf:diao4 +0x8ac0:pi3 +0x8ac1:chuo4 +0x8ac2:chan3 +0x8ac3:chen1 +0x8ac4:zhun1 +0x8ac5:ji1 +0x8ac6:qi1 +0x8ac7:tan2 +0x8ac8:zhui4 +0x8ac9:wei3 +0x8aca:ju2 +0x8acb:qing3 +0x8acc:jian4 +0x8acd:zheng1 +0x8ace:ze2 +0x8acf:zou1 +0x8ad0:qian1 +0x8ad1:zhuo2 +0x8ad2:liang4 +0x8ad3:jian4 +0x8ad4:zhu4 +0x8ad5:hao2 +0x8ad6:lun4 +0x8ad7:shen3 +0x8ad8:biao3 +0x8ad9:huai4 +0x8ada:pian2 +0x8adb:yu2 +0x8adc:die2 +0x8add:xu3 +0x8ade:pian3 +0x8adf:shi4 +0x8ae0:xuan1 +0x8ae1:shi4 +0x8ae2:hun4 +0x8ae3:hua4 +0x8ae4:e4 +0x8ae5:zhong4 +0x8ae6:di4 +0x8ae7:xie2 +0x8ae8:fu2 +0x8ae9:pu3 +0x8aea:ting2 +0x8aeb:jian4 +0x8aec:qi3 +0x8aed:yu4 +0x8aee:zi1 +0x8aef:chuan2 +0x8af0:xi3 +0x8af1:hui4 +0x8af2:yin1 +0x8af3:an1 +0x8af4:xian2 +0x8af5:nan2 +0x8af6:chen2 +0x8af7:feng3 +0x8af8:zhu1 +0x8af9:yang2 +0x8afa:yan4 +0x8afb:heng1 +0x8afc:xuan1 +0x8afd:ge2 +0x8afe:nuo4 +0x8aff:qi4 +0x8b00:mou2 +0x8b01:ye4 +0x8b02:wei4 +0x8b04:teng2 +0x8b05:zou1 +0x8b06:shan4 +0x8b07:jian3 +0x8b08:bo2 +0x8b0a:huang3 +0x8b0b:huo4 +0x8b0c:ge1 +0x8b0d:ying2 +0x8b0e:mi2 +0x8b0f:xiao3 +0x8b10:mi4 +0x8b11:xi4 +0x8b12:qiang1 +0x8b13:chen1 +0x8b14:nve4 +0x8b15:ti2 +0x8b16:su4 +0x8b17:bang4 +0x8b18:chi2 +0x8b19:qian1 +0x8b1a:shi4 +0x8b1b:jiang3 +0x8b1c:yuan4 +0x8b1d:xie4 +0x8b1e:xue4 +0x8b1f:tao1 +0x8b20:yao2 +0x8b21:yao2 +0x8b23:yu2 +0x8b24:biao1 +0x8b25:cong4 +0x8b26:qing4 +0x8b27:li2 +0x8b28:mo2 +0x8b29:mo4 +0x8b2a:shang1 +0x8b2b:zhe2 +0x8b2c:miu4 +0x8b2d:jian3 +0x8b2e:ze2 +0x8b2f:jie1 +0x8b30:lian2 +0x8b31:lou2 +0x8b32:can1 +0x8b33:ou1 +0x8b34:guan4 +0x8b35:xi2 +0x8b36:zhuo2 +0x8b37:ao2 +0x8b38:ao2 +0x8b39:jin3 +0x8b3a:zhe2 +0x8b3b:yi2 +0x8b3c:hu4 +0x8b3d:jiang4 +0x8b3e:man2 +0x8b3f:chao2 +0x8b40:han4 +0x8b41:hua2 +0x8b42:chan3 +0x8b43:xu1 +0x8b44:zeng1 +0x8b45:se4 +0x8b46:xi1 +0x8b47:she1 +0x8b48:dui4 +0x8b49:zheng4 +0x8b4a:nao2 +0x8b4b:lan2 +0x8b4c:e2 +0x8b4d:ying4 +0x8b4e:jue2 +0x8b4f:ji1 +0x8b50:zun3 +0x8b51:jiao3 +0x8b52:bo4 +0x8b53:hui4 +0x8b54:zhuan4 +0x8b55:mu2 +0x8b56:zen4 +0x8b57:zha2 +0x8b58:shi5 +0x8b59:qiao2 +0x8b5a:tan2 +0x8b5b:zen4 +0x8b5c:pu3 +0x8b5d:sheng2 +0x8b5e:xuan1 +0x8b5f:zao4 +0x8b60:tan1 +0x8b61:dang3 +0x8b62:sui4 +0x8b63:qian1 +0x8b64:ji1 +0x8b65:jiao4 +0x8b66:jing3 +0x8b67:lian2 +0x8b68:nou2 +0x8b69:yi1 +0x8b6a:ai4 +0x8b6b:zhan1 +0x8b6c:pi4 +0x8b6d:hui3 +0x8b6e:hua4 +0x8b6f:yi4 +0x8b70:yi4 +0x8b71:shan4 +0x8b72:rang4 +0x8b73:nou4 +0x8b74:qian3 +0x8b75:zhui4 +0x8b76:ta4 +0x8b77:hu4 +0x8b78:zhou1 +0x8b79:hao2 +0x8b7a:ye4 +0x8b7b:ying1 +0x8b7c:jian4 +0x8b7d:yu4 +0x8b7e:jian3 +0x8b7f:hui4 +0x8b80:du2 +0x8b81:zhe2 +0x8b82:xuan4 +0x8b83:zan4 +0x8b84:lei3 +0x8b85:shen3 +0x8b86:wei4 +0x8b87:chan3 +0x8b88:li4 +0x8b89:yi2 +0x8b8a:bian4 +0x8b8b:zhe2 +0x8b8c:yan4 +0x8b8d:e4 +0x8b8e:chou2 +0x8b8f:wei4 +0x8b90:chou2 +0x8b91:yao4 +0x8b92:chan2 +0x8b93:rang4 +0x8b94:yin3 +0x8b95:lan2 +0x8b96:chen4 +0x8b97:huo4 +0x8b98:zhe2 +0x8b99:huan1 +0x8b9a:zan4 +0x8b9b:yi4 +0x8b9c:dang3 +0x8b9d:zhan1 +0x8b9e:yan4 +0x8b9f:du2 +0x8ba0:yan2 +0x8ba1:ji4 +0x8ba2:ding4 +0x8ba3:fu4 +0x8ba4:ren4 +0x8ba5:ji1 +0x8ba6:jie2 +0x8ba7:hong2 +0x8ba8:tao3 +0x8ba9:rang4 +0x8baa:shan4 +0x8bab:qi4 +0x8bac:tuo1 +0x8bad:xun4 +0x8bae:yi4 +0x8baf:xun4 +0x8bb0:ji4 +0x8bb1:ren4 +0x8bb2:jiang3 +0x8bb3:hui4 +0x8bb4:ou1 +0x8bb5:ju4 +0x8bb6:ya4 +0x8bb7:ne4 +0x8bb8:xu3 +0x8bb9:e2 +0x8bba:lun4 +0x8bbb:xiong1 +0x8bbc:song4 +0x8bbd:feng1 +0x8bbe:she4 +0x8bbf:fang3 +0x8bc0:jue2 +0x8bc1:zheng4 +0x8bc2:gu3 +0x8bc3:he1 +0x8bc4:ping2 +0x8bc5:zu3 +0x8bc6:shi4 +0x8bc7:xiong4 +0x8bc8:zha4 +0x8bc9:su4 +0x8bca:zhen3 +0x8bcb:di3 +0x8bcc:zou1 +0x8bcd:ci2 +0x8bce:qu4 +0x8bcf:zhao4 +0x8bd0:bi4 +0x8bd1:yi4 +0x8bd2:yi2 +0x8bd3:kuang1 +0x8bd4:lei3 +0x8bd5:shi4 +0x8bd6:gua4 +0x8bd7:shi1 +0x8bd8:jie2 +0x8bd9:hui1 +0x8bda:cheng2 +0x8bdb:zhu1 +0x8bdc:shen1 +0x8bdd:hua4 +0x8bde:dan4 +0x8bdf:gou4 +0x8be0:quan2 +0x8be1:gui3 +0x8be2:xun2 +0x8be3:yi4 +0x8be4:zheng1 +0x8be5:gai1 +0x8be6:xiang2 +0x8be7:cha4 +0x8be8:hun4 +0x8be9:xu3 +0x8bea:zhou1 +0x8beb:jie4 +0x8bec:wu2 +0x8bed:yu3 +0x8bee:qiao4 +0x8bef:wu4 +0x8bf0:gao4 +0x8bf1:you4 +0x8bf2:hui4 +0x8bf3:kuang2 +0x8bf4:shuo1 +0x8bf5:song4 +0x8bf6:ai1 +0x8bf7:qing3 +0x8bf8:zhu1 +0x8bf9:zou1 +0x8bfa:nuo4 +0x8bfb:du2 +0x8bfc:zhuo2 +0x8bfd:fei3 +0x8bfe:ke4 +0x8bff:wei3 +0x8c00:yu2 +0x8c01:shui2 +0x8c02:shen3 +0x8c03:diao4 +0x8c04:chan3 +0x8c05:liang4 +0x8c06:zhun1 +0x8c07:sui4 +0x8c08:tan2 +0x8c09:shen3 +0x8c0a:yi2 +0x8c0b:mou2 +0x8c0c:chen2 +0x8c0d:die2 +0x8c0e:huang3 +0x8c0f:jian4 +0x8c10:xie2 +0x8c11:nve4 +0x8c12:ye4 +0x8c13:wei4 +0x8c14:e4 +0x8c15:yu4 +0x8c16:xuan1 +0x8c17:chan2 +0x8c18:zi1 +0x8c19:an1 +0x8c1a:yan4 +0x8c1b:di4 +0x8c1c:mi2 +0x8c1d:pian2 +0x8c1e:xu3 +0x8c1f:mo2 +0x8c20:dang3 +0x8c21:su4 +0x8c22:xie4 +0x8c23:yao2 +0x8c24:bang4 +0x8c25:shi4 +0x8c26:qian1 +0x8c27:mi4 +0x8c28:jin3 +0x8c29:man2 +0x8c2a:zhe2 +0x8c2b:jian3 +0x8c2c:miu4 +0x8c2d:tan2 +0x8c2e:zen4 +0x8c2f:qiao2 +0x8c30:lan2 +0x8c31:pu3 +0x8c32:jue2 +0x8c33:yan4 +0x8c34:qian3 +0x8c35:zhan1 +0x8c36:chen4 +0x8c37:gu3 +0x8c38:qian1 +0x8c39:hong2 +0x8c3a:xia1 +0x8c3b:jue2 +0x8c3c:hong2 +0x8c3d:han1 +0x8c3e:hong1 +0x8c3f:xi1 +0x8c40:xi1 +0x8c41:huo1 +0x8c42:liao2 +0x8c43:han3 +0x8c44:du2 +0x8c45:long2 +0x8c46:dou4 +0x8c47:jiang1 +0x8c48:qi3 +0x8c49:chi3 +0x8c4a:li3 +0x8c4b:deng1 +0x8c4c:wan1 +0x8c4d:bi1 +0x8c4e:shu4 +0x8c4f:xian4 +0x8c50:feng1 +0x8c51:zhi4 +0x8c52:zhi4 +0x8c53:yan4 +0x8c54:yan4 +0x8c55:shi3 +0x8c56:chu4 +0x8c57:hui1 +0x8c58:tun2 +0x8c59:yi4 +0x8c5a:tun2 +0x8c5b:yi4 +0x8c5c:jian1 +0x8c5d:ba1 +0x8c5e:hou4 +0x8c5f:e4 +0x8c60:cu2 +0x8c61:xiang4 +0x8c62:huan4 +0x8c63:jian1 +0x8c64:ken3 +0x8c65:gai1 +0x8c66:qu2 +0x8c67:fu1 +0x8c68:xi1 +0x8c69:bin1 +0x8c6a:hao2 +0x8c6b:yu4 +0x8c6c:zhu1 +0x8c6d:jia1 +0x8c6e:fen2 +0x8c6f:xi1 +0x8c70:bo2 +0x8c71:wen1 +0x8c72:huan2 +0x8c73:bin1 +0x8c74:di2 +0x8c75:zong1 +0x8c76:fen2 +0x8c77:yi4 +0x8c78:zhi4 +0x8c79:bao4 +0x8c7a:chai2 +0x8c7b:an4 +0x8c7c:pi2 +0x8c7d:na4 +0x8c7e:pi1 +0x8c7f:gou3 +0x8c80:na4 +0x8c81:you4 +0x8c82:diao1 +0x8c83:mo4 +0x8c84:si4 +0x8c85:xiu1 +0x8c86:huan2 +0x8c87:kun1 +0x8c88:he2 +0x8c89:he2 +0x8c8a:mo4 +0x8c8b:han4 +0x8c8c:mao4 +0x8c8d:li2 +0x8c8e:ni2 +0x8c8f:bi3 +0x8c90:yu3 +0x8c91:jia1 +0x8c92:tuan1 +0x8c93:mao1 +0x8c94:pi2 +0x8c95:xi1 +0x8c96:e4 +0x8c97:ju4 +0x8c98:mo4 +0x8c99:chu1 +0x8c9a:tan2 +0x8c9b:huan1 +0x8c9c:jue2 +0x8c9d:bei4 +0x8c9e:zhen1 +0x8c9f:yuan2 +0x8ca0:fu4 +0x8ca1:cai2 +0x8ca2:gong4 +0x8ca3:te4 +0x8ca4:yi2 +0x8ca5:hang2 +0x8ca6:wan4 +0x8ca7:pin2 +0x8ca8:huo4 +0x8ca9:fan4 +0x8caa:tan1 +0x8cab:guan4 +0x8cac:ze2 +0x8cad:zhi2 +0x8cae:er4 +0x8caf:zhu3 +0x8cb0:shi4 +0x8cb1:bi4 +0x8cb2:zi1 +0x8cb3:er4 +0x8cb4:gui4 +0x8cb5:pian3 +0x8cb6:bian3 +0x8cb7:mai3 +0x8cb8:dai4 +0x8cb9:sheng4 +0x8cba:kuang4 +0x8cbb:fei4 +0x8cbc:tie1 +0x8cbd:yi2 +0x8cbe:chi2 +0x8cbf:mao4 +0x8cc0:he4 +0x8cc1:bi4 +0x8cc2:lu4 +0x8cc3:lin4 +0x8cc4:hui4 +0x8cc5:gai1 +0x8cc6:pian2 +0x8cc7:zi1 +0x8cc8:jia3 +0x8cc9:xu4 +0x8cca:zei2 +0x8ccb:jiao3 +0x8ccc:gai4 +0x8ccd:zang1 +0x8cce:jian4 +0x8ccf:ying4 +0x8cd0:xun4 +0x8cd1:zhen4 +0x8cd2:she1 +0x8cd3:bin1 +0x8cd4:bin1 +0x8cd5:qiu2 +0x8cd6:she1 +0x8cd7:chuan4 +0x8cd8:zang1 +0x8cd9:zhou1 +0x8cda:lai4 +0x8cdb:zan4 +0x8cdc:ci4 +0x8cdd:chen1 +0x8cde:shang3 +0x8cdf:tian3 +0x8ce0:pei2 +0x8ce1:geng1 +0x8ce2:xian2 +0x8ce3:mai4 +0x8ce4:jian4 +0x8ce5:sui4 +0x8ce6:fu4 +0x8ce7:tan4 +0x8ce8:cong2 +0x8ce9:cong2 +0x8cea:zhi4 +0x8ceb:ji1 +0x8cec:zhang4 +0x8ced:du3 +0x8cee:jin4 +0x8cef:xiong1 +0x8cf0:shun3 +0x8cf1:yun3 +0x8cf2:bao3 +0x8cf3:zai1 +0x8cf4:lai4 +0x8cf5:feng4 +0x8cf6:cang4 +0x8cf7:ji1 +0x8cf8:sheng4 +0x8cf9:ai4 +0x8cfa:zhuan4 +0x8cfb:fu4 +0x8cfc:gou4 +0x8cfd:sai4 +0x8cfe:ze2 +0x8cff:liao2 +0x8d00:wei4 +0x8d01:bai4 +0x8d02:chen3 +0x8d03:zhuan4 +0x8d04:zhi4 +0x8d05:zhui4 +0x8d06:biao1 +0x8d07:yun1 +0x8d08:zeng4 +0x8d09:tan3 +0x8d0a:zan4 +0x8d0b:yan4 +0x8d0d:shan4 +0x8d0e:wan4 +0x8d0f:ying2 +0x8d10:jin4 +0x8d11:gan3 +0x8d12:xian2 +0x8d13:zang1 +0x8d14:bi4 +0x8d15:du2 +0x8d16:shu2 +0x8d17:yan4 +0x8d19:xuan4 +0x8d1a:long4 +0x8d1b:gan4 +0x8d1c:zang1 +0x8d1d:bei4 +0x8d1e:zhen1 +0x8d1f:fu4 +0x8d20:yuan2 +0x8d21:gong4 +0x8d22:cai2 +0x8d23:ze2 +0x8d24:xian2 +0x8d25:bai4 +0x8d26:zhang4 +0x8d27:huo4 +0x8d28:zhi2 +0x8d29:fan4 +0x8d2a:tan1 +0x8d2b:pin2 +0x8d2c:bian3 +0x8d2d:gou4 +0x8d2e:zhu3 +0x8d2f:guan4 +0x8d30:er4 +0x8d31:jian4 +0x8d32:bi4 +0x8d33:shi4 +0x8d34:tie1 +0x8d35:gui4 +0x8d36:kuang4 +0x8d37:dai4 +0x8d38:mao4 +0x8d39:fei4 +0x8d3a:he4 +0x8d3b:yi2 +0x8d3c:zei2 +0x8d3d:zhi4 +0x8d3e:jia3 +0x8d3f:hui4 +0x8d40:zi1 +0x8d41:ren4 +0x8d42:lu4 +0x8d43:zang1 +0x8d44:zi1 +0x8d45:gai1 +0x8d46:jin4 +0x8d47:qiu2 +0x8d48:zhen4 +0x8d49:lai4 +0x8d4a:she1 +0x8d4b:fu4 +0x8d4c:du3 +0x8d4d:ji1 +0x8d4e:shu2 +0x8d4f:shang3 +0x8d50:si4 +0x8d51:bi4 +0x8d52:zhou1 +0x8d53:geng1 +0x8d54:pei2 +0x8d55:tan4 +0x8d56:lai4 +0x8d57:feng4 +0x8d58:zhui4 +0x8d59:fu4 +0x8d5a:zhuan4 +0x8d5b:sai4 +0x8d5c:ze2 +0x8d5d:yan4 +0x8d5e:zan4 +0x8d5f:yun1 +0x8d60:zeng4 +0x8d61:shan4 +0x8d62:ying2 +0x8d63:gan4 +0x8d64:chi4 +0x8d65:xi4 +0x8d66:she4 +0x8d67:nan3 +0x8d68:xiong2 +0x8d69:xi4 +0x8d6a:cheng1 +0x8d6b:he4 +0x8d6c:cheng1 +0x8d6d:zhe3 +0x8d6e:xia2 +0x8d6f:tang2 +0x8d70:zou3 +0x8d71:zou3 +0x8d72:li4 +0x8d73:jiu3 +0x8d74:fu4 +0x8d75:zhao4 +0x8d76:gan3 +0x8d77:qi3 +0x8d78:shan4 +0x8d79:qiong2 +0x8d7a:qin2 +0x8d7b:xian3 +0x8d7c:ci1 +0x8d7d:jue2 +0x8d7e:qin3 +0x8d7f:chi2 +0x8d80:ci1 +0x8d81:chen4 +0x8d82:chen4 +0x8d83:die2 +0x8d84:ju1 +0x8d85:chao1 +0x8d86:di1 +0x8d87:se4 +0x8d88:zhan1 +0x8d89:zhu2 +0x8d8a:yue4 +0x8d8b:qu1 +0x8d8c:jie2 +0x8d8d:chi2 +0x8d8e:chu2 +0x8d8f:gua1 +0x8d90:xue4 +0x8d91:ci1 +0x8d92:tiao2 +0x8d93:duo3 +0x8d94:lie4 +0x8d95:gan3 +0x8d96:suo1 +0x8d97:cu4 +0x8d98:xi2 +0x8d99:zhao4 +0x8d9a:su4 +0x8d9b:yin3 +0x8d9c:ju2 +0x8d9d:jian4 +0x8d9e:que4 +0x8d9f:tang4 +0x8da0:chuo4 +0x8da1:cui3 +0x8da2:lu4 +0x8da3:qu4 +0x8da4:dang4 +0x8da5:qiu1 +0x8da6:zi1 +0x8da7:ti2 +0x8da8:qu1 +0x8da9:chi4 +0x8daa:huang2 +0x8dab:qiao2 +0x8dac:qiao2 +0x8dad:yao4 +0x8dae:zao4 +0x8daf:ti4 +0x8db1:zan3 +0x8db2:zan3 +0x8db3:zu2 +0x8db4:pa1 +0x8db5:bao4 +0x8db6:ku4 +0x8db7:ke1 +0x8db8:dun3 +0x8db9:jue2 +0x8dba:fu1 +0x8dbb:chen3 +0x8dbc:jian3 +0x8dbd:fang4 +0x8dbe:zhi3 +0x8dbf:sa4 +0x8dc0:yue4 +0x8dc1:pa2 +0x8dc2:qi2 +0x8dc3:yue4 +0x8dc4:qiang1 +0x8dc5:tuo4 +0x8dc6:tai2 +0x8dc7:yi4 +0x8dc8:nian3 +0x8dc9:ling2 +0x8dca:mei4 +0x8dcb:ba2 +0x8dcc:die1 +0x8dcd:ku1 +0x8dce:tuo2 +0x8dcf:jia1 +0x8dd0:ci3 +0x8dd1:pao3 +0x8dd2:qia3 +0x8dd3:zhu4 +0x8dd4:ju1 +0x8dd5:die2 +0x8dd6:zhi2 +0x8dd7:fu1 +0x8dd8:pan2 +0x8dd9:ju3 +0x8dda:shan1 +0x8ddb:bo3 +0x8ddc:ni2 +0x8ddd:ju4 +0x8dde:li4 +0x8ddf:gen1 +0x8de0:yi2 +0x8de1:ji1 +0x8de2:dai4 +0x8de3:xian3 +0x8de4:jiao1 +0x8de5:duo4 +0x8de6:zhu1 +0x8de7:quan2 +0x8de8:kua4 +0x8de9:zhuai3 +0x8dea:gui4 +0x8deb:qiong2 +0x8dec:kui3 +0x8ded:xiang2 +0x8dee:chi4 +0x8def:lu4 +0x8df0:beng4 +0x8df1:zhi4 +0x8df2:jia2 +0x8df3:tiao4 +0x8df4:cai3 +0x8df5:jian4 +0x8df6:ta4 +0x8df7:qiao1 +0x8df8:bi4 +0x8df9:xian1 +0x8dfa:duo4 +0x8dfb:ji1 +0x8dfc:ju2 +0x8dfd:ji4 +0x8dfe:shu2 +0x8dff:tu2 +0x8e00:chu4 +0x8e01:jing4 +0x8e02:nie4 +0x8e03:xiao1 +0x8e04:bo2 +0x8e05:chi4 +0x8e06:qun1 +0x8e07:mou3 +0x8e08:shu1 +0x8e09:lang2 +0x8e0a:yong3 +0x8e0b:jiao3 +0x8e0c:chou2 +0x8e0d:qiao1 +0x8e0f:ta4 +0x8e10:jian4 +0x8e11:qi2 +0x8e12:wo1 +0x8e13:wei3 +0x8e14:zhuo2 +0x8e15:jie2 +0x8e16:ji2 +0x8e17:nie1 +0x8e18:ju2 +0x8e19:ju1 +0x8e1a:lun2 +0x8e1b:lu4 +0x8e1c:leng4 +0x8e1d:huai2 +0x8e1e:ju4 +0x8e1f:chi2 +0x8e20:wan3 +0x8e21:quan2 +0x8e22:ti1 +0x8e23:bo2 +0x8e24:zu2 +0x8e25:qie4 +0x8e26:ji3 +0x8e27:cu4 +0x8e28:zong1 +0x8e29:cai3 +0x8e2a:zong1 +0x8e2b:peng4 +0x8e2c:zhi4 +0x8e2d:zheng1 +0x8e2e:dian3 +0x8e2f:zhi2 +0x8e30:yu2 +0x8e31:duo4 +0x8e32:dun4 +0x8e33:chun3 +0x8e34:yong3 +0x8e35:zhong3 +0x8e36:di4 +0x8e37:zhe3 +0x8e38:chen3 +0x8e39:chuai4 +0x8e3a:jian4 +0x8e3b:gua1 +0x8e3c:tang2 +0x8e3d:ju3 +0x8e3e:fu2 +0x8e3f:zu2 +0x8e40:die2 +0x8e41:pian2 +0x8e42:rou2 +0x8e43:nuo4 +0x8e44:ti2 +0x8e45:cha3 +0x8e46:tui3 +0x8e47:jian3 +0x8e48:dao3 +0x8e49:cuo1 +0x8e4a:xi1 +0x8e4b:ta4 +0x8e4c:qiang1 +0x8e4d:zhan3 +0x8e4e:dian1 +0x8e4f:ti2 +0x8e50:ji2 +0x8e51:nie4 +0x8e52:man2 +0x8e53:liu1 +0x8e54:zhan4 +0x8e55:bi4 +0x8e56:chong1 +0x8e57:lu4 +0x8e58:liao2 +0x8e59:cu4 +0x8e5a:tang1 +0x8e5b:dai4 +0x8e5c:suo1 +0x8e5d:xi3 +0x8e5e:kui3 +0x8e5f:ji1 +0x8e60:zhi2 +0x8e61:qiang1 +0x8e62:di2 +0x8e63:pan2 +0x8e64:zong1 +0x8e65:lian2 +0x8e66:beng4 +0x8e67:zao1 +0x8e68:nian3 +0x8e69:bie2 +0x8e6a:tui2 +0x8e6b:ju2 +0x8e6c:deng4 +0x8e6d:ceng4 +0x8e6e:xian1 +0x8e6f:fan2 +0x8e70:chu2 +0x8e71:zhong1 +0x8e72:dun1 +0x8e73:bo1 +0x8e74:cu4 +0x8e75:zu2 +0x8e76:jue2 +0x8e77:jue2 +0x8e78:lin4 +0x8e79:ta4 +0x8e7a:qiao1 +0x8e7b:qiao1 +0x8e7c:pu2 +0x8e7d:liao1 +0x8e7e:dun1 +0x8e7f:cuan1 +0x8e80:kuang4 +0x8e81:zao4 +0x8e82:ta4 +0x8e83:bi4 +0x8e84:bi4 +0x8e85:zhu2 +0x8e86:ju4 +0x8e87:chu2 +0x8e88:qiao4 +0x8e89:dun3 +0x8e8a:chou2 +0x8e8b:ji1 +0x8e8c:wu3 +0x8e8d:yue4 +0x8e8e:nian3 +0x8e8f:lin4 +0x8e90:lie4 +0x8e91:zhi2 +0x8e92:li4 +0x8e93:zhi4 +0x8e94:chan2 +0x8e95:chu2 +0x8e96:duan4 +0x8e97:wei4 +0x8e98:long2 +0x8e99:lin4 +0x8e9a:xian1 +0x8e9b:wei4 +0x8e9c:zuan1 +0x8e9d:lan2 +0x8e9e:xie4 +0x8e9f:rang2 +0x8ea0:xie3 +0x8ea1:nie4 +0x8ea2:ta4 +0x8ea3:qu2 +0x8ea4:jie4 +0x8ea5:cuan1 +0x8ea6:zuan1 +0x8ea7:xi3 +0x8ea8:kui2 +0x8ea9:jue2 +0x8eaa:lin4 +0x8eab:shen1 +0x8eac:gong1 +0x8ead:dan1 +0x8eaf:qu1 +0x8eb0:ti3 +0x8eb1:duo3 +0x8eb2:duo3 +0x8eb3:gong1 +0x8eb4:lang2 +0x8eb6:luo3 +0x8eb7:ai3 +0x8eb8:ji1 +0x8eb9:ju2 +0x8eba:tang3 +0x8ebd:yan3 +0x8ebf:kang1 +0x8ec0:qu1 +0x8ec1:lou2 +0x8ec2:lao4 +0x8ec3:tuo3 +0x8ec4:zhi2 +0x8ec6:ti3 +0x8ec7:dao4 +0x8ec9:yu4 +0x8eca:che1 +0x8ecb:ya4 +0x8ecc:gui3 +0x8ecd:jun1 +0x8ece:wei4 +0x8ecf:yue4 +0x8ed0:xin4 +0x8ed1:di4 +0x8ed2:xuan1 +0x8ed3:fan4 +0x8ed4:ren4 +0x8ed5:shan1 +0x8ed6:qiang2 +0x8ed7:shu1 +0x8ed8:tun2 +0x8ed9:chen2 +0x8eda:dai4 +0x8edb:e4 +0x8edc:na4 +0x8edd:qi2 +0x8ede:mao2 +0x8edf:ruan3 +0x8ee0:ren4 +0x8ee1:fan3 +0x8ee2:zhuan3 +0x8ee3:hong1 +0x8ee4:hu1 +0x8ee5:qu2 +0x8ee6:huang4 +0x8ee7:di3 +0x8ee8:ling2 +0x8ee9:dai4 +0x8eea:ao1 +0x8eeb:zhen3 +0x8eec:fan4 +0x8eed:kuang1 +0x8eee:ang3 +0x8eef:peng1 +0x8ef0:bei4 +0x8ef1:gu1 +0x8ef2:ku1 +0x8ef3:pao2 +0x8ef4:zhu4 +0x8ef5:rong3 +0x8ef6:e4 +0x8ef7:ba2 +0x8ef8:zhou2 +0x8ef9:zhi3 +0x8efa:yao2 +0x8efb:ke1 +0x8efc:yi4 +0x8efd:qing1 +0x8efe:shi4 +0x8eff:ping2 +0x8f00:er2 +0x8f01:qiong2 +0x8f02:ju2 +0x8f03:jiao4 +0x8f04:guang1 +0x8f05:lu4 +0x8f06:kai3 +0x8f07:quan2 +0x8f08:zhou1 +0x8f09:zai4 +0x8f0a:zhi4 +0x8f0b:she1 +0x8f0c:liang4 +0x8f0d:yu4 +0x8f0e:shao1 +0x8f0f:you2 +0x8f10:huan3 +0x8f11:yun3 +0x8f12:zhe2 +0x8f13:wan3 +0x8f14:fu3 +0x8f15:qing1 +0x8f16:zhou1 +0x8f17:ni2 +0x8f18:ling2 +0x8f19:zhe2 +0x8f1a:zhan4 +0x8f1b:liang4 +0x8f1c:zi1 +0x8f1d:hui1 +0x8f1e:wang3 +0x8f1f:chuo4 +0x8f20:guo3 +0x8f21:kan3 +0x8f22:yi3 +0x8f23:peng2 +0x8f24:qian4 +0x8f25:gun3 +0x8f26:nian3 +0x8f27:pian2 +0x8f28:guan3 +0x8f29:bei4 +0x8f2a:lun2 +0x8f2b:pai2 +0x8f2c:liang2 +0x8f2d:ruan3 +0x8f2e:rou2 +0x8f2f:ji2 +0x8f30:yang2 +0x8f31:xian2 +0x8f32:chuan2 +0x8f33:cou4 +0x8f34:chun1 +0x8f35:ge2 +0x8f36:you2 +0x8f37:hong1 +0x8f38:shu1 +0x8f39:fu4 +0x8f3a:zi1 +0x8f3b:fu2 +0x8f3c:wen1 +0x8f3d:ben4 +0x8f3e:zhan3 +0x8f3f:yu2 +0x8f40:wen1 +0x8f41:tao1 +0x8f42:gu3 +0x8f43:zhen1 +0x8f44:xia2 +0x8f45:yuan2 +0x8f46:lu4 +0x8f47:jiu1 +0x8f48:chao2 +0x8f49:zhuan3 +0x8f4a:wei4 +0x8f4b:hun2 +0x8f4d:che4 +0x8f4e:jiao4 +0x8f4f:zhan4 +0x8f50:pu2 +0x8f51:lao3 +0x8f52:fen2 +0x8f53:fan1 +0x8f54:lin2 +0x8f55:ge2 +0x8f56:se4 +0x8f57:kan3 +0x8f58:huan4 +0x8f59:yi3 +0x8f5a:ji2 +0x8f5b:dui4 +0x8f5c:er2 +0x8f5d:yu2 +0x8f5e:xian4 +0x8f5f:hong1 +0x8f60:lei3 +0x8f61:pei4 +0x8f62:li4 +0x8f63:li4 +0x8f64:lu2 +0x8f65:lin4 +0x8f66:che1 +0x8f67:ya4 +0x8f68:gui3 +0x8f69:xuan1 +0x8f6a:di4 +0x8f6b:ren4 +0x8f6c:zhuan3 +0x8f6d:e4 +0x8f6e:lun2 +0x8f6f:ruan3 +0x8f70:hong1 +0x8f71:ku1 +0x8f72:ke1 +0x8f73:lu2 +0x8f74:zhou2 +0x8f75:zhi3 +0x8f76:yi4 +0x8f77:hu1 +0x8f78:zhen3 +0x8f79:li4 +0x8f7a:yao2 +0x8f7b:qing1 +0x8f7c:shi4 +0x8f7d:zai4 +0x8f7e:zhi4 +0x8f7f:jiao4 +0x8f80:zhou1 +0x8f81:quan2 +0x8f82:lu4 +0x8f83:jiao4 +0x8f84:zhe2 +0x8f85:fu3 +0x8f86:liang4 +0x8f87:nian3 +0x8f88:bei4 +0x8f89:hui1 +0x8f8a:gun3 +0x8f8b:wang3 +0x8f8c:liang2 +0x8f8d:chuo4 +0x8f8e:zi1 +0x8f8f:cou4 +0x8f90:fu2 +0x8f91:ji2 +0x8f92:wen1 +0x8f93:shu1 +0x8f94:pei4 +0x8f95:yuan2 +0x8f96:xia2 +0x8f97:zhan3 +0x8f98:lu4 +0x8f99:che4 +0x8f9a:lin2 +0x8f9b:xin1 +0x8f9c:gu1 +0x8f9d:ci2 +0x8f9e:ci2 +0x8f9f:pi4 +0x8fa0:zui4 +0x8fa1:bian4 +0x8fa2:la4 +0x8fa3:la4 +0x8fa4:ci2 +0x8fa5:xue1 +0x8fa6:ban4 +0x8fa7:bian4 +0x8fa8:bian4 +0x8fa9:bian4 +0x8fab:bian4 +0x8fac:ban1 +0x8fad:ci2 +0x8fae:bian4 +0x8faf:bian4 +0x8fb0:chen2 +0x8fb1:ru3 +0x8fb2:nong2 +0x8fb3:nong2 +0x8fb4:zhen3 +0x8fb5:chuo4 +0x8fb6:chuo4 +0x8fb8:reng2 +0x8fb9:bian1 +0x8fba:bian1 +0x8fbd:liao2 +0x8fbe:da2 +0x8fbf:chan1 +0x8fc0:gan1 +0x8fc1:qian1 +0x8fc2:yu1 +0x8fc3:yu1 +0x8fc4:qi4 +0x8fc5:xun4 +0x8fc6:yi3 +0x8fc7:guo4 +0x8fc8:mai4 +0x8fc9:qi2 +0x8fca:za1 +0x8fcb:wang4 +0x8fcd:zhun1 +0x8fce:ying2 +0x8fcf:ti4 +0x8fd0:yun4 +0x8fd1:jin4 +0x8fd2:hang2 +0x8fd3:ya4 +0x8fd4:fan3 +0x8fd5:wu4 +0x8fd6:da2 +0x8fd7:e2 +0x8fd8:huan2 +0x8fd9:zhe4 +0x8fdb:jin4 +0x8fdc:yuan3 +0x8fdd:wei2 +0x8fde:lian2 +0x8fdf:chi2 +0x8fe0:che4 +0x8fe1:ni4 +0x8fe2:tiao2 +0x8fe3:zhi4 +0x8fe4:yi3 +0x8fe5:jiong3 +0x8fe6:jia1 +0x8fe7:chen2 +0x8fe8:dai4 +0x8fe9:er3 +0x8fea:di2 +0x8feb:po4 +0x8fec:wang3 +0x8fed:die2 +0x8fee:ze2 +0x8fef:tao2 +0x8ff0:shu4 +0x8ff1:tuo2 +0x8ff3:jing4 +0x8ff4:hui2 +0x8ff5:tong2 +0x8ff6:you4 +0x8ff7:mi2 +0x8ff8:beng4 +0x8ff9:ji1 +0x8ffa:nai3 +0x8ffb:yi2 +0x8ffc:jie2 +0x8ffd:zhui1 +0x8ffe:lie4 +0x8fff:xun4 +0x9000:tui4 +0x9001:song4 +0x9002:shi4 +0x9003:tao2 +0x9004:pang2 +0x9005:hou4 +0x9006:ni4 +0x9007:dun4 +0x9008:jiong3 +0x9009:xuan3 +0x900a:xun4 +0x900b:bu1 +0x900c:you2 +0x900d:xiao1 +0x900e:qiu2 +0x900f:tou4 +0x9010:zhu2 +0x9011:qiu2 +0x9012:di4 +0x9013:di4 +0x9014:tu2 +0x9015:jing4 +0x9016:ti4 +0x9017:dou4 +0x9018:yi3 +0x9019:zhe4 +0x901a:tong1 +0x901b:guang4 +0x901c:wu4 +0x901d:shi4 +0x901e:cheng3 +0x901f:su4 +0x9020:zao4 +0x9021:qun1 +0x9022:feng2 +0x9023:lian2 +0x9024:suo4 +0x9025:hui2 +0x9026:li3 +0x9028:lai2 +0x9029:ben4 +0x902a:cuo4 +0x902b:jue2 +0x902c:beng4 +0x902d:huan4 +0x902e:dai4 +0x902f:lu4 +0x9030:you2 +0x9031:zhou1 +0x9032:jin4 +0x9033:yu4 +0x9034:chuo4 +0x9035:kui2 +0x9036:wei1 +0x9037:ti4 +0x9038:yi4 +0x9039:da2 +0x903a:yuan3 +0x903b:luo2 +0x903c:bi1 +0x903d:nuo4 +0x903e:yu2 +0x903f:dang4 +0x9040:sui2 +0x9041:dun4 +0x9042:sui4 +0x9043:yan3 +0x9044:chuan2 +0x9045:chi2 +0x9046:ti2 +0x9047:yu4 +0x9048:shi2 +0x9049:zhen1 +0x904a:you2 +0x904b:yun4 +0x904c:e4 +0x904d:bian4 +0x904e:guo4 +0x904f:e4 +0x9050:xia2 +0x9051:huang2 +0x9052:qiu2 +0x9053:dao4 +0x9054:da2 +0x9055:wei2 +0x9057:yi2 +0x9058:gou4 +0x9059:yao2 +0x905a:chu4 +0x905b:liu2 +0x905c:xun4 +0x905d:ta4 +0x905e:di4 +0x905f:chi2 +0x9060:yuan3 +0x9061:su4 +0x9062:ta4 +0x9063:qian3 +0x9065:yao2 +0x9066:guan4 +0x9067:zhang1 +0x9068:ao2 +0x9069:shi4 +0x906a:ce4 +0x906b:chi4 +0x906c:su4 +0x906d:zao1 +0x906e:zhe1 +0x906f:dun4 +0x9070:di4 +0x9071:lou2 +0x9072:chi2 +0x9073:cuo1 +0x9074:lin2 +0x9075:zun1 +0x9076:rao4 +0x9077:qian1 +0x9078:xuan3 +0x9079:yu4 +0x907a:yi2 +0x907b:wu4 +0x907c:liao2 +0x907d:ju4 +0x907e:shi4 +0x907f:bi4 +0x9080:yao1 +0x9081:mai4 +0x9082:xie4 +0x9083:sui4 +0x9084:huan2 +0x9085:zhan1 +0x9086:teng2 +0x9087:er3 +0x9088:miao3 +0x9089:bian1 +0x908a:bian1 +0x908b:la2 +0x908c:li2 +0x908d:yuan2 +0x908e:yao2 +0x908f:luo2 +0x9090:li3 +0x9091:yi4 +0x9092:ting2 +0x9093:deng4 +0x9094:qi3 +0x9095:yong1 +0x9096:shan1 +0x9097:han2 +0x9098:yu2 +0x9099:mang2 +0x909a:ru2 +0x909b:qiong2 +0x909d:kuang4 +0x909e:fu1 +0x909f:kang4 +0x90a0:bin1 +0x90a1:fang1 +0x90a2:xing2 +0x90a3:na4 +0x90a5:shen3 +0x90a6:bang1 +0x90a7:yuan2 +0x90a8:cun1 +0x90a9:huo3 +0x90aa:xie2 +0x90ab:bang1 +0x90ac:wu1 +0x90ad:ju4 +0x90ae:you2 +0x90af:han2 +0x90b0:tai2 +0x90b1:qiu1 +0x90b2:bi4 +0x90b3:pei2 +0x90b4:bing3 +0x90b5:shao4 +0x90b6:bei4 +0x90b7:wa3 +0x90b8:di3 +0x90b9:zou1 +0x90ba:ye4 +0x90bb:lin2 +0x90bc:kuang1 +0x90bd:gui1 +0x90be:zhu1 +0x90bf:shi1 +0x90c0:ku1 +0x90c1:yu4 +0x90c2:gai1 +0x90c3:he2 +0x90c4:xi4 +0x90c5:zhi4 +0x90c6:ji2 +0x90c7:xun2 +0x90c8:hou4 +0x90c9:xing2 +0x90ca:jiao1 +0x90cb:xi2 +0x90cc:gui1 +0x90cd:nuo2 +0x90ce:lang2 +0x90cf:jia2 +0x90d0:kuai4 +0x90d1:zheng4 +0x90d3:yun4 +0x90d4:yan2 +0x90d5:cheng2 +0x90d6:dou1 +0x90d7:chi1 +0x90d8:lv3 +0x90d9:fu3 +0x90da:wu2 +0x90db:fu2 +0x90dc:gao4 +0x90dd:hao3 +0x90de:lang2 +0x90df:jia2 +0x90e0:geng3 +0x90e1:jun4 +0x90e2:ying3 +0x90e3:bo2 +0x90e4:xi4 +0x90e5:bei4 +0x90e6:li4 +0x90e7:yun2 +0x90e8:bu4 +0x90e9:xiao2 +0x90ea:qi1 +0x90eb:pi2 +0x90ec:qing1 +0x90ed:guo1 +0x90ef:tan2 +0x90f0:zou1 +0x90f1:ping2 +0x90f2:lai2 +0x90f3:ni2 +0x90f4:chen1 +0x90f5:you2 +0x90f6:bu4 +0x90f7:xiang1 +0x90f8:dan1 +0x90f9:ju2 +0x90fa:yong1 +0x90fb:qiao1 +0x90fc:yi1 +0x90fd:du1 +0x90fe:yan3 +0x90ff:mei2 +0x9100:ruo4 +0x9101:bei4 +0x9102:e4 +0x9103:yu2 +0x9104:juan4 +0x9105:yu3 +0x9106:yun4 +0x9107:hou4 +0x9108:kui2 +0x9109:xiang1 +0x910a:xiang1 +0x910b:sou1 +0x910c:tang2 +0x910d:ming2 +0x910e:xi4 +0x910f:ru4 +0x9110:chu4 +0x9111:zi1 +0x9112:zou1 +0x9113:ju2 +0x9114:wu1 +0x9115:xiang1 +0x9116:yun2 +0x9117:hao4 +0x9118:yong1 +0x9119:bi3 +0x911a:mo4 +0x911b:chao2 +0x911c:fu1 +0x911d:liao3 +0x911e:yin2 +0x911f:zhuan1 +0x9120:hu4 +0x9121:qiao1 +0x9122:yan1 +0x9123:zhang1 +0x9124:man4 +0x9125:qiao1 +0x9126:xu3 +0x9127:deng4 +0x9128:bi4 +0x9129:xin2 +0x912a:bi4 +0x912b:ceng2 +0x912c:wei2 +0x912d:zheng4 +0x912e:mao4 +0x912f:shan4 +0x9130:lin2 +0x9131:po2 +0x9132:dan1 +0x9133:meng2 +0x9134:ye4 +0x9135:cao1 +0x9136:kuai4 +0x9137:feng1 +0x9138:meng2 +0x9139:zou1 +0x913a:kuang4 +0x913b:lian3 +0x913c:zan4 +0x913d:chan2 +0x913e:you1 +0x913f:qi2 +0x9140:yan1 +0x9141:chan2 +0x9142:zan4 +0x9143:ling2 +0x9144:huan1 +0x9145:xi1 +0x9146:feng1 +0x9147:zan4 +0x9148:li4 +0x9149:you3 +0x914a:ding3 +0x914b:qiu2 +0x914c:zhuo2 +0x914d:pei4 +0x914e:zhou4 +0x914f:yi2 +0x9150:hang4 +0x9151:yu3 +0x9152:jiu3 +0x9153:yan3 +0x9154:zui4 +0x9155:mao2 +0x9156:dan1 +0x9157:xu4 +0x9158:tou2 +0x9159:zhen1 +0x915a:fen1 +0x915d:yun4 +0x915e:tai4 +0x915f:tian1 +0x9160:qia3 +0x9161:tuo2 +0x9162:zuo4 +0x9163:han1 +0x9164:gu1 +0x9165:su1 +0x9166:po4 +0x9167:chou2 +0x9168:zai4 +0x9169:ming2 +0x916a:lao4 +0x916b:chuo4 +0x916c:chou2 +0x916d:you4 +0x916e:tong2 +0x916f:zhi3 +0x9170:xian1 +0x9171:jiang4 +0x9172:cheng2 +0x9173:yin4 +0x9174:tu2 +0x9175:jiao4 +0x9176:mei2 +0x9177:ku4 +0x9178:suan1 +0x9179:lei4 +0x917a:pu2 +0x917b:zui4 +0x917c:hai3 +0x917d:yan4 +0x917e:xi3 +0x917f:niang4 +0x9180:wei2 +0x9181:lu4 +0x9182:lan3 +0x9183:yan1 +0x9184:tao2 +0x9185:pei1 +0x9186:zhan3 +0x9187:chun2 +0x9188:tan2 +0x9189:zui4 +0x918a:chuo4 +0x918b:cu4 +0x918c:kun1 +0x918d:ti2 +0x918e:mian2 +0x918f:du1 +0x9190:hu2 +0x9191:xu3 +0x9192:xing3 +0x9193:tan3 +0x9194:jiu1 +0x9195:chun2 +0x9196:yun4 +0x9197:po4 +0x9198:ke4 +0x9199:sou1 +0x919a:mi2 +0x919b:quan2 +0x919c:chou3 +0x919d:cuo2 +0x919e:yun4 +0x919f:yong4 +0x91a0:ang4 +0x91a1:zha4 +0x91a2:hai3 +0x91a3:tang2 +0x91a4:jiang4 +0x91a5:piao3 +0x91a6:shan3 +0x91a7:yu4 +0x91a8:li2 +0x91a9:zao2 +0x91aa:lao2 +0x91ab:yi1 +0x91ac:jiang4 +0x91ad:bu2 +0x91ae:jiao4 +0x91af:xi1 +0x91b0:tan2 +0x91b1:po4 +0x91b2:nong2 +0x91b3:yi4 +0x91b4:li3 +0x91b5:ju4 +0x91b6:jiao4 +0x91b7:yi4 +0x91b8:niang4 +0x91b9:ru2 +0x91ba:xun1 +0x91bb:chou2 +0x91bc:yan4 +0x91bd:ling2 +0x91be:mi2 +0x91bf:mi2 +0x91c0:niang4 +0x91c1:xin4 +0x91c2:jiao4 +0x91c3:xi3 +0x91c4:mi2 +0x91c5:yan4 +0x91c6:bian4 +0x91c7:cai3 +0x91c8:shi4 +0x91c9:you4 +0x91ca:shi4 +0x91cb:shi4 +0x91cc:li3 +0x91cd:zhong4 +0x91ce:ye3 +0x91cf:liang4 +0x91d0:li2 +0x91d1:jin1 +0x91d3:ga2 +0x91d4:yi3 +0x91d5:liao3 +0x91d6:dao1 +0x91d7:zhao1 +0x91d8:ding1 +0x91d9:po4 +0x91da:qiu2 +0x91db:he2 +0x91dc:fu3 +0x91dd:zhen1 +0x91de:zhi2 +0x91df:ba1 +0x91e0:luan4 +0x91e1:fu3 +0x91e2:nai2 +0x91e3:diao4 +0x91e4:shan4 +0x91e5:qiao3 +0x91e6:kou4 +0x91e7:chuan4 +0x91e8:zi3 +0x91e9:fan2 +0x91ea:yu2 +0x91eb:hua2 +0x91ec:han4 +0x91ed:gang1 +0x91ee:qi2 +0x91ef:mang2 +0x91f0:ri4 +0x91f1:di4 +0x91f2:si4 +0x91f3:xi4 +0x91f4:yi4 +0x91f5:chai1 +0x91f6:shi1 +0x91f7:tu3 +0x91f8:xi4 +0x91f9:nv3 +0x91fa:qian1 +0x91fc:jian4 +0x91fd:pi1 +0x91fe:ye2 +0x91ff:yin2 +0x9200:ba3 +0x9201:fang1 +0x9202:chen2 +0x9203:xing2 +0x9204:dou3 +0x9205:yue4 +0x9206:yan2 +0x9207:fu1 +0x9208:pi1 +0x9209:na4 +0x920a:xin1 +0x920b:e2 +0x920c:jue2 +0x920d:dun4 +0x920e:gou1 +0x920f:yin3 +0x9210:qian2 +0x9211:ban3 +0x9212:ji2 +0x9213:ren2 +0x9214:chao1 +0x9215:niu3 +0x9216:fen1 +0x9217:yun3 +0x9218:ji3 +0x9219:qin2 +0x921a:pi2 +0x921b:guo1 +0x921c:hong2 +0x921d:yin2 +0x921e:jun1 +0x921f:shi1 +0x9220:yi4 +0x9221:zhong1 +0x9222:nie1 +0x9223:gai4 +0x9224:ri4 +0x9225:huo3 +0x9226:tai4 +0x9227:kang4 +0x922c:duo2 +0x922d:zi1 +0x922e:ni2 +0x922f:tu2 +0x9230:shi4 +0x9231:min2 +0x9232:gu1 +0x9233:ke1 +0x9234:ling2 +0x9235:bing4 +0x9236:yi2 +0x9237:gu3 +0x9238:bo2 +0x9239:pi1 +0x923a:yu4 +0x923b:si4 +0x923c:zuo2 +0x923d:bu4 +0x923e:you2 +0x923f:dian4 +0x9240:jia3 +0x9241:zhen1 +0x9242:shi3 +0x9243:shi4 +0x9244:tie3 +0x9245:ju4 +0x9246:chan1 +0x9247:shi1 +0x9248:shi1 +0x9249:xuan4 +0x924a:zhao1 +0x924b:bao4 +0x924c:he2 +0x924d:bi4 +0x924e:sheng1 +0x924f:chu2 +0x9250:shi2 +0x9251:bo2 +0x9252:zhu4 +0x9253:chi4 +0x9254:za1 +0x9255:po1 +0x9256:tong2 +0x9257:qian2 +0x9258:fu2 +0x9259:zhai3 +0x925a:liu3 +0x925b:qian1 +0x925c:fu2 +0x925d:li4 +0x925e:yue4 +0x925f:pi1 +0x9260:yang1 +0x9261:ban4 +0x9262:bo1 +0x9263:jie2 +0x9264:gou1 +0x9265:shu4 +0x9266:zheng1 +0x9267:mu3 +0x9268:ni3 +0x9269:nie1 +0x926a:di4 +0x926b:jia1 +0x926c:mu4 +0x926d:dan4 +0x926e:shen1 +0x926f:yi3 +0x9270:si1 +0x9271:kuang4 +0x9272:ka3 +0x9273:bei3 +0x9274:jian4 +0x9275:tong2 +0x9276:xing2 +0x9277:hong2 +0x9278:jiao3 +0x9279:chi3 +0x927a:er3 +0x927b:ge4 +0x927c:bing3 +0x927d:shi4 +0x927e:mou2 +0x927f:ha1 +0x9280:yin2 +0x9281:jun1 +0x9282:zhou1 +0x9283:chong4 +0x9284:shang4 +0x9285:tong2 +0x9286:mo4 +0x9287:lei4 +0x9288:ji1 +0x9289:yu4 +0x928a:xu4 +0x928b:ren2 +0x928c:zun4 +0x928d:zhi4 +0x928e:qiong1 +0x928f:shan4 +0x9290:chi4 +0x9291:xian3 +0x9292:xing2 +0x9293:quan2 +0x9294:pi1 +0x9295:tie3 +0x9296:zhu1 +0x9297:hou2 +0x9298:ming2 +0x9299:kua3 +0x929a:yao2 +0x929b:xian1 +0x929c:xian2 +0x929d:xiu1 +0x929e:jun1 +0x929f:cha1 +0x92a0:lao3 +0x92a1:ji2 +0x92a2:pi3 +0x92a3:ru2 +0x92a4:mi3 +0x92a5:yi1 +0x92a6:yin1 +0x92a7:guang1 +0x92a8:an3 +0x92a9:diu1 +0x92aa:you3 +0x92ab:se4 +0x92ac:kao4 +0x92ad:qian2 +0x92ae:luan2 +0x92b0:ai1 +0x92b1:diao4 +0x92b2:han4 +0x92b3:rui4 +0x92b4:shi4 +0x92b5:keng1 +0x92b6:qiu2 +0x92b7:xiao1 +0x92b8:zhe2 +0x92b9:xiu4 +0x92ba:zang4 +0x92bb:ti1 +0x92bc:cuo4 +0x92bd:gua1 +0x92be:gong3 +0x92bf:zhong1 +0x92c0:dou4 +0x92c1:lv3 +0x92c2:mei2 +0x92c3:lang2 +0x92c4:wan3 +0x92c5:xin1 +0x92c6:yun2 +0x92c7:bei4 +0x92c8:wu4 +0x92c9:su4 +0x92ca:yu4 +0x92cb:chan2 +0x92cc:ting3 +0x92cd:bo2 +0x92ce:han4 +0x92cf:jia2 +0x92d0:hong2 +0x92d1:cuan1 +0x92d2:feng1 +0x92d3:chan1 +0x92d4:wan3 +0x92d5:zhi4 +0x92d6:si1 +0x92d7:xuan1 +0x92d8:wu2 +0x92d9:wu2 +0x92da:tiao2 +0x92db:gong3 +0x92dc:zhuo2 +0x92dd:lve4 +0x92de:xing2 +0x92df:qian1 +0x92e0:shen4 +0x92e1:han2 +0x92e2:lve4 +0x92e3:xie2 +0x92e4:chu2 +0x92e5:zheng4 +0x92e6:ju1 +0x92e7:xian4 +0x92e8:tie3 +0x92e9:mang2 +0x92ea:pu1 +0x92eb:li2 +0x92ec:pan4 +0x92ed:rui4 +0x92ee:cheng2 +0x92ef:gao4 +0x92f0:li3 +0x92f1:te4 +0x92f3:zhu4 +0x92f5:tu1 +0x92f6:liu3 +0x92f7:zui4 +0x92f8:ju4 +0x92f9:chang3 +0x92fa:yuan1 +0x92fb:jian4 +0x92fc:gang1 +0x92fd:diao4 +0x92fe:tao2 +0x92ff:chang2 +0x9300:lun2 +0x9301:guo3 +0x9302:ling2 +0x9303:bei1 +0x9304:lu4 +0x9305:li2 +0x9306:qiang1 +0x9307:pou2 +0x9308:juan4 +0x9309:min2 +0x930a:zui4 +0x930b:peng2 +0x930c:an4 +0x930d:pi2 +0x930e:xian4 +0x930f:ya4 +0x9310:zhui1 +0x9311:lei4 +0x9312:a1 +0x9313:kong1 +0x9314:ta4 +0x9315:kun1 +0x9316:du3 +0x9317:wei4 +0x9318:chui2 +0x9319:zi1 +0x931a:zheng1 +0x931b:ben1 +0x931c:nie1 +0x931d:cong2 +0x931e:dui4 +0x931f:tan2 +0x9320:ding4 +0x9321:qi2 +0x9322:qian2 +0x9323:zhuo2 +0x9324:qi2 +0x9325:yu4 +0x9326:jin3 +0x9327:guan3 +0x9328:mao2 +0x9329:chang1 +0x932a:tian3 +0x932b:xi2 +0x932c:lian4 +0x932d:tao2 +0x932e:gu4 +0x932f:cuo4 +0x9330:shu4 +0x9331:zhen1 +0x9332:lu4 +0x9333:meng3 +0x9334:lu4 +0x9335:hua1 +0x9336:biao3 +0x9337:ga2 +0x9338:lai2 +0x9339:ken3 +0x933c:nai4 +0x933d:wan3 +0x933e:zan4 +0x9340:de2 +0x9341:xian1 +0x9343:huo1 +0x9344:liang4 +0x9346:men2 +0x9347:kai3 +0x9348:ying1 +0x9349:di1 +0x934a:lian4 +0x934b:guo1 +0x934c:xian3 +0x934d:du4 +0x934e:tu2 +0x934f:wei2 +0x9350:cong1 +0x9351:fu4 +0x9352:rou2 +0x9353:ji2 +0x9354:e4 +0x9355:rou2 +0x9356:chen3 +0x9357:ti2 +0x9358:zha2 +0x9359:hong4 +0x935a:yang2 +0x935b:duan4 +0x935c:xia1 +0x935d:yu2 +0x935e:keng1 +0x935f:xing1 +0x9360:huang2 +0x9361:wei3 +0x9362:fu4 +0x9363:zhao1 +0x9364:cha2 +0x9365:qie4 +0x9366:she2 +0x9367:hong1 +0x9368:kui2 +0x9369:tian3 +0x936a:mou2 +0x936b:qiao1 +0x936c:qiao1 +0x936d:hou2 +0x936e:tou1 +0x936f:cong1 +0x9370:huan2 +0x9371:ye4 +0x9372:min2 +0x9373:jian4 +0x9374:duan1 +0x9375:jian4 +0x9376:si1 +0x9377:kui1 +0x9378:hu2 +0x9379:xuan1 +0x937a:zhe3 +0x937b:jie2 +0x937c:zhen1 +0x937d:bian1 +0x937e:zhong1 +0x937f:zi1 +0x9380:xiu1 +0x9381:ye2 +0x9382:mei3 +0x9383:pai4 +0x9384:ai1 +0x9385:jie4 +0x9387:mei2 +0x9388:chuo1 +0x9389:ta4 +0x938a:bang4 +0x938b:xia2 +0x938c:lian2 +0x938d:suo3 +0x938e:xi4 +0x938f:liu2 +0x9390:zu2 +0x9391:ye4 +0x9392:nou4 +0x9393:weng1 +0x9394:rong2 +0x9395:tang2 +0x9396:suo3 +0x9397:qiang1 +0x9398:ge2 +0x9399:shuo4 +0x939a:chui2 +0x939b:bo2 +0x939c:pan2 +0x939d:sa4 +0x939e:bi4 +0x939f:sang3 +0x93a0:gang1 +0x93a1:zi1 +0x93a2:wu1 +0x93a3:ying4 +0x93a4:huang3 +0x93a5:tiao2 +0x93a6:liu2 +0x93a7:kai3 +0x93a8:sun3 +0x93a9:sha1 +0x93aa:sou1 +0x93ab:wan4 +0x93ac:hao4 +0x93ad:zhen4 +0x93ae:zhen4 +0x93af:luo3 +0x93b0:yi4 +0x93b1:yuan2 +0x93b2:tang3 +0x93b3:nie4 +0x93b4:xi2 +0x93b5:jia1 +0x93b6:ge1 +0x93b7:ma3 +0x93b8:juan1 +0x93bb:suo3 +0x93bf:na2 +0x93c0:lu3 +0x93c1:suo3 +0x93c2:ou1 +0x93c3:zu2 +0x93c4:tuan2 +0x93c5:xiu1 +0x93c6:guan4 +0x93c7:xuan4 +0x93c8:lian4 +0x93c9:shou4 +0x93ca:ao2 +0x93cb:man3 +0x93cc:mo4 +0x93cd:luo2 +0x93ce:bi4 +0x93cf:wei4 +0x93d0:liu2 +0x93d1:di2 +0x93d2:qiao1 +0x93d3:cong1 +0x93d4:yi2 +0x93d5:lu4 +0x93d6:ao2 +0x93d7:keng1 +0x93d8:qiang1 +0x93d9:cui1 +0x93da:qi4 +0x93db:chang2 +0x93dc:tang1 +0x93dd:man4 +0x93de:yong1 +0x93df:chan3 +0x93e0:feng1 +0x93e1:jing4 +0x93e2:biao1 +0x93e3:shu4 +0x93e4:lou4 +0x93e5:xiu4 +0x93e6:cong1 +0x93e7:long2 +0x93e8:zan4 +0x93e9:jian4 +0x93ea:cao2 +0x93eb:li2 +0x93ec:xia4 +0x93ed:xi1 +0x93ee:kang1 +0x93f0:beng4 +0x93f3:zheng1 +0x93f4:lu4 +0x93f5:hua2 +0x93f6:ji2 +0x93f7:pu2 +0x93f8:hui4 +0x93f9:qiang1 +0x93fa:po1 +0x93fb:lin2 +0x93fc:suo3 +0x93fd:xiu4 +0x93fe:san3 +0x93ff:cheng1 +0x9400:kui4 +0x9401:si1 +0x9402:liu4 +0x9403:nao2 +0x9404:heng2 +0x9405:pie3 +0x9406:sui4 +0x9407:fan2 +0x9408:qiao2 +0x9409:quan1 +0x940a:yang2 +0x940b:tang4 +0x940c:xiang4 +0x940d:jue2 +0x940e:jiao1 +0x940f:zun1 +0x9410:liao2 +0x9411:jie2 +0x9412:lao2 +0x9413:dui4 +0x9414:tan2 +0x9415:zan1 +0x9416:ji1 +0x9417:jian3 +0x9418:zhong1 +0x9419:deng4 +0x941a:ya4 +0x941b:ying4 +0x941c:dui4 +0x941d:jue2 +0x941e:nou4 +0x941f:ti4 +0x9420:pu3 +0x9421:tie3 +0x9424:ding3 +0x9425:shan4 +0x9426:kai1 +0x9427:jian3 +0x9428:fei4 +0x9429:sui4 +0x942a:lu3 +0x942b:juan1 +0x942c:hui4 +0x942d:yu4 +0x942e:lian2 +0x942f:zhuo2 +0x9430:qiao1 +0x9431:qian1 +0x9432:zhuo2 +0x9433:lei2 +0x9434:bi4 +0x9435:tie3 +0x9436:huan2 +0x9437:ye4 +0x9438:duo2 +0x9439:guo3 +0x943a:dang1 +0x943b:ju4 +0x943c:fen2 +0x943d:da2 +0x943e:bei4 +0x943f:yi4 +0x9440:ai4 +0x9441:zong1 +0x9442:xun4 +0x9443:diao4 +0x9444:zhu4 +0x9445:heng2 +0x9446:zhui4 +0x9447:ji1 +0x9448:nie1 +0x9449:ta4 +0x944a:huo4 +0x944b:qing4 +0x944c:bin1 +0x944d:ying1 +0x944e:kui4 +0x944f:ning2 +0x9450:xu1 +0x9451:jian4 +0x9452:jian4 +0x9454:cha3 +0x9455:zhi4 +0x9456:mie4 +0x9457:li2 +0x9458:lei2 +0x9459:ji1 +0x945a:zuan4 +0x945b:kuang4 +0x945c:shang4 +0x945d:peng2 +0x945e:la4 +0x945f:du2 +0x9460:shuo4 +0x9461:chuo4 +0x9462:lv4 +0x9463:biao1 +0x9464:bao4 +0x9465:lu3 +0x9468:long2 +0x9469:e4 +0x946a:lu2 +0x946b:xin1 +0x946c:jian4 +0x946d:lan2 +0x946e:bo2 +0x946f:jian1 +0x9470:yao4 +0x9471:chan2 +0x9472:xiang1 +0x9473:jian4 +0x9474:xi1 +0x9475:guan4 +0x9476:cang2 +0x9477:nie4 +0x9478:lei3 +0x9479:cuan4 +0x947a:qu2 +0x947b:pan4 +0x947c:luo2 +0x947d:zuan1 +0x947e:luan2 +0x947f:zao2 +0x9480:nie4 +0x9481:jue2 +0x9482:tang3 +0x9483:shu3 +0x9484:lan2 +0x9485:jin1 +0x9486:qiu2 +0x9487:yi3 +0x9488:zhen1 +0x9489:ding1 +0x948a:zhao1 +0x948b:po4 +0x948c:diao3 +0x948d:tu3 +0x948e:qian1 +0x948f:chuan4 +0x9490:shan4 +0x9491:ji2 +0x9492:fan2 +0x9493:diao4 +0x9494:men2 +0x9495:nv3 +0x9496:xi2 +0x9497:chai1 +0x9498:xing2 +0x9499:gai4 +0x949a:bu4 +0x949b:tai4 +0x949c:ju4 +0x949d:dun4 +0x949e:chao1 +0x949f:zhong1 +0x94a0:na4 +0x94a1:bei4 +0x94a2:gang1 +0x94a3:ban3 +0x94a4:qian2 +0x94a5:yao4 +0x94a6:qin1 +0x94a7:jun1 +0x94a8:wu4 +0x94a9:gou1 +0x94aa:kang4 +0x94ab:fang1 +0x94ac:huo2 +0x94ad:dou3 +0x94ae:niu3 +0x94af:ba3 +0x94b0:yu4 +0x94b1:qian2 +0x94b2:zheng1 +0x94b3:qian2 +0x94b4:gu1 +0x94b5:bo1 +0x94b6:e1 +0x94b7:po1 +0x94b8:bu4 +0x94b9:ba2 +0x94ba:yue4 +0x94bb:zuan4 +0x94bc:mu4 +0x94bd:dan4 +0x94be:jia3 +0x94bf:dian4 +0x94c0:you2 +0x94c1:tie3 +0x94c2:bo2 +0x94c3:ling2 +0x94c4:shuo4 +0x94c5:qian1 +0x94c6:liu3 +0x94c7:bao4 +0x94c8:shi4 +0x94c9:xuan4 +0x94ca:she2 +0x94cb:bi4 +0x94cc:ni3 +0x94cd:pi1 +0x94ce:duo2 +0x94cf:xing2 +0x94d0:kao4 +0x94d1:lao3 +0x94d2:er4 +0x94d3:mang2 +0x94d4:ya4 +0x94d5:you3 +0x94d6:cheng2 +0x94d7:jia2 +0x94d8:ye2 +0x94d9:nao2 +0x94da:zhi4 +0x94db:dang1 +0x94dc:tong2 +0x94dd:lv3 +0x94de:diao4 +0x94df:yin1 +0x94e0:kai3 +0x94e1:zha2 +0x94e2:zhu1 +0x94e3:xian3 +0x94e4:ting3 +0x94e5:diu1 +0x94e6:xian1 +0x94e7:hua2 +0x94e8:quan2 +0x94e9:sha1 +0x94ea:jia2 +0x94eb:yao2 +0x94ec:ge4 +0x94ed:ming2 +0x94ee:zheng1 +0x94ef:se4 +0x94f0:jiao3 +0x94f1:yi3 +0x94f2:chan3 +0x94f3:chong4 +0x94f4:tang4 +0x94f5:an1 +0x94f6:yin2 +0x94f7:ru3 +0x94f8:zhu4 +0x94f9:lao2 +0x94fa:pu1 +0x94fb:wu2 +0x94fc:lai2 +0x94fd:te4 +0x94fe:lian4 +0x94ff:keng1 +0x9500:xiao1 +0x9501:suo3 +0x9502:li3 +0x9503:zheng4 +0x9504:chu2 +0x9505:guo1 +0x9506:gao4 +0x9507:tie3 +0x9508:xiu4 +0x9509:cuo4 +0x950a:lve4 +0x950b:feng1 +0x950c:xin1 +0x950d:liu3 +0x950e:kai1 +0x950f:jian3 +0x9510:rui4 +0x9511:ti4 +0x9512:lang2 +0x9513:qian1 +0x9514:ju2 +0x9515:a1 +0x9516:qiang1 +0x9517:duo3 +0x9518:tian3 +0x9519:cuo4 +0x951a:mao2 +0x951b:ben1 +0x951c:qi2 +0x951d:de2 +0x951e:kua3 +0x951f:kun1 +0x9520:chang1 +0x9521:xi2 +0x9522:gu4 +0x9523:luo2 +0x9524:chui2 +0x9525:zhui1 +0x9526:jin3 +0x9527:zhi4 +0x9528:xian1 +0x9529:juan4 +0x952a:huo1 +0x952b:pou2 +0x952c:tan2 +0x952d:ding4 +0x952e:jian4 +0x952f:ju4 +0x9530:meng3 +0x9531:zi1 +0x9532:qie4 +0x9533:ying1 +0x9534:kai3 +0x9535:qiang1 +0x9536:song1 +0x9537:e4 +0x9538:cha2 +0x9539:qiao1 +0x953a:zhong1 +0x953b:duan4 +0x953c:sou1 +0x953d:huang2 +0x953e:huan2 +0x953f:ai1 +0x9540:du4 +0x9541:mei3 +0x9542:lou4 +0x9543:zi1 +0x9544:fei4 +0x9545:mei2 +0x9546:mo4 +0x9547:zhen4 +0x9548:bo2 +0x9549:ge2 +0x954a:nie4 +0x954b:tang3 +0x954c:juan1 +0x954d:nie4 +0x954e:na2 +0x954f:liu2 +0x9550:hao4 +0x9551:bang4 +0x9552:yi4 +0x9553:jia1 +0x9554:bin1 +0x9555:rong2 +0x9556:biao1 +0x9557:tang1 +0x9558:man4 +0x9559:luo2 +0x955a:beng4 +0x955b:yong1 +0x955c:jing4 +0x955d:di2 +0x955e:zu2 +0x955f:xuan4 +0x9560:liu2 +0x9561:tan2 +0x9562:jue2 +0x9563:liao2 +0x9564:pu2 +0x9565:lu3 +0x9566:dui4 +0x9567:lan4 +0x9568:pu3 +0x9569:cuan4 +0x956a:qiang1 +0x956b:deng1 +0x956c:huo4 +0x956d:lei2 +0x956e:huan2 +0x956f:zhuo2 +0x9570:lian2 +0x9571:yi4 +0x9572:cha3 +0x9573:biao1 +0x9574:la4 +0x9575:chan2 +0x9576:xiang1 +0x9577:chang2 +0x9578:chang2 +0x9579:jiu3 +0x957a:ao3 +0x957b:die2 +0x957c:qu1 +0x957d:liao3 +0x957e:mi2 +0x957f:chang2 +0x9580:men2 +0x9581:ma4 +0x9582:shuan1 +0x9583:shan3 +0x9584:huo4 +0x9585:men2 +0x9586:yan2 +0x9587:bi4 +0x9588:han4 +0x9589:bi4 +0x958b:kai1 +0x958c:kang4 +0x958d:beng1 +0x958e:hong2 +0x958f:run4 +0x9590:san4 +0x9591:xian2 +0x9592:xian2 +0x9593:jian1 +0x9594:min3 +0x9595:xia1 +0x9597:dou4 +0x9598:zha2 +0x9599:nao4 +0x959b:peng1 +0x959c:xia3 +0x959d:ling2 +0x959e:bian4 +0x959f:bi4 +0x95a0:run4 +0x95a1:he2 +0x95a2:guan1 +0x95a3:ge2 +0x95a4:ge2 +0x95a5:fa2 +0x95a6:chu4 +0x95a7:hong4 +0x95a8:gui1 +0x95a9:min3 +0x95ab:kun3 +0x95ac:lang3 +0x95ad:lv2 +0x95ae:ting2 +0x95af:sha4 +0x95b0:ju2 +0x95b1:yue4 +0x95b2:yue4 +0x95b3:chan3 +0x95b4:qu4 +0x95b5:lin4 +0x95b6:chang1 +0x95b7:shai4 +0x95b8:kun3 +0x95b9:yan1 +0x95ba:wen2 +0x95bb:yan2 +0x95bc:e4 +0x95bd:hun1 +0x95be:yu4 +0x95bf:wen2 +0x95c0:xiang4 +0x95c1:bao1 +0x95c2:xiang4 +0x95c3:qu4 +0x95c4:yao3 +0x95c5:wen2 +0x95c6:ban3 +0x95c7:an4 +0x95c8:wei2 +0x95c9:yin1 +0x95ca:kuo4 +0x95cb:que4 +0x95cc:lan2 +0x95cd:du1 +0x95d0:tian2 +0x95d1:nie4 +0x95d2:ta4 +0x95d3:kai3 +0x95d4:he2 +0x95d5:que4 +0x95d6:chuang3 +0x95d7:guan1 +0x95d8:dou4 +0x95d9:qi3 +0x95da:kui1 +0x95db:tang2 +0x95dc:guan1 +0x95dd:piao2 +0x95de:kan4 +0x95df:xi4 +0x95e0:hui4 +0x95e1:chan3 +0x95e2:pi4 +0x95e3:dang4 +0x95e4:huan2 +0x95e5:ta4 +0x95e6:wen2 +0x95e8:men2 +0x95e9:shuan1 +0x95ea:shan3 +0x95eb:yan4 +0x95ec:han4 +0x95ed:bi4 +0x95ee:wen4 +0x95ef:chuang3 +0x95f0:run4 +0x95f1:wei2 +0x95f2:xian2 +0x95f3:hong2 +0x95f4:jian1 +0x95f5:min3 +0x95f6:kang4 +0x95f7:men4 +0x95f8:zha2 +0x95f9:nao4 +0x95fa:gui1 +0x95fb:wen2 +0x95fc:ta4 +0x95fd:min3 +0x95fe:lv2 +0x95ff:kai3 +0x9600:fa2 +0x9601:ge2 +0x9602:he2 +0x9603:kun3 +0x9604:jiu1 +0x9605:yue4 +0x9606:lang3 +0x9607:du1 +0x9608:yu4 +0x9609:yan1 +0x960a:chang1 +0x960b:xi4 +0x960c:wen2 +0x960d:hun1 +0x960e:yan2 +0x960f:e4 +0x9610:chan3 +0x9611:lan2 +0x9612:qu4 +0x9613:hui4 +0x9614:kuo4 +0x9615:que4 +0x9616:ge2 +0x9617:tian2 +0x9618:ta4 +0x9619:que4 +0x961a:kan4 +0x961b:huan2 +0x961c:fu4 +0x961d:fu4 +0x961e:le4 +0x961f:dui4 +0x9620:xin4 +0x9621:qian1 +0x9622:wu4 +0x9623:yi4 +0x9624:tuo2 +0x9625:yin1 +0x9626:yang2 +0x9627:dou3 +0x9628:e4 +0x9629:sheng1 +0x962a:ban3 +0x962b:pei2 +0x962c:keng1 +0x962d:yun3 +0x962e:ruan3 +0x962f:zhi3 +0x9630:pi2 +0x9631:jing3 +0x9632:fang2 +0x9633:yang2 +0x9634:yin1 +0x9635:zhen4 +0x9636:jie1 +0x9637:cheng1 +0x9638:e4 +0x9639:qu1 +0x963a:di3 +0x963b:zu3 +0x963c:zuo4 +0x963d:dian4 +0x963e:ling3 +0x963f:a1 +0x9640:tuo2 +0x9641:tuo2 +0x9642:bei1 +0x9643:bing3 +0x9644:fu4 +0x9645:ji4 +0x9646:lu4 +0x9647:long3 +0x9648:chen2 +0x9649:xing2 +0x964a:duo4 +0x964b:lou4 +0x964c:mo4 +0x964d:jiang4 +0x964e:shu1 +0x964f:duo4 +0x9650:xian4 +0x9651:er2 +0x9652:gui3 +0x9653:yu1 +0x9654:gai1 +0x9655:shan3 +0x9656:xun4 +0x9657:qiao4 +0x9658:xing2 +0x9659:chun2 +0x965a:fu4 +0x965b:bi4 +0x965c:xia2 +0x965d:shan3 +0x965e:sheng1 +0x965f:zhi4 +0x9660:pu1 +0x9661:dou3 +0x9662:yuan4 +0x9663:zhen4 +0x9664:chu2 +0x9665:xian4 +0x9667:nie4 +0x9668:yun3 +0x9669:xian3 +0x966a:pei2 +0x966b:pei2 +0x966c:zou1 +0x966d:yi1 +0x966e:dui3 +0x966f:lun2 +0x9670:yin1 +0x9671:ju1 +0x9672:chui2 +0x9673:chen2 +0x9674:pi2 +0x9675:ling2 +0x9676:tao2 +0x9677:xian4 +0x9678:lu4 +0x967a:xian3 +0x967b:yin1 +0x967c:zhu3 +0x967d:yang2 +0x967e:reng2 +0x967f:shan3 +0x9680:chong2 +0x9681:yan4 +0x9682:yin1 +0x9683:yu2 +0x9684:di1 +0x9685:yu2 +0x9686:long2 +0x9687:wei1 +0x9688:wei1 +0x9689:nie4 +0x968a:dui4 +0x968b:sui2 +0x968c:an3 +0x968d:huang2 +0x968e:jie1 +0x968f:sui2 +0x9690:yin3 +0x9691:gai1 +0x9692:yan3 +0x9693:hui1 +0x9694:ge2 +0x9695:yun3 +0x9696:wu4 +0x9697:wei3 +0x9698:ai4 +0x9699:xi4 +0x969a:tang2 +0x969b:ji4 +0x969c:zhang4 +0x969d:dao3 +0x969e:ao2 +0x969f:xi4 +0x96a0:yin3 +0x96a2:rao4 +0x96a3:lin2 +0x96a4:tui2 +0x96a5:deng4 +0x96a6:pi3 +0x96a7:sui4 +0x96a8:sui2 +0x96a9:yu4 +0x96aa:xian3 +0x96ab:fen1 +0x96ac:ni3 +0x96ad:er2 +0x96ae:ji1 +0x96af:dao3 +0x96b0:xi2 +0x96b1:yin3 +0x96b2:e2 +0x96b3:hui1 +0x96b4:long3 +0x96b5:xi1 +0x96b6:li4 +0x96b7:li4 +0x96b8:li4 +0x96b9:zhui1 +0x96ba:he4 +0x96bb:zhi1 +0x96bc:zhun3 +0x96bd:jun4 +0x96be:nan2 +0x96bf:yi4 +0x96c0:que4 +0x96c1:yan4 +0x96c2:qin2 +0x96c3:ya3 +0x96c4:xiong2 +0x96c5:ya3 +0x96c6:ji2 +0x96c7:gu4 +0x96c8:huan2 +0x96c9:zhi4 +0x96ca:gou4 +0x96cb:jun4 +0x96cc:ci2 +0x96cd:yong1 +0x96ce:ju1 +0x96cf:chu2 +0x96d0:hu1 +0x96d1:za2 +0x96d2:luo4 +0x96d3:yu2 +0x96d4:chou2 +0x96d5:diao1 +0x96d6:sui1 +0x96d7:han4 +0x96d8:huo4 +0x96d9:shuang1 +0x96da:guan4 +0x96db:chu2 +0x96dc:za2 +0x96dd:yong1 +0x96de:ji1 +0x96df:xi1 +0x96e0:chou2 +0x96e1:liu4 +0x96e2:li2 +0x96e3:nan2 +0x96e4:xue2 +0x96e5:za2 +0x96e6:ji2 +0x96e7:ji2 +0x96e8:yu3 +0x96e9:yu2 +0x96ea:xue3 +0x96eb:na3 +0x96ec:fou3 +0x96ed:se4 +0x96ee:mu4 +0x96ef:wen2 +0x96f0:fen1 +0x96f1:pang2 +0x96f2:yun2 +0x96f3:li4 +0x96f4:li4 +0x96f5:ang3 +0x96f6:ling2 +0x96f7:lei2 +0x96f8:an2 +0x96f9:bao2 +0x96fa:meng2 +0x96fb:dian4 +0x96fc:dang4 +0x96fd:xing2 +0x96fe:wu4 +0x96ff:zhao4 +0x9700:xu1 +0x9701:ji4 +0x9702:mu4 +0x9703:chen2 +0x9704:xiao1 +0x9705:zha2 +0x9706:ting2 +0x9707:zhen4 +0x9708:pei4 +0x9709:mei2 +0x970a:ling2 +0x970b:qi1 +0x970c:chou1 +0x970d:huo4 +0x970e:sha4 +0x970f:fei1 +0x9710:weng1 +0x9711:zhan1 +0x9712:yin1 +0x9713:ni2 +0x9714:zhu4 +0x9715:tun2 +0x9716:lin2 +0x9718:dong4 +0x9719:ying1 +0x971a:wu4 +0x971b:ling2 +0x971c:shuang1 +0x971d:ling2 +0x971e:xia2 +0x971f:hong2 +0x9720:yin1 +0x9721:mo4 +0x9722:mai4 +0x9723:yun3 +0x9724:liu4 +0x9725:meng4 +0x9726:bin1 +0x9727:wu4 +0x9728:wei4 +0x9729:huo4 +0x972a:yin2 +0x972b:xi2 +0x972c:yi4 +0x972d:ai3 +0x972e:dan4 +0x972f:deng4 +0x9730:xian4 +0x9731:yu4 +0x9732:lu4 +0x9733:long2 +0x9734:dai4 +0x9735:ji2 +0x9736:pang2 +0x9737:yang2 +0x9738:ba4 +0x9739:pi1 +0x973a:wei2 +0x973c:xi3 +0x973d:ji4 +0x973e:mai2 +0x973f:meng4 +0x9740:meng2 +0x9741:lei2 +0x9742:li4 +0x9743:huo4 +0x9744:ai3 +0x9745:fei4 +0x9746:dai4 +0x9747:long2 +0x9748:ling2 +0x9749:ai4 +0x974a:feng1 +0x974b:li4 +0x974c:bao3 +0x974e:he4 +0x974f:he4 +0x9750:bing4 +0x9751:qing1 +0x9752:qing1 +0x9753:jing4 +0x9754:tian1 +0x9755:zhen1 +0x9756:jing4 +0x9757:cheng4 +0x9758:qing4 +0x9759:jing4 +0x975a:jing4 +0x975b:dian4 +0x975c:jing4 +0x975d:tian1 +0x975e:fei1 +0x975f:fei1 +0x9760:kao4 +0x9761:mi3 +0x9762:mian4 +0x9763:mian4 +0x9764:pao4 +0x9765:ye4 +0x9766:tian3 +0x9767:hui4 +0x9768:ye4 +0x9769:ge2 +0x976a:ding1 +0x976b:cha1 +0x976c:jian1 +0x976d:ren4 +0x976e:di2 +0x976f:du4 +0x9770:wu4 +0x9771:ren4 +0x9772:qin2 +0x9773:jin4 +0x9774:xue1 +0x9775:niu3 +0x9776:ba3 +0x9777:yin3 +0x9778:sa3 +0x9779:na4 +0x977a:mo4 +0x977b:zu3 +0x977c:da2 +0x977d:ban4 +0x977e:yi4 +0x977f:yao4 +0x9780:tao2 +0x9781:tuo2 +0x9782:jia2 +0x9783:hong2 +0x9784:pao2 +0x9785:yang3 +0x9787:yin1 +0x9788:jia2 +0x9789:tao2 +0x978a:ji2 +0x978b:xie2 +0x978c:an1 +0x978d:an1 +0x978e:hen2 +0x978f:gong3 +0x9791:da2 +0x9792:qiao1 +0x9793:ting1 +0x9794:wan3 +0x9795:ying4 +0x9796:sui1 +0x9797:tiao2 +0x9798:qiao4 +0x9799:xuan4 +0x979a:kong4 +0x979b:beng3 +0x979c:ta4 +0x979d:zhang3 +0x979e:bing3 +0x979f:kuo4 +0x97a0:ju1 +0x97a1:la5 +0x97a2:xie4 +0x97a3:rou2 +0x97a4:bang1 +0x97a5:yi4 +0x97a6:qiu1 +0x97a7:qiu1 +0x97a8:he2 +0x97a9:xiao4 +0x97aa:mu4 +0x97ab:ju2 +0x97ac:jian1 +0x97ad:bian1 +0x97ae:di1 +0x97af:jian1 +0x97b1:tao1 +0x97b2:gou1 +0x97b3:ta4 +0x97b4:bei4 +0x97b5:xie2 +0x97b6:pan2 +0x97b7:ge2 +0x97b8:bi4 +0x97b9:kuo4 +0x97bb:lou2 +0x97bc:gui4 +0x97bd:qiao2 +0x97be:xue1 +0x97bf:ji1 +0x97c0:jian1 +0x97c1:jiang1 +0x97c2:chan4 +0x97c3:da2 +0x97c4:huo4 +0x97c5:xian3 +0x97c6:qian1 +0x97c7:du2 +0x97c8:wa4 +0x97c9:jian1 +0x97ca:lan2 +0x97cb:wei2 +0x97cc:ren4 +0x97cd:fu2 +0x97ce:mei4 +0x97cf:juan4 +0x97d0:ge2 +0x97d1:wei3 +0x97d2:qiao4 +0x97d3:han2 +0x97d4:chang4 +0x97d6:rou2 +0x97d7:xun4 +0x97d8:she4 +0x97d9:wei3 +0x97da:ge2 +0x97db:bei4 +0x97dc:tao1 +0x97dd:gou1 +0x97de:yun4 +0x97e0:bi4 +0x97e1:wei3 +0x97e2:hui4 +0x97e3:du2 +0x97e4:wa4 +0x97e5:du2 +0x97e6:wei2 +0x97e7:ren4 +0x97e8:fu2 +0x97e9:han2 +0x97ea:wei3 +0x97eb:yun4 +0x97ec:tao1 +0x97ed:jiu3 +0x97ee:jiu3 +0x97ef:xian1 +0x97f0:xie4 +0x97f1:xian1 +0x97f2:ji1 +0x97f3:yin1 +0x97f4:za2 +0x97f5:yun4 +0x97f6:shao2 +0x97f7:le4 +0x97f8:peng2 +0x97f9:heng2 +0x97fa:ying1 +0x97fb:yun4 +0x97fc:peng2 +0x97fd:yin1 +0x97fe:yin1 +0x97ff:xiang3 +0x9800:hu4 +0x9801:ye4 +0x9802:ding3 +0x9803:qing3 +0x9804:kui2 +0x9805:xiang4 +0x9806:shun4 +0x9807:han1 +0x9808:xu1 +0x9809:yi2 +0x980a:xu4 +0x980b:gu4 +0x980c:song4 +0x980d:kui3 +0x980e:qi2 +0x980f:hang2 +0x9810:yu4 +0x9811:wan2 +0x9812:ban1 +0x9813:dun4 +0x9814:di2 +0x9815:dan1 +0x9816:pan4 +0x9817:po1 +0x9818:ling3 +0x9819:ce4 +0x981a:jing3 +0x981b:lei3 +0x981c:he2 +0x981d:qiao1 +0x981e:e4 +0x981f:e2 +0x9820:wei3 +0x9821:jie2 +0x9822:gua1 +0x9823:shen3 +0x9824:yi2 +0x9825:shen3 +0x9826:hai2 +0x9827:dui1 +0x9828:pian1 +0x9829:ping1 +0x982a:lei4 +0x982b:fu3 +0x982c:jia2 +0x982d:tou2 +0x982e:hui4 +0x982f:kui2 +0x9830:jia2 +0x9831:le4 +0x9832:ting3 +0x9833:cheng1 +0x9834:ying3 +0x9835:jun1 +0x9836:hu2 +0x9837:han4 +0x9838:jing3 +0x9839:tui2 +0x983a:tui2 +0x983b:pin2 +0x983c:lai4 +0x983d:tui2 +0x983e:zi1 +0x983f:zi1 +0x9840:chui2 +0x9841:ding4 +0x9842:lai4 +0x9843:yan2 +0x9844:han4 +0x9845:jian1 +0x9846:ke1 +0x9847:cui4 +0x9848:jiong3 +0x9849:qin1 +0x984a:yi2 +0x984b:sai1 +0x984c:ti2 +0x984d:e2 +0x984e:e4 +0x984f:yan2 +0x9850:hun2 +0x9851:kan3 +0x9852:yong2 +0x9853:zhuan1 +0x9854:yan2 +0x9855:xian3 +0x9856:xin4 +0x9857:yi3 +0x9858:yuan4 +0x9859:sang3 +0x985a:dian1 +0x985b:dian1 +0x985c:jiang3 +0x985d:ku1 +0x985e:lei4 +0x985f:liao2 +0x9860:piao4 +0x9861:yi4 +0x9862:man2 +0x9863:qi1 +0x9864:rao4 +0x9865:hao4 +0x9866:qiao2 +0x9867:gu4 +0x9868:xun4 +0x9869:qian1 +0x986a:hui1 +0x986b:zhan4 +0x986c:ru2 +0x986d:hong1 +0x986e:bin1 +0x986f:xian3 +0x9870:pin2 +0x9871:lu2 +0x9872:lan3 +0x9873:nie4 +0x9874:quan2 +0x9875:ye4 +0x9876:ding3 +0x9877:qing3 +0x9878:han1 +0x9879:xiang4 +0x987a:shun4 +0x987b:xu1 +0x987c:xu4 +0x987d:wan2 +0x987e:gu4 +0x987f:dun4 +0x9880:qi2 +0x9881:ban1 +0x9882:song4 +0x9883:hang2 +0x9884:yu4 +0x9885:lu2 +0x9886:ling3 +0x9887:po3 +0x9888:jing3 +0x9889:jie2 +0x988a:jia2 +0x988b:tian5 +0x988c:han4 +0x988d:ying3 +0x988e:jiong3 +0x988f:hai2 +0x9890:yi2 +0x9891:pin2 +0x9892:hui4 +0x9893:tui2 +0x9894:han4 +0x9895:ying3 +0x9896:ying3 +0x9897:ke1 +0x9898:ti2 +0x9899:yong2 +0x989a:e4 +0x989b:zhuan1 +0x989c:yan2 +0x989d:e2 +0x989e:nie4 +0x989f:man2 +0x98a0:dian1 +0x98a1:sang3 +0x98a2:hao4 +0x98a3:lei4 +0x98a4:zhan4 +0x98a5:ru2 +0x98a6:pin2 +0x98a7:quan2 +0x98a8:feng1 +0x98a9:biao1 +0x98ab:fu2 +0x98ac:xia1 +0x98ad:zhan3 +0x98ae:biao1 +0x98af:sa4 +0x98b0:ba2 +0x98b1:tai2 +0x98b2:lie4 +0x98b3:gua1 +0x98b4:xuan4 +0x98b5:shao4 +0x98b6:ju4 +0x98b7:bi1 +0x98b8:si1 +0x98b9:wei3 +0x98ba:yang2 +0x98bb:yao2 +0x98bc:sou1 +0x98bd:kai3 +0x98be:sao1 +0x98bf:fan2 +0x98c0:liu2 +0x98c1:xi2 +0x98c2:liao2 +0x98c3:piao1 +0x98c4:piao1 +0x98c5:liu2 +0x98c6:biao1 +0x98c7:biao1 +0x98c8:biao3 +0x98c9:liao2 +0x98cb:se4 +0x98cc:feng1 +0x98cd:biao1 +0x98ce:feng1 +0x98cf:yang2 +0x98d0:zhan3 +0x98d1:biao1 +0x98d2:sa4 +0x98d3:ju4 +0x98d4:si1 +0x98d5:sou1 +0x98d6:yao2 +0x98d7:liu2 +0x98d8:piao1 +0x98d9:biao1 +0x98da:biao1 +0x98db:fei1 +0x98dc:fan1 +0x98dd:fei1 +0x98de:fei1 +0x98df:shi2 +0x98e0:shi2 +0x98e1:can1 +0x98e2:ji1 +0x98e3:ding4 +0x98e4:si4 +0x98e5:tuo1 +0x98e6:zhan1 +0x98e7:sun1 +0x98e8:xiang3 +0x98e9:tun2 +0x98ea:ren4 +0x98eb:yu4 +0x98ec:juan4 +0x98ed:chi4 +0x98ee:yin3 +0x98ef:fan4 +0x98f0:fan4 +0x98f1:sun1 +0x98f2:yin3 +0x98f3:zhu4 +0x98f4:yi2 +0x98f5:zhai3 +0x98f6:bi4 +0x98f7:jie3 +0x98f8:tao1 +0x98f9:liu3 +0x98fa:ci2 +0x98fb:tie4 +0x98fc:si4 +0x98fd:bao3 +0x98fe:shi4 +0x98ff:duo4 +0x9900:hai4 +0x9901:ren4 +0x9902:tian3 +0x9903:jiao3 +0x9904:jia2 +0x9905:bing3 +0x9906:yao2 +0x9907:tong2 +0x9908:ci2 +0x9909:xiang3 +0x990a:yang3 +0x990b:yang3 +0x990c:er3 +0x990d:yan4 +0x990e:le5 +0x990f:yi1 +0x9910:can1 +0x9911:bo1 +0x9912:nei3 +0x9913:e4 +0x9914:bu1 +0x9915:jun4 +0x9916:dou4 +0x9917:su4 +0x9918:yu2 +0x9919:shi4 +0x991a:yao2 +0x991b:hun2 +0x991c:guo3 +0x991d:shi4 +0x991e:jian4 +0x991f:zhui4 +0x9920:bing3 +0x9921:xian4 +0x9922:bu4 +0x9923:ye4 +0x9924:tan2 +0x9925:fei3 +0x9926:zhang1 +0x9927:wei4 +0x9928:guan3 +0x9929:e4 +0x992a:nuan3 +0x992b:hun2 +0x992c:hu2 +0x992d:huang2 +0x992e:tie4 +0x992f:hui4 +0x9930:jian1 +0x9931:hou2 +0x9932:he2 +0x9933:xing2 +0x9934:fen1 +0x9935:wei4 +0x9936:gu3 +0x9937:cha1 +0x9938:song4 +0x9939:tang2 +0x993a:bo2 +0x993b:gao1 +0x993c:xi4 +0x993d:kui4 +0x993e:liu4 +0x993f:sou1 +0x9940:tao2 +0x9941:ye4 +0x9942:yun2 +0x9943:mo2 +0x9944:tang2 +0x9945:man2 +0x9946:bi4 +0x9947:yu4 +0x9948:xiu1 +0x9949:jin3 +0x994a:san3 +0x994b:kui4 +0x994c:zhuan4 +0x994d:shan4 +0x994e:chi4 +0x994f:dan4 +0x9950:yi4 +0x9951:ji1 +0x9952:rao2 +0x9953:cheng1 +0x9954:yong1 +0x9955:tao1 +0x9956:hui4 +0x9957:xiang3 +0x9958:zhan1 +0x9959:fen1 +0x995a:hai4 +0x995b:meng2 +0x995c:yan4 +0x995d:mo2 +0x995e:chan2 +0x995f:xiang3 +0x9960:luo2 +0x9961:zuan4 +0x9962:nang3 +0x9963:shi2 +0x9964:ding4 +0x9965:ji1 +0x9966:tuo1 +0x9967:xing2 +0x9968:tun2 +0x9969:xi4 +0x996a:ren4 +0x996b:yu4 +0x996c:chi4 +0x996d:fan4 +0x996e:yin3 +0x996f:jian4 +0x9970:shi4 +0x9971:bao3 +0x9972:si4 +0x9973:duo4 +0x9974:yi2 +0x9975:er3 +0x9976:rao2 +0x9977:xiang3 +0x9978:jia2 +0x9979:le5 +0x997a:jiao3 +0x997b:yi1 +0x997c:bing3 +0x997d:bo2 +0x997e:dou4 +0x997f:e4 +0x9980:yu2 +0x9981:nei3 +0x9982:jun4 +0x9983:guo3 +0x9984:hun2 +0x9985:xian4 +0x9986:guan3 +0x9987:cha1 +0x9988:kui4 +0x9989:gu3 +0x998a:sou1 +0x998b:chan2 +0x998c:ye4 +0x998d:mo2 +0x998e:bo2 +0x998f:liu4 +0x9990:xiu1 +0x9991:jin3 +0x9992:man2 +0x9993:san3 +0x9994:zhuan4 +0x9995:nang3 +0x9996:shou3 +0x9997:kui2 +0x9998:guo2 +0x9999:xiang1 +0x999a:fen2 +0x999b:ba2 +0x999c:ni3 +0x999d:bi4 +0x999e:bo2 +0x999f:tu2 +0x99a0:han1 +0x99a1:fei1 +0x99a2:jian1 +0x99a3:an1 +0x99a4:ai3 +0x99a5:fu4 +0x99a6:xian1 +0x99a7:wen1 +0x99a8:xin1 +0x99a9:fen2 +0x99aa:bin1 +0x99ab:xing1 +0x99ac:ma3 +0x99ad:yu4 +0x99ae:feng2 +0x99af:han4 +0x99b0:di4 +0x99b1:tuo2 +0x99b2:tuo1 +0x99b3:chi2 +0x99b4:xun2 +0x99b5:zhu4 +0x99b6:zhi1 +0x99b7:pei4 +0x99b8:xin4 +0x99b9:ri4 +0x99ba:sa4 +0x99bb:yin3 +0x99bc:wen2 +0x99bd:zhi2 +0x99be:dan4 +0x99bf:lv2 +0x99c0:you2 +0x99c1:bo2 +0x99c2:bao3 +0x99c3:kuai4 +0x99c4:tuo2 +0x99c5:yi4 +0x99c6:qu1 +0x99c8:qu1 +0x99c9:jiong1 +0x99ca:bo3 +0x99cb:zhao1 +0x99cc:yuan1 +0x99cd:peng1 +0x99ce:zhou4 +0x99cf:ju4 +0x99d0:zhu4 +0x99d1:nu2 +0x99d2:ju1 +0x99d3:pi1 +0x99d4:zang3 +0x99d5:jia4 +0x99d6:ling2 +0x99d7:zhen1 +0x99d8:tai2 +0x99d9:fu4 +0x99da:yang3 +0x99db:shi3 +0x99dc:bi4 +0x99dd:tuo2 +0x99de:tuo2 +0x99df:si4 +0x99e0:liu2 +0x99e1:ma4 +0x99e2:pian2 +0x99e3:tao2 +0x99e4:zhi4 +0x99e5:rong2 +0x99e6:teng2 +0x99e7:dong4 +0x99e8:xun2 +0x99e9:quan2 +0x99ea:shen1 +0x99eb:jiong1 +0x99ec:er3 +0x99ed:hai4 +0x99ee:bo2 +0x99f0:yin1 +0x99f1:luo4 +0x99f3:dan4 +0x99f4:xie4 +0x99f5:liu2 +0x99f6:ju2 +0x99f7:song3 +0x99f8:qin1 +0x99f9:mang2 +0x99fa:liang2 +0x99fb:han4 +0x99fc:tu2 +0x99fd:xuan4 +0x99fe:tui4 +0x99ff:jun4 +0x9a00:e2 +0x9a01:cheng3 +0x9a02:xing1 +0x9a03:ai2 +0x9a04:lu4 +0x9a05:zhui1 +0x9a06:zhou1 +0x9a07:she3 +0x9a08:pian2 +0x9a09:kun1 +0x9a0a:tao2 +0x9a0b:lai2 +0x9a0c:zong1 +0x9a0d:ke4 +0x9a0e:qi2 +0x9a0f:qi2 +0x9a10:yan4 +0x9a11:fei1 +0x9a12:sao1 +0x9a13:yan3 +0x9a14:jie2 +0x9a15:yao3 +0x9a16:wu4 +0x9a17:pian4 +0x9a18:cong1 +0x9a19:pian4 +0x9a1a:qian2 +0x9a1b:fei1 +0x9a1c:huang2 +0x9a1d:jian1 +0x9a1e:huo4 +0x9a1f:yu4 +0x9a20:ti2 +0x9a21:quan2 +0x9a22:xia2 +0x9a23:zong1 +0x9a24:kui2 +0x9a25:rou2 +0x9a26:si1 +0x9a27:gua1 +0x9a28:tuo2 +0x9a29:kui4 +0x9a2a:sou1 +0x9a2b:qian1 +0x9a2c:cheng2 +0x9a2d:zhi4 +0x9a2e:liu2 +0x9a2f:pang2 +0x9a30:teng2 +0x9a31:xi1 +0x9a32:cao3 +0x9a33:du2 +0x9a34:yan4 +0x9a35:yuan2 +0x9a36:zou1 +0x9a37:sao1 +0x9a38:shan4 +0x9a39:li2 +0x9a3a:zhi4 +0x9a3b:shuang3 +0x9a3c:lu4 +0x9a3d:xi2 +0x9a3e:luo2 +0x9a3f:zhang1 +0x9a40:mo4 +0x9a41:ao4 +0x9a42:can1 +0x9a43:piao4 +0x9a44:cong1 +0x9a45:qu1 +0x9a46:bi4 +0x9a47:zhi4 +0x9a48:yu4 +0x9a49:xu1 +0x9a4a:hua2 +0x9a4b:bo1 +0x9a4c:su4 +0x9a4d:xiao1 +0x9a4e:lin2 +0x9a4f:chan3 +0x9a50:dun1 +0x9a51:liu2 +0x9a52:tuo2 +0x9a53:zeng1 +0x9a54:tan2 +0x9a55:jiao1 +0x9a56:tie3 +0x9a57:yan4 +0x9a58:luo2 +0x9a59:zhan1 +0x9a5a:jing1 +0x9a5b:yi4 +0x9a5c:ye4 +0x9a5d:tuo1 +0x9a5e:bin1 +0x9a5f:zou4 +0x9a60:yan4 +0x9a61:peng2 +0x9a62:lv2 +0x9a63:teng2 +0x9a64:xiang1 +0x9a65:ji4 +0x9a66:shuang1 +0x9a67:ju2 +0x9a68:xi1 +0x9a69:huan1 +0x9a6a:li2 +0x9a6b:biao1 +0x9a6c:ma3 +0x9a6d:yu4 +0x9a6e:tuo2 +0x9a6f:xun2 +0x9a70:chi2 +0x9a71:qu1 +0x9a72:ri4 +0x9a73:bo2 +0x9a74:lv2 +0x9a75:zang3 +0x9a76:shi3 +0x9a77:si4 +0x9a78:fu4 +0x9a79:ju1 +0x9a7a:zou1 +0x9a7b:zhu4 +0x9a7c:tuo2 +0x9a7d:nu2 +0x9a7e:jia4 +0x9a7f:yi4 +0x9a80:tai2 +0x9a81:xiao1 +0x9a82:ma4 +0x9a83:yin1 +0x9a84:jiao1 +0x9a85:hua2 +0x9a86:luo4 +0x9a87:hai4 +0x9a88:pian2 +0x9a89:biao1 +0x9a8a:li2 +0x9a8b:cheng3 +0x9a8c:yan4 +0x9a8d:xin1 +0x9a8e:qin1 +0x9a8f:jun4 +0x9a90:qi2 +0x9a91:qi2 +0x9a92:ke4 +0x9a93:zhui1 +0x9a94:zong1 +0x9a95:su4 +0x9a96:can1 +0x9a97:pian4 +0x9a98:zhi4 +0x9a99:kui2 +0x9a9a:sao1 +0x9a9b:wu4 +0x9a9c:ao2 +0x9a9d:liu2 +0x9a9e:qian1 +0x9a9f:shan4 +0x9aa0:piao4 +0x9aa1:luo2 +0x9aa2:cong1 +0x9aa3:chan3 +0x9aa4:zou4 +0x9aa5:ji4 +0x9aa6:shuang1 +0x9aa7:xiang1 +0x9aa8:gu3 +0x9aa9:wei3 +0x9aaa:wei3 +0x9aab:wei3 +0x9aac:yu2 +0x9aad:gan4 +0x9aae:yi4 +0x9aaf:ang1 +0x9ab0:tou2 +0x9ab1:xie4 +0x9ab2:bao1 +0x9ab3:bi4 +0x9ab4:chi1 +0x9ab5:ti3 +0x9ab6:di3 +0x9ab7:ku1 +0x9ab8:hai2 +0x9ab9:qiao1 +0x9aba:gou4 +0x9abb:kua4 +0x9abc:ge2 +0x9abd:tui3 +0x9abe:geng3 +0x9abf:pian2 +0x9ac0:bi4 +0x9ac1:ke1 +0x9ac2:ka4 +0x9ac3:yu2 +0x9ac4:sui3 +0x9ac5:lou2 +0x9ac6:bo2 +0x9ac7:xiao1 +0x9ac8:pang2 +0x9ac9:bo1 +0x9aca:ci1 +0x9acb:kuan1 +0x9acc:bin4 +0x9acd:mo2 +0x9ace:liao2 +0x9acf:lou2 +0x9ad0:nao2 +0x9ad1:du2 +0x9ad2:zang1 +0x9ad3:sui3 +0x9ad4:ti3 +0x9ad5:bin4 +0x9ad6:kuan1 +0x9ad7:lu2 +0x9ad8:gao1 +0x9ad9:gao1 +0x9ada:qiao4 +0x9adb:kao1 +0x9adc:qiao1 +0x9add:lao4 +0x9ade:zao4 +0x9adf:biao1 +0x9ae0:kun1 +0x9ae1:kun1 +0x9ae2:ti4 +0x9ae3:fang3 +0x9ae4:xiu1 +0x9ae5:ran2 +0x9ae6:mao2 +0x9ae7:dan4 +0x9ae8:kun1 +0x9ae9:bin4 +0x9aea:fa4 +0x9aeb:tiao2 +0x9aec:pi1 +0x9aed:zi1 +0x9aee:fa4 +0x9aef:ran2 +0x9af0:ti4 +0x9af1:pao4 +0x9af2:pi1 +0x9af3:mao2 +0x9af4:fu2 +0x9af5:er2 +0x9af6:rong2 +0x9af7:qu1 +0x9af9:xiu1 +0x9afa:gua4 +0x9afb:ji4 +0x9afc:peng2 +0x9afd:zhua1 +0x9afe:shao1 +0x9aff:sha1 +0x9b00:ti4 +0x9b01:li4 +0x9b02:bin4 +0x9b03:zong1 +0x9b04:ti4 +0x9b05:peng2 +0x9b06:song1 +0x9b07:zheng1 +0x9b08:quan2 +0x9b09:zong1 +0x9b0a:shun4 +0x9b0b:jian1 +0x9b0c:duo3 +0x9b0d:hu2 +0x9b0e:la4 +0x9b0f:jiu1 +0x9b10:qi2 +0x9b11:lian2 +0x9b12:zhen3 +0x9b13:bin4 +0x9b14:peng2 +0x9b15:mo4 +0x9b16:san1 +0x9b17:man4 +0x9b18:man2 +0x9b19:seng1 +0x9b1a:xu1 +0x9b1b:lie4 +0x9b1c:qian1 +0x9b1d:qian1 +0x9b1e:nong2 +0x9b1f:huan2 +0x9b20:kuai4 +0x9b21:ning2 +0x9b22:bin4 +0x9b23:lie4 +0x9b24:rang2 +0x9b25:dou4 +0x9b26:dou4 +0x9b27:nao4 +0x9b28:hong4 +0x9b29:xi4 +0x9b2a:dou4 +0x9b2b:han3 +0x9b2c:dou4 +0x9b2d:dou4 +0x9b2e:jiu1 +0x9b2f:chang4 +0x9b30:yu4 +0x9b31:yu4 +0x9b32:li4 +0x9b33:juan4 +0x9b34:fu3 +0x9b35:qian2 +0x9b36:gui1 +0x9b37:zong1 +0x9b38:liu4 +0x9b39:gui1 +0x9b3a:shang1 +0x9b3b:yu4 +0x9b3c:gui3 +0x9b3d:mei4 +0x9b3e:ji4 +0x9b3f:qi2 +0x9b40:jie4 +0x9b41:kui2 +0x9b42:hun2 +0x9b43:ba2 +0x9b44:po4 +0x9b45:mei4 +0x9b46:xu4 +0x9b47:yan3 +0x9b48:xiao1 +0x9b49:liang3 +0x9b4a:yu4 +0x9b4b:tui2 +0x9b4c:qi1 +0x9b4d:wang3 +0x9b4e:liang3 +0x9b4f:wei4 +0x9b50:jian1 +0x9b51:chi1 +0x9b52:piao1 +0x9b53:bi4 +0x9b54:mo2 +0x9b55:ji3 +0x9b56:xu1 +0x9b57:chou3 +0x9b58:yan3 +0x9b59:zhan3 +0x9b5a:yu2 +0x9b5b:dao1 +0x9b5c:ren2 +0x9b5d:ji4 +0x9b5f:gong1 +0x9b60:tuo2 +0x9b61:diao4 +0x9b62:ji3 +0x9b63:xu4 +0x9b64:e2 +0x9b65:e4 +0x9b66:sha1 +0x9b67:hang2 +0x9b68:tun2 +0x9b69:mo4 +0x9b6a:jie4 +0x9b6b:shen3 +0x9b6c:fan3 +0x9b6d:yuan2 +0x9b6e:bi2 +0x9b6f:lu3 +0x9b70:wen2 +0x9b71:hu2 +0x9b72:lu2 +0x9b73:za2 +0x9b74:fang2 +0x9b75:fen2 +0x9b76:na4 +0x9b77:you2 +0x9b7a:he2 +0x9b7b:xia2 +0x9b7c:qu1 +0x9b7d:han1 +0x9b7e:pi2 +0x9b7f:ling2 +0x9b80:tuo2 +0x9b81:bo1 +0x9b82:qiu2 +0x9b83:ping2 +0x9b84:fu2 +0x9b85:bi4 +0x9b86:ji4 +0x9b87:wei4 +0x9b88:ju1 +0x9b89:diao1 +0x9b8a:bo2 +0x9b8b:you2 +0x9b8c:gun3 +0x9b8d:pi1 +0x9b8e:nian2 +0x9b8f:xing1 +0x9b90:tai2 +0x9b91:bao4 +0x9b92:fu4 +0x9b93:zha3 +0x9b94:ju4 +0x9b95:gu1 +0x9b99:ta4 +0x9b9a:jie2 +0x9b9b:shu4 +0x9b9c:hou4 +0x9b9d:xiang3 +0x9b9e:er2 +0x9b9f:an4 +0x9ba0:wei2 +0x9ba1:tiao1 +0x9ba2:zhu1 +0x9ba3:yin4 +0x9ba4:lie4 +0x9ba5:luo4 +0x9ba6:tong2 +0x9ba7:yi2 +0x9ba8:qi2 +0x9ba9:bing4 +0x9baa:wei3 +0x9bab:jiao1 +0x9bac:bu4 +0x9bad:gui1 +0x9bae:xian1 +0x9baf:ge2 +0x9bb0:hui2 +0x9bb3:kao3 +0x9bb5:duo2 +0x9bb6:jun1 +0x9bb7:ti2 +0x9bb8:mian3 +0x9bb9:xiao1 +0x9bba:za3 +0x9bbb:sha1 +0x9bbc:qin1 +0x9bbd:yu2 +0x9bbe:nei3 +0x9bbf:zhe2 +0x9bc0:gun3 +0x9bc1:geng3 +0x9bc3:wu2 +0x9bc4:qiu2 +0x9bc5:ting2 +0x9bc6:fu3 +0x9bc7:wan3 +0x9bc8:tiao2 +0x9bc9:li3 +0x9bca:sha1 +0x9bcb:sha1 +0x9bcc:gao4 +0x9bcd:meng2 +0x9bd2:yong3 +0x9bd3:ni2 +0x9bd4:zi1 +0x9bd5:qi2 +0x9bd6:qing1 +0x9bd7:xiang3 +0x9bd8:nei3 +0x9bd9:chun2 +0x9bda:ji4 +0x9bdb:diao1 +0x9bdc:qie4 +0x9bdd:gu4 +0x9bde:zhou3 +0x9bdf:dong1 +0x9be0:lai2 +0x9be1:fei1 +0x9be2:ni2 +0x9be3:yi4 +0x9be4:kun1 +0x9be5:lu4 +0x9be6:jiu4 +0x9be7:chang1 +0x9be8:jing1 +0x9be9:lun2 +0x9bea:ling2 +0x9beb:zou1 +0x9bec:li2 +0x9bed:meng3 +0x9bee:zong1 +0x9bef:zhi4 +0x9bf0:nian2 +0x9bf4:shi1 +0x9bf5:shen1 +0x9bf6:hun3 +0x9bf7:shi4 +0x9bf8:hou2 +0x9bf9:xing1 +0x9bfa:zhu1 +0x9bfb:la4 +0x9bfc:zong1 +0x9bfd:ji4 +0x9bfe:bian1 +0x9bff:bian1 +0x9c00:huan4 +0x9c01:quan2 +0x9c02:ze2 +0x9c03:wei1 +0x9c04:wei1 +0x9c05:yu2 +0x9c06:qun1 +0x9c07:rou2 +0x9c08:die2 +0x9c09:huang2 +0x9c0a:lian4 +0x9c0b:yan3 +0x9c0c:qiu2 +0x9c0d:qiu1 +0x9c0e:jian4 +0x9c0f:bi4 +0x9c10:e4 +0x9c11:yang2 +0x9c12:fu4 +0x9c13:sai1 +0x9c14:jian3 +0x9c15:xia2 +0x9c16:tuo3 +0x9c17:hu2 +0x9c19:ruo4 +0x9c1b:wen1 +0x9c1c:jian1 +0x9c1d:hao4 +0x9c1e:wu1 +0x9c1f:fang2 +0x9c20:sao1 +0x9c21:liu2 +0x9c22:ma3 +0x9c23:shi2 +0x9c24:shi1 +0x9c25:guan1 +0x9c27:teng2 +0x9c28:ta4 +0x9c29:yao2 +0x9c2a:ge2 +0x9c2b:rong2 +0x9c2c:qian2 +0x9c2d:qi2 +0x9c2e:wen1 +0x9c2f:ruo4 +0x9c31:lian2 +0x9c32:ao2 +0x9c33:le4 +0x9c34:hui1 +0x9c35:min3 +0x9c36:ji4 +0x9c37:tiao2 +0x9c38:qu1 +0x9c39:jian1 +0x9c3a:sao1 +0x9c3b:man2 +0x9c3c:xi2 +0x9c3d:qiu2 +0x9c3e:biao4 +0x9c3f:ji1 +0x9c40:ji4 +0x9c41:zhu2 +0x9c42:jiang1 +0x9c43:qiu1 +0x9c44:zhuan1 +0x9c45:yong2 +0x9c46:zhang1 +0x9c47:kang1 +0x9c48:xue3 +0x9c49:bie1 +0x9c4a:jue2 +0x9c4b:qu1 +0x9c4c:xiang4 +0x9c4d:bo1 +0x9c4e:jiao3 +0x9c4f:xun2 +0x9c50:su4 +0x9c51:huang2 +0x9c52:zun4 +0x9c53:shan4 +0x9c54:shan4 +0x9c55:fan1 +0x9c56:gui4 +0x9c57:lin2 +0x9c58:xun2 +0x9c59:miao2 +0x9c5a:xi3 +0x9c5d:fen4 +0x9c5e:guan1 +0x9c5f:hou4 +0x9c60:kuai4 +0x9c61:zei2 +0x9c62:sao1 +0x9c63:zhan1 +0x9c64:gan3 +0x9c65:gui4 +0x9c66:sheng2 +0x9c67:li3 +0x9c68:chang2 +0x9c6c:ru2 +0x9c6d:ji4 +0x9c6e:xu4 +0x9c6f:huo4 +0x9c71:li4 +0x9c72:lie4 +0x9c73:li4 +0x9c74:mie4 +0x9c75:zhen1 +0x9c76:xiang3 +0x9c77:e4 +0x9c78:lu2 +0x9c79:guan4 +0x9c7a:li2 +0x9c7b:xian1 +0x9c7c:yu2 +0x9c7d:dao1 +0x9c7e:ji3 +0x9c7f:you2 +0x9c80:tun2 +0x9c81:lu3 +0x9c82:fang2 +0x9c83:ba1 +0x9c84:he2 +0x9c85:bo1 +0x9c86:ping2 +0x9c87:nian2 +0x9c88:lu2 +0x9c89:you2 +0x9c8a:zha3 +0x9c8b:fu4 +0x9c8c:bo2 +0x9c8d:bao4 +0x9c8e:hou4 +0x9c8f:pi1 +0x9c90:tai2 +0x9c91:gui1 +0x9c92:jie2 +0x9c93:kao3 +0x9c94:wei3 +0x9c95:er2 +0x9c96:tong2 +0x9c97:ze2 +0x9c98:hou4 +0x9c99:kuai4 +0x9c9a:ji4 +0x9c9b:jiao3 +0x9c9c:xian1 +0x9c9d:za3 +0x9c9e:xiang3 +0x9c9f:xun2 +0x9ca0:geng3 +0x9ca1:li2 +0x9ca2:lian2 +0x9ca3:jian1 +0x9ca4:li3 +0x9ca5:shi2 +0x9ca6:tiao2 +0x9ca7:gun3 +0x9ca8:sha1 +0x9ca9:wan3 +0x9caa:jun1 +0x9cab:ji4 +0x9cac:yong3 +0x9cad:qing1 +0x9cae:ling2 +0x9caf:qi2 +0x9cb0:zou1 +0x9cb1:fei1 +0x9cb2:kun1 +0x9cb3:chang1 +0x9cb4:gu4 +0x9cb5:ni2 +0x9cb6:nian2 +0x9cb7:diao1 +0x9cb8:jing1 +0x9cb9:shen1 +0x9cba:shi1 +0x9cbb:zi1 +0x9cbc:fen4 +0x9cbd:die2 +0x9cbe:bi4 +0x9cbf:chang2 +0x9cc0:shi4 +0x9cc1:wen1 +0x9cc2:wei1 +0x9cc3:sai1 +0x9cc4:e4 +0x9cc5:qiu1 +0x9cc6:fu4 +0x9cc7:huang2 +0x9cc8:quan2 +0x9cc9:jiang1 +0x9cca:bian1 +0x9ccb:sao1 +0x9ccc:ao2 +0x9ccd:qi2 +0x9cce:ta4 +0x9ccf:yin2 +0x9cd0:yao2 +0x9cd1:fang2 +0x9cd2:jian1 +0x9cd3:le4 +0x9cd4:biao4 +0x9cd5:xue3 +0x9cd6:bie1 +0x9cd7:man2 +0x9cd8:min3 +0x9cd9:yong2 +0x9cda:wei4 +0x9cdb:xi2 +0x9cdc:jue2 +0x9cdd:shan4 +0x9cde:lin2 +0x9cdf:zun4 +0x9ce0:huo4 +0x9ce1:gan3 +0x9ce2:li3 +0x9ce3:zhan1 +0x9ce4:guan3 +0x9ce5:niao3 +0x9ce6:yi3 +0x9ce7:fu2 +0x9ce8:li4 +0x9ce9:jiu1 +0x9cea:bu3 +0x9ceb:yan4 +0x9cec:fu2 +0x9ced:diao1 +0x9cee:ji1 +0x9cef:feng4 +0x9cf1:gan1 +0x9cf2:shi1 +0x9cf3:feng4 +0x9cf4:ming2 +0x9cf5:bao3 +0x9cf6:yuan1 +0x9cf7:zhi1 +0x9cf8:hu4 +0x9cf9:qin2 +0x9cfa:fu1 +0x9cfb:fen1 +0x9cfc:wen2 +0x9cfd:jian1 +0x9cfe:shi1 +0x9cff:yu4 +0x9d00:fou3 +0x9d01:yao1 +0x9d02:jue4 +0x9d03:jue2 +0x9d04:pi1 +0x9d05:huan1 +0x9d06:zhen4 +0x9d07:bao3 +0x9d08:yan4 +0x9d09:ya1 +0x9d0a:zheng4 +0x9d0b:fang1 +0x9d0c:feng4 +0x9d0d:wen2 +0x9d0e:ou1 +0x9d0f:te4 +0x9d10:jia1 +0x9d11:nu2 +0x9d12:ling2 +0x9d13:mie4 +0x9d14:fu2 +0x9d15:tuo2 +0x9d16:wen2 +0x9d17:li4 +0x9d18:bian4 +0x9d19:zhi4 +0x9d1a:ge1 +0x9d1b:yuan1 +0x9d1c:zi1 +0x9d1d:qu2 +0x9d1e:xiao1 +0x9d1f:chi1 +0x9d20:dan4 +0x9d21:ju1 +0x9d22:you4 +0x9d23:gu1 +0x9d24:zhong1 +0x9d25:yu4 +0x9d26:yang1 +0x9d27:rong4 +0x9d28:ya1 +0x9d29:tie3 +0x9d2a:yu4 +0x9d2c:ying1 +0x9d2d:zhui1 +0x9d2e:wu1 +0x9d2f:er2 +0x9d30:gua1 +0x9d31:ai4 +0x9d32:zhi1 +0x9d33:yan4 +0x9d34:heng2 +0x9d35:jiao1 +0x9d36:ji2 +0x9d37:lie4 +0x9d38:zhu1 +0x9d39:ren2 +0x9d3a:yi2 +0x9d3b:hong2 +0x9d3c:luo4 +0x9d3d:ru2 +0x9d3e:mou2 +0x9d3f:ge1 +0x9d40:ren4 +0x9d41:jiao1 +0x9d42:xiu1 +0x9d43:zhou1 +0x9d44:zhi1 +0x9d45:luo4 +0x9d49:luan2 +0x9d4a:jia2 +0x9d4b:ji4 +0x9d4c:yu2 +0x9d4d:huan1 +0x9d4e:tuo3 +0x9d4f:bu1 +0x9d50:wu2 +0x9d51:juan1 +0x9d52:yu4 +0x9d53:bo2 +0x9d54:xun4 +0x9d55:xun4 +0x9d56:bi4 +0x9d57:xi1 +0x9d58:jun4 +0x9d59:ju2 +0x9d5a:tu2 +0x9d5b:jing1 +0x9d5c:ti2 +0x9d5d:e2 +0x9d5e:e2 +0x9d5f:kuang2 +0x9d60:hu2 +0x9d61:wu3 +0x9d62:shen1 +0x9d63:lai4 +0x9d66:lu4 +0x9d67:ping2 +0x9d68:shu1 +0x9d69:fu2 +0x9d6a:an1 +0x9d6b:zhao4 +0x9d6c:peng2 +0x9d6d:qin2 +0x9d6e:qian1 +0x9d6f:bei1 +0x9d70:diao1 +0x9d71:lu4 +0x9d72:que4 +0x9d73:jian1 +0x9d74:ju2 +0x9d75:tu4 +0x9d76:ya1 +0x9d77:yuan1 +0x9d78:qi2 +0x9d79:li2 +0x9d7a:ye4 +0x9d7b:zhui1 +0x9d7c:kong1 +0x9d7d:zhui4 +0x9d7e:kun1 +0x9d7f:sheng1 +0x9d80:qi2 +0x9d81:jing1 +0x9d82:yi4 +0x9d83:yi4 +0x9d84:jing1 +0x9d85:zi1 +0x9d86:lai2 +0x9d87:dong1 +0x9d88:qi1 +0x9d89:chun2 +0x9d8a:geng1 +0x9d8b:ju1 +0x9d8c:qu1 +0x9d8f:ji1 +0x9d90:shu4 +0x9d92:chi4 +0x9d93:miao2 +0x9d94:rou2 +0x9d95:an1 +0x9d96:qiu1 +0x9d97:ti2 +0x9d98:hu2 +0x9d99:ti2 +0x9d9a:e4 +0x9d9b:jie1 +0x9d9c:mao2 +0x9d9d:fu2 +0x9d9e:chun1 +0x9d9f:tu2 +0x9da0:yan3 +0x9da1:he2 +0x9da2:yuan2 +0x9da3:pian1 +0x9da4:yun4 +0x9da5:mei2 +0x9da6:hu2 +0x9da7:ying1 +0x9da8:dun4 +0x9da9:wu4 +0x9daa:ju2 +0x9dac:cang1 +0x9dad:fang3 +0x9dae:gu4 +0x9daf:ying1 +0x9db0:yuan2 +0x9db1:xuan1 +0x9db2:weng1 +0x9db3:shi1 +0x9db4:he4 +0x9db5:chu2 +0x9db6:tang2 +0x9db7:xia4 +0x9db8:ruo4 +0x9db9:liu2 +0x9dba:ji2 +0x9dbb:gu2 +0x9dbc:jian1 +0x9dbd:zhun3 +0x9dbe:han4 +0x9dbf:zi1 +0x9dc0:zi1 +0x9dc1:ni4 +0x9dc2:yao4 +0x9dc3:yan4 +0x9dc4:ji1 +0x9dc5:li4 +0x9dc6:tian2 +0x9dc7:kou4 +0x9dc8:ti1 +0x9dc9:ti1 +0x9dca:ni4 +0x9dcb:tu2 +0x9dcc:ma3 +0x9dcd:jiao1 +0x9dce:gao1 +0x9dcf:tian2 +0x9dd0:chen2 +0x9dd1:li4 +0x9dd2:zhuan1 +0x9dd3:zhe4 +0x9dd4:ao2 +0x9dd5:yao3 +0x9dd6:yi1 +0x9dd7:ou1 +0x9dd8:chi4 +0x9dd9:zhi4 +0x9dda:liao2 +0x9ddb:rong2 +0x9ddc:lou2 +0x9ddd:bi4 +0x9dde:shuang1 +0x9ddf:zhuo2 +0x9de0:yu2 +0x9de1:wu2 +0x9de2:jue2 +0x9de3:yin2 +0x9de4:quan2 +0x9de5:si1 +0x9de6:jiao1 +0x9de7:yi4 +0x9de8:hua1 +0x9de9:bi4 +0x9dea:ying1 +0x9deb:su4 +0x9dec:huang2 +0x9ded:fan2 +0x9dee:jiao1 +0x9def:liao2 +0x9df0:yan4 +0x9df1:kao1 +0x9df2:jiu4 +0x9df3:xian2 +0x9df4:xian2 +0x9df5:tu2 +0x9df6:mai3 +0x9df7:zun1 +0x9df8:yu4 +0x9df9:ying1 +0x9dfa:lu4 +0x9dfb:tuan2 +0x9dfc:xian2 +0x9dfd:xue2 +0x9dfe:yi4 +0x9dff:pi4 +0x9e00:shu2 +0x9e01:luo2 +0x9e02:qi1 +0x9e03:yi2 +0x9e04:ji2 +0x9e05:zhe2 +0x9e06:yu2 +0x9e07:zhan1 +0x9e08:ye4 +0x9e09:yang2 +0x9e0a:pi4 +0x9e0b:ning2 +0x9e0c:huo4 +0x9e0d:mi2 +0x9e0e:ying1 +0x9e0f:meng2 +0x9e10:di2 +0x9e11:yue4 +0x9e12:yu2 +0x9e13:lei3 +0x9e14:bao4 +0x9e15:lu2 +0x9e16:he4 +0x9e17:long2 +0x9e18:shuang1 +0x9e19:yue4 +0x9e1a:ying1 +0x9e1b:guan4 +0x9e1c:qu2 +0x9e1d:li2 +0x9e1e:luan2 +0x9e1f:niao3 +0x9e20:jiu1 +0x9e21:ji1 +0x9e22:yuan1 +0x9e23:ming2 +0x9e24:shi1 +0x9e25:ou1 +0x9e26:ya1 +0x9e27:cang1 +0x9e28:bao3 +0x9e29:zhen4 +0x9e2a:gu1 +0x9e2b:dong1 +0x9e2c:lu2 +0x9e2d:ya1 +0x9e2e:xiao1 +0x9e2f:yang1 +0x9e30:ling2 +0x9e31:zhi1 +0x9e32:qu2 +0x9e33:yuan1 +0x9e34:xue2 +0x9e35:tuo2 +0x9e36:si1 +0x9e37:zhi4 +0x9e38:er2 +0x9e39:gua1 +0x9e3a:xiu1 +0x9e3b:heng2 +0x9e3c:zhou1 +0x9e3d:ge1 +0x9e3e:luan2 +0x9e3f:hong2 +0x9e40:wu2 +0x9e41:bo2 +0x9e42:li2 +0x9e43:juan1 +0x9e44:hu2 +0x9e45:e2 +0x9e46:yu4 +0x9e47:xian2 +0x9e48:ti2 +0x9e49:wu3 +0x9e4a:que4 +0x9e4b:miao2 +0x9e4c:an1 +0x9e4d:kun1 +0x9e4e:bei1 +0x9e4f:peng2 +0x9e50:qian1 +0x9e51:chun2 +0x9e52:geng1 +0x9e53:yuan1 +0x9e54:su4 +0x9e55:hu2 +0x9e56:he2 +0x9e57:e4 +0x9e58:gu2 +0x9e59:qiu1 +0x9e5a:zi1 +0x9e5b:mei2 +0x9e5c:mu4 +0x9e5d:ni4 +0x9e5e:yao4 +0x9e5f:weng1 +0x9e60:liu2 +0x9e61:ji2 +0x9e62:ni4 +0x9e63:jian1 +0x9e64:he4 +0x9e65:yi1 +0x9e66:ying1 +0x9e67:zhe4 +0x9e68:liao2 +0x9e69:liao2 +0x9e6a:jiao1 +0x9e6b:jiu4 +0x9e6c:yu4 +0x9e6d:lu4 +0x9e6e:xuan2 +0x9e6f:zhan1 +0x9e70:ying1 +0x9e71:huo4 +0x9e72:meng2 +0x9e73:guan4 +0x9e74:shuang1 +0x9e75:lu3 +0x9e76:jin1 +0x9e77:ling2 +0x9e78:jian3 +0x9e79:xian2 +0x9e7a:cuo2 +0x9e7b:jian3 +0x9e7c:jian3 +0x9e7d:yan2 +0x9e7e:cuo2 +0x9e7f:lu4 +0x9e80:you1 +0x9e81:cu1 +0x9e82:ji3 +0x9e83:biao1 +0x9e84:cu1 +0x9e85:biao1 +0x9e86:zhu4 +0x9e87:jun1 +0x9e88:zhu3 +0x9e89:jian1 +0x9e8a:mi2 +0x9e8b:mi2 +0x9e8c:wu2 +0x9e8d:liu2 +0x9e8e:chen2 +0x9e8f:jun1 +0x9e90:lin2 +0x9e91:ni2 +0x9e92:qi2 +0x9e93:lu4 +0x9e94:jiu4 +0x9e95:jun1 +0x9e96:jing1 +0x9e97:li4 +0x9e98:xiang1 +0x9e99:yan2 +0x9e9a:jia1 +0x9e9b:mi2 +0x9e9c:li4 +0x9e9d:she4 +0x9e9e:zhang1 +0x9e9f:lin2 +0x9ea0:jing1 +0x9ea1:ji1 +0x9ea2:ling2 +0x9ea3:yan2 +0x9ea4:cu1 +0x9ea5:mai4 +0x9ea6:mai4 +0x9ea7:ge1 +0x9ea8:chao3 +0x9ea9:fu1 +0x9eaa:mian3 +0x9eab:mian3 +0x9eac:fu1 +0x9ead:pao4 +0x9eae:qu4 +0x9eaf:qu2 +0x9eb0:mou2 +0x9eb1:fu1 +0x9eb2:xian4 +0x9eb3:lai2 +0x9eb4:qu2 +0x9eb5:mian4 +0x9eb7:feng1 +0x9eb8:fu1 +0x9eb9:qu2 +0x9eba:mian4 +0x9ebb:ma2 +0x9ebc:me5 +0x9ebd:mo5 +0x9ebe:hui1 +0x9ec0:zou1 +0x9ec1:nen1 +0x9ec2:fen2 +0x9ec3:huang2 +0x9ec4:huang2 +0x9ec5:jin1 +0x9ec6:guang1 +0x9ec7:tian1 +0x9ec8:tou3 +0x9ec9:heng2 +0x9eca:xi1 +0x9ecb:kuang3 +0x9ecc:heng2 +0x9ecd:shu3 +0x9ece:li2 +0x9ecf:nian2 +0x9ed0:chi1 +0x9ed1:hei1 +0x9ed2:hei1 +0x9ed3:yi4 +0x9ed4:qian2 +0x9ed5:dan1 +0x9ed6:xi4 +0x9ed7:tuan3 +0x9ed8:mo4 +0x9ed9:mo4 +0x9eda:qian2 +0x9edb:dai4 +0x9edc:chu4 +0x9edd:you3 +0x9ede:dian3 +0x9edf:yi1 +0x9ee0:xia2 +0x9ee1:yan3 +0x9ee2:qu1 +0x9ee3:mei3 +0x9ee4:yan3 +0x9ee5:qing2 +0x9ee6:yu4 +0x9ee7:li2 +0x9ee8:dang3 +0x9ee9:du2 +0x9eea:can3 +0x9eeb:yin1 +0x9eec:an4 +0x9eed:yan1 +0x9eee:tan3 +0x9eef:an4 +0x9ef0:zhen3 +0x9ef1:dai4 +0x9ef2:can3 +0x9ef3:yi1 +0x9ef4:mei2 +0x9ef5:dan3 +0x9ef6:yan3 +0x9ef7:du2 +0x9ef8:lu2 +0x9ef9:zhi3 +0x9efa:fen3 +0x9efb:fu2 +0x9efc:fu3 +0x9efd:min3 +0x9efe:min3 +0x9eff:yuan2 +0x9f00:cu4 +0x9f01:qu4 +0x9f02:chao2 +0x9f03:wa1 +0x9f04:zhu1 +0x9f05:zhi1 +0x9f06:mang2 +0x9f07:ao2 +0x9f08:bie1 +0x9f09:tuo2 +0x9f0a:bi4 +0x9f0b:yuan2 +0x9f0c:chao2 +0x9f0d:tuo2 +0x9f0e:ding3 +0x9f0f:mi4 +0x9f10:nai4 +0x9f11:ding3 +0x9f12:zi1 +0x9f13:gu3 +0x9f14:gu3 +0x9f15:dong1 +0x9f16:fen2 +0x9f17:tao2 +0x9f18:yuan1 +0x9f19:pi2 +0x9f1a:chang1 +0x9f1b:gao1 +0x9f1c:qi4 +0x9f1d:yuan1 +0x9f1e:tang1 +0x9f1f:teng1 +0x9f20:shu3 +0x9f21:shu3 +0x9f22:fen2 +0x9f23:fei4 +0x9f24:wen2 +0x9f25:ba2 +0x9f26:diao1 +0x9f27:tuo2 +0x9f28:tong2 +0x9f29:qu2 +0x9f2a:sheng1 +0x9f2b:shi2 +0x9f2c:you4 +0x9f2d:shi2 +0x9f2e:ting2 +0x9f2f:wu2 +0x9f30:nian4 +0x9f31:jing1 +0x9f32:hun2 +0x9f33:ju2 +0x9f34:yan3 +0x9f35:tu2 +0x9f36:ti2 +0x9f37:xi1 +0x9f38:xian3 +0x9f39:yan3 +0x9f3a:lei2 +0x9f3b:bi2 +0x9f3c:yao3 +0x9f3d:qiu2 +0x9f3e:han1 +0x9f3f:wu1 +0x9f40:wu4 +0x9f41:hou1 +0x9f42:xi4 +0x9f43:ge2 +0x9f44:zha1 +0x9f45:xiu4 +0x9f46:weng4 +0x9f47:zha1 +0x9f48:nong2 +0x9f49:nang4 +0x9f4a:qi2 +0x9f4b:zhai1 +0x9f4c:ji4 +0x9f4d:zi1 +0x9f4e:ji1 +0x9f4f:ji1 +0x9f50:qi2 +0x9f51:ji1 +0x9f52:chi3 +0x9f53:chen4 +0x9f54:chen4 +0x9f55:he2 +0x9f56:ya2 +0x9f57:ken3 +0x9f58:xie4 +0x9f59:pao2 +0x9f5a:cuo4 +0x9f5b:shi4 +0x9f5c:zi1 +0x9f5d:chi1 +0x9f5e:nian4 +0x9f5f:ju3 +0x9f60:tiao2 +0x9f61:ling2 +0x9f62:ling2 +0x9f63:chu1 +0x9f64:quan2 +0x9f65:xie4 +0x9f66:ken3 +0x9f67:nie4 +0x9f68:jiu4 +0x9f69:yao3 +0x9f6a:chuo4 +0x9f6b:kun3 +0x9f6c:yu3 +0x9f6d:chu3 +0x9f6e:yi3 +0x9f6f:ni2 +0x9f70:cuo4 +0x9f71:zou1 +0x9f72:qu3 +0x9f73:nen3 +0x9f74:xian3 +0x9f75:ou2 +0x9f76:e4 +0x9f77:wo4 +0x9f78:yi4 +0x9f79:chuo1 +0x9f7a:zou1 +0x9f7b:dian1 +0x9f7c:chu3 +0x9f7d:jin4 +0x9f7e:ya4 +0x9f7f:chi3 +0x9f80:chen4 +0x9f81:he2 +0x9f82:ken3 +0x9f83:ju3 +0x9f84:ling2 +0x9f85:pao2 +0x9f86:tiao2 +0x9f87:zi1 +0x9f88:ken3 +0x9f89:yu3 +0x9f8a:chuo4 +0x9f8b:qu3 +0x9f8c:wo4 +0x9f8d:long2 +0x9f8e:pang2 +0x9f8f:gong1 +0x9f90:pang2 +0x9f91:yan3 +0x9f92:long2 +0x9f93:long2 +0x9f94:gong1 +0x9f95:kan1 +0x9f96:ta4 +0x9f97:ling2 +0x9f98:ta4 +0x9f99:long2 +0x9f9a:gong1 +0x9f9b:kan1 +0x9f9c:gui1 +0x9f9d:qiu1 +0x9f9e:bie1 +0x9f9f:gui1 +0x9fa0:yue4 +0x9fa1:chui4 +0x9fa2:he2 +0x9fa3:jue2 +0x9fa4:xie2 +0x9fa5:yu4 +0x9fc3:shan3 +0xf90e:la4 +0xfa0c:wu4 +0xfa0d:huo4 +0xfa10:zhong3 +0xfa12:qing2 +0xfa15:xi1 +0xfa16:zhu1 +0xfa17:yi4 +0xfa18:li3 +0xfa19:shen2 +0xfa1a:xiang2 +0xfa1b:fu2 +0xfa1c:jing4 +0xfa1d:jing1 +0xfa1e:yu3 +0xfa22:zhu1 +0xfa25:yi4 +0xfa26:du1 +0xfa2a:fan4 +0xfa2b:si4 +0xfa2c:guan3 +0xfa2d:he4 diff -Nru ukui-control-center-2.0.3/shell/res/dropArrow/search.svg ukui-control-center-3.0.3/shell/res/dropArrow/search.svg --- ukui-control-center-2.0.3/shell/res/dropArrow/search.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/dropArrow/search.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,14 @@ + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/i18n/bo_CN.ts ukui-control-center-3.0.3/shell/res/i18n/bo_CN.ts --- ukui-control-center-2.0.3/shell/res/i18n/bo_CN.ts 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/i18n/bo_CN.ts 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,5355 @@ + + + + + About + + + System Summary + + + + + + version + + /about/version + + + + TextLabel + + + + + Copyright 2009-2020 @ Kylinos All rights reserved + + + + + + Kernel + + /about/Kernel + + + + + CPU + + /about/CPU + + + + + Memory + + /about/Memory + + + + + + Disk + + /about/Disk + + + + Desktop + + + + + User + + + + + Active Status + + + + + Service serial number + + + + + Active + + + + + Trial version disclaimer + + + + + About + + + + + available + + + + + Inactivated + + + + + Activated + + + + + AddAppDialog + + + OK + + + + + Cancel + + + + + AddAutoBoot + + + Add AutoBoot + + + + + Add autoboot program + + + + + + Program name + + + + + + Program exec + + + + + Open + + + + + + Program comment + + + + + + Cancel + + + + + Certain + + + + + desktop file not exist + + + + + select autoboot desktop + + + + + Select + + + + + AppDetail + + + Dialog + + + + + TextLabel + + + + + Allow notification + + + + + Number of notification centers + + + + + cancel + + + + + confirm + + + + + Area + + + + Area + + + + + + current area + + /area/current area + + + + Area showing time currency format + + + + + Regional format data + + + + + + calendar + + + + + + lunar + + + + + First day of the week + + + + + + monday + + + + + + date + + + + + 2019/12/17 + + + + + + time + + + + + 9:52 + + + + + + change format of data + + + + + + TextLabel + + + + + + Need to log off to take effect + + + + + display format area + + + + + US + + + + + CN + + + + + format of area + + /area/format of area + + + + first day of week + + + + + first language + + /area/first language + + + + system language + + + + + English + + + + + Chinese + + + + + addwgt + + + + + Add main language + + + + + solar calendar + + + + + sunday + + + + + change data format + + + + + AreaCodeLineEdit + + + Sign up by Phone + + + + + Audio + + + + Audio + + + + + AutoBoot + + + + Autoboot Settings + + /autoboot/Autoboot Settings + + + + Add autoboot app + + + + + Auto Boot + + + + + Name + + + + + Status + + + + + Delete + + + + + Backup + + + + + Backup + + /backup/Backup + + + + Back up your files to other drives, and when the original files are lost, damaged, or deleted, +you can restore them to ensure the integrity of your system. + + + + + Begin backup + + + + + + Restore + + /backup/Restore + + + + View a list of backed-upfiles to restore backed up files to the system + + + + + Begin restore + + + + + BindPhoneDialog + + + Your code here + + + + + Get + + + + + BlueToothMain + + + + + Turn off Bluetooth + + + + + + + Turn on Bluetooth + + + + + Bluetooth + + + + + Show icon on taskbar + + + + + + Can now be found as + + + + + Other Devices + + + + + Refresh + + + + + Can now be found as " + + + + + " + + + + + Bluetooth + + + Bluetooth + + + + + CertificationDialog + + + + UserCertification + + + + + User: + + + + + Passwd: + + + + + Close + + + + + Certification + + + + + ChangeFaceDialog + + + Change User Face + + + + + Select face from local + + + + + select custom face file + + + + + Select + + + + + Position: + + + + + FileName: + + + + + FileType: + + + + + Cancel + + + + + Warning + + + + + The avatar is larger than 1M, please choose again + + + + + ChangeGroupDialog + + + Dialog + + + + + User Group Settings + + + + + User groups available in the system + + + + + User group + + + + + Add user group + + + + + + Tips + + + + + Invalid Id! + + + + + + OK + + + + + Invalid Group Name! + + + + + ChangePwdDialog + + + Change Pwd + + + + + Pwd type + + + + + Cur pwd + + + + + New pwd + + + + + New pwd sure + + + + + Cancel + + + + + Confirm + + + + + Change pwd + + + + + Cur pwd checking! + + + + + General Pwd + + + + + + Current Password + + + + + + + New Password + + + + + + + New Password Identify + + + + + + Inconsistency with pwd + + + + + Contains illegal characters! + + + + + Same with old pwd + + + + + ChangeTypeDialog + + + Change Account Type + + + + + Make sure that there is at least one administrator on the computer + + + + + standard user + + + + + Standard users can use most software, but cannot install software and change system settings + + + + + administrator + + + + + Administrators can make any changes they need + + + + + Cancel + + + + + Confirm + + + + + Change type + + + + + ChangeValidDialog + + + Dialog + + + + + Password Validity Setting + + + + + Current passwd validity: + + + + + Adjust date to: + + + + + Cancel + + + + + Certain + + + + + Change valid + + + + + ChangtimeDialog + + + time + + + + + year + + + + + month + + + + + day + + + + + ColorDialog + + + Dialog + + + + + B + + + + + Cancel + + + + + OK + + + + + R + + + + + G + + + + + Custom color + + + + + CreateGroupDialog + + + Dialog + + + + + Add New Group + + + + + Name + + + + + Id + + + + + Members + + + + + Cancel + + + + + Certain + + + + + Add user group + + + + + CreateUserDialog + + + Add New Account + + + + + + UserName + + + + + PwdType + + + + + + Password + + + + + PasswordSure + + + + + Account Type + + + + + standard user + + + + + Standard users can use most software, but cannot install the software and +change system settings + + + + + administrator + + + + + Administrators can make any changes they need + + + + + Cancel + + + + + Confirm + + + + + Add new user + + + + + Password Identify + + + + + General Password + + + + + + Inconsistency with pwd + + + + + Contains illegal characters! + + + + + The user name cannot be empty + + + + + The first character must be lowercase letters! + + + + + User name can not contain capital letters! + + + + + The user name is already in use, please use a different one. + + + + + The name corresponds to the group already exists. + + + + + User name length need to less than %1 letters! + + + + + The user name can only be composed of letters, numbers and underline! + + + + + The username is configured, please change the username + + + + + CustomLineEdit + + + New Shortcut... + + + + + DataFormat + + + Dialog + + + + + change format of data + + + + + + calendar + + + + + first day + + + + + + date + + + + + + time + + + + + cancel + + + + + confirm + + + + + first day of week + + + + + solar calendar + + + + + lunar + + + + + monday + + + + + sunday + + + + + DateTime + + + DateTime + + + + + current date + + + + + + + TextLabel + + + + + timezone + + + + + + Sync network time + + /datetime/Sync network time + + + + + Change time + + /datetime/Change time + + + + + Change time zone + + /datetime/Change time zone + + + + Sync complete + + + + + Dat + + + + + 24-hour clock + + /datetime/24-hour clock + + + + change time + + + + + DefaultApp + + + Default App + + + + + Browser + + /defaultapp/Browser + + + + Mail + + /defaultapp/Mail + + + + Image Viewer + + /defaultapp/Image Viewer + + + + Audio Player + + /defaultapp/Audio Player + + + + Video Player + + /defaultapp/Video Player + + + + Text Editor + + /defaultapp/Text Editor + + + + DefaultAppWindow + + + Select Default Application + + + + + Browser + + + + + Mail + + + + + Image Viewer + + + + + Audio Player + + + + + Video Player + + + + + Text Editor + + + + + Reset to default + + + + + DefineGroupItem + + + Edit + + + + + Delete + + + + + DefineShortcutItem + + + Delete + + + + + DelGroupDialog + + + Dialog + + + + + Delete + + + + + Cancel + + + + + Remind + + + + + Delete user group + + + + + Are you sure to delete the group, which will make some file components in the file system invalid! + + + + + DelUserDialog + + + Delete the user, belonging to the user's desktop, +documents, favorites, music, pictures and video +folder will be deleted! + + + + + Cancel + + + + + KeepFile + + + + + RemoveFile + + + + + Desktop + + + + Icon Show On Desktop + + /desktop/Icon Show On Desktop + + + + Computerdesktop + + + + + Trashdesktop + + + + + Homedesktop + + + + + Volumedesktop + + + + + Networkdesktop + + + + + Set Start Menu + + + + + Always use the start menu in full screen + + + + + Icon Lock on Menu + + + + + Computermenu + + + + + Settingmenu + + + + + Filesystemmenu + + + + + Trashmenu + + + + + + Tray icon + + /desktop/Tray icon + + + + Desktop + + + + + DeviceInfoItem + + + Connect + + + + + Disconnect + + + + + Remove + + + + + DisplayPerformanceDialog + + + Dialog + + + + + Display Advanced Settings + + + + + Performance + + + + + Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. + + + + + (Note: not support connect graphical with xmanager on windows.) + + + + + Compatible + + + + + Applicable to machine with integrated graphics, there is no 3D graphics acceleration. + + + + + (Note: need connect graphical with xmanager on windows, use this option.) + + + + + Automatic + + + + + Auto select according to environment, delay the login time (about 0.5 sec). + + + + + Threshold: + + + + + Apply + + + + + Reset + + + + + (Note: select this option to use 3D graphics acceleration and xmanager.) + + + + + DisplaySet + + + Display + + + + + DisplayWindow + + + Form + + + + + Display + + + + + monitor + + + + + set as home screen + + + + + open monitor + + + + + Advanced + + + + + unify output + + + + + screen brightness adjustment + + + + + dark + + + + + bright + + + + + follow the sunrise and sunset(17:55-05:04) + + + + + custom time + + + + + opening time + + + + + closing time + + + + + color temperature + + + + + warm + + + + + cold + + + + + apply + + + + + EditGroupDialog + + + Dialog + + + + + Cancel + + + + + Certain + + + + + Edit User Group + + + + + Name + + + + + Id + + + + + Members + + + + + Tips + + + + + Invalid Id! + + + + + OK + + + + + Edit user group + + + + + EditPassDialog + + + Edit Password + + + + + Your new password here + + + + + Your code + + + + + Get phone code + + + + + Cancel + + + + + Confirm + + + + + Confirm your new password + + + + + + + + At least 6 bit, include letters and digt + + + + + Your password is valid! + + + + + Please check your password! + + + + + Resend( + + + + + ) + + + + + + Send + + + + + Reback sign in + + + + + Error code: + + + + + ! + + + + + Internal error occurring! + + + + + Failed to sign up! + + + + + Failed attempt to return value! + + + + + Check your connection! + + + + + Failed to get by phone! + + + + + Failed to get by user! + + + + + Failed to reset password! + + + + + + + Please check your information! + + + + + Please check your account! + + + + + Failed due to server error! + + + + + User existing! + + + + + Phone number already in used! + + + + + Please check your format! + + + + + Your are reach the limit! + + + + + Please check your phone number! + + + + + Please check your code! + + + + + Account doesn't exist! + + + + + Sending code error occurring! + + + + + EditPushButton + + + Reset + + + + + ExperiencePlan + + + User Experience + + + + + Join in user Experience plan + + + + + User experience plan terms, see + + + + + 《User Experience plan》 + + + + + Experienceplan + + + + + Fonts + + + + Fonts + + + + + + + Font size + + /fonts/Font size + + + + + Fonts select + + /fonts/Fonts select + + + + + Monospace font + + + + + Advanced settings + + + + + Gtk default font + + + + + Document font + + + + + titlebar font + + + + + Select text sample that looks clearest + + + + + Reset to default + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 16 + + + + + Thanks For Using The ukcc + + + + + FrameItem + + + Sync failed, please login out to retry! + + + + + Change configuration file failed, please login out to retry! + + + + + Configuration file not exist, please login out to retry! + + + + + Cloud verifyed file download failed, please login out to retry! + + + + + OSS access failed, please login out to retry! + + + + + Sync failed, please retry or login out to get a better experience! + + + + + ItemList + + + Walpaper + + + + + ScreenSaver + + + + + Menu + + + + + Quick Start + + + + + Avatar + + + + + Tab + + + + + Font + + + + + Mouse + + + + + TouchPad + + + + + KeyBoard + + + + + ShortCut + + + + + Themes + + + + + Area + + + + + Date/Time + + + + + Default Open + + + + + Notice + + + + + Option + + + + + Peony + + + + + Weather + + + + + Media + + + + + Boot + + + + + Power + + + + + Editor + + + + + Terminal + + + + + KbPreviewFrame + + + No preview found + + + + + Unable to open Preview ! + + + + + KbdLayoutManager + + + C + + + + + L + + + + + Variant + + + + + Add + + + + + Add Layout + + + + + Del + + + + + Keyboard Preview + + + + + KeyValueConverter + + + System + + + + + Devices + + + + + Personalized + + + + + Network + + + + + Account + + + + + Datetime + + + + + Update + + + + + Messages + + + + + KeyboardControl + + + Keys Settings + + + + + + Enable repeat key + + /keyboard/Enable repeat key + + + + + Delay + + /keyboard/Delay + + + + Short + + + + + Long + + + + + + Speed + + /keyboard/Speed + + + + Slow + + + + + Fast + + + + + + Tip of keyboard + + /keyboard/Tip of keyboard + + + + Reset layout + + + + + Enable numlock + + + + + Input characters to test the repetition effect: + + + + + Keyboard Layout + + + + + + Keyboard layout + + /keyboard/Keyboard layout + + + + Input characters to test the repetition effect: + + /keyboard/Input characters to test the repetition effect: + + + + Install layouts + + + + + Keyboard + + + + + KeyboardPainter + + + Close + + + + + + Keyboard layout levels + + + + + + Level %1, %2 + + + + + LayoutManager + + + Dialog + + + + + Manager Keyboard Layout + + + + + Language + + + + + Country + + + + + Variant + + + + + Layout installed + + + + + Preview + + + + + Cancel + + + + + Install + + + + + LoginDialog + + + Forget + + + + + Send + + + + + User Sign in + + + + + Quick Sign in + + + + + + Your account/phone here + + + + + + Your code here + + + + + Your phone number here + + + + + Your password here + + + + + MCodeWidget + + + SongTi + + + + + MainDialog + + + + + + + + + + + Sign in + + + + + + + + + Sign up + + + + + Login in progress + + + + + Error code: + + + + + ! + + + + + Internal error occurred! + + + + + Failed to sign up! + + + + + Failed attempt to return value! + + + + + Check your connection! + + + + + Failed to get by phone! + + + + + Failed to get by user! + + + + + Failed to reset password! + + + + + Timeout! + + + + + Phone binding falied! + + + + + + + Please check your information! + + + + + Please check your account! + + + + + Failed due to server error! + + + + + User existing! + + + + + Phone number already in used! + + + + + Please check your format! + + + + + Your are reach the limit! + + + + + Please check your phone number! + + + + + Please check your code! + + + + + Account doesn't exist! + + + + + User has bound the phone! + + + + + Sending code error occurred! + + + + + Your code is wrong! + + + + + + + + + + Please check your phone! + + + + + + Please check your password! + + + + + + + + + Sign in Cloud + + + + + Forget + + + + + Set + + + + + + + Back + + + + + Create Account + + + + + Sign up now + + + + + + Please confirm your password! + + + + + + + + Resend ( %1 ) + + + + + + + Get + + + + + Get phone code + + + + + + + + + Send + + + + + Binding Phone + + + + + + + + Please make sure your password is safety! + + + + + Bind now + + + + + MainWidget + + + + + Your account:%1 + + + + + + + Exit + + + + + Sync + + + + + Sign in + + + + + Stop sync + + + + + Sync your settings + + + + + Your account:%1 + + + + + Auto sync + + + + + Synchronize your personalized settings and data + + + + + + + + The latest time sync is: + + + + + Unauthorized device or OSS falied. +Please retry for login! + + + + + Your account is sign on on other device already! + + + + + This operation may cover your settings! + + + + + %1, + + + + + Cloud ID desktop message + + + + + Disconnected + + + + + MainWindow + + + Search + + + + + + UKCC + + + + + Home + + + + + ukcc + + + + + MouseControl + + + Mouse Key Settings + + + + + + Hand habit + + /mouse/Hand habit + + + + Pointer Settings + + + + + + Speed + + /mouse/Speed + + + + + + Slow + + + + + mouse wheel speed + + + + + + + Fast + + + + + + Doubleclick delay + + /mouse/Doubleclick delay + + + + Short + + + + + Long + + + + + + Acceleration + + /mouse/Acceleration + + + + + Visibility + + /mouse/Visibility + + + + + Pointer size + + /mouse/Pointer size + + + + Cursor Settings + + + + + Cursor weight + + + + + Thin + + + + + Coarse + + + + + + Cursor speed + + /mouse/Cursor speed + + + + + Enable flashing on text area + + /mouse/Enable flashing on text area + + + + Mouse + + + + + Lefthand + + + + + Righthand + + + + + Default(Recommended) + + + + + Medium + + + + + Large + + + + + NetConnect + + + + Netconnect Status + + /netconnect/Netconnect Status + + + + Available Network + + + + + + Refresh + + + + + + open wifi + + /netconnect/open wifi + + + + + Network settings + + + + + Connect + + + + + + Refreshing... + + + + + connected + + + + + No network + + + + + Notice + + + Notice Settings + + + + + + Set the type of notice in the operation center + + /notice/Set the type of notice in the operation center + + + + Show new feature ater system upgrade + + + + + Get notifications from the app + + + + + Show notifications on the lock screen + + + + + + Notice Origin + + /notice/Notice Origin + + + + Notice + + + + + OutputConfig + + + resolution + + /display/resolution + + + + orientation + + + + + arrow-up + + + + + 90° arrow-right + + + + + arrow-down + + + + + 90° arrow-left + + + + + refresh rate + + + + + auto + + + + + 100% + + + + + 200% + + + + + screen zoom + + /display/screen zoom + + + + %1 Hz + + + + + PassDialog + + + Get the phone binding code + + + + + Your account here + + + + + Your new password here + + + + + Confirm your new password + + + + + Your code here + + + + + + At least 6 bit, include letters and digt + + + + + Your password is valid! + + + + + PinCodeWidget + + + Is it paired with " + + + + + " + + + + + Please make sure the number displayed on " + + + + + " matches the number below. Please do not enter this code on any other accessories. + + + + + Accept + + + + + Refush + + + + + Power + + + select power plan + + + + + + Balance (suggest) + + /power/Balance (suggest) + + + + Autobalance energy and performance with available hardware + + + + + + Saving + + /power/Saving + + + + Minimize performance + + + + + + Custom + + /power/Custom + + + + Users develop personalized power plans + + + + + Power supply + + + + + Battery powered + + + + + + + Change PC sleep time: + + + + + + + Change DP close time: + + + + + When close lid: + + + + + Screen darkens use battery: + + + + + Power Other Settings + + + + + S3 to S4 when: + + + + + Power icon: + + + + + Power + + + + + + + Enter idle state %1 min and sleep after %2 min : + + + + + + + Enter idle state %1 min and close after %2 min : + + + + + + + never + + + + + + + 10 min + + + + + + + 20 min + + + + + + 30 min + + + + + + 60 min + + + + + + 120 min + + + + + 300 min + + + + + + 1 min + + + + + + 5 min + + + + + nothing + + + + + blank + + + + + suspend + + + + + hibernate + + + + + shutdown + + + + + always + + + + + present + + + + + charge + + + + + Printer + + + + Add Printers And Scanners + + /printer/Add Printers And Scanners + + + + Add printers and scanners + + + + + List Of Existing Printers + + + + + Printer + + + + + Proxy + + + Auto Proxy + + + + + + Auto proxy + + /proxy/Auto proxy + + + + Auto url + + + + + Manual Proxy + + + + + + Manual proxy + + /proxy/Manual proxy + + + + Http Proxy + + + + + + + + Port + + + + + Cetification + + + + + Https Proxy + + + + + Ftp Proxy + + + + + Socks Proxy + + + + + List of ignored hosts. more than one entry, please separate with english semicolon(;) + + + + + Proxy + + + + + QObject + + + Add Shortcut + + + + + Update Shortcut + + + + + basic + + + + + classical + + + + + default + + + + + + Unknown + + + + + Display + + + + + Power + + + + + Default App + + + + + Auto Boot + + + + + Printer + + + + + Mouse + + + + + Touchpad + + + + + Keyboard + + + + + Shortcut + + + + + Audio + + + + + Bluetooth + + + + + Background + + + + + Theme + + + + + Screenlock + + + + + Fonts + + + + + Screensaver + + + + + Desktop + + + + + Connect + + + + + Vino + + + + + User Info + + + + + Dat + + + + + Security Center + + + + + Vpn + + + + + Proxy + + + + + Cloud Account + + + + + Area + + + + + Update + + + + + Backup + + + + + Notice + + + + + About + + + + + Experienceplan + + + + + + Never + + + + + May + + + + + January + + + + + February + + + + + March + + + + + April + + + + + June + + + + + July + + + + + August + + + + + September + + + + + October + + + + + Novermber + + + + + December + + + + + min length %1 + + + + + + min digit num %1 + + + + + + min upper num %1 + + + + + + min lower num %1 + + + + + + min other num %1 + + + + + + min char class %1 + + + + + + max repeat %1 + + + + + + max class repeat %1 + + + + + + max sequence %1 + + + + + + ukui-control-center is already running! + + + + + + Pwd input error, re-enter! + + + + + PulseAudio Volume Control + + + + + Connection to PulseAudio failed. Automatic retry in 5s + +In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties +or default-server in client.conf is misconfigured. +This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window. +If this is the case, then PulseAudio should autospawn again, or if this is not configured you should +run start-pulseaudio-x11 manually. + + + + + pa_context_subscribe() failed + + + + + Failed to initialize stream_restore extension: %s + + + + + pa_ext_stream_restore_read() failed + + + + + Error + + + + + Go to monitor settings page + + + + + Go to defaultapp settings page + + + + + Go to power settings page + + + + + Go to autoboot settings page + + + + + Go to printer settings page + + + + + Go to mouse settings page + + + + + Go to touchpad settings page + + + + + Go to keyboard settings page + + + + + Go to shortcut settings page + + + + + Go to audio settings page + + + + + Go to background settings page + + + + + Go to theme settings page + + + + + Go to screenlock settings page + + + + + Go to screensaver settings page + + + + + Go to fonts settings page + + + + + Go to desktop settings page + + + + + Go to netconnect settings page + + + + + Go to vpn settings page + + + + + Go to proxy settings page + + + + + Go to userinfo settings page + + + + + Go to cloudaccount settings page + + + + + Go to datetime settings page + + + + + Go to area settings page + + + + + Go to update settings page + + + + + Go to backup settings page + + + + + Go to notice settings page + + + + + Go to about settings page + + + + + RegDialog + + + Get + + + + + Your password here + + + + + Your account here + + + + + Confirm your password + + + + + Your code here + + + + + This operation is permanent + + + + + + At least 6 bit, include letters and digt + + + + + Your password is valid! + + + + + ResolutionSlider + + + No available resolutions + + + + + Screenlock + + + + Screenlock + + + + + Screenlock Interface + + + + + Screenlock Set + + + + + + Show picture of screenlock on screenlogin + + /screenlock/Show picture of screenlock on screenlogin + + + + + Lock screen when screensaver boot + + /screenlock/Lock screen when screensaver boot + + + + Lock screen delay + + + + + Select screenlock background + + + + + Browser online wp + + + + + Browser local wp + + + + + 5m + + + + + 10m + + + + + 30m + + + + + 45m + + + + + 1m + + + + + 1h + + + + + 1.5h + + + + + 3h + + + + + Screensaver + + + + Screensaver + + + + + + Enable screensaver + + /screensaver/Enable screensaver + + + + + Screensaver program + + /screensaver/Screensaver program + + + + + idle time + + /screensaver/idle time + + + + Lock screen when screensaver boot + + + + + Default_ukui + + + + + Blank_Only + + + + + 5m + + + + + 10m + + + + + 30m + + + + + 45m + + + + + 1m + + + + + 1h + + + + + 1.5h + + + + + 3h + + + + + SecurityCenter + + + SecurityCenter + + + + + Summarize + + + + + Recognize the current security of the system, and can take the necessary settings + + + + + Run Security Center + + + + + Security Center + + + + + Virus Protection + + + + + Protect system from threats + + + + + Network Protection + + + + + Setup app that can access web + + + + + App Execution Control + + + + + App install and exe protection + + + + + Account Security + + + + + Protect account and login security + + + + + ShareMain + + + Share + + + + + Allow others to view your desktop + + + + + Allow connection to control screen + + + + + Security + + + + + You must confirm every visit for this machine + + + + + Require user to enter this password: + + + + + Shortcut + + + + System Shortcut + + /shortcut/System Shortcut + + + + Show all shortcut + + + + + Reset default + + + + + + Custom Shortcut + + /shortcut/Custom Shortcut + + + + Add custom shortcut + + /shortcut/Add custom shortcut + + + + + disable + + + + + Shortcut + + + + + ShowAllShortcut + + + Dialog + + + + + System Shortcuts + + + + + Show all shortcut + + + + + + Desktop + + + + + SuccessDiaolog + + + Reback sign in + + + + + Sign up success! + + + + + + + + Confirm + + + + + Reset success! + + + + + Sign in success! + + + + + Binding phone success! + + + + + Theme + + + + Theme Mode + + /theme/Theme Mode + + + + + Icon theme + + /theme/Icon theme + + + + Control theme + + + + + + Cursor theme + + /theme/Cursor theme + + + + Effect setting + + + + + + Performance mode + + /theme/Performance mode + + + + + Transparency + + /theme/Transparency + + + + Reset to default + + + + + Theme + + + + + Default + + + + + Light + + + + + Dark + + + + + TimeZoneChooser + + + Cancel + + + + + Confirm + + + + + Change time zone + + + + + + change timezone + + + + + Touchpad + + + + Touchpad Settings + + /touchpad/Touchpad Settings + + + + Enabled touchpad + + + + + Disable touchpad while typing + + + + + Enable mouse clicks with touchpad + + + + + Scrolling + + + + + No touchpad found + + + + + Touchpad + + + + + Disable rolling + + + + + Vertical edge scrolling + + + + + Horizontal edge scrolling + + + + + Vertical two-finger scrolling + + + + + Horizontal two-finger scrolling + + + + + UkmediaInputWidget + + + Input + + + + + Input Device + + /audio/Input Device + + + + Volume + + /audio/Volume + + + + Input Level + + /audio/Input Level + + + + Low + + + + + High + + + + + Connector + + + + + UkmediaMainWidget + + + sound error + + + + + load sound failed + + + + + Establishing connection to PulseAudio. Please wait... + + + + + pa_ext_stream_restore_write() failed + + + + + UkmediaOutputWidget + + + Output + + + + + Output Device + + /audio/Output Device + + + + Master Volume + + /audio/Master Volume + + + + Balance + + /audio/Balance + + + + Right + + + + + Connector + + + + + Profile + + /audio/Profile + + + + Card + + /audio/Card + + + + Left + + + + + UkmediaSoundEffectsWidget + + + System Sound + + /audio/System Sound + + + + Sound Theme + + /audio/Sound Theme + + + + Alert Sound + + /audio/Alert Sound + + + + Alert Volume + + /audio/Alert Volume + + + + Boot Music + + /audio/Boot Music + + + + Beep Switch + + /audio/Beep Switch + + + + Window Closed + + + + + Volume Change + + + + + Setting Menu + + + + + UnifiedOutputConfig + + + resolution + + + + + orientation + + + + + arrow-up + + + + + 90° arrow-right + + + + + arrow-down + + + + + 90° arrow-left + + + + + refresh rate + + + + + auto + + + + + Update + + + + Update + + + + + + System Update + + /update/System Update + + + + Last check time: + + + + + Check for updates + + + + + UserInfo + + + Current User + + + + + + + Change pwd + + /userinfo/Change pwd + + + + + + Change type + + /userinfo/Change type + + + + + Change valid + + /userinfo/Change valid + + + + User group + + + + + + Login no passwd + + /userinfo/Login no passwd + + + + + enable autoLogin + + /userinfo/enable autoLogin + + + + Currently in Live mode, please create a new user and log out + + + + + Other Users + + + + + Add new user + + + + + User Info + + + + + standard user + + + + + administrator + + + + + root + + + + + Delete + + + + + Warning + + + + + The user is logged in, please delete the user after logging out + + + + + Vino + + + + Vino + + + + + Vpn + + + Add Vpn Connect + + + + + Add vpn connect + + /vpn/Add vpn connect + + + + Vpn + + + + + Wallpaper + + + Desktop Background + + + + + + Select from + + /wallpaper/Select from + + + + Picture options + + + + + + Browser online wp + + /wallpaper/Browser online wp + + + + + Browser local wp + + /wallpaper/Browser local wp + + + + + Reset to default + + /wallpaper/Reset to default + + + + + + Cancel + + + + + Ok + + + + + Background + + + + + picture + + + + + color + + + + + Custom color + + + + + wallpaper + + + + + centered + + + + + scaled + + + + + stretched + + + + + zoom + + + + + spanned + + + + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + + + + + allFiles(*.*) + + + + + + select custom wallpaper file + + + + + + Select + + + + + + Position: + + + + + + FileName: + + + + + + FileType: + + + + + Widget + + + unify output + + /display/unify output + + + + night mode + + /display/night mode + + + + Some applications need to be logouted to take effect + + + + + Information + + + + + Theme follow night mode + + + + + Hint + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after 10 seconds + + + + + Save Config + + + + + Restore Config + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after %1 seconds + + + + + please insure at least one output! + + + + + + Warning + + + + + Morning time should be earlier than evening time! + + + + + Sorry, your configuration could not be applied. +Common reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU. + + + + + @title:window + Unsupported Configuration + + + + + addShortcutDialog + + + Dialog + + + + + Shortcut name + + + + + Shortcut exec + + + + + Open + + + + + Invalid executable, please re-enter + + + + + + Cancel + + + + + Certain + + + + + Add custom shortcut + + + + + select desktop + + + + + changtimedialog + + + Dialog + + + + + current date + + + + + time + + + + + year + + + + + month + + + + + day + + + + + cancel + + + + + confirm + + + + + networkaccount + + + Cloud Account + + + + diff -Nru ukui-control-center-2.0.3/shell/res/i18n/bo.qm ukui-control-center-3.0.3/shell/res/i18n/bo.qm --- ukui-control-center-2.0.3/shell/res/i18n/bo.qm 2020-05-14 07:08:48.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/i18n/bo.qm 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - - + + version + /about/version - - TextLabel - - - - - Copyright 2009-2020 @ Kylinos All rights reserved + + Copyright 2009-2021 @ Kylinos All rights reserved - + + Kernel + /about/Kernel - + + CPU + /about/CPU - + + Memory + /about/Memory - + Disk - + Desktop - + User - + Active Status - - Service serial number + + Serial - - Active + + Protocol - - Trial version disclaimer + + Active - + About - - Disk One: - - - - - Disk Two: - - - - - available + + The system has expired. The expiration time is: - + Inactivated - + Activated @@ -125,45 +118,64 @@ - + Add autoboot program - + + Program name - + + Program exec - + Open - + + Program comment - + + Cancel - + Certain - + + desktop file not exist + + + + select autoboot desktop + + + Desktop files(*.desktop) + + + + + Select + + AppDetail @@ -173,184 +185,340 @@ - - TextLabel + + App - + Allow notification - + Number of notification centers - + cancel - + confirm + AppUpdateWid + + + Lack of local disk space! + + + + + + + + + + Update + + + + + Network abnormal! + + + + + + Download failed! + + + + + failed to get from the source! + + + + + The download cache has been removed + + + + + + + Ready to install + + + + + Being installed + + + + + + Update succeeded! + + + + + + Update failed! + + + + + Failure reason: + + + + + + details + + + + + + Update log + + + + + + + + Newest: + + + + + + Download size: + + + + + Current version: + + + + + back + + + + + A single update will not automatically backup the system, if you want to backup, please click Update All. + + + + + Prompt information + + + + + Do not backup, continue to update + + + + + + Cancel + + + + + Cancel update + + + + + This time will no longer prompt + + + + + In the pause + + + + + + Get depends failed! + + + + + In the update + + + + + No content. + + + + Area - + Area - + current area + /area/current area - + Area showing time currency format - + Regional format data - - + + calendar - - + + lunar - + First day of the week - - + + monday - - + + date - + 2019/12/17 - - + + time - + 9:52 - - + + change format of data - - - TextLabel - - - - + + Need to log off to take effect - - display format area + + US - - US + + CN - - CN + + first day of week - - format of area + + + first language + /area/first language - - first day of week + + + system language - - first language + + country - - system language + + regional format + /area/regional format - + English - + Chinese - + addwgt - + Add main language - + solar calendar - + sunday - + change data format @@ -367,7 +535,7 @@ Audio - + Audio @@ -376,37 +544,46 @@ AutoBoot + Autoboot Settings + /autoboot/Autoboot Settings - + Add autoboot app - - Autoboot + + Auto Boot - + Name - + Status + + + Delete + + Backup - + + Backup + /backup/Backup @@ -415,22 +592,24 @@ - + Begin backup - + + Restore + /backup/Restore - - View a list of backed-upfiles to restore backed up files to the system + + View a list of backed-upfiles to backed up files to the system - + Begin restore @@ -444,3116 +623,4599 @@ - Get phone code + Get - CertificationDialog + BiometricEnrollDialog - - - UserCertification + + Bluetooth - - - User: + + Dialog - - Passwd: + + Biometrics - - Close + + Continue to enroll - - Certification + + Finish - - - ChangeFaceDialog - - Change User Face + + FingerPrint - - Select face from local + + Fingervein - - select custom face file + + Iris - - Select + + Face - - Position: + + VoicePrint - - FileName: + + Enroll - - FileType: + + Verify - - Cancel + + Search - - Warning + + Permission is required. +Please authenticate yourself to continue - - The avatar is larger than 2M, please choose again + + + Enroll successfully - - - ChangePwdDialog - - Change Pwd + + + Verify successfully - - Pwd type + + Not Match - - New pwd + + D-Bus calling error - - New pwd sure + + Device is busy - - Cancel + + No such device - - Confirm + + Permission denied + + + BiometricMoreInfoDialog - - General Pwd + + Dialog - - - New Password + + Biometrics - - - New Password Identify + + Default device - - - Inconsistency with pwd + + Verify Type: - - Password length needs to more than %1 character! + + Bus Type: - - Password length needs to less than %1 character! + + Device Status: - - - ChangeTypeDialog - - Change Account Type + + Storage Type: - - Make sure that there is at least one administrator on the computer + + Identification Type: - - standard user + + Connected - - Standard users can use most software, but cannot install software and change system settings + + Unconnected - - administrator + + FingerPrint - - Administrators can make any changes they need + + Fingervein - - Cancel + + Iris - - Confirm + + Face - - - ChangeValidDialog - - Dialog + + VoicePrint - - Password Validity Setting + + Hardware Verification - - Current passwd validity: + + Software Verification - - Adjust date to: + + Mix Verification - - Cancel + + Other Verification - - Certain + + Device Storage - - - ChangtimeDialog - - time + + OS Storage - - - year + + Mix Storage - - - month + + Serial - - day + + USB - - - ColorDialog - - Dialog + + PCIE - - B + + Any - - Cancel + + Other - - OK + + Hardware Identification - - R + + Software Identification - - G + + Mix Identification - - Custom color + + Other Identification - CreateUserDialog + BlueToothMain - - Add New Account + + Bluetooth + + + Bluetooth - - - UserName + + Bluetooth + + + BluetoothNameLabel - - PwdType + + + Can now be found as + + + CertificationDialog - - - Password + + + UserCertification - - PasswordSure + + User: - - Account Type + + Passwd: - - standard user - - - - - Standard users can use most software, but cannot install the software and -change system settings - - - - - administrator - - - - - Administrators can make any changes they need - - - - - Cancel + + Close - - Confirm + + Certification + + + ChangeFaceDialog - - Password Identify + + Change User Face - - General Password + + System Icon - - - Inconsistency with pwd + + Select face from local - - Password length needs to more than %1 character! + + Save - - Password length needs to less than %1 character! + + select custom face file - - The user name cannot be empty + + Select - - The first character must be lowercase letters! + + Position: - - User name can not contain capital letters! + + FileName: - - The user name is already in use, please use a different one. + + FileType: - - User name length need to less than %1 letters! + + + Cancel - - The user name can only be composed of letters, numbers and underline! + + Warning - - The username is configured, please change the username + + The avatar is larger than 1M, please choose again - DataFormat + ChangeGroupDialog - + Dialog - - change format of data + + User Group Settings - - - calendar + + Cancel - - first day + + User group - - - date + + Add user group - - - time + + + Tips - - cancel + + Invalid Id! - - confirm + + + OK - - first day of week + + Invalid Group Name! + + + ChangePwdDialog - - solar calendar + + Change Pwd - - lunar + + Pwd type - - monday + + Cur pwd - - sunday + + New pwd - - - DateTime - - DateTime + + New pwd sure - - current date + + Cancel - - - - TextLabel + + Confirm - - timezone + + Change pwd - - - Sync system time + + General Pwd - - - Change time + + + Current Password - - - Change time zone + + + + New Password - - Sync complete + + + + New Password Identify - - Datetime + + Pwd input error, re-enter! - - 24-hour clock + + + Inconsistency with pwd - - change time + + Contains illegal characters! - - - DefaultApp - - Defaultapp + + Same with old pwd - DefaultAppWindow + ChangeTypeDialog - - Select Default Application + + Change Account Type - - Browser + + Make sure that there is at least one administrator on the computer - - Mail + + standard user - - Image Viewer + + Standard users can use most software, but cannot install software and change system settings - - Audio Player + + administrator - - Video Player + + Administrators can make any changes they need - - Text Editor + + Cancel - - - DefineShortcutItem - - Delete + + Confirm - - - DelUserDialog - - Delete the user, belonging to the user's desktop, -documents, favorites, music, pictures and video -folder will be deleted! + + Change type + + + ChangeValidDialog - - Cancel + + Dialog - - KeepFile + + Password Validity Setting - - RemoveFile + + Current passwd validity: - - - Desktop - - Icon Show On Desktop + + Adjust date to: - - Computerdesktop + + Cancel - - Trashdesktop + + Certain - - Homedesktop + + Change valid + + + ChangtimeDialog - - Volumedesktop + + time - - Networkdesktop + + year - - Set Start Menu + + month - - Always use the start menu in full screen + + day + + + ColorDialog - - Icon Lock on Menu + + Dialog - - Computermenu + + B - - Settingmenu + + Cancel - - Filesystemmenu + + OK - - Trashmenu + + R - - Tray icon + + G - - Desktop + + Custom color - DisplayPerformanceDialog + CreateGroupDialog - + Dialog - - Display Advanced Settings + + Add New Group - - Performance + + Name - - Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. + + Id - - (Note: not support connect graphical with xmanager on windows.) + + Members - - Compatible + + Cancel - - Applicable to machine with integrated graphics, there is no 3D graphics acceleration. + + Certain - - (Note: need connect graphical with xmanager on windows, use this option.) + + Add user group + + + CreateUserDialog - - Automatic + + Add New Account - - Auto select according to environment, delay the login time (about 0.5 sec). + + + UserName - - Threshold: + + PwdType - - Apply + + + Password - - Reset + + PasswordSure - - (Note: select this option to use 3D graphics acceleration and xmanager.) + + Account Type - - - DisplaySet - - Display + + standard user - - - DisplayWindow - - Form + + Standard users can use most software, but cannot install the software and +change system settings - - monitor + + administrator - - set as home screen + + Administrators can make any changes they need - - open monitor + + Cancel - - Advanced + + Confirm - - unify output + + Add new user - - screen brightness adjustment + + Password Identify - - dark + + General Password - - bright + + + Inconsistency with pwd - - follow the sunrise and sunset(17:55-05:04) + + Contains illegal characters! - - custom time + + The user name cannot be empty - - opening time + + The first character must be lowercase letters! - - closing time + + User name can not contain capital letters! - - color temperature + + The user name is already in use, please use a different one. - - warm + + The name corresponds to the group already exists. - - cold + + User name length need to less than %1 letters! - - apply + + The user name can only be composed of letters, numbers and underline! + + + + + The username is configured, please change the username - EditPassDialog + CustomLineEdit - - Edit Password - - - - - Your new password here + + New Shortcut... + + + DataFormat - - Your code + + Dialog - - Get phone code + + change format of data - - Cancel + + + calendar - - Confirm + + first day - - Confirm your new password + + + date - - - - - At least 6 bit, include letters and digt + + + time - - Your password is valid! + + cancel - - Please check your password! + + confirm - - Resend( + + first day of week - - ) + + solar calendar - - - Send + + lunar - - Reback sign in + + monday - - Error code: + + sunday + + + DateTime - - ! + + DateTime - - Internal error occurring! + + current date - - Failed to sign up! + + timezone - - Failed attempt to return value! + + + Sync from network + /date/Sync from network - - Check your connection! + + + Change time + /date/Change time - - Failed to get by phone! + + + Change time zone + /date/Change time zone - - Failed to get by user! + + Sync complete - - Failed to reset password! + + Date - - - - Please check your information! + + 24-hour clock + /date/24-hour clock - - Please check your account! + + change time + + + DefaultApp - - Failed due to server error! + + Default App - - User existing! + + Browser + /defaultapp/Browser - - Phone number already in used! + + Mail + /defaultapp/Mail - - Please check your format! + + Image Viewer + /defaultapp/Image Viewer - - Your are reach the limit! + + Audio Player + /defaultapp/Audio Player - - Please check your phone number! + + Video Player + /defaultapp/Video Player - - Please check your code! + + Text Editor + /defaultapp/Text Editor + + + DefaultAppWindow - - Account doesn't exist! + + Select Default Application - - Sending code error occurring! + + Browser - - - EditPushButton - - Reset + + Mail - - - ExperiencePlan - - User Experience + + Image Viewer - - Join in user Experience plan + + Audio Player - - User experience plan terms, see + + Video Player - - 《User Experience plan》 + + Text Editor - - Experienceplan + + Reset to default - Fonts + DefineGroupItem - - - Fonts + + Edit - - Font size + + Delete + + + DefineShortcutItem - - Fonts select + + Delete + + + DelGroupDialog - - - Monospace font + + Dialog - - Advanced settings + + TextLabel - - Gtk default font + + Delete - - Document font + + Cancel - - Peony font + + Delete user group - - titlebar font + + Are you sure to delete the group, which will make some file components in the file system invalid! + + + DelUserDialog - - Select text sample that looks clearest + + keep the user's data, like desktop,documents, favorites, music, pictures and so on - - Reset to default + + delete whole data belong user - - 11 + + Cancel - - 12 + + Delete - - 13 + + Delete the user ' - - 14 + + 'and: + + + Desktop - - 15 + + + Icon Show On Desktop + /desktop/Icon Show On Desktop - - 16 + + Computerdesktop - - 17 + + Trashdesktop - - 18 + + Homedesktop - - Thanks For Using The ukcc + + Volumedesktop - - - ItemList - - Walpaper + + Networkdesktop - - ScreenSaver + + Set Start Menu - - Menu + + Always use the start menu in full screen - - Quick Start + + Icon Lock on Menu - - Tab + + Computermenu - - Weather + + Settingmenu - - Media + + Filesystemmenu - - - KbdLayoutManager - - C + + Trashmenu - - L + + + Tray icon + /desktop/Tray icon - - Variant + + Desktop + + + DeviceInfoItem - - Add + + Connect - - Add Layout + + Disconnect - - Del + + Remove - KeyValueConverter + DeviceType - - System + + FingerPrint - - Devices + + FingerVein - - Personalized + + Iris - - Network + + Face - - Account + + VoicePrint + + + DisplayPerformanceDialog - - Datetime + + Dialog - - Update + + Display Advanced Settings - - Messages + + Performance - - - KeyboardControl - - Keys Settings + + Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. - - Enable repeat key + + (Note: not support connect graphical with xmanager on windows.) - - Delay + + Compatible - - Short + + Applicable to machine with integrated graphics, there is no 3D graphics acceleration. - - Long + + (Note: need connect graphical with xmanager on windows, use this option.) - - Speed + + Automatic - - Slow + + Auto select according to environment, delay the login time (about 0.5 sec). - - Fast + + Threshold: - - Test repetition rate of the input character: + + Apply - - Tip of keyboard + + Reset - - reset default layout + + (Note: select this option to use 3D graphics acceleration and xmanager.) + + + DisplaySet - - Reset layout + + Display + + + DisplayWindow - - Enable numlock + + Form - - Keyboard Layout + + Display - - Keyboard layout + + monitor - - Install layouts + + set as home screen - - Keyboard + + open monitor + + + + + Advanced + + + + + unify output + + + + + screen brightness adjustment + + + + + dark + + + + + bright + + + + + follow the sunrise and sunset(17:55-05:04) + + + + + custom time + + + + + opening time + + + + + closing time + + + + + color temperature + + + + + warm + + + + + cold + + + + + apply - LayoutManager + EditGroupDialog - + Dialog - - Manager Keyboard Layout + + Cancel - - Language + + Certain - - Country + + Edit User Group - - Variant + + Name - - Layout installed + + Id - - Preview + + Members - - Cancel + + Tips - - Install + + Invalid Id! + + + + + OK + + + + + Edit user group - LoginDialog + EditPushButton - - Forget + + Reset + + + ExperiencePlan - - Send + + User Experience - - User Sign in + + Join in user Experience plan - - Quick Sign in + + User experience plan terms, see - - - Your account here + + 《User Experience plan》 - - - Your code here + + Experienceplan + + + Fonts - - Your phone number here + + + Fonts - - Your password here + + + + Font size + + /fonts/Font size + + + + + Fonts select + + /fonts/Fonts select + + + + Monospace font + + + + + Advanced settings + + + + + Mono font + + + + + Gtk default font + + + + + Document font + + + + + titlebar font + + + + + Select text sample that looks clearest + + + + + Reset to default + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 16 + + + + + Thanks For Using The ukcc - MCodeWidget + FrameItem - - SongTi + + + Sync failed,please relogin! + + + + + Change configuration file failed,please relogin! + + + + + Configuration file not exist,please relogin! + + + + + Cloud verifyed file download failed,please relogin! + + + + + OSS access failed,please relogin! - MainDialog + HistoryUpdateListWig - - - - - - - - - Sign in + + Success - - - - - - Sign up + + Failed + + + ItemList - - Login in progress + + ScreenSaver - - Error code: + + Menu - - ! + + Quick Start - - Internal error occurring! + + Avatar - - Failed to sign up! + + Tab - - Failed attempt to return value! + + Font - - Check your connection! + + Wallpaper - - Failed to get by phone! + + Mouse - - Failed to get by user! + + TouchPad - - Failed to reset password! + + KeyBoard - - Phone binding falied! + + ShortCut - - - - Please check your information! + + Themes - - Please check your account! + + Area - - Failed due to server error! + + Date/Time + + + + + Default Open + + + + + Notice + + + + + Option + + + + + Peony + + + + + Weather + + + + + Media + + + + + Boot + + + + + Power + + + + + Editor + + + + + Terminal + + + + + KbPreviewFrame + + + No preview found + + + + + Unable to open Preview ! + + + + + KbdLayoutManager + + + C + + + + + L + + + + + Variant + + + + + Add + + + + + Add Layout + + + + + Del + + + + + Keyboard Preview + + + + + KeyValueConverter + + + System + + + + + Devices + + + + + Personalized + + + + + Network + + + + + Account + + + + + Datetime + + + + + Update + + + + + Messages + + + + + KeyboardControl + + + Keys Settings + + + + + + Enable repeat key + + /keyboard/Enable repeat key + + + + + Delay + + /keyboard/Delay + + + + Short + + + + + Long + + + + + + Speed + + /keyboard/Speed + + + + Slow + + + + + Fast + + + + + + Tip of keyboard + + /keyboard/Tip of keyboard + + + + Input Settings + + + + + Input Set + + + + + Enable numlock + + + + + Input characters to test the repetition effect: + + + + + + Keyboard layout + + /keyboard/Keyboard layout + + + + Input characters to test the repetition effect: + + /keyboard/Input characters to test the repetition effect: + + + + Keyboard + + + + + KeyboardPainter + + + Close + + + + + + Keyboard layout levels + + + + + + Level %1, %2 + + + + + LayoutManager + + + Dialog + + + + + Manager Keyboard Layout + + + + + Language + + + + + Country + + + + + Variant + + + + + Layout installed + + + + + Preview + + + + + Cancel + + + + + Install + + + + + LoginDialog + + + Forget + + + + + Send + + + + + User Sign in + + + + + Quick Sign in + + + + + Your account/phone here + + + + + + Your code here + + + + + Your phone number here + + + + + Your account/phone/email here + + + + + Your password here + + + + + MCodeWidget + + + SongTi + + + + + MainDialog + + + + + + + + + Sign in + + + + + Sign up + + + + + Login in progress + + + + + Error code: + + + + + ! + + + + + Internal error occurred! + + + + + Failed to sign up! + + + + + Failed attempt to return value! + + + + + Check your connection! + + + + + Failed to get by phone! + + + + + Failed to get by user! + + + + + Failed to reset password! + + + + + Timeout! + + + + + Phone binding falied! + + + + + + Please check your information! + + + + + Please check your account! + + + + + Failed due to server error! + + + + + User and passsword can't be empty! + + + + + User existing! + + + + + User doesn't exist! + + + + + Network can not reach! + + + + + Phone can't be empty! + + + + + Account or password error! + + + + + Phone number already in used! + + + + + Please check your format! + + + + + Your are reach the limit! + + + + + Please check your phone number! + + + + + Please check your code! + + + + + Account doesn't exist! + + + + + User has bound the phone! + + + + + Sending code error occurred! + + + + + Phone code is expired! + + + + + Phone code error! + + + + + Code can not be empty! + + + + + MCode can not be empty! + + + + + Your code is wrong! + + + + + + Please check your phone! + + + + + + Sign in Cloud + + + + + Resend ( %1 ) + + + + + Get + + + + + MainWidget + + + Your account:%1 + + + + + + + Exit + + + + + Sync + + + + + Sign in + + + + + + + Waiting for initialization... + + + + + + + + + + + + + + + + + Network can not reach! + + + + + Logout failed,please check your connection + + + + + Waitting for sync! + + + + + Stop sync + + + + + Sync your settings + + + + + Your account:%1 + + + + + Auto sync + + + + + Synchronize your personalized settings and data + + + + + The Cloud Account Service version is out of date! + + + + + KylinID open error! + + + + + Unauthorized device or OSS falied. +Please retry or relogin! + + + + + Authorization failed! + + + + + + + + + + + The latest time sync is: + + + + + This operation may cover your settings! + + + + + %1, + + + + + Cloud ID desktop message + + + + + + Disconnected + + + + + MainWindow + + + Search + + + + + + Settings + + + + + Main menu + + + + + Minimize + + + + + Maximize/Normal + + + + + Close + + + + + Help + + + + + About + + + + + Exit + + + + + Home + + + + + ukcc + + + + + Warnning + + + + + This function has been controlled + + + + + MouseControl + + + Mouse Key Settings + + + + + + Hand habit + + /mouse/Hand habit + + + + Pointer Settings + + + + + + Speed + + /mouse/Speed + + + + + + Slow + + + + + mouse wheel speed + + + + + + + Fast + + + + + + Doubleclick delay + + /mouse/Doubleclick delay + + + + Short + + + + + Long + + + + + + Acceleration + + /mouse/Acceleration + + + + + Visibility + + /mouse/Visibility + + + + + Pointer size + + /mouse/Pointer size + + + + Cursor Settings + + + + + Cursor weight + + + + + Thin + + + + + Coarse + + + + + + Cursor speed + + /mouse/Cursor speed + + + + + Enable flashing on text area + + /mouse/Enable flashing on text area + + + + Mouse + + + + + Lefthand + + + + + Righthand + + + + + Default(Recommended) + + + + + Medium + + + + + Large + + + + + NetConnect + + + + Netconnect Status + + /netconnect/Netconnect Status + + + + Available Network + + + + + + Refresh + + + + + + open wifi + + /netconnect/open wifi + + + + + Network settings + + + + + + Connect + + + + + + Refreshing... + + + + + connected + + + + + No network + + + + + Notice + + + Notice Settings + + + + + + Set notice type of operation center + + /notice/Set notice type of operation center + + + + Show new feature ater system upgrade + + + + + Get notifications from the app + + + + + Show notifications on the lock screen + + + + + + Notice Origin + + /notice/Notice Origin + + + + Notice + + + + + OutputConfig + + + resolution + + /display/resolution + + + + orientation + + + + + arrow-up + + + + + 90° arrow-right + + + + + arrow-down + + + + + frequency + + + + + 90° arrow-left + + + + + auto + + + + + 100% + + + + + 200% + + + + + screen zoom + + /display/screen zoom + + + + %1 Hz + + + + + PassDialog + + + Get the phone binding code + + + + + Your account here + + + + + Your new password here + + + + + Confirm your new password + + + + + Your code here + + + + + + At least 6 bit, include letters and digt + + + + + Your password is valid! + + + + + Power + + + select power plan + + + + + + Balance (suggest) + + /power/Balance (suggest) + + + + Autobalance energy and performance with available hardware + + + + + + Saving + + /power/Saving + + + + Minimize performance + + + + + + Custom + + /power/Custom + + + + Users develop personalized power plans + + + + + Power supply + + + + + Battery powered + + + + + + + Change PC sleep time: + + + + + + + Change DP close time: + + + + + When close lid: + + + + + Screen darkens use battery: + + + + + General Settings + + + + + Power icon: + + + + + Power + + + + + Enter idle state %1 min and sleep after %2 min : + + + + + Enter idle state %1 min and close after %2 min : + + + + + + + never + + + + + + + 10 min + + + + + + + 20 min + + + + + + 30 min + + + + + + 60 min + + + + + + 120 min + + + + + 300 min + + + + + + 1 min + + + + + + 5 min + + + + + nothing + + + + + blank + + + + + suspend + + + + + hibernate + + + + + shutdown - - User existing! + + always - - Phone number already in used! + + present - - Please check your format! + + charge - - Your are reach the limit! + + When the power button is pressed: - - Please check your phone number! + + Perform operations when battery is low: + + + Printer - - Please check your code! + + + Add Printers And Scanners + /printer/Add Printers And Scanners - - Account doesn't exist! + + Add printers and scanners - - User has bound the phone! + + Attrs - - Sending code error occurring! + + List Of Existing Printers - - Your code is wrong! + + Printer + + + Proxy - - - - Please check your password! + + Auto Proxy - - - - At least 6 bit, include letters and digt + + + Auto proxy + /proxy/Auto proxy - - - - - - Sign in Cloud + + Auto url - - Forget + + Manual Proxy - - Set + + + Manual proxy + /proxy/Manual proxy - - - - Back + + Http Proxy - - Create Account + + + + + Port - - Sign up now + + Cetification - - - - - Resend ( %1 ) + + Https Proxy - - - Get phone code + + Ftp Proxy - - - - - - - Send + + Socks Proxy - - Binding Phone + + List of ignored hosts. more than one entry, please separate with english semicolon(;) - - Bind now + + Proxy - MainWidget - - - - - Your account:%1 - - + QObject - - - - Exit + + Customize Shortcut - - Sync + + Update Shortcut - - Sign in + + basic - - Stop sync + + classical - - Sync your settings + + default - - Your account:%1 + + + Unknown - - Auto sync + + Display - - Synchronize your personalized settings and data + + Power - - Disconnected + + Default App - - - MainWindow - - UKCC + + TouchScreen - - ukcc + + Auto Boot - - HOME + + Printer - - - ModulePageWidget - - QLabel{font-size: 18px; color: palette(Shadow);} + + Mouse - - - MouseControl - - Mouse Key Settings + + Touchpad - - Hand habit + + Keyboard - - Pointer Settings + + Shortcut - - Speed + + Audio - - - - Slow + + Bluetooth - - mouse wheel speed + + Background - - - - Fast + + Theme - - Doubleclick delay + + Screenlock - - Short + + Fonts - - Long + + Screensaver - - Sensitivity + + Desktop - - Low + + Connect - - High + + Vino - - Visibility + + User Info - - Pointer size + + Security Center - - Cursor Settings + + Vpn - - Cursor weight + + Proxy - - Thin + + Cloud Account - - Coarse + + Date - - Cursor speed + + Area - - Enable flashing on text area + + Backup - - Mouse + + Upgrade - - Lefthand + + Notice - - Righthand + + About - - Default(Recommended) + + Experienceplan - - Medium + + + + Never - - Large + + 10min - - - NetConnect - - Netconnect Status + + 20min - - - Waitting... + + 40min - - Available Network + + 80min - - Refresh + + interactive - - open wifi + + + suspend - - - Network settings + + + hibernate - - Netconnect + + + shutdown - - connected + + nothing - - No network + + blank - - - Notice - - Notice Settings + + May - - Set the type of notice in the operation center + + January - - Show new feature ater system upgrade + + February - - Get notifications from the app + + March - - Show notifications on the lock screen + + April - - Notice Origin + + June - - Notice + + July - - - OutputConfig - - resolution + + August - - orientation + + September - - arrow-up + + October - - 90° arrow-right + + Novermber - - arrow-down + + December - - 90° arrow-left + + min length %1 + - - refresh rate + + min digit num %1 + - - auto + + min upper num %1 + - - - 100% + + min lower num %1 + - - - - 200% + + min other num %1 + - - 300% + + min char class %1 + - - screen zoom + + max repeat %1 + - - %1 Hz + + max class repeat %1 + - - - PassDialog - - Get the phone binding code + + max sequence %1 + - - Your account here + + ukui-control-center is already running! - - Your new password here + + ukui-control-center - - Confirm your new password + + PulseAudio Volume Control - - Your code here + + Connection to PulseAudio failed. Automatic retry in 5s + +In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties +or default-server in client.conf is misconfigured. +This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window. +If this is the case, then PulseAudio should autospawn again, or if this is not configured you should +run start-pulseaudio-x11 manually. - - - At least 6 bit, include letters and digt + + pa_context_subscribe() failed - - Your password is valid! + + Failed to initialize stream_restore extension: %s - - - Power - - select power plan + + pa_ext_stream_restore_read() failed - - Balance (suggest) + + Go to monitor settings page - - Autobalance energy and performance with available hardware + + Go to defaultapp settings page - - Saving + + Go to power settings page - - Minimize performance + + Go to autoboot settings page - - Custom + + Go to printer settings page - - Users develop personalized power plans + + Go to mouse settings page - - Power supply + + Go to touchpad settings page - - Battery powered + + Go to keyboard settings page - - Change pc sleep time: + + Go to shortcut settings page - - Change dp close time: + + Go to audio settings page - - When close lid: + + Go to bluetooth settings page - - Screen darkens use battery: + + Go to background settings page - - Power Other Settings + + Go to theme settings page - - S3 to S4 when: + + Go to screenlock settings page - - Power icon: + + Go to screensaver settings page - - Power + + Go to fonts settings page - - - - never + + Go to desktop settings page - - - - 10 min + + Go to netconnect settings page - - - - 20 min + + Go to vpn settings page - - - 30 min + + Go to proxy settings page - - - 60 min + + Go to userinfo settings page - - - 120 min + + Go to cloudaccount settings page - - 300 min + + Go to datetime settings page - - - 1 min + + Go to area settings page - - - 5 min + + Go to update settings page - - nothing + + Go to backup settings page - - blank + + Go to upgrade settings page - - suspend + + Go to notice settings page - - hibernate + + Go to about settings page + + + RegDialog - - shutdown + + Get - - always + + Your password here - - present + + Your account here - - charge + + Confirm your password - - - Printer - - Add Printers And Scanners + + Your code here - - Add printers and scanners + + This operation is permanent - - List Of Existing Printers + + + At least 6 bit, include letters and digt - - Printer + + Your password is valid! - Proxy + ResolutionSlider - - Auto Proxy + + No available resolutions + + + Screenlock - - Auto proxy + + + Screenlock - - Auto url + + Screenlock Interface - - Manual Proxy + + Screenlock Set - - Manual proxy + + + Show picture of screenlock on screenlogin + /screenlock/Show picture of screenlock on screenlogin - - Http Proxy + + + Lock screen when screensaver boot + /screenlock/Lock screen when screensaver boot - - - - - Port + + Lock screen delay - - Cetification + + Select screenlock background - - Https Proxy + + Browser online wp - - Ftp Proxy + + Browser local wp - - Socks Proxy + + 5m - - List of ignored hosts. more than one entry, please separate with english semicolon(;) + + 10m - - Proxy + + 30m - - - QObject - - Update Shortcut + + 45m - - basic + + 1m - - classical + + 1h - - default + + 1.5h - - - Unknown + + 3h + + + Screensaver - - Display + + + Screensaver - - Defaultapp + + + Enable screensaver + /screensaver/Enable screensaver - - Power + + + Screensaver program + /screensaver/Screensaver program - - Autoboot + + + idle time + /screensaver/idle time - - Printer + + Lock screen when screensaver boot - - Mouse + + Default_ukui - - Touchpad + + Blank_Only - - Keyboard + + 5m - - Shortcut + + 10m - - Audio + + 30m - - Background + + 45m - - Theme + + 1m - - Screenlock + + 1h - - Fonts + + 1.5h - - Screensaver + + 3h + + + SecurityCenter - - Desktop + + SecurityCenter - - Netconnect + + + Computer Security Overview + /securitycenter/Computer Security Overview - - Vpn + + Understand current computer security situation and take measures - - Proxy + + Run Security Center - - Userinfo + + Security Center - - NetworkAccount + + Account Security + /securitycenter/Account Security - - Datetime + + Protect account and login security - - Area + + Safety check-up + /securitycenter/Safety check-up - - SecurityCenter + + Detect abnormal configuration - - Update + + Virus defense + /securitycenter/Virus defense - - Backup + + Real time protection from virus threat - - Notice + + App protection + /securitycenter/App protection - - About + + App install - - Experienceplan + + Net protection + /securitycenter/Net protection - - - Never + + Manage and control network - - Year + + Secure Config + /securitycenter/Secure Config - - Jan + + Simple Config + + + ShareMain - - Feb + + Share - - Mar + + Allow others to view your desktop - - Apr + + Allow connection to control screen - - May + + Security - - Jun + + You must confirm every visit for this machine - - Jul + + Require user to enter this password: - - Aug + + + Password can not be blank - - Sep + + Password length must be less than or equal to 8 + + + Shortcut - - Oct + + + + System Shortcut - - Nov + + Custom Shortcut - - Dec + + Customize Shortcut - - Day + + Add custom shortcut - - min length %1 - + + + disable - - min digit num %1 - + + Shortcut + + + SuccessDiaolog - - min upper num %1 - + + Reback sign in - - min lower num %1 - + + Sign up success! - - min other num %1 - + + + + + Confirm - - min char class %1 - + + Reset success! - - max repeat %1 - + + Sign in success! - - max class repeat %1 - + + Binding phone success! + + + SyncDialog - - max sequence %1 - + + Sync - - ukui-control-center is already running! + + Do not - - - RegDialog - - Get + + + Last sync at %1 - - Your password here + + Sync now? - - Your account here + + Wallpaper - - Confirm your password + + ScreenSaver - - Your code here + + Font - - This operation is permanent + + Avatar - - - At least 6 bit, include letters and digt + + Menu - - Your password is valid! + + Tab - - - ResolutionSlider - - No available resolutions + + Quick Start - - - Screenlock - - - Screenlock + + Themes - - Screenlock Interface + + Mouse - - Screenlock Set + + TouchPad - - Show picture of screenlock on screenlogin + + KeyBoard - - Lock screen when screensaver boot + + ShortCut - - Lock screen delay + + Area - - Select screenlock background + + Date/Time - - Browser online wp + + Default Open - - Browser local wp + + Notice - - 5m + + Option - - 10m + + Peony - - 30m + + Boot - - 45m + + Power - - 1m + + Editor - - 1h + + Terminal - - 1.5h + + Weather - - 3h + + Media - Screensaver + TabWid - - - Screensaver + + + + + + + + Check Update - - Enable screensaver + + Service connection abnormal,please retest! - - Screensaver program + + + Prompt information - - idle time + + Update now - - Lock screen when screensaver boot + + Cancel update - - Default_ukui + + No,I Don't Backup - - Blank_Only + + + Being updated... - - 5m + + + + + + + + UpdateAll - - 10m + + The backup restore partition could not be found. The system will not be backed up in this update! - - 30m + + Kylin backup restore tool is doing other operations, please update later. + + + + + The source manager configuration file is abnormal, the system temporarily unable to update! - - 45m + + Backup already, no need to backup again. - - 1m + + + Start backup,getting progress - - 1h + + Kylin backup restore tool does not exist, this update will not backup the system! - - 1.5h + + Backup complete. - - 3h + + In backup - - - SecurityCenter - - - SecurityCenter + + Failed to write configuration file, this update will not back up the system! - - Summarize + + Insufficient backup space, this update will not backup your system! - - Recognize the current security of the system, and can take the necessary settings + + Kylin backup restore tool could not find the UUID, this update will not backup the system! - - Run Security Center + + Backup interrupted, stop updating! - - Virus Protection + + Backup finished! - - Protect system from threats + + Kylin backup restore tool exception: - - Network Protection + + There will be no backup in this update! - - Setup app that can access web + + Getting update list - - App Execution Control + + + Software source update failed: - - App install and exe protection + + + Update software source : - - Account Security + + Reconnect times: - - Protect account and login security + + Update - - - Shortcut - - System Shortcut + + View history - - Show all shortcut + + Update Settings - - Reset default + + Allowed to renewable notice - - Custom Shortcut + + Backup current system before updates all - - Add custom shortcut + + + Your system is the latest! - - Shortcut + + Updatable app detected on your system! - - - ShowAllShortcut - - Dialog + + + Last refresh: - - System Shortcuts + + Last Checked: - - - Desktop + + Updating the software source - - - SuccessDiaolog - - Reback sign in + + This update will not backup the current system, do you want to continue the update? - - Sign up success! + + Yes, keep updating - - - - - Confirm + + No, backup now - - Reset success! + + Not updated - - Sign in success! + + Part of the update failed! - - Binding phone success! + + An important update is in progress, please wait. @@ -3561,61 +5223,71 @@ Theme + Theme Mode + /theme/Theme Mode + Icon theme + /theme/Icon theme - + Control theme - + + Cursor theme + /theme/Cursor theme - + Effect setting - + + Performance mode + /theme/Performance mode - + + Transparency + /theme/Transparency - + Reset to default - + Theme - + Default - + Light - + Dark @@ -3623,28 +5295,80 @@ TimeZoneChooser - + Cancel - + Confirm - - + + Change time zone + + + + + change timezone + TouchScreen + + + + + TouchScreen + + + + + monitor + + + + + touch id + + + + + map + + + + + calibration + + + + + No touch screen found + + + + + input device + + + + + TextLabel + + + + Touchpad + Touchpad Settings + /touchpad/Touchpad Settings @@ -3672,131 +5396,174 @@ - + Touchpad - + + Disable rolling - + + Edge scrolling + + + + + Two-finger scrolling + + + + Vertical edge scrolling - + Horizontal edge scrolling - + Vertical two-finger scrolling - + Horizontal two-finger scrolling - UkmediaInputWidget + UkccAbout - - Input + + + UKCC - - Input Device + + Version: - - Volume + + The control panel provides a friendly graphical user interface to manage common configuration items of the operating system. System configuration provides system, equipment, personalization, network, account, time and date, account, time and date, update, notification and operation module operations. - - Input Level + + Service and Support: + + + + + UkmediaInputWidget + + + Input - - Low + + Input Device + /audio/Input Device - - High + + Volume + /audio/Volume - - Connector + + Input Level + /audio/Input Level - - Select Device + + Connector UkmediaMainWidget - + sound error - + load sound failed + + + Establishing connection to PulseAudio. Please wait... + + + + + pa_ext_stream_restore_write() failed + + UkmediaOutputWidget - + Output - + Output Device + /audio/Output Device - + Master Volume + /audio/Master Volume - + Balance + /audio/Balance - + Right - + Connector - + Profile + /audio/Profile + + + + Card + + /audio/Card - + Left @@ -3804,42 +5571,53 @@ UkmediaSoundEffectsWidget - + System Sound + /audio/System Sound - + Sound Theme + /audio/Sound Theme - + Alert Sound + /audio/Alert Sound - + + Alert Volume + + /audio/Alert Volume + + + Boot Music + /audio/Boot Music - + Beep Switch + /audio/Beep Switch - + Window Closed - + Volume Change - + Setting Menu @@ -3847,146 +5625,246 @@ UnifiedOutputConfig - + resolution - + orientation - + arrow-up - + 90° arrow-right - + arrow-down - + 90° arrow-left - - refresh rate + + frequency - + auto + + + UpdateDbus - - aa + + ukui-control-center - - - Update - - - Update + + ukui-control-center-update + + + UpdateLog - - System Update + + Update log + + + UpdateSource - - Last check time: + + Connection failed, please reconnect! + + + Upgrade - - CheckUpdate + + Upgrade + /upgrade/Upgrade UserInfo - + Current User - - + Change pwd - - + Change type - - Change valid + + + Password + + /userinfo/Password + + + + + Type + + /userinfo/Type + + + + + Valid + + /userinfo/Valid + + + + Group - + + Login no passwd + /userinfo/Login no passwd - + + enable autoLogin + /userinfo/enable autoLogin + + + + Currently in Live mode, please create a new user and log out + + + + + Biometric Password + + + + + advanced settings + + + + + enable biometrics + + + + + types of biometric password + - + + biometric device + + + + Other Users - + Add new user - - Userinfo + + User Info - - standard user + + root - - administrator + + Standard - - root + + Admin + + + + + Del + + + + + Warning + + + + + The user is logged in, please delete the user after logging out + + + + + Add biometric feature + + + + + Rename - + + Verify + + + + Delete + Vino + + + Vino + + + + Vpn @@ -3994,12 +5872,13 @@ - + Add vpn connect + /vpn/Add vpn connect - + Vpn @@ -4007,166 +5886,191 @@ Wallpaper - + Desktop Background - + + Select from + /wallpaper/Select from - - Picture options - - - - + + Browser online wp + /wallpaper/Browser online wp - + + Browser local wp + /wallpaper/Browser local wp - + + Reset to default + /wallpaper/Reset to default - - - + + Cancel - - Ok - - - - + Background - + picture - + color - + Custom color - - wallpaper + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) - - centered + + allFiles(*.*) - - scaled + + + select custom wallpaper file - - stretched + + + Select - - zoom + + + Position: - - spanned + + + FileName: - - - select custom wallpaper file + + + FileType: + + + Widget - - - Select + + unify output + /display/unify output - - - Position: + + night mode + /display/night mode - - - FileName: + + Some applications need to be logouted to take effect - - - FileType: + + Information - - - Widget - - night mode + + Theme follow night mode - - Some applications need to be logouted to take effect + + Hint + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after 9 seconds + + + + + Save Config + + + + + Restore Config - + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after %1 seconds + + + + please insure at least one output! - - + + Warning - - Morning time should be earlier than evening time! + + Open time should be earlier than close time! + + + + + Warnning - + Sorry, your configuration could not be applied. Common reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU. - - @title:window - Unsupported Configuration + + %1 @@ -4178,37 +6082,48 @@ - + Shortcut name - + Shortcut exec - + Open - + Invalid executable, please re-enter - + + Cancel - + Certain - + + Add custom shortcut + + + + + Desktop files(*.desktop) + + + + select desktop @@ -4221,47 +6136,66 @@ - + current date - + time - + year - + month - + day - + cancel - + confirm + m_updatelog + + + No content. + + + + + History Log + + + + + Update Details + + + + networkaccount - NetworkAccount + Cloud Account + /networkaccount/Cloud Account diff -Nru ukui-control-center-2.0.3/shell/res/i18n/en_US.ts ukui-control-center-3.0.3/shell/res/i18n/en_US.ts --- ukui-control-center-2.0.3/shell/res/i18n/en_US.ts 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/i18n/en_US.ts 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,6594 @@ + + + + + About + + + System Summary + + + + + version + + /about/version + + + + Version + + + + + Kylin Linux Desktop V10 (SP1) + + + + + Copyright © 2009-2021 KylinSoft. All rights reserved. + + + + + + Kernel + + /about/Kernel + + + + + CPU + + /about/CPU + + + + + Memory + + /about/Memory + + + + Disk + + + + + Desktop + + + + + User + + + + + Active Status + + + + + Serial + + + + + Protocol + + + + + Active + + + + + About + + /about/About + + + + Activated + + + + + The system has expired. The expiration time is: + + + + + Inactivated + + + + + AddAppDialog + + + OK + + + + + Cancel + + + + + AddAutoBoot + + + Add AutoBoot + + + + + Add autoboot program + + + + + + Program name + + + + + + Program exec + + + + + Open + + + + + + Program comment + + + + + + Cancel + + + + + Certain + + + + + Desktop files(*.desktop) + + + + + select autoboot desktop + + + + + Select + + + + + desktop file not allowed add + + + + + desktop file not exist + + + + + AppDetail + + + Dialog + + + + + App + + + + + Allow notification + + + + + Number of notification centers + + + + + cancel + + + + + confirm + + + + + AppUpdateWid + + + Lack of local disk space! + + + + + + + + + + Update + + + + + Network abnormal! + + + + + + Download failed! + + + + + failed to get from the source! + + + + + The download cache has been removed + + + + + Being installed + + + + + + Update succeeded! + + + + + + Update failed! + + + + + Failure reason: + + + + + + details + + + + + + Update log + + + + + + + + Newest: + + + + + + Download size: + + + + + Current version: + + + + + back + + + + + A single update will not automatically backup the system, if you want to backup, please click Update All. + + + + + Prompt information + + + + + Do not backup, continue to update + + + + + + Cancel + + + + + Cancel update + + + + + This time will no longer prompt + + + + + In the pause + + + + + Calculate the download progress + + + + + + Get depends failed! + + + + + In the update + + + + + + + Ready to install + + + + + + + Update succeeded , It is recommended that you restart later! + + + + + + + Update succeeded , It is recommended that you log out later and log in again! + + + + + No content. + + + + + Area + + + + Area + + + + + + current area + + /area/current area + + + + Area showing time currency format + + + + + Regional format data + + + + + + calendar + + + + + + lunar + + + + + First day of the week + + + + + + monday + + + + + + date + + + + + 2019/12/17 + + + + + + time + + + + + 9:52 + + + + + + change format of data + + + + + + Need to log off to take effect + + + + + first day of week + + + + + + first language + + /area/first language + + + + + system language + + + + + country + + + + + regional format + + /area/regional format + + + + US + + + + + CN + + + + + English + + + + + Chinese + + + + + addwgt + + + + + Add main language + + + + + solar calendar + + + + + sunday + + + + + change data format + + + + + Audio + + + + Audio + + + + + AutoBoot + + + + Autoboot Settings + + /autoboot/Autoboot Settings + + + + Auto Boot + + + + + Add autoboot app + + + + + Name + + + + + Status + + + + + Delete + + + + + Backup + + + + + Backup + + /backup/Backup + + + + Back up your files to other drives, and when the original files are lost, damaged, or deleted, +you can restore them to ensure the integrity of your system. + + + + + Begin backup + + + + + + Restore + + /backup/Restore + + + + View a list of backed-upfiles to backed up files to the system + + + + + Begin restore + + + + + BiometricEnrollDialog + + + Dialog + + + + + Biometrics + + + + + Continue to enroll + + + + + Finish + + + + + FingerPrint + + + + + Fingervein + + + + + Iris + + + + + Face + + + + + VoicePrint + + + + + Enroll + + + + + Verify + + + + + Search + + + + + Permission is required. +Please authenticate yourself to continue + + + + + + Enroll successfully + + + + + + Verify successfully + + + + + Not Match + + + + + D-Bus calling error + + + + + Device is busy + + + + + No such device + + + + + Permission denied + + + + + BiometricMoreInfoDialog + + + Dialog + + + + + Biometrics + + + + + Default device + + + + + Verify Type: + + + + + Bus Type: + + + + + Device Status: + + + + + Storage Type: + + + + + Identification Type: + + + + + Connected + + + + + Unconnected + + + + + FingerPrint + + + + + Fingervein + + + + + Iris + + + + + Face + + + + + VoicePrint + + + + + Hardware Verification + + + + + Software Verification + + + + + Mix Verification + + + + + Other Verification + + + + + Device Storage + + + + + OS Storage + + + + + Mix Storage + + + + + Serial + + + + + USB + + + + + PCIE + + + + + Any + + + + + Other + + + + + Hardware Identification + + + + + Software Identification + + + + + Mix Identification + + + + + Other Identification + + + + + BlueToothMain + + + Bluetooth + + /bluetooth/Bluetooth + + + + Bluetooth adapter + + + + + Show icon on taskbar + + /bluetooth/Show icon on taskbar + + + + Allow Bluetooth devices to be discoverable + + /bluetooth/Discoverable + + + + My Devices + + + + + Other Devices + + /bluetooth/Other Devices + + + + Refresh + + + + + + + + Turn on Bluetooth + + + + + Bluetooth + + + Bluetooth + + + + + BluetoothNameLabel + + + + + + + Can now be found as "%1" + + + + + CertificationDialog + + + + UserCertification + + + + + User: + + + + + Passwd: + + + + + Close + + + + + Certification + + + + + ChangeFaceDialog + + + Change User Face + + + + + System Icon + + + + + Select face from local + + + + + Save + + + + + select custom face file + + + + + Select + + + + + Position: + + + + + FileName: + + + + + FileType: + + + + + + Cancel + + + + + Warning + + + + + The avatar is larger than 1M, please choose again + + + + + ChangeGroupDialog + + + Dialog + + + + + User Group Settings + + + + + Cancel + + + + + User group + + + + + Add user group + + + + + + Tips + + + + + Invalid Id! + + + + + + OK + + + + + Invalid Group Name! + + + + + ChangePwdDialog + + + Change Pwd + + + + + Pwd type + + + + + Cur pwd + + + + + New pwd + + + + + New pwd sure + + + + + Cancel + + + + + Confirm + + + + + Change pwd + + + + + General Pwd + + + + + + Current Password + + + + + + + New Password + + + + + + + New Password Identify + + + + + Pwd input error, re-enter! + + + + + + Inconsistency with pwd + + + + + Contains illegal characters! + + + + + Same with old pwd + + + + + ChangeTypeDialog + + + Change Account Type + + + + + Make sure that there is at least one administrator on the computer + + + + + standard user + + + + + Standard users can use most software, but cannot change system settings + + + + + administrator + + + + + Administrators can make any changes they need + + + + + Cancel + + + + + Confirm + + + + + Change type + + + + + ChangeUserName + + + + Change Username + + + + + Cancel + + + + + Save + + + + + ChangeValidDialog + + + Dialog + + + + + Password Validity Setting + + + + + Current passwd validity: + + + + + Adjust date to: + + + + + Cancel + + + + + Certain + + + + + Change valid + + + + + ChangtimeDialog + + + time + + + + + year + + + + + month + + + + + day + + + + + ColorDialog + + + Dialog + + + + + B + + + + + R + + + + + G + + + + + Cancel + + + + + OK + + + + + Custom color + + + + + CreateGroupDialog + + + Dialog + + + + + Cancel + + + + + Certain + + + + + Add New Group + + + + + Name + + + + + Id + + + + + Members + + + + + Add user group + + + + + CreateUserDialog + + + Add New Account + + + + + + UserName + + + + + PwdType + + + + + + Password + + + + + PasswordSure + + + + + Account Type + + + + + standard user + + + + + Standard users can use most software, but cannot change system settings + + + + + administrator + + + + + Administrators can make any changes they need + + + + + Cancel + + + + + Confirm + + + + + Add new user + + + + + Password Identify + + + + + General Password + + + + + + Inconsistency with pwd + + + + + Contains illegal characters! + + + + + The user name cannot be empty + + + + + Must be begin with lower letters! + + + + + Can not contain capital letters! + + + + + Name already in use, change another one. + + + + + Name corresponds to group already exists. + + + + + Name length must less than %1 letters! + + + + + Can only contain letters,digits,underline! + + + + + Username's folder exists, change another one + + + + + CustomLineEdit + + + New Shortcut... + + + + + DataFormat + + + Dialog + + + + + change format of data + + + + + + calendar + + + + + first day + + + + + + date + + + + + + time + + + + + cancel + + + + + confirm + + + + + first day of week + + + + + solar calendar + + + + + lunar + + + + + monday + + + + + sunday + + + + + DateTime + + + DateTime + + + + + current date + + + + + + Change time + + /date/Change time + + + + + Change time zone + + /date/Change time zone + + + + Date + + + + + 24-hour clock + + /date/24-hour clock + + + + Sync from network + + + + + change time + + + + + + + + + + + Sync from network failed + + + + + DefaultApp + + + Default App + + + + + Browser + + /defaultapp/Browser + + + + Mail + + /defaultapp/Mail + + + + Image Viewer + + /defaultapp/Image Viewer + + + + Audio Player + + /defaultapp/Audio Player + + + + Video Player + + /defaultapp/Video Player + + + + Text Editor + + /defaultapp/Text Editor + + + + DefaultAppWindow + + + Select Default Application + + + + + Browser + + + + + Mail + + + + + Image Viewer + + + + + Audio Player + + + + + Video Player + + + + + Text Editor + + + + + Reset to default + + + + + DefineGroupItem + + + Edit + + + + + Delete + + + + + DefineShortcutItem + + + Delete + + + + + DelGroupDialog + + + Dialog + + + + + TextLabel + + + + + Cancel + + + + + Delete + + + + + Delete user group + + + + + Are you sure to delete the group, which will make some file components in the file system invalid! + + + + + DelUserDialog + + + keep the user's data, like desktop,documents, favorites, music, pictures and so on + + + + + delete whole data belong user + + + + + Cancel + + + + + Delete + + + + + Delete the user ' + + + + + 'and: + + + + + Desktop + + + + Icon Show On Desktop + + /desktop/Icon Show On Desktop + + + + Computerdesktop + + + + + Trashdesktop + + + + + Homedesktop + + + + + Volumedesktop + + + + + Networkdesktop + + + + + Set Start Menu + + + + + Always use the start menu in full screen + + + + + Icon Lock on Menu + + + + + Computermenu + + + + + Settingmenu + + + + + Filesystemmenu + + + + + Trashmenu + + + + + + Tray icon + + /desktop/Tray icon + + + + Desktop + + + + + DeviceInfoItem + + + Connect + + + + + Disconnect + + + + + Remove + + + + + DeviceType + + + FingerPrint + + + + + FingerVein + + + + + Iris + + + + + Face + + + + + VoicePrint + + + + + DisplayPerformanceDialog + + + Dialog + + + + + Display Advanced Settings + + + + + Performance + + + + + Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. + + + + + (Note: not support connect graphical with xmanager on windows.) + + + + + Compatible + + + + + Applicable to machine with integrated graphics, there is no 3D graphics acceleration. + + + + + (Note: need connect graphical with xmanager on windows, use this option.) + + + + + Automatic + + + + + Auto select according to environment, delay the login time (about 0.5 sec). + + + + + Threshold: + + + + + Apply + + + + + Reset + + + + + (Note: select this option to use 3D graphics acceleration and xmanager.) + + + + + DisplaySet + + + Display + + + + + DisplayWindow + + + Form + + + + + Display + + + + + monitor + + + + + set as home screen + + + + + open monitor + + + + + Advanced + + + + + unify output + + + + + screen brightness adjustment + + + + + dark + + + + + bright + + + + + follow the sunrise and sunset(17:55-05:04) + + + + + custom time + + + + + opening time + + + + + closing time + + + + + color temperature + + + + + warm + + + + + cold + + + + + apply + + + + + EditGroupDialog + + + Dialog + + + + + Cancel + + + + + Certain + + + + + Edit User Group + + + + + Name + + + + + Id + + + + + Members + + + + + Tips + + + + + Invalid Id! + + + + + OK + + + + + Edit user group + + + + + ExperiencePlan + + + User Experience + + + + + Join in user Experience plan + + + + + User experience plan terms, see + + + + + 《User Experience plan》 + + + + + Experienceplan + + + + + Fonts + + + + Fonts + + + + + + + Font size + + /fonts/Font size + + + + + Fonts select + + /fonts/Fonts select + + + + Monospace font + + + + + Reset to default + + + + + Mono font + + + + + Advanced settings + + + + + Gtk default font + + + + + Document font + + + + + titlebar font + + + + + Select text sample that looks clearest + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 16 + + + + + Thanks For Using The ukcc + + + + + FrameItem + + + + Sync failed,please relogin! + + + + + Change configuration file failed,please relogin! + + + + + Configuration file not exist,please relogin! + + + + + Cloud verifyed file download failed,please relogin! + + + + + OSS access failed,please relogin! + + + + + HistoryUpdateListWig + + + Success + + + + + Failed + + + + + ItemList + + + ScreenSaver + + + + + Font + + + + + Avatar + + + + + Menu + + + + + Tab + + + + + Quick Start + + + + + Wallpaper + + + + + Themes + + + + + Mouse + + + + + TouchPad + + + + + KeyBoard + + + + + ShortCut + + + + + Area + + + + + Date/Time + + + + + Default Open + + + + + Notice + + + + + Option + + + + + Peony + + + + + Boot + + + + + Power + + + + + Editor + + + + + Terminal + + + + + Weather + + + + + Media + + + + + KbPreviewFrame + + + No preview found + + + + + Unable to open Preview ! + + + + + KbdLayoutManager + + + C + + + + + L + + + + + Variant + + + + + Add + + + + + Add Layout + + + + + Del + + + + + Keyboard Preview + + + + + KeyValueConverter + + + System + + + + + Devices + + + + + Personalized + + + + + Network + + + + + Account + + + + + Datetime + + + + + Update + + + + + Messages + + + + + KeyboardControl + + + Keys Settings + + + + + + Enable repeat key + + /keyboard/Enable repeat key + + + + + Delay + + /keyboard/Delay + + + + Short + + + + + Long + + + + + + Speed + + /keyboard/Speed + + + + Slow + + + + + Fast + + + + + Input characters to test the repetition effect: + + + + + + Tip of keyboard + + /keyboard/Tip of keyboard + + + + Enable numlock + + + + + Input Settings + + + + + Input Set + + + + + + Keyboard layout + + /keyboard/Keyboard layout + + + + Keyboard + + + + + Input characters to test the repetition effect: + + /keyboard/Input characters to test the repetition effect: + + + + KeyboardPainter + + + Close + + + + + + Keyboard layout levels + + + + + + Level %1, %2 + + + + + LayoutManager + + + Dialog + + + + + Manager Keyboard Layout + + + + + Language + + + + + Country + + + + + Variant + + + + + Layout installed + + + + + Preview + + + + + Cancel + + + + + Install + + + + + LoginDialog + + + Forget + + + + + Send + + + + + User Sign in + + + + + Quick Sign in + + + + + Your account/phone here + + + + + + Your code here + + + + + Your phone number here + + + + + Your account/phone/email here + + + + + Your password here + + + + + MCodeWidget + + + SongTi + + + + + MainDialog + + + + + + + + + Sign in + + + + + Sign up + + + + + Login in progress + + + + + Error code: + + + + + ! + + + + + Internal error occurred! + + + + + Failed to sign up! + + + + + Failed attempt to return value! + + + + + Check your connection! + + + + + Failed to get by phone! + + + + + Failed to get by user! + + + + + Failed to reset password! + + + + + Timeout! + + + + + Phone binding falied! + + + + + + Please check your information! + + + + + Please check your account! + + + + + Failed due to server error! + + + + + User and passsword can't be empty! + + + + + User existing! + + + + + User doesn't exist! + + + + + Network can not reach! + + + + + Phone can't be empty! + + + + + Account or password error! + + + + + Phone number already in used! + + + + + Please check your format! + + + + + Your are reach the limit! + + + + + Please check your phone number! + + + + + Please check your code! + + + + + Account doesn't exist! + + + + + User has bound the phone! + + + + + Sending code error occurred! + + + + + Phone code is expired! + + + + + Phone code error! + + + + + Code can not be empty! + + + + + MCode can not be empty! + + + + + Your code is wrong! + + + + + + Please check your phone! + + + + + + Sign in Cloud + + + + + Resend ( %1 ) + + + + + Get + + + + + MainWidget + + + Your account:%1 + + + + + + + Exit + + + + + Sync + + + + + Sign in + + + + + + Waiting for initialization... + + + + + Logout failed,please check your connection + + + + + + Stop sync + + + + + Sync your settings + + + + + Your account:%1 + + + + + Auto sync + + + + + + + + + + The latest time sync is: + + + + + + + + + + + + + + + + + Network can not reach! + + + + + Waitting for sync! + + + + + Synchronize your personalized settings and data + + + + + The Cloud Account Service version is out of date! + + + + + KylinID open error! + + + + + Unauthorized device or OSS falied. +Please retry or relogin! + + + + + Authorization failed! + + + + + This operation may cover your settings! + + + + + %1, + + + + + Kylin Cloud Account + + + + + Cloud ID desktop message + + + + + + Disconnected + + + + + MainWindow + + + + + Settings + + + + + Search + + + + + Main menu + + + + + Minimize + + + + + Maximize/Normal + + + + + Close + + + + + Help + + + + + About + + + + + Exit + + + + + Home + + + + + Warnning + + + + + This function has been controlled + + + + + MouseControl + + + Mouse Key Settings + + + + + + Hand habit + + /mouse/Hand habit + + + + mouse wheel speed + + + + + + + Slow + + + + + + + Fast + + + + + + Doubleclick delay + + /mouse/Doubleclick delay + + + + Short + + + + + Long + + + + + Pointer Settings + + + + + + Speed + + /mouse/Speed + + + + + Acceleration + + /mouse/Acceleration + + + + + Visibility + + /mouse/Visibility + + + + + Pointer size + + /mouse/Pointer size + + + + Cursor Settings + + + + + + Enable flashing on text area + + /mouse/Enable flashing on text area + + + + Cursor weight + + + + + Thin + + + + + Coarse + + + + + + Cursor speed + + /mouse/Cursor speed + + + + Mouse + + + + + Lefthand + + + + + Righthand + + + + + Default(Recommended) + + + + + Medium + + + + + Large + + + + + MyLabel + + + double-click to test + + + + + NetConnect + + + + Netconnect Status + + /netconnect/Netconnect Status + + + + Available Network + + + + + + + Refresh + + + + + + open wifi + + /netconnect/open wifi + + + + + Network settings + + + + + + Connect + + + + + Connected + + + + + + No net + + + + + Detail + + + + + None + + + + + Refreshing... + + + + + NetDetail + + + SSID: + + + + + Protocol + + + + + Security Type: + + + + + Hz: + + + + + Chan: + + + + + Link Speed(rx/tx) + + + + + BandWidth: + + + + + IPV4: + + + + + IPV4 Dns: + + + + + IPV4 GateWay: + + + + + IPV4 Prefix: + + + + + IPV6: + + + + + IPV6 Prefix: + + + + + IPV6 GateWay: + + + + + Mac: + + + + + Notice + + + Notice Settings + + + + + + Set notice type of operation center + + /notice/Set notice type of operation center + + + + Show new feature ater system upgrade + + + + + Get notifications from the app + + + + + Show notifications on the lock screen + + + + + + Notice Origin + + /notice/Notice Origin + + + + Notice + + + + + OutputConfig + + + resolution + + /display/resolution + + + + orientation + + + + + arrow-up + + + + + 90° arrow-right + + + + + arrow-down + + + + + 90° arrow-left + + + + + frequency + + + + + auto + + + + + screen zoom + + /display/screen zoom + + + + + %1 Hz + + + + + Power + + + select power plan + + + + + + Balance (suggest) + + /power/Balance (suggest) + + + + Autobalance energy and performance with available hardware + + + + + + Saving + + /power/Saving + + + + Minimize performance + + + + + + Custom + + /power/Custom + + + + Users develop personalized power plans + + + + + Power supply + + + + + Battery powered + + + + + + + Change PC sleep time: + + + + + + + Change DP close time: + + + + + When close lid: + + + + + Screen darkens use battery: + + + + + General Settings + + + + + Power icon: + + + + + Power + + + + + Enter idle state %1 min and sleep after %2 min : + + + + + Enter idle state %1 min and close after %2 min : + + + + + + + never + + + + + + + 10 min + + + + + + + 20 min + + + + + + 30 min + + + + + + 60 min + + + + + + 120 min + + + + + 300 min + + + + + + 1 min + + + + + + 5 min + + + + + nothing + + + + + blank + + + + + suspend + + + + + hibernate + + + + + shutdown + + + + + always + + + + + present + + + + + charge + + + + + When the power button is pressed: + + + + + Perform operations when battery is low: + + + + + Printer + + + + Add Printers And Scanners + + /printer/Add Printers And Scanners + + + + List Of Existing Printers + + + + + Printer + + /printer/Printer + + + + Add printers and scanners + + + + + Attrs + + + + + Proxy + + + Auto Proxy + + + + + + Auto proxy + + /proxy/Auto proxy + + + + Auto url + + + + + Manual Proxy + + + + + + Manual proxy + + /proxy/Manual proxy + + + + Http Proxy + + + + + + + + Port + + + + + Cetification + + + + + Https Proxy + + + + + Ftp Proxy + + + + + Socks Proxy + + + + + List of ignored hosts. more than one entry, please separate with english semicolon(;) + + + + + Proxy + + + + + QObject + + + ukui-control-center + + + + + ukui-control-center is already running! + + + + + Display + + + + + Power + + + + + Default App + + + + + TouchScreen + + + + + Auto Boot + + + + + Printer + + + + + Mouse + + + + + Touchpad + + + + + Keyboard + + + + + Shortcut + + + + + Audio + + + + + Bluetooth + + + + + Background + + + + + Theme + + + + + Screenlock + + + + + Fonts + + + + + Screensaver + + + + + Desktop + + + + + Connect + + + + + Vino + + + + + User Info + + + + + Security Center + + + + + Vpn + + + + + Proxy + + + + + Cloud Account + + + + + Date + + + + + Area + + + + + Backup + + + + + Update + + + + + Upgrade + + + + + Notice + + + + + Search + + + + + About + + + + + Experienceplan + + + + + Go to monitor settings page + + + + + Go to defaultapp settings page + + + + + Go to power settings page + + + + + Go to autoboot settings page + + + + + Go to printer settings page + + + + + Go to mouse settings page + + + + + Go to touchpad settings page + + + + + Go to keyboard settings page + + + + + Go to shortcut settings page + + + + + Go to audio settings page + + + + + Go to bluetooth settings page + + + + + Go to background settings page + + + + + Go to theme settings page + + + + + Go to screenlock settings page + + + + + Go to screensaver settings page + + + + + Go to fonts settings page + + + + + Go to desktop settings page + + + + + Go to netconnect settings page + + + + + Go to vpn settings page + + + + + Go to proxy settings page + + + + + Go to userinfo settings page + + + + + Go to cloudaccount settings page + + + + + Go to datetime settings page + + + + + Go to area settings page + + + + + Go to update settings page + + + + + Go to backup settings page + + + + + Go to upgrade settings page + + + + + Go to notice settings page + + + + + Go to about settings page + + + + + Go to search settings page + + + + + Customize Shortcut + + + + + + + Never + + + + + 10min + + + + + 20min + + + + + 40min + + + + + 80min + + + + + interactive + + + + + + suspend + + + + + + hibernate + + + + + + shutdown + + + + + nothing + + + + + blank + + + + + PulseAudio Volume Control + + + + + Connection to PulseAudio failed. Automatic retry in 5s + +In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties +or default-server in client.conf is misconfigured. +This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window. +If this is the case, then PulseAudio should autospawn again, or if this is not configured you should +run start-pulseaudio-x11 manually. + + + + + pa_context_subscribe() failed + + + + + pa_context_get_card_info_list() failed + + + + + Failed to initialize stream_restore extension: %s + + + + + Connection failed, attempting reconnect + + + + + pa_ext_stream_restore_read() failed + + + + + pa_context_get_card_info_by_index() failed + + + + + Card callback failure + + + + + blue-crystal + + + + + dark-sense + + + + + DMZ-Black + + + + + DMZ-White + + + + + basic + + + + + classical + + + + + + default + + + + + fashion + + + + + Unknown + + + + + min length %1 + + + + + + min digit num %1 + + + + + + min upper num %1 + + + + + + min lower num %1 + + + + + + min other num %1 + + + + + + min char class %1 + + + + + + max repeat %1 + + + + + + max class repeat %1 + + + + + + max sequence %1 + + + + + + January + + + + + February + + + + + March + + + + + April + + + + + May + + + + + June + + + + + July + + + + + August + + + + + September + + + + + October + + + + + Novermber + + + + + December + + + + + system upgrade new backup + + + + + system upgrade increment backup + + + + + ResolutionSlider + + + No available resolutions + + + + + Screenlock + + + + Screenlock + + + + + Screenlock Interface + + + + + Screenlock Set + + + + + + Show picture of screenlock on screenlogin + + /screenlock/Show picture of screenlock on screenlogin + + + + + Lock screen when screensaver boot + + /screenlock/Lock screen when screensaver boot + + + + Lock screen delay + + + + + Select screenlock background + + + + + Browser online wp + + + + + Browser local wp + + + + + 1m + + + + + 5m + + + + + 10m + + + + + 30m + + + + + 45m + + + + + 1h + + + + + 1.5h + + + + + 3h + + + + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + + + + + allFiles(*.*) + + + + + select custom wallpaper file + + + + + Select + + + + + Position: + + + + + FileName: + + + + + FileType: + + + + + Cancel + + + + + Screensaver + + + + Screensaver + + + + + + Enable screensaver + + /screensaver/Enable screensaver + + + + + Screensaver program + + /screensaver/Screensaver program + + + + + idle time + + /screensaver/idle time + + + + Lock screen when screensaver boot + + + + + Default_ukui + + + + + Blank_Only + + + + + 1m + + + + + 5m + + + + + 10m + + + + + 30m + + + + + 45m + + + + + 1h + + + + + 1.5h + + + + + 3h + + + + + Search + + + Form + + + + + Search + + /search/Search + + + + + Create Index + + + + + Creating index can help you getting results quickly. + + + + + Block Folders + + + + + Following folders will not be searched. You can set it by adding and removing folders. + + + + + Choose folder + + + + + Web Engine + + + + + Default web searching engine + + + + + baidu + + + + + sougou + + + + + 360 + + + + + delete + + + + + Directories + + + + + select blocked folder + + + + + Select + + + + + Position: + + + + + FileName: + + + + + FileType: + + + + + Cancel + + + + + + + + Warning + + + + + Add blocked folder failed, choosen path is empty! + + + + + Add blocked folder failed, it is not in home path! + + + + + Add blocked folder failed, its parent dir is exist! + + + + + Add blocked folder failed, it has been already blocked! + + + + + SecurityCenter + + + SecurityCenter + + + + + + Computer Security Overview + + /securitycenter/Computer Security Overview + + + + Understand current computer security situation and take measures + + + + + Run Security Center + + + + + Security Center + + + + + Account Security + + /securitycenter/Account Security + + + + Protect account and login security + + + + + Safety check-up + + /securitycenter/Safety check-up + + + + Detect abnormal configuration + + + + + Virus defense + + /securitycenter/Virus defense + + + + Real time protection from virus threat + + + + + App protection + + /securitycenter/App protection + + + + App install + + + + + Net protection + + /securitycenter/Net protection + + + + Secure Config + + /securitycenter/Secure Config + + + + Simple Config + + + + + Manage and control network + + + + + ShareMain + + + Share + + + + + Allow others to view your desktop + + + + + Allow connection to control screen + + + + + Security + + + + + You must confirm every visit for this machine + + + + + Require user to enter this password: + + + + + + Password can not be blank + + + + + + Password length must be less than or equal to 8 + + + + + Shortcut + + + + + System Shortcut + + /shortcut/System Shortcut + + + + Custom Shortcut + + + + + Shortcut + + + + + Customize Shortcut + + /shortcut/Customize Shortcut + + + + Add custom shortcut + + /shortcut/Add custom shortcut + + + + Edit + + + + + Delete + + + + + SyncDialog + + + Sync + + + + + Do not + + + + + + Last sync at %1 + + + + + Sync now? + + + + + Wallpaper + + + + + ScreenSaver + + + + + Font + + + + + Avatar + + + + + Menu + + + + + Tab + + + + + Quick Start + + + + + Themes + + + + + Mouse + + + + + TouchPad + + + + + KeyBoard + + + + + ShortCut + + + + + Area + + + + + Date/Time + + + + + Default Open + + + + + Notice + + + + + Option + + + + + Peony + + + + + Boot + + + + + Power + + + + + Editor + + + + + Terminal + + + + + Weather + + + + + Media + + + + + TabWid + + + + + + + + + Check Update + + + + + Service connection abnormal,please retest! + + + + + + Prompt information + + + + + Update now + + + + + Cancel update + + + + + No,I Don't Backup + + + + + + Being updated... + + + + + + + + + + + UpdateAll + + + + + The backup restore partition could not be found. The system will not be backed up in this update! + + + + + Kylin backup restore tool is doing other operations, please update later. + + + + + The source manager configuration file is abnormal, the system temporarily unable to update! + + + + + Backup already, no need to backup again. + + + + + Kylin backup restore tool does not exist, this update will not backup the system! + + + + + Backup complete. + + + + + + Start backup,getting progress + + + + + In backup: + + + + + Failed to write configuration file, this update will not back up the system! + + + + + Insufficient backup space, this update will not backup your system! + + + + + Kylin backup restore tool could not find the UUID, this update will not backup the system! + + + + + Backup interrupted, stop updating! + + + + + Backup finished! + + + + + Kylin backup restore tool exception: + + + + + There will be no backup in this update! + + + + + Getting update list + + + + + + Software source update failed: + + + + + + Update software source : + + + + + Reconnect times: + + + + + Update + + + + + View history + + + + + Update Settings + + + + + Allowed to renewable notice + + + + + Backup current system before updates all + + + + + + Your system is the latest! + + + + + + Updatable app detected on your system! + + + + + + Last refresh: + + + + + Last Checked: + + + + + Updating the software source + + + + + This update will not backup the current system, do you want to continue the update? + + + + + Yes, keep updating + + + + + No, backup now + + + + + Not updated + + + + + Part of the update failed! + + + + + An important update is in progress, please wait. + + + + + The backup restore partition is abnormal. You may not have a backup restore partition.For more details,see /var/log/backup.log + + + + + Calculating Capacity... + + + + + Theme + + + + Theme Mode + + /theme/Theme Mode + + + + + Icon theme + + /theme/Icon theme + + + + Control theme + + + + + + Cursor theme + + /theme/Cursor theme + + + + Effect setting + + + + + + Performance mode + + /theme/Performance mode + + + + + Transparency + + /theme/Transparency + + + + Reset to default + + + + + Theme + + + + + Default + + + + + Light + + + + + Dark + + + + + TimeZoneChooser + + + Cancel + + + + + Confirm + + + + + Change time zone + + + + + + change timezone + + + + + TouchScreen + + + + + TouchScreen + + + + + monitor + + + + + touch id + + + + + map + + + + + calibration + + + + + No touch screen found + + + + + input device + + + + + TextLabel + + + + + Touchpad + + + + Touchpad Settings + + /touchpad/Touchpad Settings + + + + Enabled touchpad + + + + + Disable touchpad while typing + + + + + Enable mouse clicks with touchpad + + + + + Scrolling + + + + + No touchpad found + + + + + Touchpad + + + + + + Disable rolling + + + + + Edge scrolling + + + + + Two-finger scrolling + + + + + Vertical edge scrolling + + + + + Horizontal edge scrolling + + + + + Vertical two-finger scrolling + + + + + Horizontal two-finger scrolling + + + + + UkccAbout + + + + Settings + + + + + Version: + + + + + The control panel provides a friendly graphical user interface to manage common configuration items of the operating system. System configuration provides system, equipment, personalization, network, account, time and date, account, time and date, update, notification and operation module operations. + + + + + Service and Support: + + + + + UkmediaInputWidget + + + Input + + + + + Input Device: + + /audio/Input Device + + + + Volume + + /audio/Volume + + + + Input Level + + /audio/Input Level + + + + Connector + + + + + UkmediaMainWidget + + + sound error + + + + + load sound failed + + + + + Establishing connection to PulseAudio. Please wait... + + + + + pa_ext_stream_restore_write() failed + + + + + + (unplugged) + + + + + + (unavailable) + + + + + (plugged in) + + + + + UkmediaOutputWidget + + + Output + + + + + Output Device: + + /audio/Output Device + + + + Master Volume + + /audio/Master Volume + + + + Balance + + /audio/Balance + + + + Left + + + + + Right + + + + + Connector + + + + + Profile + + /audio/Profile + + + + Card + + /audio/Card + + + + UkmediaSoundEffectsWidget + + + System Sound + + /audio/System Sound + + + + Sound Theme + + /audio/Sound Theme + + + + Alert Sound + + /audio/Alert Sound + + + + Alert Volume + + /audio/Alert Volume + + + + Logout Music + + + + + Beep Switch + + + + + Poweroff Music + + + + + Startup Music + + + + + Wakeup Music + + + + + Volume Change + + + + + UnifiedOutputConfig + + + resolution + + + + + orientation + + + + + arrow-up + + + + + 90° arrow-right + + + + + arrow-down + + + + + 90° arrow-left + + + + + frequency + + + + + + auto + + + + + + + + %1 Hz + + + + + Update + + + + Update + + + + + + System Update + + /update/System Update + + + + Last check time: + + + + + Check for updates + + + + + UpdateDbus + + + ukui-control-center + + + + + ukui-control-center-update + + + + + UpdateLog + + + Update log + + + + + UpdateSource + + + Connection failed, please reconnect! + + + + + Upgrade + + + Upgrade + + /upgrade/Upgrade + + + + UserInfo + + + Current User + + + + + Change pwd + + + + + Change type + + + + + + Password + + /userinfo/Password + + + + + Type + + /userinfo/Type + + + + Valid + + + + + Group + + + + + + Login no passwd + + /userinfo/Login no passwd + + + + enable autoLogin + + /userinfo/enable autoLogin + + + + Automatic login at boot + + + + + Currently in Live mode, please create a new user and log out + + + + + Biometric Password + + + + + advanced settings + + + + + enable biometrics + + + + + types of biometric password + + + + + biometric device + + + + + Other Users + + + + + User Info + + + + + Standard + + + + + Admin + + + + + root + + + + + Add new user + + + + + Del + + + + + Warning + + + + + The user is logged in, please delete the user after logging out + + + + + Hint + + + + + The system only allows one user to log in automatically.After it is turned on, the automatic login of other users will be turned off.Is it turned on? + + + + + Trun on + + + + + Close on + + + + + Add biometric feature + + + + + Rename + + + + + Verify + + + + + Delete + + + + + Vino + + + Vino + + + + + Vpn + + + Add Vpn Connect + + + + + Vpn + + + + + Add vpn connect + + /vpn/Add vpn connect + + + + Wallpaper + + + Desktop Background + + + + + + Select from + + /wallpaper/Select from + + + + + Browser online wp + + /wallpaper/Browser online wp + + + + + Browser local wp + + /wallpaper/Browser local wp + + + + + Reset to default + + /wallpaper/Reset to default + + + + Background + + + + + picture + + + + + color + + + + + Custom color + + + + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + + + + + allFiles(*.*) + + + + + + select custom wallpaper file + + + + + + Select + + + + + + Position: + + + + + + FileName: + + + + + + FileType: + + + + + + Cancel + + + + + Widget + + + %1 + + + + + Information + + + + + Some applications need to be logouted to take effect + + + + + unify output + + /display/unify output + + + + night mode + + /display/night mode + + + + Theme follow night mode + + + + + Hint + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +the settings will be saved after 14 seconds + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +the settings will be saved after %1 seconds + + + + + Save Config + + + + + monitor + + /display/monitor + + + + Restore Config + + + + + + Warning + + + + + please insure at least one output! + + + + + Open time should be earlier than close time! + + + + + Warnning + + + + + Sorry, your configuration could not be applied. +Common reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU. + + + + + addShortcutDialog + + + Dialog + + + + + Exec + + + + + Open + + + + + Name + + + + + Key + + + + + Invalid executable, please re-enter + + + + + + Cancel + + + + + Save + + + + + Add custom shortcut + + + + + shortcut conflict + + + + + invaild shortcut + + + + + repeated naming + + + + + Desktop files(*.desktop) + + + + + select desktop + + + + + changtimedialog + + + Dialog + + + + + current date + + + + + time + + + + + year + + + + + month + + + + + day + + + + + cancel + + + + + confirm + + + + + m_updatelog + + + History Log + + + + + Update Details + + + + + No content. + + + + + networkaccount + + + Cloud Account + + /networkaccount/Cloud Account + + + diff -Nru ukui-control-center-2.0.3/shell/res/i18n/fa.ts ukui-control-center-3.0.3/shell/res/i18n/fa.ts --- ukui-control-center-2.0.3/shell/res/i18n/fa.ts 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/i18n/fa.ts 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,5355 @@ + + + + + About + + + System Summary + + + + + + version + نسخه + /about/version + + + + TextLabel + + + + + Copyright 2009-2020 @ Kylinos All rights reserved + + + + + + Kernel + + /about/Kernel + + + + + CPU + پردازنده + /about/CPU + + + + + Memory + + /about/Memory + + + + + + Disk + + /about/Disk + + + + Desktop + + + + + User + کاربر + + + + Active Status + + + + + Service serial number + + + + + Active + + + + + Trial version disclaimer + + + + + About + + + + + available + + + + + Inactivated + + + + + Activated + + + + + AddAppDialog + + + OK + تأیید + + + + Cancel + لغو + + + + AddAutoBoot + + + Add AutoBoot + + + + + Add autoboot program + + + + + + Program name + + + + + + Program exec + + + + + Open + باز‌کردن + + + + + Program comment + + + + + + Cancel + + + + + Certain + + + + + desktop file not exist + + + + + select autoboot desktop + + + + + Select + + + + + AppDetail + + + Dialog + + + + + TextLabel + + + + + Allow notification + + + + + Number of notification centers + + + + + cancel + + + + + confirm + + + + + Area + + + + Area + + + + + + current area + + /area/current area + + + + Area showing time currency format + + + + + Regional format data + + + + + + calendar + تقویم + + + + + lunar + قمری + + + + First day of the week + اولین روز هفته + + + + + monday + دوشنبه + + + + + date + تاریخ + + + + 2019/12/17 + + + + + + time + + + + + 9:52 + + + + + + change format of data + + + + + + TextLabel + + + + + + Need to log off to take effect + + + + + display format area + + + + + US + + + + + CN + + + + + format of area + + /area/format of area + + + + first day of week + + + + + first language + + /area/first language + + + + system language + + + + + English + + + + + Chinese + + + + + addwgt + + + + + Add main language + + + + + solar calendar + + + + + sunday + + + + + change data format + + + + + AreaCodeLineEdit + + + Sign up by Phone + + + + + Audio + + + + Audio + + + + + AutoBoot + + + + Autoboot Settings + + /autoboot/Autoboot Settings + + + + Add autoboot app + + + + + Auto Boot + + + + + Name + + + + + Status + + + + + Delete + + + + + Backup + + + + + Backup + + /backup/Backup + + + + Back up your files to other drives, and when the original files are lost, damaged, or deleted, +you can restore them to ensure the integrity of your system. + + + + + Begin backup + + + + + + Restore + + /backup/Restore + + + + View a list of backed-upfiles to restore backed up files to the system + + + + + Begin restore + + + + + BindPhoneDialog + + + Your code here + + + + + Get + + + + + BlueToothMain + + + + + Turn off Bluetooth + + + + + + + Turn on Bluetooth + + + + + Bluetooth + + + + + Show icon on taskbar + + + + + + Can now be found as + + + + + Other Devices + + + + + Refresh + + + + + Can now be found as " + + + + + " + + + + + Bluetooth + + + Bluetooth + + + + + CertificationDialog + + + + UserCertification + + + + + User: + + + + + Passwd: + + + + + Close + + + + + Certification + + + + + ChangeFaceDialog + + + Change User Face + + + + + Select face from local + + + + + select custom face file + + + + + Select + + + + + Position: + + + + + FileName: + + + + + FileType: + + + + + Cancel + + + + + Warning + + + + + The avatar is larger than 1M, please choose again + + + + + ChangeGroupDialog + + + Dialog + + + + + User Group Settings + + + + + User groups available in the system + + + + + User group + + + + + Add user group + + + + + + Tips + + + + + Invalid Id! + + + + + + OK + + + + + Invalid Group Name! + + + + + ChangePwdDialog + + + Change Pwd + + + + + Pwd type + + + + + Cur pwd + + + + + New pwd + + + + + New pwd sure + + + + + Cancel + لغو + + + + Confirm + + + + + Change pwd + + + + + Cur pwd checking! + + + + + General Pwd + + + + + + Current Password + + + + + + + New Password + + + + + + + New Password Identify + + + + + + Inconsistency with pwd + + + + + Contains illegal characters! + + + + + Same with old pwd + + + + + ChangeTypeDialog + + + Change Account Type + + + + + Make sure that there is at least one administrator on the computer + + + + + standard user + + + + + Standard users can use most software, but cannot install software and change system settings + + + + + administrator + + + + + Administrators can make any changes they need + + + + + Cancel + + + + + Confirm + + + + + Change type + + + + + ChangeValidDialog + + + Dialog + + + + + Password Validity Setting + + + + + Current passwd validity: + + + + + Adjust date to: + + + + + Cancel + + + + + Certain + + + + + Change valid + + + + + ChangtimeDialog + + + time + + + + + year + + + + + month + + + + + day + + + + + ColorDialog + + + Dialog + + + + + B + + + + + Cancel + + + + + OK + + + + + R + + + + + G + + + + + Custom color + + + + + CreateGroupDialog + + + Dialog + + + + + Add New Group + + + + + Name + + + + + Id + + + + + Members + + + + + Cancel + + + + + Certain + + + + + Add user group + + + + + CreateUserDialog + + + Add New Account + + + + + + UserName + + + + + PwdType + + + + + + Password + + + + + PasswordSure + + + + + Account Type + + + + + standard user + + + + + Standard users can use most software, but cannot install the software and +change system settings + + + + + administrator + + + + + Administrators can make any changes they need + + + + + Cancel + + + + + Confirm + + + + + Add new user + + + + + Password Identify + + + + + General Password + + + + + + Inconsistency with pwd + + + + + Contains illegal characters! + + + + + The user name cannot be empty + + + + + The first character must be lowercase letters! + + + + + User name can not contain capital letters! + + + + + The user name is already in use, please use a different one. + + + + + The name corresponds to the group already exists. + + + + + User name length need to less than %1 letters! + + + + + The user name can only be composed of letters, numbers and underline! + + + + + The username is configured, please change the username + + + + + CustomLineEdit + + + New Shortcut... + + + + + DataFormat + + + Dialog + + + + + change format of data + + + + + + calendar + + + + + first day + + + + + + date + + + + + + time + + + + + cancel + + + + + confirm + + + + + first day of week + + + + + solar calendar + + + + + lunar + + + + + monday + + + + + sunday + + + + + DateTime + + + DateTime + + + + + current date + + + + + + + TextLabel + + + + + timezone + + + + + + Sync network time + + /datetime/Sync network time + + + + + Change time + + /datetime/Change time + + + + + Change time zone + + /datetime/Change time zone + + + + Sync complete + + + + + Dat + + + + + 24-hour clock + + /datetime/24-hour clock + + + + change time + + + + + DefaultApp + + + Default App + + + + + Browser + + /defaultapp/Browser + + + + Mail + + /defaultapp/Mail + + + + Image Viewer + + /defaultapp/Image Viewer + + + + Audio Player + + /defaultapp/Audio Player + + + + Video Player + + /defaultapp/Video Player + + + + Text Editor + + /defaultapp/Text Editor + + + + DefaultAppWindow + + + Select Default Application + + + + + Browser + + + + + Mail + + + + + Image Viewer + + + + + Audio Player + + + + + Video Player + + + + + Text Editor + + + + + Reset to default + + + + + DefineGroupItem + + + Edit + + + + + Delete + + + + + DefineShortcutItem + + + Delete + + + + + DelGroupDialog + + + Dialog + + + + + Delete + + + + + Cancel + + + + + Remind + + + + + Delete user group + + + + + Are you sure to delete the group, which will make some file components in the file system invalid! + + + + + DelUserDialog + + + Delete the user, belonging to the user's desktop, +documents, favorites, music, pictures and video +folder will be deleted! + + + + + Cancel + + + + + KeepFile + + + + + RemoveFile + + + + + Desktop + + + + Icon Show On Desktop + + /desktop/Icon Show On Desktop + + + + Computerdesktop + + + + + Trashdesktop + + + + + Homedesktop + + + + + Volumedesktop + + + + + Networkdesktop + + + + + Set Start Menu + + + + + Always use the start menu in full screen + + + + + Icon Lock on Menu + + + + + Computermenu + + + + + Settingmenu + + + + + Filesystemmenu + + + + + Trashmenu + + + + + + Tray icon + + /desktop/Tray icon + + + + Desktop + + + + + DeviceInfoItem + + + Connect + + + + + Disconnect + + + + + Remove + + + + + DisplayPerformanceDialog + + + Dialog + + + + + Display Advanced Settings + + + + + Performance + + + + + Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. + + + + + (Note: not support connect graphical with xmanager on windows.) + + + + + Compatible + + + + + Applicable to machine with integrated graphics, there is no 3D graphics acceleration. + + + + + (Note: need connect graphical with xmanager on windows, use this option.) + + + + + Automatic + + + + + Auto select according to environment, delay the login time (about 0.5 sec). + + + + + Threshold: + + + + + Apply + + + + + Reset + + + + + (Note: select this option to use 3D graphics acceleration and xmanager.) + + + + + DisplaySet + + + Display + + + + + DisplayWindow + + + Form + + + + + Display + + + + + monitor + + + + + set as home screen + + + + + open monitor + + + + + Advanced + + + + + unify output + + + + + screen brightness adjustment + + + + + dark + + + + + bright + + + + + follow the sunrise and sunset(17:55-05:04) + + + + + custom time + + + + + opening time + + + + + closing time + + + + + color temperature + + + + + warm + + + + + cold + + + + + apply + + + + + EditGroupDialog + + + Dialog + + + + + Cancel + + + + + Certain + + + + + Edit User Group + + + + + Name + + + + + Id + + + + + Members + + + + + Tips + + + + + Invalid Id! + + + + + OK + + + + + Edit user group + + + + + EditPassDialog + + + Edit Password + + + + + Your new password here + + + + + Your code + + + + + Get phone code + + + + + Cancel + + + + + Confirm + + + + + Confirm your new password + + + + + + + + At least 6 bit, include letters and digt + + + + + Your password is valid! + + + + + Please check your password! + + + + + Resend( + + + + + ) + + + + + + Send + + + + + Reback sign in + + + + + Error code: + + + + + ! + + + + + Internal error occurring! + + + + + Failed to sign up! + + + + + Failed attempt to return value! + + + + + Check your connection! + + + + + Failed to get by phone! + + + + + Failed to get by user! + + + + + Failed to reset password! + + + + + + + Please check your information! + + + + + Please check your account! + + + + + Failed due to server error! + + + + + User existing! + + + + + Phone number already in used! + + + + + Please check your format! + + + + + Your are reach the limit! + + + + + Please check your phone number! + + + + + Please check your code! + + + + + Account doesn't exist! + + + + + Sending code error occurring! + + + + + EditPushButton + + + Reset + + + + + ExperiencePlan + + + User Experience + + + + + Join in user Experience plan + + + + + User experience plan terms, see + + + + + 《User Experience plan》 + + + + + Experienceplan + + + + + Fonts + + + + Fonts + + + + + + + Font size + + /fonts/Font size + + + + + Fonts select + + /fonts/Fonts select + + + + + Monospace font + + + + + Advanced settings + + + + + Gtk default font + + + + + Document font + + + + + titlebar font + + + + + Select text sample that looks clearest + + + + + Reset to default + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 16 + + + + + Thanks For Using The ukcc + + + + + FrameItem + + + Sync failed, please login out to retry! + + + + + Change configuration file failed, please login out to retry! + + + + + Configuration file not exist, please login out to retry! + + + + + Cloud verifyed file download failed, please login out to retry! + + + + + OSS access failed, please login out to retry! + + + + + Sync failed, please retry or login out to get a better experience! + + + + + ItemList + + + Walpaper + + + + + ScreenSaver + + + + + Menu + + + + + Quick Start + + + + + Avatar + + + + + Tab + + + + + Font + + + + + Mouse + + + + + TouchPad + + + + + KeyBoard + + + + + ShortCut + + + + + Themes + + + + + Area + + + + + Date/Time + + + + + Default Open + + + + + Notice + + + + + Option + + + + + Peony + + + + + Weather + + + + + Media + + + + + Boot + + + + + Power + + + + + Editor + + + + + Terminal + + + + + KbPreviewFrame + + + No preview found + + + + + Unable to open Preview ! + + + + + KbdLayoutManager + + + C + + + + + L + + + + + Variant + + + + + Add + + + + + Add Layout + + + + + Del + + + + + Keyboard Preview + + + + + KeyValueConverter + + + System + + + + + Devices + + + + + Personalized + + + + + Network + + + + + Account + + + + + Datetime + + + + + Update + + + + + Messages + + + + + KeyboardControl + + + Keys Settings + + + + + + Enable repeat key + + /keyboard/Enable repeat key + + + + + Delay + + /keyboard/Delay + + + + Short + + + + + Long + + + + + + Speed + + /keyboard/Speed + + + + Slow + + + + + Fast + + + + + + Tip of keyboard + + /keyboard/Tip of keyboard + + + + Reset layout + + + + + Enable numlock + + + + + Input characters to test the repetition effect: + + + + + Keyboard Layout + + + + + + Keyboard layout + + /keyboard/Keyboard layout + + + + Input characters to test the repetition effect: + + /keyboard/Input characters to test the repetition effect: + + + + Install layouts + + + + + Keyboard + + + + + KeyboardPainter + + + Close + + + + + + Keyboard layout levels + + + + + + Level %1, %2 + + + + + LayoutManager + + + Dialog + + + + + Manager Keyboard Layout + + + + + Language + + + + + Country + + + + + Variant + + + + + Layout installed + + + + + Preview + + + + + Cancel + + + + + Install + + + + + LoginDialog + + + Forget + + + + + Send + + + + + User Sign in + + + + + Quick Sign in + + + + + + Your account/phone here + + + + + + Your code here + + + + + Your phone number here + + + + + Your password here + + + + + MCodeWidget + + + SongTi + + + + + MainDialog + + + + + + + + + + + Sign in + + + + + + + + + Sign up + + + + + Login in progress + + + + + Error code: + + + + + ! + + + + + Internal error occurred! + + + + + Failed to sign up! + + + + + Failed attempt to return value! + + + + + Check your connection! + + + + + Failed to get by phone! + + + + + Failed to get by user! + + + + + Failed to reset password! + + + + + Timeout! + + + + + Phone binding falied! + + + + + + + Please check your information! + + + + + Please check your account! + + + + + Failed due to server error! + + + + + User existing! + + + + + Phone number already in used! + + + + + Please check your format! + + + + + Your are reach the limit! + + + + + Please check your phone number! + + + + + Please check your code! + + + + + Account doesn't exist! + + + + + User has bound the phone! + + + + + Sending code error occurred! + + + + + Your code is wrong! + + + + + + + + + + Please check your phone! + + + + + + Please check your password! + + + + + + + + + Sign in Cloud + + + + + Forget + + + + + Set + + + + + + + Back + + + + + Create Account + + + + + Sign up now + + + + + + Please confirm your password! + + + + + + + + Resend ( %1 ) + + + + + + + Get + + + + + Get phone code + + + + + + + + + Send + + + + + Binding Phone + + + + + + + + Please make sure your password is safety! + + + + + Bind now + + + + + MainWidget + + + + + Your account:%1 + + + + + + + Exit + + + + + Sync + + + + + Sign in + + + + + Stop sync + + + + + Sync your settings + + + + + Your account:%1 + + + + + Auto sync + + + + + Synchronize your personalized settings and data + + + + + + + + The latest time sync is: + + + + + Unauthorized device or OSS falied. +Please retry for login! + + + + + Your account is sign on on other device already! + + + + + This operation may cover your settings! + + + + + %1, + + + + + Cloud ID desktop message + + + + + Disconnected + + + + + MainWindow + + + Search + + + + + + UKCC + + + + + Home + + + + + ukcc + + + + + MouseControl + + + Mouse Key Settings + + + + + + Hand habit + + /mouse/Hand habit + + + + Pointer Settings + + + + + + Speed + + /mouse/Speed + + + + + + Slow + + + + + mouse wheel speed + + + + + + + Fast + + + + + + Doubleclick delay + + /mouse/Doubleclick delay + + + + Short + + + + + Long + + + + + + Acceleration + + /mouse/Acceleration + + + + + Visibility + + /mouse/Visibility + + + + + Pointer size + + /mouse/Pointer size + + + + Cursor Settings + + + + + Cursor weight + + + + + Thin + + + + + Coarse + + + + + + Cursor speed + + /mouse/Cursor speed + + + + + Enable flashing on text area + + /mouse/Enable flashing on text area + + + + Mouse + + + + + Lefthand + + + + + Righthand + + + + + Default(Recommended) + + + + + Medium + + + + + Large + + + + + NetConnect + + + + Netconnect Status + + /netconnect/Netconnect Status + + + + Available Network + + + + + + Refresh + + + + + + open wifi + + /netconnect/open wifi + + + + + Network settings + + + + + Connect + + + + + + Refreshing... + + + + + connected + + + + + No network + + + + + Notice + + + Notice Settings + + + + + + Set the type of notice in the operation center + + /notice/Set the type of notice in the operation center + + + + Show new feature ater system upgrade + + + + + Get notifications from the app + + + + + Show notifications on the lock screen + + + + + + Notice Origin + + /notice/Notice Origin + + + + Notice + + + + + OutputConfig + + + resolution + + /display/resolution + + + + orientation + + + + + arrow-up + + + + + 90° arrow-right + + + + + arrow-down + + + + + 90° arrow-left + + + + + refresh rate + + + + + auto + + + + + 100% + + + + + 200% + + + + + screen zoom + + /display/screen zoom + + + + %1 Hz + + + + + PassDialog + + + Get the phone binding code + + + + + Your account here + + + + + Your new password here + + + + + Confirm your new password + + + + + Your code here + + + + + + At least 6 bit, include letters and digt + + + + + Your password is valid! + + + + + PinCodeWidget + + + Is it paired with " + + + + + " + + + + + Please make sure the number displayed on " + + + + + " matches the number below. Please do not enter this code on any other accessories. + + + + + Accept + + + + + Refush + + + + + Power + + + select power plan + + + + + + Balance (suggest) + + /power/Balance (suggest) + + + + Autobalance energy and performance with available hardware + + + + + + Saving + + /power/Saving + + + + Minimize performance + + + + + + Custom + + /power/Custom + + + + Users develop personalized power plans + + + + + Power supply + + + + + Battery powered + + + + + + + Change PC sleep time: + + + + + + + Change DP close time: + + + + + When close lid: + + + + + Screen darkens use battery: + + + + + Power Other Settings + + + + + S3 to S4 when: + + + + + Power icon: + + + + + Power + + + + + + + Enter idle state %1 min and sleep after %2 min : + + + + + + + Enter idle state %1 min and close after %2 min : + + + + + + + never + + + + + + + 10 min + + + + + + + 20 min + + + + + + 30 min + + + + + + 60 min + + + + + + 120 min + + + + + 300 min + + + + + + 1 min + + + + + + 5 min + + + + + nothing + + + + + blank + + + + + suspend + + + + + hibernate + + + + + shutdown + + + + + always + + + + + present + + + + + charge + + + + + Printer + + + + Add Printers And Scanners + + /printer/Add Printers And Scanners + + + + Add printers and scanners + + + + + List Of Existing Printers + + + + + Printer + + + + + Proxy + + + Auto Proxy + + + + + + Auto proxy + + /proxy/Auto proxy + + + + Auto url + + + + + Manual Proxy + + + + + + Manual proxy + + /proxy/Manual proxy + + + + Http Proxy + + + + + + + + Port + + + + + Cetification + + + + + Https Proxy + + + + + Ftp Proxy + + + + + Socks Proxy + + + + + List of ignored hosts. more than one entry, please separate with english semicolon(;) + + + + + Proxy + + + + + QObject + + + Add Shortcut + + + + + Update Shortcut + + + + + basic + + + + + classical + + + + + default + + + + + + Unknown + + + + + Display + + + + + Power + + + + + Default App + + + + + Auto Boot + + + + + Printer + + + + + Mouse + + + + + Touchpad + + + + + Keyboard + + + + + Shortcut + + + + + Audio + + + + + Bluetooth + + + + + Background + + + + + Theme + + + + + Screenlock + + + + + Fonts + + + + + Screensaver + + + + + Desktop + + + + + Connect + + + + + Vino + + + + + User Info + + + + + Dat + + + + + Security Center + + + + + Vpn + + + + + Proxy + + + + + Cloud Account + + + + + Area + + + + + Update + + + + + Backup + + + + + Notice + + + + + About + + + + + Experienceplan + + + + + + Never + + + + + May + + + + + January + + + + + February + + + + + March + + + + + April + + + + + June + + + + + July + + + + + August + + + + + September + + + + + October + + + + + Novermber + + + + + December + + + + + min length %1 + + + + + + min digit num %1 + + + + + + min upper num %1 + + + + + + min lower num %1 + + + + + + min other num %1 + + + + + + min char class %1 + + + + + + max repeat %1 + + + + + + max class repeat %1 + + + + + + max sequence %1 + + + + + + ukui-control-center is already running! + + + + + + Pwd input error, re-enter! + + + + + PulseAudio Volume Control + + + + + Connection to PulseAudio failed. Automatic retry in 5s + +In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties +or default-server in client.conf is misconfigured. +This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window. +If this is the case, then PulseAudio should autospawn again, or if this is not configured you should +run start-pulseaudio-x11 manually. + + + + + pa_context_subscribe() failed + + + + + Failed to initialize stream_restore extension: %s + + + + + pa_ext_stream_restore_read() failed + + + + + Error + + + + + Go to monitor settings page + + + + + Go to defaultapp settings page + + + + + Go to power settings page + + + + + Go to autoboot settings page + + + + + Go to printer settings page + + + + + Go to mouse settings page + + + + + Go to touchpad settings page + + + + + Go to keyboard settings page + + + + + Go to shortcut settings page + + + + + Go to audio settings page + + + + + Go to background settings page + + + + + Go to theme settings page + + + + + Go to screenlock settings page + + + + + Go to screensaver settings page + + + + + Go to fonts settings page + + + + + Go to desktop settings page + + + + + Go to netconnect settings page + + + + + Go to vpn settings page + + + + + Go to proxy settings page + + + + + Go to userinfo settings page + + + + + Go to cloudaccount settings page + + + + + Go to datetime settings page + + + + + Go to area settings page + + + + + Go to update settings page + + + + + Go to backup settings page + + + + + Go to notice settings page + + + + + Go to about settings page + + + + + RegDialog + + + Get + + + + + Your password here + + + + + Your account here + + + + + Confirm your password + + + + + Your code here + + + + + This operation is permanent + + + + + + At least 6 bit, include letters and digt + + + + + Your password is valid! + + + + + ResolutionSlider + + + No available resolutions + + + + + Screenlock + + + + Screenlock + + + + + Screenlock Interface + + + + + Screenlock Set + + + + + + Show picture of screenlock on screenlogin + + /screenlock/Show picture of screenlock on screenlogin + + + + + Lock screen when screensaver boot + + /screenlock/Lock screen when screensaver boot + + + + Lock screen delay + + + + + Select screenlock background + + + + + Browser online wp + + + + + Browser local wp + + + + + 5m + + + + + 10m + + + + + 30m + + + + + 45m + + + + + 1m + + + + + 1h + + + + + 1.5h + + + + + 3h + + + + + Screensaver + + + + Screensaver + + + + + + Enable screensaver + + /screensaver/Enable screensaver + + + + + Screensaver program + + /screensaver/Screensaver program + + + + + idle time + + /screensaver/idle time + + + + Lock screen when screensaver boot + + + + + Default_ukui + + + + + Blank_Only + + + + + 5m + + + + + 10m + + + + + 30m + + + + + 45m + + + + + 1m + + + + + 1h + + + + + 1.5h + + + + + 3h + + + + + SecurityCenter + + + SecurityCenter + + + + + Summarize + + + + + Recognize the current security of the system, and can take the necessary settings + + + + + Run Security Center + + + + + Security Center + + + + + Virus Protection + + + + + Protect system from threats + + + + + Network Protection + + + + + Setup app that can access web + + + + + App Execution Control + + + + + App install and exe protection + + + + + Account Security + + + + + Protect account and login security + + + + + ShareMain + + + Share + + + + + Allow others to view your desktop + + + + + Allow connection to control screen + + + + + Security + + + + + You must confirm every visit for this machine + + + + + Require user to enter this password: + + + + + Shortcut + + + + System Shortcut + + /shortcut/System Shortcut + + + + Show all shortcut + + + + + Reset default + + + + + + Custom Shortcut + + /shortcut/Custom Shortcut + + + + Add custom shortcut + + /shortcut/Add custom shortcut + + + + + disable + + + + + Shortcut + + + + + ShowAllShortcut + + + Dialog + + + + + System Shortcuts + + + + + Show all shortcut + + + + + + Desktop + + + + + SuccessDiaolog + + + Reback sign in + + + + + Sign up success! + + + + + + + + Confirm + + + + + Reset success! + + + + + Sign in success! + + + + + Binding phone success! + + + + + Theme + + + + Theme Mode + + /theme/Theme Mode + + + + + Icon theme + + /theme/Icon theme + + + + Control theme + + + + + + Cursor theme + + /theme/Cursor theme + + + + Effect setting + + + + + + Performance mode + + /theme/Performance mode + + + + + Transparency + + /theme/Transparency + + + + Reset to default + + + + + Theme + + + + + Default + + + + + Light + + + + + Dark + + + + + TimeZoneChooser + + + Cancel + + + + + Confirm + + + + + Change time zone + + + + + + change timezone + + + + + Touchpad + + + + Touchpad Settings + + /touchpad/Touchpad Settings + + + + Enabled touchpad + + + + + Disable touchpad while typing + + + + + Enable mouse clicks with touchpad + + + + + Scrolling + + + + + No touchpad found + + + + + Touchpad + + + + + Disable rolling + + + + + Vertical edge scrolling + + + + + Horizontal edge scrolling + + + + + Vertical two-finger scrolling + + + + + Horizontal two-finger scrolling + + + + + UkmediaInputWidget + + + Input + + + + + Input Device + + /audio/Input Device + + + + Volume + + /audio/Volume + + + + Input Level + + /audio/Input Level + + + + Low + + + + + High + + + + + Connector + + + + + UkmediaMainWidget + + + sound error + + + + + load sound failed + + + + + Establishing connection to PulseAudio. Please wait... + + + + + pa_ext_stream_restore_write() failed + + + + + UkmediaOutputWidget + + + Output + + + + + Output Device + + /audio/Output Device + + + + Master Volume + + /audio/Master Volume + + + + Balance + + /audio/Balance + + + + Right + + + + + Connector + + + + + Profile + + /audio/Profile + + + + Card + + /audio/Card + + + + Left + + + + + UkmediaSoundEffectsWidget + + + System Sound + + /audio/System Sound + + + + Sound Theme + + /audio/Sound Theme + + + + Alert Sound + + /audio/Alert Sound + + + + Alert Volume + + /audio/Alert Volume + + + + Boot Music + + /audio/Boot Music + + + + Beep Switch + + /audio/Beep Switch + + + + Window Closed + + + + + Volume Change + + + + + Setting Menu + + + + + UnifiedOutputConfig + + + resolution + + + + + orientation + + + + + arrow-up + + + + + 90° arrow-right + + + + + arrow-down + + + + + 90° arrow-left + + + + + refresh rate + + + + + auto + + + + + Update + + + + Update + + + + + + System Update + + /update/System Update + + + + Last check time: + + + + + Check for updates + + + + + UserInfo + + + Current User + + + + + + + Change pwd + + /userinfo/Change pwd + + + + + + Change type + + /userinfo/Change type + + + + + Change valid + + /userinfo/Change valid + + + + User group + + + + + + Login no passwd + + /userinfo/Login no passwd + + + + + enable autoLogin + + /userinfo/enable autoLogin + + + + Currently in Live mode, please create a new user and log out + + + + + Other Users + + + + + Add new user + + + + + User Info + + + + + standard user + + + + + administrator + + + + + root + + + + + Delete + + + + + Warning + + + + + The user is logged in, please delete the user after logging out + + + + + Vino + + + + Vino + + + + + Vpn + + + Add Vpn Connect + + + + + Add vpn connect + + /vpn/Add vpn connect + + + + Vpn + + + + + Wallpaper + + + Desktop Background + + + + + + Select from + + /wallpaper/Select from + + + + Picture options + + + + + + Browser online wp + + /wallpaper/Browser online wp + + + + + Browser local wp + + /wallpaper/Browser local wp + + + + + Reset to default + + /wallpaper/Reset to default + + + + + + Cancel + + + + + Ok + + + + + Background + + + + + picture + + + + + color + + + + + Custom color + + + + + wallpaper + + + + + centered + + + + + scaled + + + + + stretched + + + + + zoom + + + + + spanned + + + + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + + + + + allFiles(*.*) + + + + + + select custom wallpaper file + + + + + + Select + + + + + + Position: + + + + + + FileName: + + + + + + FileType: + + + + + Widget + + + unify output + + /display/unify output + + + + night mode + + /display/night mode + + + + Some applications need to be logouted to take effect + + + + + Information + + + + + Theme follow night mode + + + + + Hint + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after 10 seconds + + + + + Save Config + + + + + Restore Config + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after %1 seconds + + + + + please insure at least one output! + + + + + + Warning + + + + + Morning time should be earlier than evening time! + + + + + Sorry, your configuration could not be applied. +Common reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU. + + + + + @title:window + Unsupported Configuration + + + + + addShortcutDialog + + + Dialog + + + + + Shortcut name + + + + + Shortcut exec + + + + + Open + + + + + Invalid executable, please re-enter + + + + + + Cancel + + + + + Certain + + + + + Add custom shortcut + + + + + select desktop + + + + + changtimedialog + + + Dialog + + + + + current date + + + + + time + + + + + year + + + + + month + + + + + day + + + + + cancel + + + + + confirm + + + + + networkaccount + + + Cloud Account + + + + Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/i18n/tr.qm and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/i18n/tr.qm differ diff -Nru ukui-control-center-2.0.3/shell/res/i18n/tr.ts ukui-control-center-3.0.3/shell/res/i18n/tr.ts --- ukui-control-center-2.0.3/shell/res/i18n/tr.ts 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/i18n/tr.ts 2021-05-20 13:08:14.000000000 +0000 @@ -9,100 +9,166 @@ Sistem Özeti - + version Sürüm: - - TextLabel - + Copyright 2009-2020 @ Kylinos All rights reserved + Telif Hakkı 2009-2020 @ Kylinos Tüm hakları saklıdır - - Copyright 2009-2020 @ Kylinos All rights reserved - Telif Hakkı 2009-2020 @ Kylinos Tüm hakları saklıdır + Copyright 2009-2021 @ Kylinos All rights reserved + Telif Hakkı 2009-2020 @ Kylinos Tüm hakları saklıdır {2009-2021 ?} + + + + Version + + + + + Kylin Linux Desktop V10 (SP1) + + + + + Copyright © 2009-2021 KylinSoft. All rights reserved. + - + + Kernel Çekirdek: - + + CPU CPU: - + + Memory Hafıza: - + Disk Disk: - + Desktop Masaüstü: - + User Kullanıcı: - + Active Status Aktif Durum - + + Serial + + + + + Protocol + + + Service serial number - Servis Seri No + Servis Seri No - + Active Aktif - Trial version disclaimer - Deneme sürümü sorumluluk reddi + Deneme sürümü sorumluluk reddi + + + Devices Summary + Cihaz Özeti + + + about + Hakkında - + About Hakkında - - Disk One: - Disk Bir: + Disk: + Disk: - - Disk Two: - Disk İki: + available + Uygun - - available - Uygun + + The system has expired. The expiration time is: + - + Inactivated Aktif değil - + Activated Aktif + + UNKNOWN + BİLİNMEYEN + + + Current desktop env: + Aktif Masaüstü: + + + OS Version: + OS Sürümü: + + + CPU Arch: + CPU Mimarisi: + + + Kernel Version + Kernel Sürümü: + + + Manufacturers: + Üreticiler: + + + Product Name: + Ürün Adı: + + + Version: + Sürüm: + + + Serial Number: + Seri Numarası: + AddAppDialog @@ -120,50 +186,69 @@ AddAutoBoot - + Add AutoBoot Otomatik Başlatma Ekle - + Add autoboot program Oto başlat programı ekle - + + Program name Program adı - + + Program exec Program komutu - + Open - + + Program comment Program Açıklaması - + + Cancel İptal - + Certain Belirli - + + desktop file not exist + + + + select autoboot desktop otomatik önyükleme masaüstü seç + + + Desktop files(*.desktop) + + + + + Select + Seç + AppDetail @@ -173,184 +258,384 @@ - - TextLabel - + + App + - + Allow notification Bildirime İzin Ver - + Number of notification centers Bildirim merkezi numarası - + cancel İptal - + confirm Onayla + AppUpdateWid + + + Lack of local disk space! + + + + + + + + + + Update + + + + + Network abnormal! + + + + + + Download failed! + + + + + failed to get from the source! + + + + + The download cache has been removed + + + + + + + Ready to install + + + + + Being installed + + + + + + + Update succeeded , It is recommended that you restart later! + + + + + + + Update succeeded , It is recommended that you log out later and log in again! + + + + + + Update succeeded! + + + + + + Update failed! + + + + + Failure reason: + + + + + + details + + + + + + Update log + + + + + + + + Newest: + + + + + + Download size: + + + + + Current version: + + + + + back + + + + + A single update will not automatically backup the system, if you want to backup, please click Update All. + + + + + Prompt information + + + + + Do not backup, continue to update + + + + + + Cancel + İptal + + + + Cancel update + + + + + This time will no longer prompt + + + + + In the pause + + + + + Calculate the download progress + + + + + + Get depends failed! + + + + + In the update + + + + + No content. + + + + Area - + Area Alan - + Area showing time currency format Zaman para birimi biçimini gösteren alan - + Regional format data Bölgesel format verileri - - + + lunar Ay takvimi - + First day of the week Haftanın ilk günü - + day + Gün + + + 2019/12/17 - + 9:52 - - - TextLabel - + area + Alan - + current area Güncel Alan + /area/current area - display format area - Zaman Biçimi Düzeni + Zaman Biçimi Düzeni - + US - US + ABD - format of area - Zaman Biçimi + Zaman Biçimi + /area/format of area - + addwgt Widget Ekle - + Add main language Ana Dil Ekle - - + + calendar Takvim - + first day of week Haftanın ilk günü - - + + date Tarih - - + + time Zaman - - + + change format of data Zaman Biçimini Düzenle - + + first language Sistem Dili + /area/first language - + + system language Sistem Dili - + CN CN - + Need to cancel to take effect + Etkili olması için iptal etmeniz gerekiyor + + + + Need to log off to take effect Etkili olması için oturumu kapatmanız gerekiyor - + + country + + + + + regional format + + /area/regional format + + + English İngilizce - + Chinese Çince - + add main language + Ana dil ekle + + + solar calendar Güneş Takvimi - - + + monday Pazartesi - + sunday Pazar - + change data format Zaman Biçimini Düzenle @@ -358,16 +643,15 @@ AreaCodeLineEdit - Sign up by Phone - Telefonla kaydolun + Telefonla kaydolun Audio - + Audio Ses @@ -376,39 +660,61 @@ AutoBoot + Autoboot Settings Otomatik Açılış Ayarları + /autoboot/Autoboot Settings - + Add autoboot app Otomatik Yükleme Uygulaması Ekle - + autoboot + Otomatik Başlat + + Autoboot - Oto başlat + Oto. başlat + + + + Auto Boot + Oto. Başlat - + Name İsim - + Status Durum + + + Delete + Sil + Backup - + + Backup Yedekle + Back up your files to other drives, and when the original files are lost, damaged, or deleted, you can restore them to ensure +the integrity of your system. + Dosyalarınızı diğer sürücülere yedekleyin ve orijinal dosyalar kaybolduğunda, hasar gördüğünde veya silindiğinde, bunları sağlamak için geri yükleyebilirsiniz. +sisteminizin bütünlüğü. + + Back up your files to other drives, and when the original files are lost, damaged, or deleted, you can restore them to ensure the integrity of your system. @@ -416,3246 +722,6388 @@ sisteminizin bütünlüğünü sağlamak için bunları geri yükleyebilirsiniz. - + Begin backup Yedekleme Başlat - + + Restore Geri Yükle - + + View a list of backed-upfiles to backed up files to the system + + + View a list of backed-upfiles to restore backed up files to the system - Yedeklenen dosyaları sisteme geri yüklemek için yedeklenmiş dosyaların listesini görüntüle + Yedeklenen dosyaları sisteme geri yüklemek için yedeklenmiş dosyaların listesini görüntüle - + Begin restore Yükleme Başlat + + backup + Yedekleme + BindPhoneDialog - + Your account here + Hesabınız burada + + + Your password here + Parolanız burada + + Your code here - Kodunuz Burada + Kodunuz Burada + + + Get + Al - Get phone code - Telefon kodu al + Telefon kodu al - CertificationDialog + BiometricEnrollDialog - - - UserCertification - Kullanıcı Sertifikası + + Dialog + - - User: - Kullanıcı: + + Biometrics + - - Passwd: - Parola: + + Continue to enroll + - - Close - Kapat + + Finish + - - Certification - Sertifika + + FingerPrint + - - - ChangeFaceDialog - - select custom face file - Özel yüz dosyası seç + + Fingervein + - - Select - Seç: + + Iris + - - Position: - Konum: + + Face + - - FileName: - Dosya Adı: + + VoicePrint + - - FileType: - Dosya türü: + + Enroll + - - Cancel - İptal + + Verify + - - Warning - Uyarı + + Search + Ara - - The avatar is larger than 2M, please choose again - Avatar 2M'den büyük, lütfen başka seçin + + Permission is required. +Please authenticate yourself to continue + - - Change User Face - Kullanıcı Logosunu Değiştir - - - - Select face from local - Bilgisayardan Logo Seçin + + + Enroll successfully + - - - ChangePwdDialog - - Change Pwd - Parola Değiştir + + + Verify successfully + - - Pwd type - Parola türü + + Not Match + - - New pwd - Yeni parola + + D-Bus calling error + - - New pwd sure - Yeniden Parola + + Device is busy + - - Cancel - İptal + + No such device + - - Confirm - Onayla + + Permission denied + + + + BiometricMoreInfoDialog - - General Pwd - Genel Parola + + Dialog + - - - New Password - Yeni Parola + + Biometrics + - - - New Password Identify - Yeni Parola Tanımlama + + Default device + - - Password length needs to more than %1 character! - Şifre uzunluğu %1 karakterden fazla olmalı! + + Verify Type: + - - Password length needs to less than %1 character! - Şifre uzunluğu %1 karakterden az olmalı! + + Bus Type: + - - - Inconsistency with pwd - Parola ile tutarsızlık + + Device Status: + - - - ChangeTypeDialog - - Make sure that there is at least one administrator on the computer - Bilgisayarda en az bir yönetici olduğundan emin olun + + Storage Type: + - - Standard users can use most software, but cannot install software and change system settings - Standart kullanıcılar çoğu yazılımı kullanabilir, ancak yazılım yükleyemez ve sistem ayarlarını değiştiremez + + Identification Type: + - - Change Account Type - Hesap Türünü Değiştir + + Connected + - - standard user - Standart kullanıcı + + Unconnected + - - administrator - Yönetici + + FingerPrint + - - Administrators can make any changes they need - Yöneticiler istedikleri değişiklikleri yapabilir + + Fingervein + - - Cancel - İptal + + Iris + - - Confirm - Onayla + + Face + - - - ChangeValidDialog - - Dialog + + VoicePrint - - Password Validity Setting - Şifre Geçerlilik Ayarı + + Hardware Verification + - - Current passwd validity: - Mevcut şifre geçerliliği: + + Software Verification + - - Adjust date to: - Tarihi şu şekilde ayarlayın: + + Mix Verification + - - Cancel - İptal + + Other Verification + - - Certain + + Device Storage - - - ChangtimeDialog - - day - Gün + + OS Storage + - - time - Saat + + Mix Storage + - - - year - Yıl + + Serial + - - - month - Ay + + USB + - - - ColorDialog - - Dialog + + PCIE - - B + + Any - - Cancel - İptal + + Other + - - OK - Tamam + + Hardware Identification + - - R + + Software Identification - - G + + Mix Identification - - Custom color + + Other Identification - CreateUserDialog + BlueToothMain - - - UserName - Kullanıcı Adı + + Bluetooth + + /bluetooth/Bluetooth - - - Password - Parola + + Bluetooth adapter + - - Account Type - Hesap Türü + + Show icon on taskbar + + /bluetooth/Show icon on taskbar - - Add New Account - Yeni Hesap Ekle + + Allow Bluetooth devices to be discoverable + + /bluetooth/Discoverable - - PwdType - Parola Türü + + My Devices + - - PasswordSure - Parola Güvenliği + + Other Devices + + /bluetooth/Other Devices - - standard user - Standart kullanıcı + + Refresh + Yenile - - Standard users can use most software, but cannot install the software and -change system settings - Standart kullanıcılar çoğu yazılımı kullanabilir, ancak yazılımı ve -sistem ayarlarını değiştir + + + + + Turn on Bluetooth + + + + Bluetooth - - administrator - Yönetici + + Bluetooth + + + + BluetoothNameLabel - - Administrators can make any changes they need - Yöneticiler istedikleri değişiklikleri yapabilir + + + + + + Can now be found as "%1" + + + + CertificationDialog - - Cancel - İptal + + + UserCertification + Kullanıcı Sertifikası - - Confirm - Onayla + + User: + Kullanıcı: - - Password Identify - Parola Tanımlama + + Passwd: + Parola: - - General Password - Genel Parola + + Close + Kapat - - - Inconsistency with pwd - Parola ile tutarsız + + Certification + Sertifika + + + ChangeFaceDialog - - Password length needs to more than %1 character! - Şifre uzunluğu %1 karakterden fazla olmalı! + + select custom face file + Özel yüz dosyası seç - - Password length needs to less than %1 character! - Şifre uzunluğu %1 karakterden az olmalı! + + Select + Seç: - - The user name cannot be empty - Kullanıcı adı boş olamaz + + Position: + Konum: - - The first character must be lowercase letters! - İlk karakter küçük harf olmalıdır! + + FileName: + Dosya Adı: - - User name can not contain capital letters! - Kullanıcı adı büyük harf içeremez! + + FileType: + Dosya türü: - - The user name is already in use, please use a different one. - Kullanıcı adı zaten kullanılıyor, lütfen farklı bir ad kullanın. + + + Cancel + İptal - - User name length need to less than %1 letters! - Kullanıcı adı uzunluğu %1 harften az olmalı! + + Warning + Uyarı - - The user name can only be composed of letters, numbers and underline! - Kullanıcı adı sadece harf, rakam ve altı çizili olabilir! + + The avatar is larger than 1M, please choose again + Avatar 2M'den büyük, lütfen başka seçin {1M?} - - The username is configured, please change the username - Kullanıcı adı yapılandırıldı, lütfen kullanıcı adını değiştirin + The avatar is larger than 2M, please choose again + Avatar 2M'den büyük, lütfen başka seçin - - - DataFormat - - Dialog - + + Change User Face + Kullanıcı Logosunu Değiştir - - change format of data - Veri biçimini değiştir + + System Icon + - - - calendar - Takvim + + Select face from local + Bilgisayardan Logo Seçin - - first day - Haftanın İlk Günü + + Save + + + + ChangeGroupDialog - - - date - Tarih + + Dialog + - - - time - Saat + + User Group Settings + Kullanıcı Grubu Ayarları - - cancel - İptal + + Cancel + İptal - - confirm - Doğrula + User groups available in the system + Sistemde bulunan kullanıcı grupları - - first day of week - Haftanın ilk günü + Add new user + Yeni Kullanıcı Ekle - - lunar - Ay Takvimi + + User group + Kullanıcı Grubu - - solar calendar - Güneş Takvimi + + Add user group + Kullanıcı grubu ekle - - monday - Pazartesi + + + Tips + - - sunday - Pazar + + Invalid Id! + + + + + + OK + Tamam + + + + Invalid Group Name! + - DateTime + ChangePwdDialog - - DateTime - Tarih Zaman + + Change Pwd + Parola Değiştir - - current date - Şimdiki tarih + + Pwd type + Parola türü - - - - TextLabel - + + Cur pwd + - - timezone - Zaman dilimi + + New pwd + Yeni parola - - - Sync system time - Sistem Saatini Senkronize Et + + New pwd sure + Yeniden Parola - - - Change time - Saati değiştir + + Cancel + İptal - - - Change time zone - Zaman dilimini değiştir + + Confirm + Onayla - - Sync complete - Senkronizasyon Tamamlandı + + Change pwd + Parola Değiştir - - Datetime - Tarih Saat + + General Pwd + Genel Parola - - 24-hour clock - 24 saat biçimi + + + Current Password + - - change time - Saati değiştir + + + + New Password + Yeni Parola - - - DefaultApp - - Defaultapp - Varsayılan Uygulama + + + + New Password Identify + Yeni Parola Tanımlama + + + + Pwd input error, re-enter! + + + + + Contains illegal characters! + Uygun olmayan karakterler içeriyor! + + + + Same with old pwd + + + + Password length needs to more than %1 character! + Şifre uzunluğu %1 karakterden fazla olmalı! + + + Password length needs to less than %1 character! + Şifre uzunluğu %1 karakterden az olmalı! + + + Password length needs to more than 5 character! + Şifre uzunluğu 5 karakterden fazla olmalıdır! + + + + + Inconsistency with pwd + Parola ile tutarsızlık - DefaultAppWindow + ChangeTypeDialog - - Select Default Application - Varsayılan Uygulama Seç + + Make sure that there is at least one administrator on the computer + Bilgisayarda en az bir yönetici olduğundan emin olun - - Browser - Web Tarayıcı: + Standard users can use most software, but cannot install software and change system settings + Standart kullanıcılar çoğu yazılımı kullanabilir, ancak yazılım yükleyemez ve sistem ayarlarını değiştiremez - - Mail - E-Posta: + + Change Account Type + Hesap Türünü Değiştir - - Image Viewer - Resim Görüntüleyici: + + standard user + Standart kullanıcı - - Audio Player - Ses Oynatıcı: + + Standard users can use most software, but cannot change system settings + - - Video Player - Video Oynatıcı: + + administrator + Yönetici - - Text Editor - Metin Düzenleyici: + + Administrators can make any changes they need + Yöneticiler istedikleri değişiklikleri yapabilir + + + + Cancel + İptal + + + + Confirm + Onayla + + + + Change type + Türü Değiştir - DefineShortcutItem + ChangeUserName - - Delete - Sil + + + Change Username + + + + + Cancel + İptal + + + + Save + - DelUserDialog + ChangeVaildDialog - - Delete the user, belonging to the user's desktop, -documents, favorites, music, pictures and video -folder will be deleted! - Kullanıcıyı sil, kullanıcının masaüstü, belgeler, sık kullanılanlar, müzik, resim ve video klasörü silinecektir! + Password Validity Setting + Parola Geçerlilik Ayarı + + + Current passwd validity: + Mevcut şifre geçerliliği: + + + Adjust date to: + Tarihi şu şekilde ayarlayın: + + + Cancel + İptal + + + Certain + Belirli + + + + ChangeValidDialog + + + Dialog + + + + + Password Validity Setting + Şifre Geçerlilik Ayarı + + + + Current passwd validity: + Mevcut şifre geçerliliği: + + + + Adjust date to: + Tarihi şu şekilde ayarlayın: - + Cancel İptal - - KeepFile - Dosyayı Tut + + Certain + Belirli - - RemoveFile - Dosya Sil + + Change valid + Geçerliliğini Değiştir - Desktop + ChangtimeDialog - - Icon Show On Desktop - Masaüstünde Simgeleri Göster + + day + Gün - - Computerdesktop - Bilgisayar + + time + Saat - - Trashdesktop - Çöp + + year + Yıl - - Homedesktop - Giriş + + month + Ay + + + ColorDialog - - Volumedesktop - Birimler + + Dialog + - - Networkdesktop - + + B + M - - Set Start Menu - Başlat Menüsü Ayarla + + Cancel + İptal - - Always use the start menu in full screen - Her zaman tam ekranda başlat menüsünü kullanın + + OK + Tamam - - Icon Lock on Menu - Menüde Kilit Simgesi + + R + K - - Computermenu - Bilgisayar + + G + Y - - Trashmenu - Çöp Kutusu + + Custom color + Özel renk + + + CreateGroupDialog - - Filesystemmenu - Dosya Sistemi + + Dialog + - - Tray icon - Tepsi Simgesi + + Add New Group + Yeni Grup Ekle - - Settingmenu - Ayarlar + + Name + İsim - - Desktop - Masaüstü + + Id + Id + + + + Members + Üyeler + + + Group Name + Grup Adı + + + Group Id + Grup ID + + + Group Members + Grup Üyeleri + + + + Cancel + İptal + + + + Certain + Belirli + + + + Add user group + Kullanıcı grubu ekle + + + + CreateUserDialog + + + + UserName + Kullanıcı Adı + + + + + Password + Parola + + + + Account Type + Hesap Türü + + + + Add New Account + Yeni Hesap Ekle + + + + PwdType + Parola Türü + + + + PasswordSure + Parola Güvenliği + + + + standard user + Standart kullanıcı + + + + Standard users can use most software, but cannot change system settings + + + + Standard users can use most software, but cannot install the software and +change system settings + Standart kullanıcılar çoğu yazılımı kullanabilir, ancak yazılımı ve +sistem ayarlarını değiştir + + + + administrator + Yönetici + + + + Administrators can make any changes they need + Yöneticiler istedikleri değişiklikleri yapabilir + + + + Cancel + İptal + + + + Confirm + Onayla + + + + Password Identify + Parola Tanımlama + + + + General Password + Genel Parola + + + + + Inconsistency with pwd + Parola ile tutarsız + + + + Must be begin with lower letters! + + + + + Can not contain capital letters! + + + + + Name already in use, change another one. + + + + + Name corresponds to group already exists. + + + + + Name length must less than %1 letters! + + + + + Can only contain letters,digits,underline! + + + + + Username's folder exists, change another one + + + + Password length needs to more than %1 character! + Şifre uzunluğu %1 karakterden fazla olmalı! + + + Password length needs to less than %1 character! + Şifre uzunluğu %1 karakterden az olmalı! + + + + Add new user + Yeni Kullanıcı Ekle + + + Password cannot be made up entirely by Numbers! + Parola tamamen Sayılarla oluşturulamaz! + + + + Contains illegal characters! + Uygun olmayan karakterler içeriyor! + + + + The user name cannot be empty + Kullanıcı adı boş olamaz + + + The first character must be lowercase letters! + İlk karakter küçük harf olmalıdır! + + + User name can not contain capital letters! + Kullanıcı adı büyük harf içeremez! + + + The user name is already in use, please use a different one. + Kullanıcı adı zaten kullanılıyor, lütfen farklı bir ad kullanın. + + + User name length need to less than %1 letters! + Kullanıcı adı uzunluğu %1 harften az olmalı! + + + The user name can only be composed of letters, numbers and underline! + Kullanıcı adı sadece harf, rakam ve altı çizili olabilir! + + + The username is configured, please change the username + Kullanıcı adı yapılandırıldı, lütfen kullanıcı adını değiştirin + + + + CustomLineEdit + + + New Shortcut... + Yeni Kısayol + + + + DataFormat + + + Dialog + + + + + change format of data + Veri biçimini değiştir + + + + + calendar + Takvim + + + + first day + Haftanın İlk Günü + + + + + date + Tarih + + + + + time + Saat + + + + cancel + İptal + + + + confirm + Doğrula + + + + first day of week + Haftanın ilk günü + + + + lunar + Ay Takvimi + + + + solar calendar + Güneş Takvimi + + + + monday + Pazartesi + + + + sunday + Pazar + + + + DateTime + + + DateTime + Tarih Zaman + + + + current date + Şimdiki tarih + + + timezone + Zaman dilimi + + + Sync system time + Sistem Saatini Senkronize Et + /datetime/Sync system time + + + + Sync from network + + + + + + Change time + Saati değiştir + /date/Change time + + + + + Change time zone + Zaman dilimini değiştir + /date/Change time zone + + + Sync complete + Senkronizasyon Tamamlandı + + + datetime + Tarih Saat + + + Datetime + Tarih Saat + + + + Date + + + + + 24-hour clock + 24 saat biçimi + /date/24-hour clock + + + + change time + Saati değiştir + + + + + + + + + + Sync from network failed + + + + + DefaultApp + + defaultapp + Varsayılan Uygulama + + + Defaultapp + Varsayılan Uygulama + + + + Default App + Varsayılan Uygulama + + + + Browser + Web Tarayıcı: + /defaultapp/Browser + + + + Mail + E-Posta: + /defaultapp/Mail + + + + Image Viewer + Resim Görüntüleyici: + /defaultapp/Image Viewer + + + + Audio Player + Ses Oynatıcı: + /defaultapp/Audio Player + + + + Video Player + Video Oynatıcı: + /defaultapp/Video Player + + + + Text Editor + Metin Düzenleyici: + /defaultapp/Text Editor + + + + DefaultAppWindow + + + Select Default Application + Varsayılan Uygulama Seç + + + + Browser + Web Tarayıcı: + + + + Mail + E-Posta: + + + + Image Viewer + Resim Görüntüleyici: + + + + Audio Player + Ses Oynatıcı: + + + + Video Player + Video Oynatıcı: + + + + Text Editor + Metin Düzenleyici: + + + + Reset to default + Varsayılana dön + + + + DefineGroupItem + + + Edit + Düzenle + + + + Delete + Sil + + + + DefineShortcutItem + + + Delete + Sil + + + + DelGroupDialog + + + Dialog + + + + + TextLabel + + + + Are you sure to delete this group, +which will make some file components +in the file system invalid! + Bu grubu silmek istediğinizden emin misiniz, +bazı dosya bileşenleri oluşturacak +dosya sisteminde geçersiz! + + + + Delete + Sil + + + + Cancel + İptal + + + RemoveFile + Dosya Sil + + + Remind + Hatırlat + + + Are you sure to delete "%1" group, +which will make some file components +in the file system invalid! + %1 grubu silmek istediğinizden emin misiniz, +bazı dosya bileşenleri oluşturacak +dosya sisteminde geçersiz! + + + + Delete user group + + + + + Are you sure to delete the group, which will make some file components in the file system invalid! + + + + + DelUserDialog + + Delete the user, belonging to the user's desktop, +documents, favorites, music, pictures and video +folder will be deleted! + Kullanıcıyı sil, kullanıcının masaüstü, belgeler, sık kullanılanlar, müzik, resim ve video klasörü silinecektir! + + + + keep the user's data, like desktop,documents, favorites, music, pictures and so on + + + + + delete whole data belong user + + + + + Cancel + İptal + + + + Delete + Sil + + + KeepFile + Dosyayı Tut + + + RemoveFile + Dosya Sil + + + + Delete the user ' + + + + + 'and: + + + + + Desktop + + + + Icon Show On Desktop + Masaüstünde Simgeleri Göster + /desktop/Icon Show On Desktop + + + + Computerdesktop + Bilgisayar + + + + Trashdesktop + Çöp + + + + Homedesktop + Giriş + + + + Volumedesktop + Birimler + + + + Networkdesktop + + + + + Set Start Menu + Başlat Menüsü Ayarla + + + + Always use the start menu in full screen + Her zaman tam ekranda başlat menüsünü kullanın + + + + Icon Lock on Menu + Menüde Kilit Simgesi + + + + Computermenu + Bilgisayar + + + + Trashmenu + Çöp Kutusu + + + + Filesystemmenu + Dosya Sistemi + + + + + Tray icon + Tepsi Simgesi + /desktop/Tray icon + + + Homemenu + Giriş + + + + Settingmenu + Ayarlar + + + Networkmenu + + + + desktop + Masaüstü + + + + Desktop + Masaüstü + + + + DeviceInfoItem + + + Connect + Bağlan + + + + Disconnect + Bağlantıyı kes + + + + Remove + + + + + DeviceType + + + FingerPrint + + + + + FingerVein + + + + + Iris + + + + + Face + + + + + VoicePrint + + + + + Dialog_login_reg + + Sign in + Oturum aç + + + Sign up + Kayıt ol + + + Login in progress + Giriş devam ediyor + + + Error code: + Hata kodu: + + + ! + ! + + + Internal error occurring! + Dahili hata meydana geliyor! + + + Failed to sign up! + Kayıt başarısız oldu! + + + Failed attempt to return value! + Değer döndürme denemesi başarısız oldu! + + + Check your connection! + Bağlantınızı kontrol edin! + + + Failed to get by phone! + Telefonla ulaşılamadı! + + + Failed to get by user! + Kullanıcı tarafından alınamadı! + + + Failed to reset password! + Şifre sıfırlanamadı! + + + Phone binding falied! + Telefon bağlantısı hatalı! + + + Please check your information! + Lütfen bilgilerinizi kontrol edin! + + + Please check your account! + Lütfen hesabınızı kontrol edin! + + + Failed due to server error! + Sunucu hatası nedeniyle başarısız oldu! + + + User existing! + Kullanıcı var! + + + Phone number already in used! + Telefon numarası zaten kullanılıyor! + + + Please check your format! + Lütfen formatınızı kontrol edin! + + + Your are reach the limit! + Sınıra ulaştın! + + + Please check your phone number! + Lütfen telefon numaranızı kontrol edin! + + + Please check your code! + Lütfen kodunuzu kontrol edin! + + + Account doesn't exist! + Hesap mevcut değil! + + + User has bound the phone! + Kullanıcı telefonu bağladı! + + + Sending code error occurring! + Kod gönderme hatası oluşuyor! + + + Your code is wrong! + Kodunuz yanlış! + + + Binding Phone + Telefon Bağlanıyor + + + Bind now + Şimdi bağla + + + Resend ( %1 ) + Yeniden gönder (%1) + + + Get phone code + Telefon kodunu alın + + + Send + Gönder + + + At least 6 bit, include letters and digt + En az 6 bit, harf ve rakam içermelidir + + + Please check your password! + Lütfen şifrenizi kontrol edin! + + + Sign in Cloud + Bulutta oturum açın + + + Forget + Unut + + + Set + Ayarla + + + Back + Geri + + + Create Account + Hesap Oluştur + + + Sign up now + Şimdi kayıt ol + + + + DisplayPerformanceDialog + + + Dialog + + + + + Display Advanced Settings + Gelişmiş Ayarları Göster + + + + Performance + Performans + + + + Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. + 3D grafiklerin oluşturulmasını hızlandırabilen ayrı grafiklere sahip makine için geçerlidir. + + + + (Note: not support connect graphical with xmanager on windows.) + (Not: Pencerede xmanager ile grafiksel bağlantıyı desteklemez.) + + + + Compatible + Uyumlu + + + + Applicable to machine with integrated graphics, there is no 3D graphics acceleration. + Dahili ekran kartı olan bilgisayara uygulanabilir, 3D grafik hızlandırma yoktur. + + + + (Note: need connect graphical with xmanager on windows, use this option.) + (Not: Pencerede xmanager ile grafiksel olarak bağlanmanız gerekir, bu seçeneği kullanın.) + + + + Automatic + Otomatik + + + + Auto select according to environment, delay the login time (about 0.5 sec). + Ortama göre otomatik seçim, oturum açma süresini geciktirir (yaklaşık 0,5 sn.). + + + + Threshold: + Eşik: + + + + Apply + Uygula + + + + Reset + Sıfırla + + + + (Note: select this option to use 3D graphics acceleration and xmanager.) + (Not: 3D grafik hızlandırma ve xmanager kullanmak için bu seçeneği seçin.) + + + + DisplaySet + + display + Ekran + + + + Display + Ekran + + + + DisplayWindow + + + Form + + + + + monitor + Ekran: + + + + set as home screen + Ana Ekran Yap + + + close monitor + Ekranı Kapat + + + + unify output + Çıktıyı Birleştir + + + + open monitor + Monitörü Aç + + + + Display + Ekran + + + + Advanced + Gelişmiş + + + + screen brightness adjustment + Ekran Parlaklığı + + + + dark + Koyu + + + + bright + Açık + + + + follow the sunrise and sunset(17:55-05:04) + Gün doğumunu ve gün batımını takip et(17:55-05:04) + + + + custom time + Özel zaman + + + + opening time + Açılış zamanı + + + + closing time + Kapanış zamanı + + + + color temperature + Renk Sıcaklığı + + + + warm + Ilık + + + + cold + Soğuk + + + + apply + Uygula + + + + EditGroupDialog + + + Dialog + + + + + Cancel + İptal + + + + Certain + Belirli + + + + Edit User Group + Kullanıcı Grubunu Düzenle + + + + Name + İsim + + + + Id + Id + + + + Members + Üyeler + + + + Tips + + + + + Invalid Id! + + + + + OK + Tamam + + + + Edit user group + + + + + EditPassDialog + + Edit Password + Parolayı Düzenle + + + Your account here + Hesabınız burada + + + Your password here + Parolanız burada + + + Your new password here + Yeni parolanız burada + + + Your code here + Kodunuz burada + + + Your code + Kodunuz + + + Get phone code + Telefon kodunu al + + + Cancel + İptal + + + Confirm + Onayla + + + Confirm your new password + Yeni parolanızı onaylayın + + + At least 6 bit, include letters and digt + En az 6 karakter, harf ve rakam ekleyin + + + Your password is valid! + Parolanız geçerlidir! + + + Please check your password! + Lütfen şifrenizi kontrol edin! + + + Resend( + Yeniden gönder( + + + ) + ) + + + Send + Gönder + + + Success! + Başarılı! + + + Reback sign in + Yeniden oturum aç + + + Error code: + Hata kodu: + + + ! + ! + + + Internal error occurring! + Dahili hata oluştu! + + + Failed to sign up! + Kaydolamadı! + + + Failed attempt to return value! + Değer döndürülemedi! + + + Check your connection! + Bağlantınızı kontrol edin! + + + Failed to get by phone! + Telefonla alınamadı! + + + Failed to get by user! + Kullanıcı tarafından alınamadı! + + + Failed to reset password! + Şifre sıfırlanamadı! + + + Please check your information! + Lütfen bilgilerinizi kontrol edin! + + + Please check your account! + Lütfen hesabınızı kontrol edin! + + + Failed due to server error! + Sunucu hatası nedeniyle başarısız oldu! + + + User existing! + Kullanıcı mevcut! + + + Phone number already in used! + Telefon numarası zaten kullanılıyor! + + + Please check your format! + Lütfen biçiminizi kontrol edin! + + + Your are reach the limit! + Sınıra ulaşıyorsunuz! + + + Please check your phone number! + Lütfen telefon numaranızı kontrol edin! + + + Please check your code! + Lütfen kodunuzu kontrol edin! + + + Account doesn't exist! + Hesap mevcut değil! + + + Sending code error occurring! + Gönderme kodu hatası oluştu! + + + + EditPushButton + + Reset + Sıfırla + + + + ExperiencePlan + + + User Experience + Kullanıcı Deneyimi + + + + Join in user Experience plan + Kullanıcı Deneyimi planına katılın + + + + User experience plan terms, see + Kullanıcı deneyimi planı şartları, bkz + + + + 《User Experience plan》 + (Kullanıcı Deneyimi Planı) + + + experienceplan + Deneyim Planı + + + + Experienceplan + Deneyim Planı + + + + Fonts + + + + Fonts + Yazı Tipi + + + + + Fonts select + Font Seç + /fonts/Fonts select + + + + + + Font size + Font Boyutu + /fonts/Font size + + + + Mono font + + + + + Reset to default + Varsayılana Sıfırla + + + + Gtk default font + Gtk Fontu + + + + Document font + Belge Fontu: + + + + Monospace font + Monospace Fontu: + + + + Advanced settings + Gelişmiş Ayarlar + + + Peony font + Peony Fontu: + + + + titlebar font + Başlık Fontu: + + + + Select text sample that looks clearest + En net görünen metin örneğini seç + + + fonts + Fontlar + + + + 11 + 11 + + + + 12 + 12 + + + + 13 + 13 + + + + 14 + 14 + + + + 15 + 15 + + + + 16 + 16 + + + + Thanks For Using The ukcc + Denetim Merkezini kullandığınız için teşekkürler + + + + FrameItem + + Sync failed, please login out to retry! + Senkronizasyon başarısız, tekrar denemek için lütfen giriş yapın! + + + Change configuration file failed, please login out to retry! + Yapılandırma dosyasını değiştiremedi, tekrar denemek için lütfen oturumu kapatın! + + + Configuration file not exist, please login out to retry! + Yapılandırma dosyası mevcut değil, lütfen yeniden denemek için giriş yapın! + + + Cloud verifyed file download failed, please login out to retry! + Bulutla doğrulanmış dosya indirme işlemi başarısız oldu, yeniden denemek için lütfen oturumu kapatın! + + + OSS access failed, please login out to retry! + OSS erişimi başarısız, yeniden denemek için lütfen oturumu kapatın! + + + Sync failed, please retry or login out to get a better experience! + Senkronizasyon başarısız oldu, daha iyi bir deneyim için lütfen tekrar deneyin veya oturum açın! + + + Change configuration file failed, please retry or login out to get a better experience! + Yapılandırma dosyasını değiştirme başarısız oldu, daha iyi bir deneyim için lütfen tekrar deneyin veya oturumu kapatın! + + + Configuration file not exist, please retry or login out to get a better experience! + Yapılandırma dosyası mevcut değil, daha iyi bir deneyim için lütfen yeniden deneyin veya oturum açın! + + + Cloud verifyed file download failed, please retry or login out to get a better experience! + Bulutla doğrulanmış dosya indirme işlemi başarısız oldu, daha iyi bir deneyim için lütfen tekrar deneyin veya oturumu kapatın! + + + OSS access failed, please retry or login out to get a better experience! + OSS erişimi başarısız oldu, daha iyi bir deneyim için lütfen tekrar deneyin veya oturumu kapatın! + + + + + Sync failed,please relogin! + + + + + Change configuration file failed,please relogin! + + + + + Configuration file not exist,please relogin! + + + + + Cloud verifyed file download failed,please relogin! + + + + + OSS access failed,please relogin! + + + + + HistoryUpdateListWig + + + Success + + + + + Failed + + + + + ItemList + + Walpaper + Duvar Kağıdı + + + + ScreenSaver + Ekran Koruyucu + + + + Menu + Menü + + + + Quick Start + Hızlı Başlat + + + + Avatar + Avatar + + + + Tab + Sekme + + + + Font + + + + + Wallpaper + + + + + Themes + Temalar + + + + Area + Alan + + + + Date/Time + Tarih/Zaman + + + + Default Open + Varsayılan Açık + + + + Notice + Bildirim + + + + Option + Seçenek + + + + Peony + Peony + + + + Weather + Hava Durumu + + + + Media + Medya + + + + Boot + Boot + + + + Power + Güç + + + + Editor + Düzenleyici + + + + Terminal + Uçbirim + + + + Mouse + Fare + + + + TouchPad + Dokunmatik Yüzey + + + + KeyBoard + Klavye + + + + ShortCut + Kısayol + + + + KbPreviewFrame + + + No preview found + Önizleme bulunamadı + + + + Unable to open Preview ! + Önizleme açılamıyor! + + + + KbdLayoutManager + + + C + C + + + + L + L + + + + Variant + Varyant + + + + Add + Ekle + + + + Add Layout + Düzen Ekle + + + + Del + Sil + + + + Keyboard Preview + Klavye Önizleme + + + + KeyValueConverter + + system + Sistem + + + devices + Aygıtlar + + + personalized + Özelleştirme + + + network + + + + account + Hesap + + + datetime + Tarih Saat + + + update + Güncelleme + + + messages + Mesajlar + + + + System + Sistem + + + + Devices + Aygıtlar + + + + Personalized + Özelleştirme + + + + Network + + + + + Account + Hesap + + + + Datetime + Tarih-Zaman + + + + Update + Güncelleme + + + + Messages + Mesajlar + + + + KeyboardControl + + + Keys Settings + Anahtar Ayarları + + + + + Enable repeat key + Yenileme tuşunu etkinleştir + /keyboard/Enable repeat key + + + + + Delay + Gecikme + /keyboard/Delay + + + + Short + Kısa + + + + Long + Uzun + + + + + Speed + Hız + /keyboard/Speed + + + + Slow + Yavaş + + + + Fast + Hızlı + + + + Input characters to test the repetition effect: + Tekrarlama etkisini test etmek için karakterleri girin: + + + + Input Settings + + + + + Input Set + + + + + Input characters to test the repetition effect: + Tekrarlama etkisini test etmek için karakterleri girin: + /keyboard/Input characters to test the repetition effect: + + + + + Tip of keyboard + Klavye İpucu + /keyboard/Tip of keyboard + + + reset default layout + Varsayılan Düzene Dön + /keyboard/reset default layout + + + Reset layout + Düzeni Sıfırla + + + Message of capslock + Capslock mesajı + + + + Enable numlock + Numlock Etkinleştir + + + Keyboard Layout + Klavye Düzeni + + + + + Keyboard layout + Klavye Düzeni + /keyboard/Keyboard layout + + + Install layouts + Klavye kur + + + keyboard + Klavye + + + + Keyboard + Klavye + + + + KeyboardPainter + + + Close + Kapat + + + + + Keyboard layout levels + Klavye düzeni seviyeleri + + + + + Level %1, %2 + Seviye %1, %2 + + + + LayoutManager + + + Dialog + + + + + Manager Keyboard Layout + Yönetici Klavye Düzeni + + + + Language + Dil + + + + Country + Ülke + + + + Variant + Düzen + + + + Layout installed + Düzen yüklendi + + + + Preview + Önizleme + + + + Cancel + İptal + + + + Install + Kur + + + + LoginDialog + + + Forget + Unut + + + + Send + Gönder + + + + User Sign in + Kullanıcı Girişi + + + + Quick Sign in + Hızlı Giriş + + + + Your account/phone here + Hesabınız/telefonunuz burada + + + Your account here + Kodunuz Burada + + + + Your phone number here + Telefon Numaranız Burada + + + + Your account/phone/email here + + + + + Your password here + Parolanız Burada + + + + + Your code here + Kodunuz Burada + + + + MCodeWidget + + + SongTi + SongTi + + + + MainDialog + + + + + + + + + Sign in + Oturum Aç + + + + Sign up + Kayıt Ol + + + + Login in progress + Giriş devam ediyor + + + + Error code: + Hata kodu: + + + + ! + ! + + + Internal error occurring! + Dahili hata oluştu! + + + + Internal error occurred! + Dahili hata oluştu! + + + + Failed to sign up! + Oturum açma hatalı! + + + + Failed attempt to return value! + Değer döndürme denemesi başarısız oldu! + + + + Check your connection! + Bağlantınızı kontrol edin! + + + + Failed to get by phone! + Telefonla ulaşılamadı! + + + + Failed to get by user! + Kullanıcı tarafından alınamadı! + + + + Failed to reset password! + Şifre sıfırlanamadı! + + + + Timeout! + Zaman aşımı! + + + + Phone binding falied! + Telefon bağlantısı hatalı! + + + + + Please check your information! + Lütfen bilginizi kontrol edin! + + + + Please check your account! + Lütfen hesabınızı kontrol edin! + + + + Failed due to server error! + Sunucu hatası nedeniyle başarısız oldu! + + + + User and passsword can't be empty! + + + + + User existing! + Kullanıcı var! + + + + User doesn't exist! + + + + + Network can not reach! + + + + + Phone can't be empty! + + + + + Account or password error! + + + + + Phone number already in used! + Telefon numarası zaten kullanılıyor! + + + + Please check your format! + Lütfen formatınızı kontrol edin! + + + + Your are reach the limit! + Sınıra ulaştınız! + + + + Please check your phone number! + Lütfen telefon numaranızı kontrol edin! + + + + Please check your code! + Lütfen kodunuzu kontrol edin! + + + + Account doesn't exist! + Hesap mevcut değil! + + + + User has bound the phone! + Kullanıcı telefonu bağladı! + + + + Sending code error occurred! + Kod gönderme hatası oluştu! + + + + Phone code is expired! + + + + + Phone code error! + + + + + Code can not be empty! + + + + + MCode can not be empty! + + + + Sending code error occurring! + Gönderme kodu hatası oluştu! + + + + Your code is wrong! + Kodunuz yanlış! + + + + + Please check your phone! + Lütfen telefonunuzu kontrol edin! + + + Please check your password! + Lütfen şifrenizi kontrol edin! + + + At least 6 bit, include letters and digt + En az 6 karakter, harf ve rakam ekleyin + + + + + Sign in Cloud + Giriş yap Bulut + + + Forget + Unut + + + Set + Ayarla + + + Back + Geri + + + Create Account + Hesap Oluştur + + + Sign up now + Şimdi kayıt ol + + + Please confirm your password! + Lütfen şifrenizi doğrulayınız! + + + + Resend ( %1 ) + Yeniden gönder (%1) + + + + Get + Al + + + Get phone code + Telefon kodunu alın + + + Send + Gönder + + + Binding Phone + Telefon Bağlanıyor + + + Please make sure your password is safety! + Lütfen şifrenizin güvenli olduğundan emin olun! + + + Bind now + Şimdi bağla + + + + MainWidget + + + + Disconnected + Bağlantı kesildi + + + + Your account:%1 + Hesabınız: % 1 + + + Unauthorized device or OSS falied. +Please retry for login! + Yetkisiz cihaz veya işletim sistemi başarısız oldu. +Lütfen giriş için tekrar deneyin! + + + + + + Exit + Çıkış + + + + Sync + Senk. + + + + Sign in + Giriş Yap + + + + + Stop sync + Senk. durdur + + + + Sync your settings + Ayarlarınızı senkronize edin + + + + Your account:%1 + Hesabınız: %1 + + + + Auto sync + Otomatik Senk. + + + + Synchronize your personalized settings and data + Kişiselleştirilmiş ayarlarınızı ve verilerinizi senkronize edin + + + + + + + + + The latest time sync is: + En son zaman senkronizasyonu: + + + + + Waiting for initialization... + + + + + + + + + + + + + + + + + Network can not reach! + + + + + Logout failed,please check your connection + + + + + Waitting for sync! + + + + + The Cloud Account Service version is out of date! + + + + + KylinID open error! + + + + + Unauthorized device or OSS falied. +Please retry or relogin! + + + + + Authorization failed! + + + + + This operation may cover your settings! + Bu işlem ayarlarınızı kapsayabilir! + + + + Cloud ID desktop message + Cloud ID masaüstü mesajı + + + Synchronize your computer's settings into your cloud account here. + Bilgisayarınızın ayarlarını burada bulut hesabınızla senkronize edin. + + + Media + Medya + + + Weather + Hava Durumu + + + Sync downloading,please wait! + Senkronizasyon indiriliyor, lütfen bekleyin! + + + Sync uploading,please wait! + Yüklemeyi senkronize edin, lütfen bekleyin! + + + Sync failed, please check your internet connection or login out to retry! + Senkronizasyon başarısız oldu, lütfen internet bağlantınızı kontrol edin veya yeniden denemek için oturumu kapatın! + + + + %1, + %1, + + + Synchronized failed: %1 please retry or login out to get a better experience. + Senkronize edilemedi:%1 daha iyi bir deneyim için lütfen tekrar deneyin veya oturumu kapatın. + + + %1 + %1 + + + Synchronized failed: %1, please retry or login out to get a better experience. + Senkronize edilemedi:%1, daha iyi bir deneyim için lütfen tekrar deneyin veya oturumu kapatın. + + + + MainWindow + + + Search + Ara + + + UKCC + Denetim Merkezi + + + + + + Settings + + + + + Main menu + + + + + Minimize + + + + + Maximize/Normal + + + + + Close + Kapat + + + + Help + + + + + About + Hakkında + + + + Exit + Çıkış + + + + Home + + + + ukcc + Denetim Merkezi + + + + Warnning + + + + + This function has been controlled + + + + HOME + GİRİŞ + + + + MouseControl + + + Mouse Key Settings + Fare Ayarları + + + + + Hand habit + Kullanılan El + /mouse/Hand habit + + + + Pointer Settings + İşaretçi Ayarları + + + + + Speed + Hız + /mouse/Speed + + + + + + Slow + Yavaş + + + + mouse wheel speed + Fare Hızı + + + + + + Fast + Hızlı + + + + + Doubleclick delay + Çift Tıklama Gecikmesi + /mouse/Doubleclick delay + + + + Short + Kısa + + + + Long + Uzun + + + + + Acceleration + + /mouse/Acceleration + + + Sensitivity + Hassaslık + /mouse/Sensitivity + + + Low + Düşük + + + High + Yüksek + + + + + Visibility + Görünürlük + /mouse/Visibility + + + + + Pointer size + İşaretçi Boyutu + /mouse/Pointer size + + + + Cursor Settings + İmleç Ayarları + + + + Cursor weight + İmleç Genişliği + + + Cursor weight + İmleç ağırlığı + + + + Thin + İnce + + + + Coarse + Kalın + + + + + Cursor speed + İmleç Hızı + /mouse/Cursor speed + + + + + Enable flashing on text area + Metin alanında yanıp sönmeyi etkinleştir + /mouse/Enable flashing on text area + + + mouse + Fare + + + + Mouse + Fare + + + + Lefthand + Sol el + + + + Righthand + Sağ el + + + + Default(Recommended) + Standart (Önerilen) + + + + Medium + Orta + + + + Large + Büyük + + + + MyLabel + + + double-click to test + + + + + NetConnect + + + + Netconnect Status + Bağlantı Durumu + /netconnect/Netconnect Status + + + Waitting... + Bekleniyor... + + + + Available Network + Uygun Ağ + + + + + + Refresh + Yenile + + + + + open wifi + Wifi aç + /netconnect/open wifi + + + + + Network settings + Ağ Ayarları + + + Change net settings + Bağlantı ayarlarını değiştir + + + netconnect + Ağ bağlantısı + + + Netconnect + Bağlantı + + + + Connected + + + + + + No net + + + + + Detail + + + + + None + + + + + Refreshing... + Yenileniyor... + + + connected + Bağlandı + + + No network + Bağlantı yok + + + + + Connect + Bağlan + + + Disconnect + Bağlantıyı kes + + + + NetDetail + + + SSID: + + + + + Protocol + + + + + Security Type: + + + + + Hz: + + + + + Chan: + + + + + BandWidth: + + + + + IPV4: + + + + + IPV4 Dns: + + + + + IPV4 GateWay: + + + + + IPV4 Prefix: + + + + + IPV6: + + + + + IPV6 Prefix: + + + + + IPV6 GateWay: + + + + + Mac: + + + + + Notice + + + Notice Settings + Bildirim Ayarları + + + Set the type of notice in the operation center + İşlem Merkezinde Bildirim Türünü Ayarla + /notice/Set the type of notice in the operation center + + + + + Set notice type of operation center + + /notice/Set notice type of operation center + + + + Show new feature ater system upgrade + Sistem yükseltmesinden sonra yeni özelliği göster + + + + Get notifications from the app + Uygulamalardan Bildirim Al + + + + Show notifications on the lock screen + Kilit ekranında bildirimleri göster + + + + + Notice Origin + Bildirim Kaynağı + /notice/Notice Origin + + + notice + Bildirim + + + + Notice + Bildirim + + + + OutputConfig + + + resolution + Çözünürlük: + + + + orientation + Yönlendirme: + + + + arrow-up + Yukarı + + + + 90° arrow-right + 90° Sağa + + + + arrow-down + Aşağı + + + + frequency + + + + + 90° arrow-left + 90° sola + + + refresh rate + Yenileme Hızı: + + + + auto + Otomatik + + + 100% + %100 + + + 200% + %200 + + + 300% + %300 + + + + screen zoom + Ekran Yakınlaştırma: + + + + + %1 Hz + + + + + PassDialog + + Get the phone binding code + Telefon bağlama kodunu alın + + + Your account here + Hesabınız burada + + + Your new password here + Parolanız burada + + + Confirm your new password + Yeni şifrenizi onaylayın + + + Your code here + Kodunuz burada + + + At least 6 bit, include letters and digt + En az 6 karakter, harf ve rakam ekleyin + + + Your password is valid! + Parolanız geçerlidir! + + + + Power + + + select power plan + Güç Yönetimini Ayarla + + + + + Balance (suggest) + Dengeli (Önerilen) + /power/Balance (suggest) - - - DisplayPerformanceDialog - - Dialog - + + + Saving + Kaydediliyor + /power/Saving - - Display Advanced Settings - Gelişmiş Ayarları Göster + + Minimize performance + Performansı en aza indir - - Performance - Performans + Bala&nce (suggest) + Denge (önerilen) + - - Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. - 3D grafiklerin oluşturulmasını hızlandırabilen ayrı grafiklere sahip makine için geçerlidir. + + Autobalance energy and performance with available hardware + Mevcut donanım ile enerji ve performansı otomatik olarak dengeleme - - (Note: not support connect graphical with xmanager on windows.) - (Not: Pencerede xmanager ile grafiksel bağlantıyı desteklemez.) + + + Custom + Özel + /power/Custom - - Compatible - Uyumlu + + Users develop personalized power plans + Kullanıcılar kişiselleştirilmiş güç planları geliştirir - - Applicable to machine with integrated graphics, there is no 3D graphics acceleration. - Dahili ekran kartı olan bilgisayara uygulanabilir, 3D grafik hızlandırma yoktur. + + Power supply + A/C Gücünde - - (Note: need connect graphical with xmanager on windows, use this option.) - (Not: Pencerede xmanager ile grafiksel olarak bağlanmanız gerekir, bu seçeneği kullanın.) + + Battery powered + Pil Gücünde - - Automatic - Otomatik + + + + Change PC sleep time: + PC uyku süresini değiştirin: - - Auto select according to environment, delay the login time (about 0.5 sec). - Ortama göre otomatik seçim, oturum açma süresini geciktirir (yaklaşık 0,5 sn.). + + + + Change DP close time: + DP kapanış zamanını değiştirin: - - Threshold: - Eşik: + + General Settings + - - Apply - Uygula + Change pc sleep time: + Uyku Moduna Al: - - Reset - Sıfırla + Change dp close time: + Bilgisayarı Kapat: - - (Note: select this option to use 3D graphics acceleration and xmanager.) - (Not: 3D grafik hızlandırma ve xmanager kullanmak için bu seçeneği seçin.) + + When close lid: + Kapak Kapandığında: - - - DisplaySet - - Display - Ekran + + Screen darkens use battery: + Pilde Ekranı Kapatma Süresi: - - - DisplayWindow - - Form - + Power Other Settings + Diğer Güç Ayarları - - monitor - Ekran: + S3 to S4 when: + S3 ile S4 durumlarında: - - set as home screen - Ana Ekran Yap + Power Icon Settings + Güç Simgesi Ayarları - - unify output - Çıktıyı Birleştir + + Power icon: + Güç Simgesi: - - open monitor - Monitörü Aç + power + Güç - - Advanced - Gelişmiş + + Power + Güç - - screen brightness adjustment - Ekran Parlaklığı + + Enter idle state %1 min and sleep after %2 min : + - - dark - Koyu + + Enter idle state %1 min and close after %2 min : + - - bright - Açık + + + + never + Asla - - follow the sunrise and sunset(17:55-05:04) - Gün doğumunu ve gün batımını takip et(17:55-05:04) + + + + 10 min + 10 dk - - custom time - Özel zaman + + + 30 min + 30 dk - - opening time - Açılış zamanı + + + 60 min + 60 dk - - closing time - Kapanış zamanı + + + 120 min + 120 dk - - color temperature - Renk Sıcaklığı + + 300 min + 300 dk - - warm - Ilık + + + + 20 min + 20 dk - - cold - Soğuk + + + 1 min + 1 dk - - apply - Uygula + + + 5 min + 5 dk - - - EditPassDialog - - Edit Password - Parolayı Düzenle + + nothing + Hiçbiri - - Your new password here - Yeni parolanız burada + + blank + Boş - - Your code - Kodunuz + + suspend + Askıya Al - - Get phone code - Telefon kodunu al + + hibernate + Beklemeye Al - - Cancel - İptal + + shutdown + Kapat - - Confirm - Onayla + + always + Her Zaman - - Confirm your new password - Yeni parolanızı onaylayın + + present + Mevcut - - - - - At least 6 bit, include letters and digt - En az 6 karakter, harf ve rakam ekleyin + + charge + Şarj - - Your password is valid! - Parolanız geçerlidir! + + When the power button is pressed: + - - Please check your password! - Lütfen şifrenizi kontrol edin! + + Perform operations when battery is low: + + + + Printer - - Resend( - Yeniden gönder( + + + Add Printers And Scanners + Yazıcı ve Tarayıcı Ekle - - ) - ) + + Add printers and scanners + Yazıcı Ve Tarayıcı Ekle - - - Send - Gönder + + Attrs + - - Reback sign in - Yeniden oturum aç + + List Of Existing Printers + Mevcut Yazıcıların Listesi - - Error code: - Hata kodu: + printer + Yazıcı - - ! - ! + + Printer + Yazıcı + + + Proxy - - Internal error occurring! - Dahili hata oluştu! + + Auto Proxy + Otomatik - - Failed to sign up! - Kaydolamadı! + + + Auto proxy + Otomatik + /proxy/Auto proxy - - Failed attempt to return value! - Değer döndürülemedi! + + Auto url + Oto URL - - Check your connection! - Bağlantınızı kontrol edin! + + Manual Proxy + Elle - - Failed to get by phone! - Telefonla alınamadı! + + + Manual proxy + Elle + /proxy/Manual proxy - - Failed to get by user! - Kullanıcı tarafından alınamadı! + + Http Proxy + HTTP Proxy - - Failed to reset password! - Şifre sıfırlanamadı! + + + + + Port + Port - - - - Please check your information! - Lütfen bilgilerinizi kontrol edin! + + Cetification + Sertifika - - Please check your account! - Lütfen hesabınızı kontrol edin! + + Https Proxy + HTTPS Proxy - - Failed due to server error! - Sunucu hatası nedeniyle başarısız oldu! + + Ftp Proxy + Ftp Proxy - - User existing! - Kullanıcı mevcut! + + Socks Proxy + Socks Proxy - - Phone number already in used! - Telefon numarası zaten kullanılıyor! + + List of ignored hosts. more than one entry, please separate with english semicolon(;) + Yok sayılan ana bilgisayarların listesi. birden fazla giriş için (;) ile ayırın - - Please check your format! - Lütfen biçiminizi kontrol edin! + proxy + Ağ Vekili - - Your are reach the limit! - Sınıra ulaşıyorsunuz! + + Proxy + Ağ Vekili + + + QObject - - Please check your phone number! - Lütfen telefon numaranızı kontrol edin! + display + Ekran - - Please check your code! - Lütfen kodunuzu kontrol edin! + defaultapp + Varsayılan Uyg. - - Account doesn't exist! - Hesap mevcut değil! + power + Güç - - Sending code error occurring! - Gönderme kodu hatası oluştu! + autoboot + Otomatik Başlat - - - EditPushButton - - Reset - Sıfırla + printer + Yazıcı - - - ExperiencePlan - - User Experience - Kullanıcı Deneyimi + mousecontrol + Fare Kontrolü - - Join in user Experience plan - Kullanıcı Deneyimi planına katılın + mouse + Fare - - User experience plan terms, see - Kullanıcı deneyimi planı şartları, bkz + touchpad + Dokunmatik Yüzey - - 《User Experience plan》 - (Kullanıcı Deneyimi Planı) + keyboard + Klavye - - Experienceplan - Deneyim Planı + shortcut + Kısayol - - - Fonts - - - Fonts - Yazı Tipi + audio + Ses - - Fonts select - Font Seç + background + Arkaplan - - Font size - Font Boyutu + screenlock + Kilit Ekranı - - Reset to default - Varsayılana Sıfırla + fonts + Fontlar - - Gtk default font - Gtk Fontu + + Screensaver + Ekran koruyucu - - Document font - Belge Fontu: + desktop + Masaüstü - - - Monospace font - Monospace Fontu: + netconnect + Ağ Bağlantısı - - Advanced settings - Gelişmiş Ayarlar + vpn + VPN - - Peony font - Peony Fontu: + proxy + Ağ Vekili - - titlebar font - Başlık Fontu: + userinfo + Kullanıcı Bilgisi - - Select text sample that looks clearest - En net görünen metin örneğini seç + datetime + Tarih Saat - - 11 - 11 + area + Alan - - 12 - 12 + update + Güncelleme - - 13 - 13 + backup + Yedekleme - - 14 - 14 + notice + Bildirim - - 15 - 15 + about + Hakkında - - 16 - 16 + experienceplan + Deneyim Planı - - 17 - 17 + theme + Tema - - 18 - 18 + ukui-control-center had already running! + ukui-kontrol-merkezi zaten çalışıyor! - - Thanks For Using The ukcc - Denetim Merkezini kullandığınız için teşekkürler + basicIcon + Temel Simge - - - ItemList - - Walpaper - Duvar Kağıdı + classicalIcon + Klasik Tema - - ScreenSaver - Ekran Koruyucu + defaultIcon + Varsayılan Simge - - Menu - Menü + + blue-crystal + - - Quick Start - Hızlı Başlat + + dark-sense + - - Tab - Sekme + + DMZ-Black + - - Weather - Hava Durumu + + DMZ-White + - - Media - Medya + + basic + Temel - - - KbdLayoutManager - - C - C + + classical + Klasik - - L - L + + + default + Varsayılan - - Variant - Varyant + + fashion + - - Add - Ekle + + Unknown + Bilinmeyen - - Add Layout - Düzen Ekle + + Customize Shortcut + - - Del - Sil + Update Shortcut + Kısayoları Güncelle - - - KeyValueConverter - - System - Sistem + Add Shortcut + Kısayol Ekle - - Devices - Aygıtlar + + Display + Ekran - - Personalized - Özelleştirme + Defaultapp + Uygulama - - Network - + + Power + Güç - - Account - Hesap + Autoboot + Otomatik Başlat - - Datetime - Tarih-Zaman + + TouchScreen + - - Update - Güncelleme + + Default App + Varsayılan Uyg. - - Messages - Mesajlar + + Auto Boot + Otomatik Başlat - - - KeyboardControl - - Keys Settings - Anahtar Ayarları + + Printer + Yazıcı - - Enable repeat key - Yenileme tuşunu etkinleştir + + Mouse + Fare - - Delay - Gecikme + + Touchpad + Touchpad - - Short - Kısa + + Keyboard + Klavye - - Long - Uzun + + Shortcut + Kısayol - - Speed - Hız + + Audio + Ses - - Slow - Yavaş + + Bluetooth + - - Fast - Hızlı + + Background + Arkaplan - - Test repetition rate of the input character: - Giriş karakterinin tekrarlama oranını test edin: + + Theme + Tema - - Tip of keyboard - Klavye İpucu + + Screenlock + Ekran kilidi - - reset default layout - Varsayılan Düzene Dön + + Fonts + Yazı Tipi - - Reset layout - Düzeni Sıfırla + + Desktop + Masaüstü - - Enable numlock - Numlock Etkinleştir + + Connect + Bağlan - - Keyboard Layout - Klavye Düzeni + + Vino + - - Keyboard layout - Klavye Düzeni + + User Info + Kullanıcı Bilgisi - - Install layouts - Klavye kur + + Date + - - Keyboard - Klavye + + Security Center + Güvenlik Merkezi - - - LayoutManager - - Dialog - + Netconnect + - - Manager Keyboard Layout - Yönetici Klavye Düzeni + + Vpn + VPN - - Language - Dil + + Proxy + Ağ Vekili - - Country - Ülke + Userinfo + Kullanıcı - - Variant - Düzen + + Cloud Account + Bulut Hesabı - - Layout installed - Düzen yüklendi + Datetime + Tarih saat - - Preview - Önizleme + + Area + Alan - - Cancel - İptal + SecurityCenter + Güvenlik Merkezi - - Install - Kur + + Update + Güncelleme - - - LoginDialog - - Forget - Unut + + Backup + Yedekleme - - Send - Gönder + + Upgrade + - - User Sign in - Kullanıcı Girişi + + Notice + Bildirim - - Quick Sign in - Hızlı Giriş + + Search + Ara - - - Your account here - Kodunuz Burada + + About + Hakkında - - Your phone number here - Telefon Numaranız Burada + + Experienceplan + Deneyim planı - - Your password here - Parolanız Burada + + min length %1 + + En az uzunluk %1 + - - - Your code here - Kodunuz Burada + + min digit num %1 + + En az basamak sayısı %1 + - - - MCodeWidget - - SongTi - ŞarkıTi + + min upper num %1 + + En az üst sayı %1 + - - - MainDialog - - - - - - - - - Sign in - Oturum Aç + + min lower num %1 + + En az alt sayı %1 + - - - - - - Sign up - Kayıt Ol + + min other num %1 + + En az diğer sayı %1 + - - Login in progress - Giriş devam ediyor + + min char class %1 + + En az karakter sınıfı %1 + - - Error code: - Hata kodu: + + max repeat %1 + + En fazla tekrar %1 + - - ! - ! + + max class repeat %1 + + En fazla sınıf tekrarı %1 + - - Internal error occurring! - Dahili hata oluştu! + + max sequence %1 + + En fazla dizi %1 - - Failed to sign up! - Kaydolamadı! + + + + Never + Asla - - Failed attempt to return value! - Değer döndürülemedi! + + 10min + - - Check your connection! - Bağlantınızı kontrol edin! + + 20min + - - Failed to get by phone! - Telefonla alınamadı! + + 40min + - - Failed to get by user! - Kullanıcı tarafından alınamadı! + + 80min + - - Failed to reset password! - Şifre sıfırlanamadı! + + interactive + - - Phone binding falied! - Telefon bağlama başarısız! + + + suspend + Askıya Al - - - - Please check your information! - Lütfen bilgilerinizi kontrol edin! + + + hibernate + Beklemeye Al - - Please check your account! - Lütfen hesabınızı kontrol edin! + + + shutdown + Kapat - - Failed due to server error! - Sunucu hatası nedeniyle başarısız oldu! + + nothing + Hiçbiri - - User existing! - Kullanıcı mevcut! + + blank + Boş - - Phone number already in used! - Telefon numarası zaten kullanılıyor! + Year + Yıl - - Please check your format! - Lütfen biçiminizi kontrol edin! + Jan + Oca - - Your are reach the limit! - Sınıra ulaşıyorsunuz! + Feb + Şub - - Please check your phone number! - Lütfen telefon numaranızı kontrol edin! + Mar + Mar - - Please check your code! - Lütfen kodunuzu kontrol edin! + Apr + Nis - - Account doesn't exist! - Hesap mevcut değil! + + May + May - - User has bound the phone! - Kullanıcı telefonu bağladı! + + January + Ocak - - Sending code error occurring! - Gönderme kodu hatası oluştu! + + February + Şubat - - Your code is wrong! - Kodunuz yanlış! + + March + Mart - - - - Please check your password! - Lütfen şifrenizi kontrol edin! + + April + Nisan - - - - At least 6 bit, include letters and digt - En az 6 karakter, harf ve rakam ekleyin + + June + Haziran - - - - - - Sign in Cloud - Giriş yap Bulut + + July + Temmuz - - Forget - Unut + + August + Ağustos - - Set - Ayarla + + September + Eylül - - - - Back - Geri + + October + Ekim - - Create Account - Hesap Oluştur + + Novermber + Kasım - - Sign up now - Şimdi kayıt ol + + December + Aralık - - - - - Resend ( %1 ) - Tekrar gönder ( %1) + Jun + Haz - - - Get phone code - Telefon kodunu al + Jul + Tem - - - - - - - Send - Gönder + Aug + Ağu - - Binding Phone - Telefon Bağlama + Sep + Eyl - - Bind now - Şimdi bağla + Oct + Eki - - - MainWidget - - Disconnected - Bağlantı kesildi + Nov + Kas - - - - Your account:%1 - Hesabınız: % 1 + Dec + Ara - - - - Exit - Çıkış + Day + Gün - - Sync - Senk + + ukui-control-center is already running! + Ukui Denetim Merkezi zaten çalışıyor! - - Sign in - Giriş Yap + + ukui-control-center + - - Stop sync - Senk. Durdur + Are you sure to delete "%1" group, +which will make some file components +in the file system invalid! + %1 grubu silmek istediğinizden emin misiniz, +bazı dosya bileşenleri oluşturacak +dosya sisteminde geçersiz! - - Sync your settings - Ayarlarınızı senkronize edin + + PulseAudio Volume Control + - - Your account:%1 - Hesabınız: %1 + + Connection to PulseAudio failed. Automatic retry in 5s + +In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties +or default-server in client.conf is misconfigured. +This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window. +If this is the case, then PulseAudio should autospawn again, or if this is not configured you should +run start-pulseaudio-x11 manually. + - - Auto sync - Otomatik Senk + + pa_context_subscribe() failed + - - Synchronize your personalized settings and data - Kişiselleştirilmiş ayarlarınızı ve verilerinizi senkronize edin + + pa_context_get_card_info_list() failed + - - - MainWindow - - UKCC - Denetim Merkezi + + Failed to initialize stream_restore extension: %s + - - ukcc - Denetim Merkezi + + Connection failed, attempting reconnect + - - HOME - GİRİŞ + + pa_ext_stream_restore_read() failed + - - - ModulePageWidget - - QLabel{font-size: 18px; color: palette(Shadow);} - + + pa_context_get_card_info_by_index() failed + - - - MouseControl - - Mouse Key Settings - Fare Ayarları + + Card callback failure + - - Hand habit - Kullanılan El + + Go to monitor settings page + - - Pointer Settings - İşaretçi Ayarları + + Go to defaultapp settings page + - - Speed - Hız + + Go to power settings page + - - - - Slow - Yavaş + + Go to autoboot settings page + - - mouse wheel speed - Fare Hızı + + Go to printer settings page + - - - - Fast - Hızlı + + Go to mouse settings page + - - Doubleclick delay - Çift Tıklama Gecikmesi + + Go to touchpad settings page + - - Short - Kısa + + Go to keyboard settings page + - - Long - Uzun + + Go to shortcut settings page + - - Sensitivity - Hassaslık + + Go to audio settings page + - - Low - Düşük + + Go to bluetooth settings page + - - High - Yüksek + + Go to background settings page + - - Visibility - Görünürlük + + Go to theme settings page + - - Pointer size - İşaretçi Boyutu + + Go to screenlock settings page + - - Cursor Settings - İmleç Ayarları + + Go to screensaver settings page + - - Cursor weight - İmleç Genişliği + + Go to fonts settings page + - - Thin - İnce + + Go to desktop settings page + - - Coarse - Kalın + + Go to netconnect settings page + - - Cursor speed - İmleç Hızı + + Go to vpn settings page + - - Enable flashing on text area - Metin alanında yanıp sönmeyi etkinleştir + + Go to proxy settings page + - - Mouse - Fare + + Go to userinfo settings page + - - Lefthand - Sol el + + Go to cloudaccount settings page + - - Righthand - Sağ el + + Go to datetime settings page + - - Default(Recommended) - Standart (Önerilen) + + Go to area settings page + - - Medium - Orta + + Go to update settings page + - - Large - Büyük + + Go to backup settings page + - - - NetConnect - - Netconnect Status - Bağlantı Durumu + + Go to upgrade settings page + - - - Waitting... - Bekleniyor... + + Go to notice settings page + - - Available Network - Uygun Ağ + + Go to about settings page + - - Refresh - Yenile + + Go to search settings page + - - open wifi - Wifi aç + + system upgrade new backup + - - - Network settings - Ağ Ayarları + + system upgrade increment backup + + + + RegDialog - - Netconnect - Bağlantı + Get + Al - - connected - Bağlandı + Your password here + Parolanız burada - - No network - Bağlantı yok + Your account here + Hesabınız burada - - - Notice - - Notice Settings - Bildirim Ayarları + Confirm your password + Parolanızı doğrulayın - - Set the type of notice in the operation center - İşlem Merkezinde Bildirim Türünü Ayarla + Your code here + Kodunuz burada - - Show new feature ater system upgrade - Sistem yükseltmesinden sonra yeni özelliği göster + This operation is permanent + Bu işlem kalıcıdır - - Get notifications from the app - Uygulamalardan Bildirim Al + At least 6 bit, include letters and digt + En az 6 karakter, harf ve rakam ekleyin - - Show notifications on the lock screen - Kilit ekranında bildirimleri göster + Your password is valid! + Parolanız geçerlidir! + + + ResolutionSlider - - Notice Origin - Bildirim Kaynağı + (recommend) + (Önerilen) - - Notice - Bildirim + + No available resolutions + Kullanılabilir çözünürlük yok - OutputConfig + Screenlock - - resolution - Çözünürlük: + + + Screenlock + Ekran kilidi - - orientation - Yönlendirme: + + Screenlock Interface + Ekran Kilidi Arayüzü - - arrow-up - Yukarı + + Screenlock Set + Ekran Kilidi Ayarı - - 90° arrow-right - 90° Sağa + + + Lock screen when screensaver boot + Ekran koruyucu açıldığında ekranı kilitle + /screenlock/Lock screen when screensaver boot - - arrow-down - Aşağı + + Lock screen delay + Ekran kilidi gecikmesi - - 90° arrow-left - 90° sola + Min + Dk - - refresh rate - Yenileme Hızı: + + Select screenlock background + Kilit Ekranı Arkaplanını Seç - - auto - Otomatik + + Browser online wp + İnternetten Al - - - 100% - %100 + + Browser local wp + Bilgisayardan Ekle - - - - 200% - %200 + + + Show picture of screenlock on screenlogin + Ekran girişinde ekran kilidinin resmini göster + /screenlock/Show picture of screenlock on screenlogin - - 300% - %300 + Enabel screenlock + Ekran kilidi aktif - - screen zoom - Ekran Yakınlaştırma: + Open + - - %1 Hz - + screenlock + Ekran kilidi - - - PassDialog - - Get the phone binding code - Telefon bağlama kodunu alın + picture + Resim - - Your account here - Hesabınız burada + Never + Asla - - Your new password here - Parolanız burada + + 5m + 5 dk - - Confirm your new password - Yeni şifrenizi onaylayın + + 10m + 10 dk - - Your code here - Kodunuz burada + + 30m + 30 dk - - - At least 6 bit, include letters and digt - En az 6 karakter, harf ve rakam ekleyin + + 45m + 45 dk - - Your password is valid! - Parolanız geçerlidir! + + 1m + 1 dk - - - Power - - select power plan - Güç Yönetimini Ayarla + + 1h + 1 sa - - Balance (suggest) - Dengeli (Önerilen) + + 1.5h + 1.5 sa - - Saving - Kaydediliyor + + 3h + 3 sa - - Minimize performance - Performansı en aza indir + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + Duvarkağıdı Dosyaları(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) - - Autobalance energy and performance with available hardware - Mevcut donanım ile enerji ve performansı otomatik olarak dengeleme + + allFiles(*.*) + Tüm Dosyalar(*.*) - - Custom - Özel + + select custom wallpaper file + Özel duvar kağıdı dosyasını seç - - Users develop personalized power plans - Kullanıcılar kişiselleştirilmiş güç planları geliştirir + + Select + - - Power supply - A/C Gücünde + + Position: + Konum: - - Battery powered - Pil Gücünde + + FileName: + Dosya Adı: - - Change pc sleep time: - Uyku Moduna Al: + + FileType: + - - Change dp close time: - Bilgisayarı Kapat: + + Cancel + İptal + + + Screensaver - - When close lid: - Kapak Kapandığında: + + + Screensaver + Ekran Koruyucu - - Screen darkens use battery: - Pilde Ekranı Kapatma Süresi: + + + Enable screensaver + Ekran Koruyucu Aktif + /screensaver/Enable screensaver - - Power Other Settings - Diğer Güç Ayarları + + + Screensaver program + Ekran Koruyucu Programı + /screensaver/Screensaver program - - S3 to S4 when: - S3 ile S4 durumlarında: + + + idle time + Bekleme Süresi + /screensaver/idle time - - Power icon: - Güç Simgesi: + Min + Dk - - Power - Güç + + Lock screen when screensaver boot + Ekran koruyucu açıldığında ekranı kilitle - - - - never - Asla + screensaver + Ekran Koruyucu - - - - 10 min - 10 dk + + Default_ukui + Ukui Varsayılanı - - - 30 min - 30 dk + + Blank_Only + Sadece Kalın - - - 60 min - 60 dk + Random + Rasgele - - - 120 min - 120 dk + Never + Asla - - 300 min - 300 dk + + 5m + 5 dk - - - - 20 min - 20 dk + + 10m + 10 dk - - - 1 min - 1 dk + + 30m + 30 dk - - - 5 min - 5 dk + + 45m + 45 dk - - nothing - Hiçbiri + + 1m + 1 dk - - blank - Boş + + 1h + 1 sa - - suspend - Askıya Al + + 1.5h + 1.5 sa - - hibernate - Beklemeye Al + + 3h + 3 sa + + + Search - - shutdown - Kapat + + Form + - - always - Her Zaman + + Search + Ara - - present - Mevcut + + + Create Index + - - charge - Şarj + + Creating index can help you getting results quickly. + - - - Printer - - Add Printers And Scanners - Yazıcı ve Tarayıcı Ekle + + Block Folders + - - Add printers and scanners - Yazıcı Ve Tarayıcı Ekle + + Following folders will not be searched. You can set it by adding and removing folders. + - - List Of Existing Printers - Mevcut Yazıcıların Listesi + + Choose folder + - - Printer - Yazıcı + + Web Engine + - - - Proxy - - Auto Proxy - Otomatik + + Default web searching engine + - - Auto proxy - Otomatik + + baidu + - - Auto url - Oto URL + + sougou + - - Manual Proxy - Elle + + 360 + 3 sa {360?} - - Manual proxy - Elle + + delete + - - Http Proxy - HTTP Proxy + + Directories + - - - - - Port - Port + + select blocked folder + - - Cetification - Sertifika + + Select + - - Https Proxy - HTTPS Proxy + + Position: + Konum: - - Ftp Proxy - Ftp Proxy + + FileName: + Dosya Adı: - - Socks Proxy - Socks Proxy + + FileType: + - - List of ignored hosts. more than one entry, please separate with english semicolon(;) - Yok sayılan ana bilgisayarların listesi. birden fazla giriş için (;) ile ayırın + + Cancel + İptal - - Proxy - Ağ Vekili + + + + + Warning + Uyarı - - - QObject - - Screensaver - Ekran koruyucu + + Add blocked folder failed, choosen path is empty! + - - basic - Temel + + Add blocked folder failed, it is not in home path! + - - classical - Klasik + + Add blocked folder failed, its parent dir is exist! + - - default - Varsayılan + + Add blocked folder failed, it has been already blocked! + + + + SearchWidget - - - Unknown - Bilinmeyen + Touchpad + Dokunmatik Yüzey + + + SecurityCenter - - Update Shortcut - Kısayoları Güncelle + + SecurityCenter + Güvenlik Merkezi - - Display - Ekran + + + Computer Security Overview + + /securitycenter/Computer Security Overview - - Defaultapp - Uygulama + + Understand current computer security situation and take measures + - - Power - Güç + Summarize + Özetler - - Autoboot - Otomatik Başlat + Recognize the current security of the system, and can take the necessary settings + Sistemin mevcut güvenliğini tanır ve gerekli ayarları yapabilir - - Printer - Yazıcı + + Run Security Center + Güvenlik Merkezi'ni çalıştırın - - Mouse - Fare + + Security Center + Güvenlik Merkezi - - Touchpad - Touchpad + Virus Protection + Virüs Koruması - - Keyboard - Klavye + Protect system from threats + Sistemi tehditlerden koruyun - - Shortcut - Kısayol + Network Protection + Ağ Koruması - - Audio - Ses + Setup app that can access web + Web'e erişebilen kurulum uygulaması - - Background - Arkaplan + App Execution Control + Uygulama Yürütme Denetimi - - Theme - Tema + App install and exe protection + Uygulama yükleme ve exe koruması - - Screenlock - Ekran kilidi + + Account Security + Hesap güvenliği + /securitycenter/Account Security - - Fonts - Yazı Tipi + + Protect account and login security + Hesabı ve giriş güvenliğini koruyun - - Desktop - Masaüstü + + Safety check-up + + /securitycenter/Safety check-up - - Netconnect - + + Detect abnormal configuration + - - Vpn - VPN + + Virus defense + + /securitycenter/Virus defense - - Proxy - Ağ Vekili + + Real time protection from virus threat + - - Userinfo - Kullanıcı + + App protection + + /securitycenter/App protection - - NetworkAccount - Ağ hesabı + + App install + - - Datetime - Tarih saat + + Net protection + + /securitycenter/Net protection - - Area - Alan + + Manage and control network + - - SecurityCenter - Güvenlik Merkezi + + Secure Config + + /securitycenter/Secure Config - - Update - Güncelleme + + Simple Config + + + + ShareMain - - Backup - Yedekleme + + Share + Paylaş - - Notice - Bildirim + + Allow others to view your desktop + Başkalarının masaüstünüzü görüntülemesine izin verin - - About - Hakkında + + Allow connection to control screen + - - Experienceplan - Deneyim planı + + Security + Güvenlik - - min length %1 - - en az uzunluk %1 - + + You must confirm every visit for this machine + Bu makine için her ziyareti onaylamalısınız - - min digit num %1 - - En az basamak sayısı %1 - + + Require user to enter this password: + Kullanıcının bu şifreyi girmesini zorunlu kılın: - - min upper num %1 - - En az üst sayı %1 - + + + Password can not be blank + - - min lower num %1 - - En az alt sayı %1 - + + + Password length must be less than or equal to 8 + + + + Shortcut - - min other num %1 - - En az diğer sayı %1 - + + + + System Shortcut + Sistem Kısayolları + /shortcut/System Shortcut - - min char class %1 - - En az karakter sınıfı %1 - + Show all shortcut + Tüm Kısayolları Göster - - max repeat %1 - - En fazla tekrar %1 - + + Custom Shortcut + Özel Kısayollar - - max class repeat %1 - - En fazla sınıf tekrarı %1 - + + Customize Shortcut + + /shortcut/Customize Shortcut - - max sequence %1 - - En fazla dizi %1 - + + Add custom shortcut + Özel Kısayol Ekle + /shortcut/Add custom shortcut - - - Never - Asla + + Edit + Düzenle - - Year - Yıl + + Delete + Sil - - Jan - Oca + disable + Kapalı - - Feb - Şub + Reset default + Varsayılana Sıfırla - - Mar - Mar + shortcut + Kısayol - - Apr - Nis + + Shortcut + Kısayol - - May - May + Desktop + Masaüstü - - Jun - Haz + System + Sistem + + + ShowAllShortcut - - Jul - Tem + System Shortcuts + Sistem Kısayolları - - Aug - Ağu + Show all shortcut + Tüm kısayolları göster - - Sep - Eyl + Desktop + Masaüstü + + + SuccessDiaolog - - Oct - Eki + Reback sign in + Yeniden oturum açma - - Nov - Kas + Sign up success! + Kayıt başarılı! - - Dec - Ara + Reset success! + Sıfırlama başarılı! - - Day - Gün + Sign in success! + Giriş başarılı! - - ukui-control-center is already running! - Ukui Denetim Merkezi zaten çalışıyor! + Binding phone success! + Telefon bağlama başarılı! + + + Confirm + Onayla - RegDialog + SyncDialog - - Get - Al + + Sync + - - Your password here - Parolanız burada + + Do not + - - Your account here - Hesabınız burada + + + Last sync at %1 + - - Confirm your password - Parolanızı doğrulayın + + Sync now? + - - Your code here - Kodunuz burada + + Wallpaper + - - This operation is permanent - Bu işlem kalıcıdır + + ScreenSaver + Ekran Koruyucu - - - At least 6 bit, include letters and digt - En az 6 karakter, harf ve rakam ekleyin + + Font + - - Your password is valid! - Parolanız geçerlidir! + + Avatar + Avatar - - - ResolutionSlider - - No available resolutions - Kullanılabilir çözünürlük yok + + Menu + Menü - - - Screenlock - - - Screenlock - Ekran kilidi + + Tab + Sekme - - Screenlock Interface - Ekran Kilidi Arayüzü + + Quick Start + Hızlı Başlat - - Screenlock Set - Ekran Kilidi Ayarı + + Themes + Temalar - - Lock screen when screensaver boot - Ekran koruyucu açıldığında ekranı kilitle + + Mouse + Fare - - Lock screen delay - Ekran kilidi gecikmesi + + TouchPad + Dokunmatik Yüzey - - Select screenlock background - Kilit Ekranı Arkaplanını Seç + + KeyBoard + Klavye - - Browser online wp - İnternetten Al + + ShortCut + Kısayol - - Browser local wp - Bilgisayardan Ekle + + Area + Alan - - Show picture of screenlock on screenlogin - Ekran girişinde ekran kilidinin resmini göster + + Date/Time + Tarih/Zaman - - 5m - 5 dk + + Default Open + Varsayılan Açık - - 10m - 10 dk + + Notice + Bildirim - - 30m - 30 dk + + Option + Seçenek - - 45m - 45 dk + + Peony + Peony - - 1m - 1 dk + + Boot + Boot - - 1h - 1 sa + + Power + Güç - - 1.5h - 1.5 sa + + Editor + Düzenleyici - - 3h - 3 sa + + Terminal + Uçbirim + + + + Weather + Hava Durumu + + + + Media + Medya - Screensaver + TabWid - - - Screensaver - Ekran Koruyucu + + + + + + + + Check Update + - - Enable screensaver - Ekran Koruyucu Aktif + + Service connection abnormal,please retest! + - - Screensaver program - Ekran Koruyucu Programı + + + Prompt information + - - idle time - Bekleme Süresi + + Update now + - - Lock screen when screensaver boot - Ekran koruyucu açıldığında ekranı kilitle + + Cancel update + - - Default_ukui - Ukui Varsayılanı + + No,I Don't Backup + - - Blank_Only - Sadece Kalın + + + Being updated... + - - 5m - 5 dk + + + + + + + + UpdateAll + - - 10m - 10 dk + + The backup restore partition could not be found. The system will not be backed up in this update! + - - 30m - 30 dk + + Kylin backup restore tool is doing other operations, please update later. + - - 45m - 45 dk + + The source manager configuration file is abnormal, the system temporarily unable to update! + - - 1m - 1 dk + + Backup already, no need to backup again. + - - 1h - 1 sa + + + Start backup,getting progress + - - 1.5h - 1.5 sa + + Kylin backup restore tool does not exist, this update will not backup the system! + - - 3h - 3 sa + + Backup complete. + - - - SecurityCenter - - - SecurityCenter - Güvenlik Merkezi + + In backup: + - - Summarize - Özetler + + Failed to write configuration file, this update will not back up the system! + - - Recognize the current security of the system, and can take the necessary settings - Sistemin mevcut güvenliğini tanır ve gerekli ayarları yapabilir + + Insufficient backup space, this update will not backup your system! + - - Run Security Center - Güvenlik Merkezi'ni çalıştırın + + Kylin backup restore tool could not find the UUID, this update will not backup the system! + - - Virus Protection - Virüs Koruması + + The backup restore partition is abnormal. You may not have a backup restore partition.For more details,see /var/log/backup.log + - - Protect system from threats - Sistemi tehditlerden koruyun + + Calculating Capacity... + - - Network Protection - Ağ Koruması + + Backup interrupted, stop updating! + - - Setup app that can access web - Web'e erişebilen kurulum uygulaması + + Backup finished! + - - App Execution Control - Uygulama Yürütme Denetimi + + Kylin backup restore tool exception: + - - App install and exe protection - Uygulama yükleme ve exe koruması + + There will be no backup in this update! + - - Account Security - Hesap güvenliği + + Getting update list + - - Protect account and login security - Hesabı ve giriş güvenliğini koruyun + + + Software source update failed: + - - - Shortcut - - System Shortcut - Sistem Kısayolları + + + Update software source : + - - Show all shortcut - Tüm Kısayolları Göster + + Reconnect times: + - - Custom Shortcut - Özel Kısayollar + + Update + - - Add custom shortcut - Özel Kısayol Ekle + + View history + - - Reset default - Varsayılana Sıfırla + + Update Settings + - - Shortcut - Kısayol + + Allowed to renewable notice + - - - ShowAllShortcut - - Dialog - + + Backup current system before updates all + - - System Shortcuts - Sistem Kısayolları + + + Your system is the latest! + - - - Desktop - Masaüstü + + + Updatable app detected on your system! + - - - SuccessDiaolog - - Reback sign in - Yeniden oturum açma + + + Last refresh: + + + + + Last Checked: + + + + + Updating the software source + + + + + This update will not backup the current system, do you want to continue the update? + - - Sign up success! - Kayıt başarılı! + + Yes, keep updating + - - Reset success! - Sıfırlama başarılı! + + No, backup now + - - Sign in success! - Giriş başarılı! + + Not updated + - - Binding phone success! - Telefon bağlama başarılı! + + Part of the update failed! + - - - - - Confirm - Onayla + + An important update is in progress, please wait. + Theme + Theme Mode Tema Modu + /theme/Theme Mode - + Theme Tema - + Default Varsayılan - + Light Açık - + Dark Koyu + Middle + Orta + + + Icon theme Simge Teması + /theme/Icon theme - + Control theme Kontrol Teması - + + Cursor theme İmleç Teması + /theme/Cursor theme - + Effect setting Efekt Ayarları - + + Transparency Şeffaflık + /theme/Transparency + + + Transparent effects + Şeffaflık Etkileri - + + Performance mode Performans Modu + /theme/Performance mode - + Transparent + Şeffaflık + + + Low + Düşük + + + High + Yüksek + + + Reset to default Varsayılana Dön + + theme + Tema + TimeZoneChooser - + Cancel İptal - + Confirm Onayla - - + + Change time zone + Zaman dilimini değiştir + + + + change timezone zaman dilimini değiştir + + change zonne + Dilimi Değiştir + + + Change Timezone + Zaman Dilimini Değiştir + + + + TouchScreen + + + + + TouchScreen + + + + + monitor + Ekran: + + + + touch id + + + + + map + + + + + calibration + + + + + No touch screen found + + + + + input device + + + + + TextLabel + + Touchpad + Touchpad Settings Dokunmatik Yüzey Ayarları + /touchpad/Touchpad Settings @@ -3683,75 +7131,154 @@ Dokunmatik yüzey bulunamadı - + touchpad + Dokunmatik Yüzey + + + Touchpad Dokunmatik Yüzey - + + Disable rolling Kaydırma kapalı - + + Edge scrolling + + + + + Two-finger scrolling + + + + Vertical edge scrolling Dikey kenar kaydırma - + Horizontal edge scrolling Yatay kenar kaydırma - + Vertical two-finger scrolling Dikey iki parmakla kaydırma - + Horizontal two-finger scrolling Yatay iki parmakla kaydırma + UkccAbout + + UKCC + Denetim Merkezi + + + + + Settings + + + + + Version: + + + + + The control panel provides a friendly graphical user interface to manage common configuration items of the operating system. System configuration provides system, equipment, personalization, network, account, time and date, account, time and date, update, notification and operation module operations. + + + + + Service and Support: + + + + + UkmediaApplicationWidget + + Application Volume + Uygulama Sesi + + + No application is currently playing or recording audio + Şu anda hiçbir uygulama ses çalmıyor veya ses kaydetmiyor + + + UkmediaInputWidget - + Input Giriş - Input Device - Giriş Aygıtı + Giriş Aygıtı + /audio/Input Device + + + + Input Device: + + /audio/Input Device - + Volume Ses + /audio/Volume - + Input Level Giriş Seviyesi + /audio/Input Level - Low - Az + Az - High - Çok + Yüksek - - Select Device - Aygıt Seç + Select input device + Giriş cihazını seçin + + + Input device + Giriş aygıtı + + + volume + Ses + + + Input level + Giriş Seviyesi + + + low + Düşük + + + high + Yüksek - + Connector Bağlayıcı @@ -3759,55 +7286,117 @@ UkmediaMainWidget - + sound error Ses hatası - + load sound failed Yükleme sesi başarısız + + + Establishing connection to PulseAudio. Please wait... + + + + + pa_ext_stream_restore_write() failed + + + + + + (unplugged) + + + + + + (unavailable) + + + + + (plugged in) + + UkmediaOutputWidget - + Output Çıkış - Output Device - Çıkış Aygıtı + Çıkış Aygıtı + /audio/Output Device + + + + Output Device: + + /audio/Output Device - + Master Volume Ana Ses + /audio/Master Volume - + Balance Denge + /audio/Balance - + Right Sağ - + Profile Profil + /audio/Profile + + + + Card + Kart + /audio/Card + + + Select output device + Çıkış cihazını seçin + + + Output device + Çıkış aygıtı + + + Master volume + Ana ses + + + Channel balance + Kanal Dengesi - + Left Sol - + right + Sağ + + + Connector Ses Çıkışı @@ -3815,189 +7404,437 @@ UkmediaSoundEffectsWidget - + System sound + Sistem Sesi + + + Sound theme + Ses Teması + + + Prompt voice + Ses İstemi + + + Boot music + Açılış Sesi + + + System sound theme + Sistem Sesi Teması + + + prompt voice + Ses İstemi + + + Shutdown + Kapat + + + Lagout + Çıkış + + + System Sound Sistem Sesi + /audio/System Sound - + Sound Theme Ses Teması + /audio/Sound Theme - + Alert Sound Uyarı Sesi + /audio/Alert Sound + + + + Alert Volume + + /audio/Alert Volume + + + + Poweroff Music + + + + + Startup Music + + + + + Wakeup Music + + + + + Logout Music + - Boot Music - Açılış Müziği + Açılış Müziği + /audio/Boot Music - + Beep Switch Sesli Uyarı Anahtarı - Window Closed - Pencere Kapalı + Pencere Kapalı - + Volume Change Ses Değişimi - Setting Menu - Ayar Menüsü + Ayar Menüsü UnifiedOutputConfig - + resolution Çözünürlük: - + orientation Uyumluluk - + arrow-up Yukarı - + 90° arrow-right 90° sağa - + arrow-down Aşağı - - 90° arrow-left - 90° sola + + 90° arrow-left + 90° sola + + + + frequency + + + + refresh rate + Yenileme Oranı + + + + auto + Oto + + + aa + aa + + + + Update + + + + Update + Güncelle + + + + + System Update + Sistem Güncelle + /update/System Update + + + + Last check time: + Son kontrol zamanı: + + + + Check for updates + Güncellemeleri kontrol et + + + CheckUpdate + Güncelleme Kontrolü + + + + UpdateDbus + + + ukui-control-center + + + + + ukui-control-center-update + + + + + UpdateLog + + + Update log + + + + + UpdateSource + + + Connection failed, please reconnect! + + + + + Upgrade + + + Upgrade + + /upgrade/Upgrade + + + + UserInfo + + userinfo + Kullanıcı + + + Userinfo + Kullanıcı + + + + User Info + Kullanıcı Bilgisi + + + standard user + Standart Kullanıcı + + + administrator + Yönetici + + + + root + Root + + + + Hint + - - refresh rate - Yenileme Oranı + + The system only allows one user to log in automatically.After it is turned on, the automatic login of other users will be turned off.Is it turned on? + - - auto - Oto + + Trun on + - - aa - aa + + Close on + - - - Update - - - Update - Güncelle + + Add biometric feature + - - System Update - Sistem Güncelle + + Rename + - - Last check time: - Son kontrol zamanı: + + Verify + - - CheckUpdate - Güncelleme Kontrolü + + Delete + Sil - - - UserInfo - - Userinfo - Kullanıcı + + Standard + - - standard user - Standart Kullanıcı + + Admin + - - administrator - Yönetici + + Del + Sil - - root - Root + + Warning + Uyarı - - Delete - Sil + + The user is logged in, please delete the user after logging out + - + Current User Mevcut Kullanıcı - - + Change pwd Parola Değiştir - - + Change type Tür Değiştir - + Change valid + Geçerli olanı değiştir + /userinfo/Change valid + + + User group + Kullanıcı Grubu + + Change vaild - Geçerli Değişiklik + Geçerli Değişiklik + + + + + Password + Parola + /userinfo/Password + + + + + Type + + /userinfo/Type + + + + Valid + - + + Group + + + + + Login no passwd Şifresiz giriş + /userinfo/Login no passwd - + enable autoLogin Otomatik giriş + /userinfo/enable autoLogin + + + + Automatic login at boot + + + + + Currently in Live mode, please create a new user and log out + Şu anda Canlı modda, lütfen yeni bir kullanıcı oluşturun ve oturumu kapatın + + + + Biometric Password + + + + + advanced settings + + + + + enable biometrics + + + + + types of biometric password + - + + biometric device + + + + Other Users Diğer Kullanıcılar - + Add new user Yeni Kullanıcı Ekle + Vino + + + Vino + + + + Vpn @@ -4005,12 +7842,17 @@ Vpn Bağlantısı Ekle - + Add vpn connect Vpn Bağlantısı Ekle + /vpn/Add vpn connect - + vpn + VPN + + + Vpn VPN @@ -4018,128 +7860,149 @@ Wallpaper - + Desktop Background Masaüstü Arkaplanı - + + Select from Seç + /wallpaper/Select from - Picture options - Resim Ayarları + Resim Ayarları - + + Browser local wp Bilgisayardan Seç + /wallpaper/Browser local wp - + + Reset to default Varsayılana Dön + /wallpaper/Reset to default - + + Browser online wp İnternetten Al + /wallpaper/Browser online wp + + + Restore default wp + Varsayılan wp'yi geri yükle - Ok - Tamam + Tamam + + + Add + Ekle - + background + Arkaplan + + + Background Arkaplan - + picture Resim - + color Renk Add custom shortcut - Özel Kısayol Ekle + Özel Kısayol Ekle - + Custom color Özel Renk - wallpaper - Duvar Kağıdı + Duvar Kağıdı - centered - Ortalanmış + Ortalanmış - scaled - Döşe + Döşe - stretched - Uzatılmış + Uzatılmış - zoom - Yakınlaştır + Yakınlaştır - spanned - Yayılmış + Yayılmış + + + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + Duvarkağıdı Dosyaları(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + + + + allFiles(*.*) + Tüm Dosyalar(*.*) - - + + select custom wallpaper file - özel duvar kağıdı dosyasını seç + Özel duvar kağıdı dosyasını seç - - + + Select Seç - - + + Position: Konum: - - + + FileName: Dosya Adı: - - + + FileType: Dosya Türü: - - - + + Cancel İptal @@ -4147,43 +8010,106 @@ Widget - + screen zoom + Ekranı Yaklaştır + + + + unify output + Çıktıyı Birleştir + + + night mode - Gece modu + Gece Modu - + Some applications need to be logouted to take effect Bazı uygulamaların aktif olması için oturum açılması gerekir - + + Information + + + + + Theme follow night mode + + + + + Hint + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +the settings will be saved after 14 seconds + + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +the settings will be saved after %1 seconds + + + + + Save Config + + + + + Restore Config + + + + please insure at least one output! Lütfen en az bir çıktı alın! - - + + Warning Uyarı - + + Open time should be earlier than close time! + + + + + Warnning + + + Morning time should be earlier than evening time! - Sabah vakti akşam saatinden daha erken olmalı! + Sabah vakti akşam saatinden daha erken olmalı! - + Sorry, your configuration could not be applied. Common reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU. Maalesef, yapılandırmanız uygulanamadı. Genel nedenler, toplam ekran boyutunun çok büyük olması veya GPU'nuz tarafından desteklenenden daha fazla ekran etkinleştirmenizdir. - @title:window Unsupported Configuration - Desteklenmeyen Yapılandırma + Desteklenmeyen Yapılandırma + + + Some applications need to be restarted to take effect + Bazı uygulamaların etkili olması için yeniden başlatılması gerekiyor + + + + %1 + %1 @@ -4194,39 +8120,89 @@ - Shortcut name - Kısayol Adı + Kısayol Adı - Shortcut exec - Kısayol komutu + Kısayol komutu + + + + Exec + - + Open - + + Name + İsim + + + + Key + + + + Invalid executable, please re-enter Geçersiz yürütülebilir dosya, lütfen tekrar girin - + + Cancel İptal - + + Save + + + Certain - Belli + Belli + + + + Add custom shortcut + Özel kısayol ekle + + + + shortcut conflict + - + + invaild shortcut + + + + + repeated naming + + + + + Desktop files(*.desktop) + + + + select desktop - masaüstü seç + Masaüstü seç + + + + area_code_lineedit + + Sign up by Phone + Telefonla Kaydolun @@ -4237,47 +8213,167 @@ - + current date Güncel tarih - + time Saat - + year Yıl - + month Ay - + day Gün - + cancel İptal - + confirm Doğrula + config_list_widget + + wallpaper + Duvarkağıdı + + + Sync your settings + Ayarlarınızı senkronize edin + + + Your account:%1 + Hesabınız:%1 + + + Exit + Çıkış + + + Sync + Senkronize + + + Sign in + Oturum aç + + + Stop sync + Senkronizasyonu durdur + + + Auto sync + Otomatik senkronizasyon + + + Synchronize your personalized settings and data + Kişiselleştirilmiş ayarlarınızı ve verilerinizi senkronize edin + + + Login Cloud to get a better experience + Daha iyi bir deneyim için Cloud'a giriş yapın + + + Sign in/Sign up + Giriş yap/Kayıt Ol + + + You must sign in when you attempt to sync your settings. + Ayarlarınızı eşitlemeye çalıştığınızda oturum açmalısınız.。 + + + Your account:%1 + Hesabınız:%1 + + + Disconnected + Bağlantı Kesildi + + + + item_list + + Menu + Menü + + + Quick Start + Hızlı Başlat + + + Tab + Sekme + + + ScreenSaver + Ekran Koruyucu + + + User Profile + Kullanıcı Profili + + + Weather + Hava Durumu + + + Media + Medya + + + Walpaper + Duvar Kağıdı + + + + m_updatelog + + + No content. + + + + + History Log + + + + + Update Details + + + + networkaccount - NetworkAccount - Ağ Hesabı + Cloud Account + Bulut Hesabı + /networkaccount/Cloud Account + + + + ql_pushbutton_edit + + Reset + Sıfırla Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/i18n/zh_CN.qm and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/i18n/zh_CN.qm differ diff -Nru ukui-control-center-2.0.3/shell/res/i18n/zh_CN.ts ukui-control-center-3.0.3/shell/res/i18n/zh_CN.ts --- ukui-control-center-2.0.3/shell/res/i18n/zh_CN.ts 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/i18n/zh_CN.ts 2021-05-20 13:08:14.000000000 +0000 @@ -9,69 +9,101 @@ 系统概述 - + version 版本 + /about/version - - TextLabel - + Copyright 2009-2020 @ Kylinos All rights reserved + 版权所有2009-2020@kylinos保留所有权利 - - Copyright 2009-2020 @ Kylinos All rights reserved - 版权所有2009-2020@kylinos保留所有权利 + Copyright 2009-2021 @ Kylinos All rights reserved + 版权所有2009-2021@kylinos保留所有权利 + + + + Version + 版本 + + + + Kylin Linux Desktop V10 (SP1) + 银河麒麟桌面操作系统V10 (SP1) + + + Copyright @ 2009-2021 KylinSoft. All rights reserved. + 版权所有 @ 2009-2021 麒麟软件 保留所有权利。 + + + + Copyright © 2009-2021 KylinSoft. All rights reserved. + 版权所有 © 2009-2021 麒麟软件 保留所有权利。 - + + Kernel 内核 + /about/Kernel - + + CPU CPU + /about/CPU - + + Memory 内存 + /about/Memory - + Disk 硬盘 - + Desktop 桌面 - + User 用户名 - + Active Status 激活状态 - - Service serial number + + Serial 序列号 - + + Protocol + 免责协议 + + + Service serial number + 序列号 + + + Active 激活 - Trial version disclaimer - 试用版免责声明 + 试用版免责声明 Devices Summary @@ -82,32 +114,31 @@ 关于 - + About 关于 + /about/About - - Disk One: - + + The system has expired. The expiration time is: + 您的系统已激活,技术服务已到期: - - Disk Two: - + Disk: + 硬盘: - available - + 可用 - + Inactivated 未激活 - + Activated 已激活 @@ -164,110 +195,321 @@ AddAutoBoot - + Add AutoBoot 添加自启动程序 - + Add autoboot program 添加自启动程序 - + + Program name 程序名 - + + Program exec 程序路径 - + Open 浏览 - + + Program comment 程序描述 - + + Cancel 取消 - + Certain 确定 - + + Desktop files(*.desktop) + 桌面文件(*.desktop) + + + select autoboot desktop 选择自启动程序 + + + Select + 选择 + + + + desktop file not allowed add + 此应用不允许添加 + + + + desktop file not exist + desktop文件不存在 + AppDetail Dialog - + 更改时间 - - TextLabel - + + App + - + Allow notification 允许通知 - + Number of notification centers 最大通知数量 - + cancel 取消 - + confirm 确认 + AppUpdateWid + + + Lack of local disk space! + 磁盘空间不足! + + + + + + + + + Update + 更新 + + + + Network abnormal! + 网络异常! + + + + + Download failed! + 下载失败! + + + + failed to get from the source! + 从源中获取失败! + + + + The download cache has been removed + 下载缓存已被删除 + + + + Being installed + 正在安装 + + + Update succeeded , please restart the system! + 更新成功,请重启系统! + + + Update succeeded , please log in to the system again! + 更新成功,请注销重新登录系统! + + + + + Update succeeded! + 更新成功! + + + + + Update failed! + 更新失败! + + + + Failure reason: + 失败原因: + + + + + details + 详情 + + + + + Update log + 更新日志 + + + + + + + Newest: + 最新: + + + + + Download size: + 下载大小: + + + + Current version: + 当前版本: + + + + back + 收起 + + + + In the pause + 暂停中 + + + + + Cancel + 取消 + + + + + + Update succeeded , It is recommended that you restart later! + 更新成功,建议您稍后重启! + + + + + + Update succeeded , It is recommended that you log out later and log in again! + 更新成功,建议您稍后注销重新登录系统! + + + + A single update will not automatically backup the system, if you want to backup, please click Update All. + 单个更新不会自动备份系统,如需备份,请点击全部更新。 + + + + Prompt information + 提示信息 + + + + Do not backup, continue to update + 不备份,继续更新 + + + + Cancel update + 取消更新 + + + + This time will no longer prompt + 本次更新不再提示 + + + Calculate the download speed + 正在获取当前下载进度 + + + + + Get depends failed! + 依赖获取异常! + + + + In the update + 更新中 + + + + + + Ready to install + 准备安装 + + + + Calculate the download progress + 正在计算当前下载速度 + + + + No content. + 暂无内容. + + + Area - + Area - 语言和地区 + 区域语言 - + Area showing time currency format - + 显示日期、货币、时间、货币格式的区域 - + Regional format data 区域格式数据 - - + + lunar 农历 - + First day of the week 一周的第一天 @@ -276,97 +518,89 @@ - - 2019/12/17 - - - - - 9:52 - - - - - - TextLabel - - - area - 语言和地区 + 区域语言 - + current area 当前区域 + /area/current area - display format area - 显示日期、时间、货币格式的区域 + 显示日期、时间、货币格式的区域 - + US 美国 - - format of area - 区域格式数据 - - - + addwgt - + - + Add main language 添加首语言 - - + + calendar 日历 - + first day of week 一周的第一天 - - + + date 日期 - - + + 2019/12/17 + 2019/12/17 + + + + time 时间 - - + + 9:52 + 9:52 + + + + change format of data 更改数据格式 - + + first language 首选语言 + /area/first language - + + system language - 系统,菜单的显示语言 + 显示语言 - + CN 中国 @@ -375,18 +609,29 @@ 需要注销生效 - - + + Need to log off to take effect 需要注销生效 - + + country + 显示日期,时间,货币格式的区域 + + + + regional format + 区域格式数据 + /area/regional format + + + English 英语 - + Chinese 简体中文 @@ -395,23 +640,23 @@ 添加首语言 - + solar calendar 公历 - - + + monday 星期一 - + sunday 星期天 - + change data format 更改数据格式 @@ -419,16 +664,15 @@ AreaCodeLineEdit - Sign up by Phone - 请输入手机号码 + 请输入手机号码 Audio - + Audio 声音 @@ -437,11 +681,13 @@ AutoBoot + Autoboot Settings 开机启动设置 + /autoboot/Autoboot Settings - + Add autoboot app 添加自启动程序 @@ -450,28 +696,39 @@ 开机启动 - Autoboot + 开机启动 + + + + Auto Boot 开机启动 - + Name 程序名称 - + Status 当前状态 + + + Delete + 删除 + Backup - + + Backup 备份 + /backup/Backup Back up your files to other drives, and when the original files are lost, damaged, or deleted, you can restore them to ensure @@ -485,22 +742,28 @@ 将您的文件备份到其他驱动器,当源文件丢失、受损、删除时还原它们,保证系统的完整性。 - + Begin backup 开始备份 - + + Restore 还原 + /backup/Restore - - View a list of backed-upfiles to restore backed up files to the system + + View a list of backed-upfiles to backed up files to the system 查看备份列表,将已备份文件还原至系统 - + View a list of backed-upfiles to restore backed up files to the system + 查看备份列表,将已备份文件还原至系统 + + + Begin restore 开始还原 @@ -520,3781 +783,6297 @@ 输入密码 - Your code here - 输入验证码 + 输入验证码 + + + Get + 获取验证码 - Get phone code - 获取绑定手机验证码 + 获取绑定手机验证码 - CertificationDialog + BiometricEnrollDialog - - - UserCertification - 用户认证 + + Dialog + - - User: - 用户名: + + Biometrics + 生物识别 - - Passwd: - 密码: + + Continue to enroll + 继续录入 - - Close - 关闭 + + Finish + 完成 - - Certification - 认证 + + FingerPrint + 指纹 - - - ChangeFaceDialog - - select custom face file - 选择自定义头像文件 + + Fingervein + 指静脉 - - Select - 选择 + + Iris + 虹膜 - - Position: - 位置: + + Face + 人脸 - - FileName: - 文件名: + + VoicePrint + 声纹 - - FileType: - 文件类型: + + Enroll + 录入 - - Cancel - 取消 + + Verify + 验证 - - Warning - 警告 + + Search + 搜索 - - The avatar is larger than 2M, please choose again - 警告,头像大于2M请重新选择 + + Permission is required. +Please authenticate yourself to continue + 需要授权,请先进行认证已继续操作 - - Change User Face - 更改用户头像 + + + Enroll successfully + 录入成功 - - Select face from local - 从本地选择用户头像 + + + Verify successfully + 验证成功 - - - ChangePwdDialog - - Change Pwd - 更改密码 + + Not Match + 不匹配 - - Pwd type - 密码类型 + + D-Bus calling error + D-Bus获取错误 - - New pwd - 新密码 + + Device is busy + 设备忙 - - New pwd sure - 新密码确认 + + No such device + 设备不存在 - - Cancel - 取消 + + Permission denied + 权限不够 + + + BiometricMoreInfoDialog - - Confirm - 确定 + + Dialog + - - General Pwd - 通用密码 + + Biometrics + 生物识别 - - - New Password - 新密码 + + Default device + 默认设备 - - - New Password Identify - 新密码确认 + + Verify Type: + 验证类型: - - Password length needs to more than %1 character! - 密码长度至少大于%1个字符! + + Bus Type: + 总线类型: - - Password length needs to less than %1 character! - 密码长度需要小于%1个字符! + + Device Status: + 设备状态: - Password length needs to more than 5 character! - 密码长度需要大于5个字符! + + Storage Type: + 存储类型: - - - Inconsistency with pwd - 与新密码不同 + + Identification Type: + 验证类型: - - - ChangeTypeDialog - - Make sure that there is at least one administrator on the computer - 请确保该计算机上至少有一个管理员用户 + + Connected + 已连接 - - Standard users can use most software, but cannot install software and change system settings - 标准账户可以使用大多数软件,但是不能安装软件和更改系统配置 + + Unconnected + 未连接 - - Change Account Type - 更改用户类型 + + FingerPrint + 指纹 - - standard user - 标准用户 + + Fingervein + 指静脉 - - administrator - 管理员用户 + + Iris + 虹膜 - - Administrators can make any changes they need - 管理员账户可以更改任何系统配置,包括安装软件和升级软件 + + Face + 人脸 - - Cancel - 取消 + + VoicePrint + 声纹 - - Confirm - 确定 + + Hardware Verification + 硬件验证 - - - ChangeVaildDialog - Password Validity Setting - 密码有效期设置 + + Software Verification + 软件验证 - Current passwd validity: - 当前密码有效期至: + + Mix Verification + 混合验证 - Adjust date to: - 调整有效期至: + + Other Verification + 其他验证 - Cancel - 取消 + + Device Storage + 设备存储 - Certain - 确定 + + OS Storage + 系统存储 - - - ChangeValidDialog - - Dialog - + + Mix Storage + 混合存储 - - Password Validity Setting - 密码有效期设置 + + Serial + 串口 - - Current passwd validity: - 当前密码有效期至: + + USB + USB - - Adjust date to: - 调整有效期至: + + PCIE + PCIE - - Cancel - 取消 + + Any + 任意类型 - - Certain - 确定 + + Other + 其他 - - - ChangtimeDialog - - day - 日期 + + Hardware Identification + 硬件识别 - - time - 时间 + + Software Identification + 软件识别 - - - year - 年份 + + Mix Identification + 混合识别 - - - month - 月份 + + Other Identification + 其他识别 - ColorDialog + BlueToothMain - - Dialog - + Turn off Bluetooth + 关闭蓝牙 - - B - + + + + + Turn on Bluetooth + 开启蓝牙 - - Cancel - 取消 + + Bluetooth + 蓝牙 + /bluetooth/Bluetooth - - OK - 确定 + + Bluetooth adapter + 蓝牙适配器 - - R - + + Show icon on taskbar + 在任务栏上显示蓝牙图标 + /bluetooth/Show icon on taskbar - - G - + + Allow Bluetooth devices to be discoverable + 允许蓝牙设备可以被发现 + /bluetooth/Discoverable - - Custom color - 自定颜色 + Discoverable + 设备可见性 + /bluetooth/Discoverable - - - CreateUserDialog - - - UserName - 用户名 + + My Devices + 我的设备 - - - Password - 密码 + Can now be found as + 现在可被发现为 - - Account Type - 用户类型 + + Other Devices + 蓝牙设备 + /bluetooth/Other Devices - - Add New Account - 添加新用户 + + Refresh + 刷新 + + + Bluetooth - - PwdType - 密码类型 + + Bluetooth + 蓝牙 + + + BluetoothNameLabel - - PasswordSure - 确认密码 + Can now be found as + 现在可被发现为 - - standard user - 标准用户 + + + + + + Can now be found as "%1" + 现在可被发现为"%1" + + + CertificationDialog - - Standard users can use most software, but cannot install the software and -change system settings - 标准账户可以使用大多数软件,但是不能安装软件和更改系统配置 + + + UserCertification + 用户认证 - - administrator - 管理员用户 + + User: + 用户名: - - Administrators can make any changes they need - 管理员账户可以更改任何系统配置,包括安装软件和升级软件 + + Passwd: + 密码: - - Cancel - 取消 + + Close + 关闭 - - Confirm - 确定 + + Certification + 认证 + + + ChangeFaceDialog - - Password Identify - 密码确认 + + select custom face file + 选择自定义头像文件 - - General Password - 通用密码 + + Select + 选择 - - - Inconsistency with pwd - 和密码不一致 + + Position: + 位置: - - Password length needs to more than %1 character! - 密码长度至少大于%1个字符! + + FileName: + 文件名: - - Password length needs to less than %1 character! - 密码长度需要小于%1个字符! + + FileType: + 文件类型: - - The user name cannot be empty - 用户名不能为空 + + + Cancel + 取消 - - The first character must be lowercase letters! - 首字符必须为小写字符! + + Warning + 警告 - - User name can not contain capital letters! - 用户名不能包含大写字符! + + The avatar is larger than 1M, please choose again + 警告,头像大于1M请重新选择 - - The user name is already in use, please use a different one. - 用户名已存在,请换用其他用户名。 + The avatar is larger than 2M, please choose again + 警告,头像大于2M请重新选择 - - User name length need to less than %1 letters! - 用户名长度需要小于%1个字符! + + Change User Face + 更改用户头像 - - The user name can only be composed of letters, numbers and underline! - 用户名只能由字母、数字以及下划线组成! + + System Icon + 系统头像 - - The username is configured, please change the username - 用户配置已存在,请更换用户名 + + Select face from local + 从本地选择用户头像 + + + + Save + 确定 - DataFormat + ChangeGroupDialog - + Dialog - - - - - change format of data - 更改数据格式 - - - - - calendar - 日历 + 用户组 - - first day - 一周第一天 + + User Group Settings + 用户组设置 - - - date - 日期 + User groups available in the system + 系统中可用的用户组 - - - time - 时间 + + Cancel + 取消 - - cancel - 取消 + Add new user + 添加新用户 - - confirm - 确认 + + User group + 用户组 - - first day of week - 一周的第一天 + + Add user group + 添加用户组 - - lunar - 农历 + + + Tips + 提示 - - solar calendar - 公历 + + Invalid Id! + 无效组ID! - - monday - 星期一 + + + OK + 确定 - - sunday - 星期天 + + Invalid Group Name! + 无效组名! - DateTime + ChangePwdDialog - - DateTime - 时间和日期 + + Change Pwd + 更改密码 - - current date - 时间和日期 + + Pwd type + 密码类型 - - - - TextLabel - + + Cur pwd + 当前密码 - - timezone - 时区 + + New pwd + 新密码 - - - Sync system time - 同步系统时间 + + New pwd sure + 新密码确认 - - - Change time - 手动更改时间 + + Cancel + 取消 - - - Change time zone - 更改时区 + + Confirm + 确定 - - Sync complete - 同步完成 + + Change pwd + 更改密码 - datetime - 时间和日期 + Cur pwd checking! + 当前密码检查! - - Datetime - 时间和日期 + + General Pwd + 通用密码 - - 24-hour clock - 24小时制 + + + Current Password + 当前密码 - - change time - 更改时间 + + + + New Password + 新密码 - - - DefaultApp - defaultapp - 默认应用 + + + + New Password Identify + 新密码确认 - - Defaultapp - 默认应用 + + Pwd input error, re-enter! + 密码输入错误,重新输入! - - - DefaultAppWindow - - Select Default Application - 默认应用 + + Contains illegal characters! + 含有非法字符! - - Browser - 浏览器 + + Same with old pwd + 与旧密码相同 - - Mail - 电子邮件 + Password length needs to more than %1 character! + 密码长度至少大于%1个字符! - - Image Viewer - 图像查看器 + Password length needs to less than %1 character! + 密码长度需要小于%1个字符! - - Audio Player - 音频播放器 + Password length needs to more than 5 character! + 密码长度需要大于5个字符! - - Video Player - 视频播放器 - - - - Text Editor - 文档编辑器 + + + Inconsistency with pwd + 与新密码不同 - DefineShortcutItem + ChangeTypeDialog - - Delete - 删除 + + Make sure that there is at least one administrator on the computer + 请确保该计算机上至少有一个管理员用户 - - - DelUserDialog - - Delete the user, belonging to the user's desktop, -documents, favorites, music, pictures and video -folder will be deleted! - 删除用户,用户所属的桌面、文档、收藏夹、音乐、图片和视频文件夹中的内容将全部被删除! + Standard users can use most software, but cannot install software and change system settings + 标准账户可以使用大多数软件,但是不能安装软件和更改系统配置 - - Cancel - 取消 + + Change Account Type + 更改用户类型 - - KeepFile - 保留文件 + + standard user + 标准用户 - - RemoveFile - 删除文件 + + Standard users can use most software, but cannot change system settings + 标准账户可以使用大多数软件,但是不能修改系统配置 - - - Desktop - - Icon Show On Desktop - 显示在桌面的图标 + + administrator + 管理员用户 - - Computerdesktop - 计算机 + + Administrators can make any changes they need + 管理员账户可以更改任何系统配置,包括安装软件和升级软件 - - Trashdesktop - 垃圾箱 + + Cancel + 取消 - - Homedesktop - 家目录 + + Confirm + 确定 - - Volumedesktop - 挂载卷 + + Change type + 更改类型 + + + ChangeUserName - - Networkdesktop - 网络 + + + Change Username + 修改用户名 - - Set Start Menu - 设置开始菜单 + + Cancel + 取消 - - Always use the start menu in full screen - 一直使用全屏"开始"菜单 + + Save + 确定 + + + ChangeVaildDialog - - Icon Lock on Menu - 锁定在开始菜单的图标 + Password Validity Setting + 密码有效期设置 - - Computermenu - 计算机 + Current passwd validity: + 当前密码有效期至: - - Trashmenu - 回收站 + Adjust date to: + 调整有效期至: - - Filesystemmenu - 个人 + Cancel + 取消 - - Tray icon - 显示在托盘上的图标 + Certain + 确定 + + + ChangeValidDialog - Homemenu - 家目录 + + Dialog + 更改时间 - - Settingmenu - 设置 + + Password Validity Setting + 密码有效期设置 - Networkmenu - 网络 + + Current passwd validity: + 当前密码有效期至: - desktop - 桌面 + + Adjust date to: + 调整有效期至: - - Desktop - 桌面 + + Cancel + 取消 - - - Dialog_login_reg - Sign in - 登录 + + Certain + 确定 - Sign up - 注册云账户 + + Change valid + 密码时效 + + + ChangtimeDialog - Login in progress - 登录中 + + day + 日期 - Error code: - 错误代码: + + time + 时间 - ! - + + year + 年份 - Internal error occurring! - 服务器错误! + + month + 月份 + + + ColorDialog - Failed to sign up! - 注册失败! + + Dialog + 更改时间 - Failed attempt to return value! - 登录返回值异常! + + B + - Check your connection! - 登录失败或网络异常! + + R + - Failed to get by phone! - 手机获取验证码失败! + + G + - Failed to get by user! - 用户名获取验证码失败! + + Cancel + 取消 - Failed to reset password! - 重置密码失败! + + OK + 确定 - Phone binding falied! - 手机绑定失败! + + Custom color + 自定颜色 + + + CreateGroupDialog - Please check your information! - 缺少必要信息! + + Dialog + 添加用户组 - Please check your account! - 账户或密码错误! + + Add New Group + 添加用户组 - Failed due to server error! - 服务器错误! + + Name + 组名 - User existing! - 用户名已存在! + + Id + 组ID - Phone number already in used! - 手机号码已被使用! + + Members + 组成员 - Please check your format! - 手机号码格式错误! + Group Name + 组名 - Your are reach the limit! - 该手机当日接收短信次数达到上限! + Group Id + 组ID - Please check your phone number! - 手机号码其他错误! + Group Members + 组成员 - Please check your code! - 手机验证码错误! + + Cancel + 取消 - Account doesn't exist! - 用户名不存在! + + Certain + 确定 - User has bound the phone! - 用户已经绑定手机号! + + Add user group + 添加用户组 + + + CreateUserDialog - Sending code error occurring! - 发送验证码异常! + + + UserName + 用户名 - Your code is wrong! - 验证码错误! + + + Password + 密码 - Binding Phone - 绑定手机 + + Account Type + 用户类型 - Bind now - 绑定 + + Add New Account + 添加新用户 - Resend ( %1 ) - 重新发送(%1) + + PwdType + 密码类型 - Get phone code - 获取绑定手机验证码 + + PasswordSure + 确认密码 - Send - 发送验证码 + + standard user + 标准用户 - At least 6 bit, include letters and digt - 至少六位,包含大小写字母、数字 + + Standard users can use most software, but cannot change system settings + 标准账户可以使用大多数软件,但是不能修改系统配置 - Please check your password! - 两次密码设置不一致! + Standard users can use most software, but cannot install the software and +change system settings + 标准账户可以使用大多数软件,但是不能安装软件和更改系统配置 - Sign in Cloud - 登录云账户 - + + administrator + 管理员用户 + - Forget - 忘记密码 + + Administrators can make any changes they need + 管理员账户可以更改任何系统配置,包括安装软件和升级软件 - Set - 设置 + + Cancel + 取消 - Back - 返回登录 + + Confirm + 确定 - Create Account - 注册云账户 + + Password Identify + 密码确认 - Sign up now - 立即注册 + + General Password + 通用密码 - - - DisplayPerformanceDialog - - Dialog - + + + Inconsistency with pwd + 和密码不一致 - - Display Advanced Settings - 显示高级设置 + + Must be begin with lower letters! + 用户名必须以小写字母开始! - - Performance - 性能模式 + + Can not contain capital letters! + 用户名不能包含大写字母! - - Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. - 适用于具有独立显卡的机器,能够充分发挥显卡的性能,对3D图形绘制进行加速。 + + Name already in use, change another one. + 该用户名已存在,请更改。 - - (Note: not support connect graphical with xmanager on windows.) - (注意:本模式不支持Windows上个使用Xmanager等工具连接图形显示) + + Name corresponds to group already exists. + 用户名对应组已存在,请更改。 - - Compatible - 兼容模式 + + Name length must less than %1 letters! + 用户名长度必须小于%1! - - Applicable to machine with integrated graphics, there is no 3D graphics acceleration. - 适用于集成显卡,BMC显卡等只具备基础显示功能,无3D图形绘制加速。 + + Can only contain letters,digits,underline! + 用户名仅能包含字母,数字及下划线 - - (Note: need connect graphical with xmanager on windows, use this option.) - (注意:需要使用Windows上Xmanager等工具连接图形的机器请选择本项) + + Username's folder exists, change another one + 用户目录已存在,请更改 - - Automatic - 自动检测 + Password length needs to more than %1 character! + 密码长度至少大于%1个字符! - - Auto select according to environment, delay the login time (about 0.5 sec). - 自动检测显示环境,会增加登录延时(0.5秒左右) + Password length needs to less than %1 character! + 密码长度需要小于%1个字符! - - Threshold: - 阈值设置: + + Add new user + 添加新用户 - - Apply - 应用 + Password cannot be made up entirely by Numbers! + 密码复杂度过低! - - Reset - 重置 + + Contains illegal characters! + 含有非法字符! - - (Note: select this option to use 3D graphics acceleration and xmanager.) - (注意:使用3D图形加速,且用Xmanager连接图形时选择本项) + + The user name cannot be empty + 用户名不能为空 - - - DisplaySet - display - 显示器 + The first character must be lowercase letters! + 首字符必须为小写字符! - - Display - 显示器 + User name can not contain capital letters! + 用户名不能包含大写字符! - - - DisplayWindow - - Form - + The user name is already in use, please use a different one. + 用户名已存在,请换用其他用户名。 - - monitor - 显示器 + The name corresponds to the group already exists. + 用户名对应组已存在,请更换用户名. - - set as home screen - 设为主屏 + User name length need to less than %1 letters! + 用户名长度需要小于%1个字符! - close monitor - 关闭显示器 + The user name can only be composed of letters, numbers and underline! + 用户名只能由字母、数字以及下划线组成! - - unify output - 统一输出 + The username is configured, please change the username + 用户配置已存在,请更换用户名 + + + CustomLineEdit - - open monitor - 打开显示器 + + New Shortcut... + 新快捷键... + + + DataFormat - - Advanced - 高级显示 + + Dialog + 更改时间 - - screen brightness adjustment - 调整屏幕亮度 + + change format of data + 更改数据格式 - - dark - + + + calendar + 日历 - - bright - + + first day + 一周第一天 - - follow the sunrise and sunset(17:55-05:04) - 跟随日出日落(17:55-05:04) + + + date + 日期 - - custom time - 自定义时间 + + + time + 时间 - - opening time - 开启时间 + + cancel + 取消 - - closing time - 关闭时间 + + confirm + 确认 - - color temperature - 色温 + + first day of week + 一周的第一天 - - warm - + + lunar + 农历 - - cold - + + solar calendar + 公历 - - apply - 应用 + + monday + 星期一 - - - EditPassDialog - - Edit Password - 修改密码 + + sunday + 星期天 + + + DateTime - Your account here - 请输入用户名 + + DateTime + 时间日期 - Your password here - 输入密码 + + current date + 当前时间 - - Your new password here - 新密码 + timezone + 时区 - Your code here - 输入验证码 + Sync system time + 同步系统时间 - - Your code - 请输入验证码 + Sync from network successful + 时间同步成功 + /date/Sync from network successful - - Get phone code - 获取绑定手机验证码 + + + Sync from network failed + 时间同步失败 - - Cancel - 取消 + + + Change time + 手动更改时间 + /date/Change time - - Confirm - 确定 + + + Change time zone + 更改时区 + /date/Change time zone - - Confirm your new password - 确认新密码 + Sync complete + 同步完成 - - - - - At least 6 bit, include letters and digt - 至少六位,包含大小写字母、数字 + datetime + 时间日期 - - Your password is valid! - 您的密码是有效的! + Datetime + 时间日期 - - Please check your password! - 两次密码设置不一致! + Dat + 时间日期 - - Resend( - 重新发送( + + Date + 时间日期 - - ) - + + 24-hour clock + 24小时制 + /date/24-hour clock - - - Send - 发送验证码 + + Sync from network + 同步网络时间 - Success! - 成功! + + + - - Reback sign in - 重新登录 + Sync network time + 同步网络时间 - - Error code: - 错误代码: + + change time + 更改时间 + + + DefaultApp - - ! - + defaultapp + 默认应用 - - Internal error occurring! - 服务器错误! + Defaultapp + 默认应用 - - Failed to sign up! - 注册失败! + + Default App + 默认应用 - - Failed attempt to return value! - 尝试获取返回值失败! + + Browser + 浏览器 + /defaultapp/Browser - - Check your connection! - 登录失败或网络异常! + + Mail + 电子邮件 + /defaultapp/Mail - - Failed to get by phone! - 手机获取验证码失败! + + Image Viewer + 图像查看器 + /defaultapp/Image Viewer - - Failed to get by user! - 用户名获取验证码失败! + + Audio Player + 音频播放器 + /defaultapp/Audio Player - - Failed to reset password! - 重置密码失败! + + Video Player + 视频播放器 + /defaultapp/Video Player - - - - Please check your information! - 缺少必要信息! + + Text Editor + 文档编辑器 + /defaultapp/Text Editor + + + DefaultAppWindow - - Please check your account! - 账户或密码错误! + + Select Default Application + 默认应用 - - Failed due to server error! - 服务器错误! + + Browser + 浏览器 - - User existing! - 用户名已存在! + + Mail + 电子邮件 - - Phone number already in used! - 手机号码已被使用! + + Image Viewer + 图像查看器 - - Please check your format! - 手机号码格式错误! + + Audio Player + 音频播放器 - - Your are reach the limit! - 该手机当日接收短信次数达到上限! + + Video Player + 视频播放器 - - Please check your phone number! - 手机号码其他错误! + + Text Editor + 文档编辑器 - - Please check your code! - 手机验证码错误! + + Reset to default + 恢复默认设置 + + + DefineGroupItem - - Account doesn't exist! - 用户名不存在! + + Edit + 编辑 - - Sending code error occurring! - 发送验证码异常! + + Delete + 删除 - EditPushButton + DefineShortcutItem - - Reset - 重置密码 + + Delete + 删除 - ExperiencePlan + DelGroupDialog - - User Experience - 用户体验 + + Dialog + 删除用户组 - - Join in user Experience plan - 加入用户体验计划 + + TextLabel + - - User experience plan terms, see - 用户体验计划条款,参见 + Are you sure to delete this group, +which will make some file components +in the file system invalid! + 确定删除此用户组? 这将使得文件系统\n中的某些文件组件ID无效! - - 《User Experience plan》 - 《用户体验计划》 + + Delete + 删除 - experienceplan - 体验计划 + + Cancel + 取消 - - Experienceplan - 体验计划 + RemoveFile + 删除文件 - - - Fonts - - - Fonts - 字体 + Remind + 提醒 - - Fonts select - 字体选择 + Are you sure to delete "%1" group, +which will make some file components +in the file system invalid! + 确定删除"%1"组,这将使得文件系统 +中的某些文件组件ID无效! - - Font size - 字体大小 + + Delete user group + 删除用户组 - - Reset to default - 恢复默认设置 + + Are you sure to delete the group, which will make some file components in the file system invalid! + 确定删除该用户组,这将使得文件系统中的某些文件组件ID无效! + + + DelUserDialog - - Gtk default font - 通用字体 + Delete the user, belonging to the user's desktop, +documents, favorites, music, pictures and video +folder will be deleted! + 删除用户,用户所属的桌面、文档、收藏夹、音乐、图片和视频文件夹中的内容将全部被删除! - - Document font - 文档字体 + + keep the user's data, like desktop,documents, favorites, music, pictures and so on + 保留用户下所属的桌面、文件、收藏夹、音乐等文件 - - - Monospace font - 等宽字体 + + delete whole data belong user + 删除该用户所有文件 - - Advanced settings - 高级设置 + + Cancel + 取消 - - Peony font - 桌面字体 + + Delete + 删除 - - titlebar font - 标题字体 + KeepFile + 保留文件 - - Select text sample that looks clearest - 选择看起来清晰的字体效果 + RemoveFile + 删除文件 - fonts - 字体 + + Delete the user ' + 是否删除用户' - - 11 - + + 'and: + '同时: + + + Desktop - - 12 - + + + Icon Show On Desktop + 显示在桌面的图标 + /desktop/Icon Show On Desktop - - 13 - + + Computerdesktop + 计算机 - - 14 - + + Trashdesktop + 垃圾箱 - - 15 - + + Homedesktop + 家目录 - - 16 - + + Volumedesktop + 挂载卷 - - 17 - + + Networkdesktop + 网络 - - 18 - + + Set Start Menu + 设置开始菜单 - - Thanks For Using The ukcc - + + Always use the start menu in full screen + 一直使用全屏"开始"菜单 - - - FrameItem - - Sync failed, please login out to retry! - 同步失败,请检查网络或退出云账户重试! + + Icon Lock on Menu + 锁定在开始菜单的图标 - - Change configuration file failed, please login out to retry! - 配置文件更改失败,请检查网络或退出云账户重试! + + Computermenu + 计算机 - - Configuration file not exist, please login out to retry! - 配置文件不存在,请检查网络或退出云账户重试! + + Trashmenu + 回收站 - - Cloud verifyed file download failed, please login out to retry! - 云校验失败,请检查网络或退出云账户重试! + + Filesystemmenu + 个人 - - OSS access failed, please login out to retry! - 文件存储访问失败,请检查网络或退出云账户重试! + + + Tray icon + 显示在托盘上的图标 + /desktop/Tray icon - - Sync failed, please retry or login out to get a better experience! - 同步失败,建议重试或者重新登录来获取最佳体验! + Homemenu + 家目录 - Change configuration file failed, please retry or login out to get a better experience! - 配置文件设置失败,建议重试或者重新登录来获取最佳体验! + + Settingmenu + 设置 - Configuration file not exist, please retry or login out to get a better experience! - 配置文件不存在,建议重试或者重新登录来获取最佳体验! + Networkmenu + 网络 - Cloud verifyed file download failed, please retry or login out to get a better experience! - 云端校验失败,建议重试或者重新登录来获取最佳体验! + desktop + 桌面 - OSS access failed, please retry or login out to get a better experience! - 文件存储访问失败,建议重试或者重新登录来获取最佳体验! + + Desktop + 桌面 - ItemList + DeviceInfoItem - - Walpaper - 桌面壁纸 + + Connect + 连接 - - ScreenSaver - 屏保 + + Disconnect + 断开 - - Menu - 开始菜单 + + Remove + 移除 + + + + DeviceType + + + FingerPrint + 指纹 - - Quick Start - 快速启动项 + + FingerVein + 指静脉 - - Tab - 任务栏 + + Iris + 虹膜 - - Weather - 麒麟天气 + + Face + 人脸 - - Media - 麒麟影音 + + VoicePrint + 声纹 - KbdLayoutManager + Dialog_login_reg - - C - 按国家 + Sign in + 登录 - - L - 按语言 + Sign up + 注册云账户 - - Variant - 变体 + Login in progress + 登录中 - - Add - 添加 + Error code: + 错误代码: - - Add Layout - 添加布局 + ! + - - Del - 删除 + Internal error occurring! + 服务器错误! - - - KeyValueConverter - system - 系统 + Failed to sign up! + 注册失败! - devices - 设备 + Failed attempt to return value! + 登录返回值异常! - personalized - 个性化 + Check your connection! + 登录失败或网络异常! - network - 网络 + Failed to get by phone! + 手机获取验证码失败! + + + Failed to get by user! + 用户名获取验证码失败! + + + Failed to reset password! + 重置密码失败! + + + Phone binding falied! + 手机绑定失败! + + + Please check your information! + 缺少必要信息! + + + Please check your account! + 账户或密码错误! + + + Failed due to server error! + 服务器错误! + + + User existing! + 用户名已存在! + + + Phone number already in used! + 手机号码已被使用! + + + Please check your format! + 手机号码格式错误! + + + Your are reach the limit! + 该手机当日接收短信次数达到上限! + + + Please check your phone number! + 手机号码其他错误! + + + Please check your code! + 手机验证码错误! + + + Account doesn't exist! + 用户名不存在! + + + User has bound the phone! + 用户已经绑定手机号! + + + Sending code error occurring! + 发送验证码异常! + + + Your code is wrong! + 验证码错误! + + + Binding Phone + 绑定手机 + + + Bind now + 绑定 + + + Resend ( %1 ) + 重新发送(%1) + + + Get phone code + 获取绑定手机验证码 + + + Send + 发送验证码 + + + At least 6 bit, include letters and digt + 至少六位,包含大小写字母、数字 + + + Please check your password! + 两次密码设置不一致! + + + Sign in Cloud + 登录云账户 + + + Forget + 忘记密码 + + + Set + 设置 + + + Back + 返回登录 + + + Create Account + 注册云账户 + + + Sign up now + 立即注册 + + + + DisplayPerformanceDialog + + + Dialog + 更改时间 + + + + Display Advanced Settings + 显示高级设置 + + + + Performance + 性能模式 + + + + Applicable to machine with discrete graphics, which can accelerate the rendering of 3D graphics. + 适用于具有独立显卡的机器,能够充分发挥显卡的性能,对3D图形绘制进行加速。 + + + + (Note: not support connect graphical with xmanager on windows.) + (注意:本模式不支持Windows上个使用Xmanager等工具连接图形显示) + + + + Compatible + 兼容模式 + + + + Applicable to machine with integrated graphics, there is no 3D graphics acceleration. + 适用于集成显卡,BMC显卡等只具备基础显示功能,无3D图形绘制加速。 + + + + (Note: need connect graphical with xmanager on windows, use this option.) + (注意:需要使用Windows上Xmanager等工具连接图形的机器请选择本项) + + + + Automatic + 自动检测 + + + + Auto select according to environment, delay the login time (about 0.5 sec). + 自动检测显示环境,会增加登录延时(0.5秒左右) + + + + Threshold: + 阈值设置: + + + + Apply + 应用 + + + + Reset + 重置 + + + + (Note: select this option to use 3D graphics acceleration and xmanager.) + (注意:使用3D图形加速,且用Xmanager连接图形时选择本项) + + + + DisplaySet + + display + 显示器 + + + + Display + 显示器 + + + + DisplayWindow + + + monitor + 显示器 + + + + set as home screen + 设为主屏 + + + close monitor + 关闭显示器 + + + + unify output + 统一输出 + + + + open monitor + 打开显示器 + + + + Form + + + + + Display + 显示器 + + + + Advanced + 高级显示 + + + + screen brightness adjustment + 调整屏幕亮度 + + + + dark + + + + + bright + + + + + follow the sunrise and sunset(17:55-05:04) + 跟随日落日出(17:55-05:04) + + + + custom time + 自定义时间 + + + + opening time + 开启时间 + + + + closing time + 关闭时间 + + + + color temperature + 色温 + + + + warm + + + + + cold + + + + + apply + 应用 + + + + EditGroupDialog + + + Dialog + 编辑用户组 + + + + Cancel + 取消 + + + + Certain + 确定 + + + + Edit User Group + 编辑用户组 + + + + Name + 组名 + + + + Id + 组ID + + + + Members + 组成员 + + + + Tips + 提示 + + + + Invalid Id! + 无效组ID! + + + + OK + 确定 + + + + Edit user group + 编辑用户组 + + + + EditPassDialog + + Edit Password + 修改密码 + + + Your account here + 请输入用户名 + + + Your password here + 输入密码 + + + Your new password here + 新密码 + + + Your code here + 输入验证码 + + + Your code + 请输入验证码 + + + Get phone code + 获取绑定手机验证码 + + + Cancel + 取消 + + + Confirm + 确定 + + + Confirm your new password + 确认新密码 + + + At least 6 bit, include letters and digt + 至少六位,包含大小写字母、数字 + + + Your password is valid! + 您的密码是有效的! + + + Please check your password! + 两次密码设置不一致! + + + Resend( + 重新发送( + + + ) + ) + + + Send + 发送验证码 + + + Success! + 成功! + + + Reback sign in + 重新登录 + + + Error code: + 错误代码: + + + ! + + + + Internal error occurring! + 服务器错误! + + + Failed to sign up! + 注册失败! + + + Failed attempt to return value! + 尝试获取返回值失败! + + + Check your connection! + 登录失败或网络异常! + + + Failed to get by phone! + 手机获取验证码失败! + + + Failed to get by user! + 用户名获取验证码失败! + + + Failed to reset password! + 重置密码失败! + + + Please check your information! + 缺少必要信息! + + + Please check your account! + 账户或密码错误! + + + Failed due to server error! + 服务器错误! + + + User existing! + 用户名已存在! + + + Phone number already in used! + 手机号码已被使用! + + + Please check your format! + 手机号码格式错误! + + + Your are reach the limit! + 该手机当日接收短信次数达到上限! + + + Please check your phone number! + 手机号码其他错误! + + + Please check your code! + 手机验证码错误! + + + Account doesn't exist! + 用户名不存在! + + + Sending code error occurring! + 发送验证码异常! + + + + EditPushButton + + Reset + 重置密码 + + + + ExperiencePlan + + + User Experience + 用户体验 + + + + Join in user Experience plan + 加入用户体验计划 + + + + User experience plan terms, see + 用户体验计划条款,参见 + + + + 《User Experience plan》 + 《用户体验计划》 + + + experienceplan + 体验计划 + + + + Experienceplan + 体验计划 + + + + Fonts + + + + Fonts + 字体 + + + + + Fonts select + 字体选择 + /fonts/Fonts select + + + + + + Font size + 字体大小 + /fonts/Font size + + + + Mono font + 等宽字体 + + + + Reset to default + 恢复默认设置 + + + + Gtk default font + 通用字体 + + + + Document font + 文档字体 + + + + Monospace font + 等宽字体 + + + + Advanced settings + 高级设置 + + + Peony font + 桌面字体 + + + + titlebar font + 标题字体 + + + + Select text sample that looks clearest + 选择看起来清晰的字体效果 + + + fonts + 字体 + + + + 11 + 11 + + + + 12 + 12 + + + + 13 + 13 + + + + 14 + 14 + + + + 15 + + + + + 16 + 16 + + + + Thanks For Using The ukcc + 欢迎使用设置 + + + + FrameItem + + Sync failed, please login out to retry! + 同步失败,请检查网络或退出云账户重试! + + + Change configuration file failed, please login out to retry! + 配置文件更改失败,请检查网络或退出云账户重试! + + + Configuration file not exist, please login out to retry! + 配置文件不存在,请检查网络或退出云账户重试! + + + Cloud verifyed file download failed, please login out to retry! + 云校验失败,请检查网络或退出云账户重试! + + + OSS access failed, please login out to retry! + 文件存储访问失败,请检查网络或退出云账户重试! + + + Sync failed, please retry or login out to get a better experience! + 同步失败,建议重试或者重新登录来获取最佳体验! + + + Change configuration file failed, please retry or login out to get a better experience! + 配置文件设置失败,建议重试或者重新登录来获取最佳体验! + + + Configuration file not exist, please retry or login out to get a better experience! + 配置文件不存在,建议重试或者重新登录来获取最佳体验! + + + Cloud verifyed file download failed, please retry or login out to get a better experience! + 云端校验失败,建议重试或者重新登录来获取最佳体验! + + + OSS access failed, please retry or login out to get a better experience! + 文件存储访问失败,建议重试或者重新登录来获取最佳体验! + + + + + Sync failed,please relogin! + 同步失败,请重新登录! + + + + Change configuration file failed,please relogin! + 修改配置文件失败,请重新登录! + + + + Configuration file not exist,please relogin! + 配置文件不存在,请重试! + + + + Cloud verifyed file download failed,please relogin! + 云文件验证失败,请重试! + + + + OSS access failed,please relogin! + 连接失败,请重试或重新登录! + + + + HistoryUpdateListWig + + + Success + 更新成功 + + + + Failed + 更新失败 + + + + ItemList + + Walpaper + 桌面壁纸 + + + + ScreenSaver + 屏保 + + + + Menu + 开始菜单 + + + + Quick Start + 快速启动项 + + + + Avatar + 头像 + + + + Tab + 任务栏 + + + + Font + 字体 + + + + Wallpaper + 桌面壁纸 + + + + Themes + 主题 + + + + Area + 区域语言 + + + + Date/Time + 时间日期 + + + + Default Open + 默认打开方式 + + + + Notice + 侧边栏 + + + + Option + 登录选项 + + + + Peony + 文件管理器 + + + + Weather + 麒麟天气 + + + + Media + 麒麟影音 + + + + Boot + 开机启动项 + + + + Power + 电源 + + + + Editor + 文本编辑器 + + + + Terminal + 终端 + + + + Mouse + 鼠标 + + + + TouchPad + 触摸板 + + + + KeyBoard + 键盘 + + + + ShortCut + 快捷键 + + + + KbPreviewFrame + + Keyboard Preview + 布局预览 + + + + No preview found + 无预览 + + + + Unable to open Preview ! + 无法打开预览! + + + + KbdLayoutManager + + + C + 按国家 + + + + L + 按语言 + + + + Variant + 变体 + + + + Add + 添加 + + + + Add Layout + 添加布局 + + + + Del + 删除 + + + + Keyboard Preview + 布局预览 + + + + KeyValueConverter + + system + 系统 + + + devices + 设备 + + + personalized + 个性化 + + + network + 网络 account 账户 - datetime - 时间和日期 + datetime + 时间日期 + + + update + 更新和备份 + + + messages + 通知关于 + + + + System + 系统 + + + + Devices + 设备 + + + + Personalized + 个性化 + + + + Network + 网络 + + + + Account + 账户 + + + + Datetime + 时间语言 + + + + Update + 安全更新 + + + + Messages + 通知关于 + + + + KeyboardControl + + + Keys Settings + 通用设置 + + + + + Enable repeat key + 启用按键重复设置 + /keyboard/Enable repeat key + + + + + Delay + 延迟 + /keyboard/Delay + + + + Short + + + + + Long + + + + + + Speed + 速度 + /keyboard/Speed + + + + Slow + + + + + Fast + + + + + Input characters to test the repetition effect: + 输入字符测试重复效果: + + + + Input Settings + 输入法设置 + + + + Input Set + 输入法设置 + + + Input settings + 输入法设置 + + + + Input characters to test the repetition effect: + 输入字符测试重复效果: + /keyboard/Input characters to test the repetition effect: + + + + + Tip of keyboard + 启用按键提示 + /keyboard/Tip of keyboard + + + reset default layout + 恢复默认布局 + /keyboard/reset default layout + + + Reset layout + 重置布局 + + + Message of capslock + 大写锁定提示 + + + + Enable numlock + 小键盘开启提示 + + + Keyboard Layout + 键盘布局 + + + + + Keyboard layout + 键盘布局 + /keyboard/Keyboard layout + + + Install layouts + 安装其他布局 + + + keyboard + 键盘 + + + + Keyboard + 键盘 + + + + KeyboardPainter + + + Close + 关闭 + + + + + Keyboard layout levels + 键盘布局等级 + + + + + Level %1, %2 + 等级 %1 %2 + + + Keyboard Preview + 布局预览 + + + + LayoutManager + + + Dialog + 更改时间 + + + + Manager Keyboard Layout + 管理键盘布局 + + + + Language + 语言 + + + + Country + 国家 + + + + Variant + 变体 + + + + Layout installed + 安装布局 + + + + Preview + 预览 + + + + Cancel + 取消 + + + + Install + 安装 + + + + LoginDialog + + + Forget + 忘记密码 + + + + Send + 发送验证码 + + + + User Sign in + 帐号密码登录 + + + + Quick Sign in + 短信快捷登录 + + + + Your account/phone here + 请输入用户名/手机号码 + + + Your account here + 请输入用户名 + + + + Your phone number here + 手机号码 + + + + Your account/phone/email here + 请输入用户名/手机号码/邮箱 + + + + Your password here + 输入密码 + + + + + Your code here + 输入验证码 + + + + MCodeWidget + + + SongTi + 宋体 + + + + MainDialog + + + + + + + + + Sign in + 登录 + + + + Sign up + 注册云账户 + + + + Login in progress + 登录中 + + + + Error code: + 错误代码: + + + + ! + + + + Internal error occurring! + 服务器错误! + + + + Internal error occurred! + 服务器错误! + + + + Failed to sign up! + 注册失败! + + + + Failed attempt to return value! + 返回值失败! + + + + Check your connection! + 登录失败或网络异常! + + + + Failed to get by phone! + 手机获取验证码失败! + + + + Failed to get by user! + 用户名获取验证码失败! + + + + Failed to reset password! + 重置密码失败! + + + + Timeout! + 登录超时,请重新输入验证码登录! + + + + Phone binding falied! + 手机绑定失败! + + + + + Please check your information! + 缺少必要信息! + + + + Please check your account! + 账户或密码错误! + + + + Failed due to server error! + 服务器错误! + + + + User and passsword can't be empty! + 用户以及密码不能为空! + + + + User existing! + 用户名已存在! + + + + User doesn't exist! + 用户不存在! + + + + Network can not reach! + 网络不可达! + + + + Phone can't be empty! + 手机号不能为空! + + + + Account or password error! + 账户或密码错误! + + + + Phone number already in used! + 手机号码已被使用! + + + + Please check your format! + 手机号码格式错误! + + + + Your are reach the limit! + 该手机当日接收短信次数达到上限! + + + + Please check your phone number! + 手机号码其他错误! + + + + Please check your code! + 手机验证码错误! + + + + Account doesn't exist! + 用户名不存在! + + + + User has bound the phone! + 用户已经绑定手机号! + + + + Sending code error occurred! + 发送验证码异常! + + + + Phone code is expired! + 验证码过期! + + + + Phone code error! + 验证码错误! + + + + Code can not be empty! + 图片验证码不能为空! + + + + MCode can not be empty! + 手机验证码不能为空! + + + Sending code error occurring! + 发送验证码异常! + + + + Your code is wrong! + 验证码错误! + + + + + Please check your phone! + 请检查您的手机号码格式! + + + Please check your password! + 两次密码设置不一致! + + + At least 6 bit, include letters and digt + 至少六位,包含大小写字母、数字 + + + + + Sign in Cloud + 登录云账户 + + + Forget + 忘记密码 + + + Set + 设置 + + + Back + 返回登录 + + + Create Account + 注册云账户 + + + Sign up now + 立即注册 + + + Please confirm your password! + 两次密码输入不一致! + + + + Resend ( %1 ) + 重新发送(%1) + + + + Get + 获取验证码 + + + Get phone code + 获取绑定手机验证码 + + + Send + 发送验证码 + + + Binding Phone + 绑定手机 + + + Please make sure your password is safety! + 请确保您的密码符合要求! + + + Bind now + 绑定 + + + + MainWidget + + + + Disconnected + 未连接 + + + + Your account:%1 + 您的云账户:%1 + + + Unauthorized device or OSS falied. +Please retry for login! + OSS访问失败,请检查您的网络后再登录! + + + + + + Exit + 退出登录 + + + + Sync + 同步中 + + + + Sign in + 登录 + + + Enable item sync + 开启单项同步 + + + + Logout failed,please check your connection + 登录失败,请检查你的网络连接 + + + + + Stop sync + 结束同步 + + + + Sync your settings + 同步您的设置 + + + + Your account:%1 + 您的云账户:%1 + + + + Auto sync + 自动同步 + + + + Waitting for sync! + 等待同步! + + + + Synchronize your personalized settings and data + 同步您账户的数据以及个性化设置 + + + + This operation may cover your settings! + 该操作可能覆盖您现有的设置! + + + + + + + + + The latest time sync is: + 上次同步时间为: + + + + + Waiting for initialization... + 等待云账户初始化... + + + + + + + + + + + + + + + + Network can not reach! + 网络不可达! + + + + The Cloud Account Service version is out of date! + 云账户服务版本已经过期,请升级! + + + + KylinID open error! + 麒麟ID客户端打开失败! + + + + Unauthorized device or OSS falied. +Please retry or relogin! + 设备凭证已过期,请重新登录! + + + + Authorization failed! + 认证失败,请重新登录! + + + + Kylin Cloud Account + 云账户 + + + + + 该操作可能覆盖您目前的快捷键! + + + + Cloud ID desktop message + 云账户消息 + + + Synchronize your computer's settings into your cloud account here. + 将本机的设置同步至云账户,通过云账户随时随地开启个性设置! + + + Media + 麒麟影音 + + + Weather + 麒麟天气 + + + Sync downloading,please wait! + 同步下载中,请稍后......! + + + Sync uploading,please wait! + 同步上传中,请稍后......! + + + Sync failed, please check your internet connection or login out to retry! + 同步失败,请检查您的网络连接或者登出再重试一次! + + + + %1, + %1, + + + Synchronized failed: %1 please retry or login out to get a better experience. + 同步失败:%1 请重试或者重新登录来获取最佳体验! + + + %1 + %1 + + + Synchronized failed: %1, please retry or login out to get a better experience. + 同步失败:%1,请重试或者重新登录来获取最佳体验! + + + + MainWindow + + + Search + 搜索 + + + UKCC + 设置 + + + + + + Settings + 设置 + + + + Main menu + 主菜单 + + + + Minimize + 最小化 + + + + Maximize/Normal + 最大化/正常 + + + + Close + 关闭 + + + + Help + 帮助 + + + + About + 关于 + + + + Exit + 退出 + + + ukcc + 控制面板 + + + + Warnning + 警告 + + + + This function has been controlled + 该功能已被管控 + + + + Home + 首页 + + + + MouseControl + + + Mouse Key Settings + 鼠标键设置 + + + + + Hand habit + 惯用手 + /mouse/Hand habit + + + + Pointer Settings + 指针设置 + + + + + Speed + 速度 + /mouse/Speed + + + + + + Slow + + + + + mouse wheel speed + 鼠标滚轮速度 + + + + + + Fast + + + + + + Doubleclick delay + 鼠标双击间隔时长 + /mouse/Doubleclick delay + + + + Short + + + + + Long + + + + + + Acceleration + 鼠标加速 + /mouse/Acceleration + + + + Cursor weight + 光标粗细 + + + Sensitivity + 敏感度 + /mouse/Sensitivity + + + Low + + + + High + + + + + + Visibility + 按Ctrl键显示指针位置 + /mouse/Visibility + + + + + Pointer size + 指针大小 + /mouse/Pointer size + + + + Cursor Settings + 光标设置 + + + Cursor weight + 光标粗细 + + + + Thin + + + + + Coarse + + + + + + Cursor speed + 光标速度 + /mouse/Cursor speed + + + + + Enable flashing on text area + 启用文本区域的光标闪烁 + /mouse/Enable flashing on text area + + + mouse + 鼠标 + + + + Mouse + 鼠标 + + + + Lefthand + 左手 + + + + Righthand + 右手 + + + + Default(Recommended) + 默认(推荐) + + + + Medium + 中等 + + + + Large + 较大 + + + + MyLabel + + + double-click to test + 双击测试 + + + + NetConnect + + + + Netconnect Status + 网络状态 + /netconnect/Netconnect Status + + + Waitting... + 加载中... + + + + Available Network + 可用网络 + + + + + + Refresh + 刷新 + + + + + open wifi + 打开wifi + /netconnect/open wifi + + + + + Network settings + 网络设置 + + + Change net settings + 更改网络设置 + + + netconnect + 网络连接 + + + Netconnect + 网络连接 + + + Link + 连接 + + + + Connected + 已连接 + + + + + No net + 无连接 + + + + Detail + 网络详情 + + + + None + + + + + Refreshing... + 刷新中... + + + connected + 已连接 + + + No network + 无网络连接 + + + + + Connect + 网络连接 + + + Disconnect + 未连接 + + + + NetDetail + + + SSID: + SSID: + + + + Protocol + 协议: + + + + Security Type: + 安全类型: + + + + Hz: + 网络频带: + + + + Chan: + 网络通道: + + + + Link Speed(rx/tx) + 链接速度(接收/传输): + + + + BandWidth: + 带宽: + + + + IPV4: + IPV4: + + + + IPV4 Dns: + IPV4 Dns: + + + + IPV4 GateWay: + 网关: + + + + IPV4 Prefix: + 前缀: + + + + IPV6: + IPV6: + + + + IPV6 Prefix: + 前缀: + + + + IPV6 GateWay: + 网关: + + + + Mac: + 物理地址: + + + + Notice + + + Notice Settings + 通知 + + + Set the type of notice in the operation center + 设置在通知中心显示的通知信息 + /notice/Set the type of notice in the operation center + + + + + Set notice type of operation center + 设置在通知中心显示的通知信息 + /notice/Set notice type of operation center + + + + Show new feature ater system upgrade + 系统版本更新后显示新增内容 + + + + Get notifications from the app + 获取来自应用和其他发送者的通知 + + + + Show notifications on the lock screen + 在锁屏界面上显示通知 + + + + + Notice Origin + 设置通知来源 + /notice/Notice Origin + + + notice + 通知 + + + + Notice + 通知 + + + + OutputConfig + + + resolution + 分辨率 + /display/resolution + + + + orientation + 方向 + + + + arrow-up + 不旋转 + + + + 90° arrow-right + 90° 顺时针 + + + + arrow-down + 上下颠倒 + + + + 90° arrow-left + 90° 逆时针 + + + + frequency + 刷新率 + + + refresh rate + 刷新率 + + + + auto + 自动 + + + + screen zoom + 缩放屏幕 + /display/screen zoom + + + + + %1 Hz + + + + + PassDialog + + Get the phone binding code + 获取绑定手机验证码 + + + Your account here + 请输入用户名 + + + Your new password here + 新密码 + + + Confirm your new password + 确认新密码 + + + Your code here + 输入验证码 + + + At least 6 bit, include letters and digt + 至少六位,包含大小写字母、数字 + + + Your password is valid! + 您的密码是有效的! + + + + Power + + + select power plan + 电源计划 + + + + + Balance (suggest) + 平衡(推荐) + /power/Balance (suggest) + + + + + Saving + 节能 + /power/Saving + + + + Minimize performance + 尽可能降低计算机性能 + + + Bala&nce (suggest) + + + + + + Autobalance energy and performance with available hardware + 利用可用的硬件自动平衡消耗与性能 + + + + + Custom + 自定义 + /power/Custom + + + + Users develop personalized power plans + 用户制定个性化电源计划 + + + + Power supply + 电源供给 + + + + Battery powered + 电池供给 + + + + + + Change PC sleep time: + 系统进入空闲状态并于此时间后睡眠: - update - 更新和备份 + + + + Change DP close time: + 系统进入空闲状态并于此时间后关闭显示器: - messages - 通知和操作 + Change pc sleep time: + 系统进入空闲状态并于此时间后挂起: - - System - 系统 + Change dp close time: + 系统进入空闲状态并于此时间后关闭显示器: - - Devices - 设备 + + When close lid: + 关闭笔记本电脑上盖时: - - Personalized - 个性化 + + Screen darkens use battery: + 无操作状态下于此时间后减小屏幕亮度: - - Network - 网络 + Power Other Settings + 电源图标设置 - - Account - 账户 + S3 to S4 when: + 挂起此时间后转为睡眠: - - Datetime - 时间和日期 + Power Icon Settings + 电源图标设置 - - Update - 更新 + + Power icon: + 电源图标: - - Messages - 通知和操作 + power + 电源 + + + + Power + 电源 + + + Change PC sleep time after %1 min: + 系统%1分钟后进入空闲状态并于此时间后挂起: + + + Change DP close time after %1 min: + 系统%1分钟后进入空闲状态并于此时间后关闭显示器: + + + + Enter idle state %1 min and sleep after %2 min : + 系统%1分钟后进入空闲状态并于%2分钟后挂起: + + + + Enter idle state %1 min and close after %2 min : + 系统%1分钟后进入空闲状态并于%2分钟后关闭显示器: + + + + + + never + 从不 + + + + + + 10 min + 10分钟 + + + + + 30 min + 30分钟 + + + + + 60 min + 60分钟 + + + + + 120 min + 120分钟 + + + + 300 min + 300分钟 + + + + + + 20 min + 20分钟 + + + + + 1 min + 1分钟 + + + + + 5 min + 5分钟 + + + + nothing + 无操作 + + + + blank + 关闭显示器 + + + + suspend + 睡眠 + + + + hibernate + 休眠 + + + + shutdown + 关机 + + + + always + 显示电源图标在托盘栏 + + + + present + 仅当存在电池时显示 + + + + charge + 仅当使用电池时显示 + + + + Perform operations when battery is low: + 低电量执行操作: + + + + General Settings + 通用设置 + + + + When the power button is pressed: + 按电源键时执行: - KeyboardControl + Printer - - Keys Settings - 通用设置 + + + Add Printers And Scanners + 添加打印机和扫描仪 + /printer/Add Printers And Scanners - - Enable repeat key - 启用按键重复设置 + + Add printers and scanners + 添加打印机和扫描仪 - - Delay - 延迟 + + Attrs + 属性 - - Short - + Attributes + 属性 - - Long - + + List Of Existing Printers + 可用打印机列表 - - Speed - 速度 + printer + 打印机 - - Slow - + + Printer + 打印机 + /printer/Printer + + + Proxy - - Fast - + + Auto Proxy + 自动设置代理 - - Test repetition rate of the input character: - 输入字符测试重复效果: + + + Auto proxy + 开启自动代理 + /proxy/Auto proxy - - Tip of keyboard - 大写锁定提示 + + Auto url + 自动配置URL - - reset default layout - 恢复默认布局 + + Manual Proxy + 手动设置代理 - - Reset layout - 重置布局 + + + Manual proxy + 开启手动代理 + /proxy/Manual proxy - Message of capslock - 大写锁定提示 + + Http Proxy + HTTP代理 - - Enable numlock - 小键盘开启提示 + + + + + Port + 端口 - - Keyboard Layout - 键盘布局 + + Cetification + 认证 - - Keyboard layout - 键盘布局 + + Https Proxy + HTTPS代理 + + + + Ftp Proxy + FTP代理 + + + + Socks Proxy + SOCKS代理 + + + + List of ignored hosts. more than one entry, please separate with english semicolon(;) + 忽略的主机列表,请使用英文分号(;) + + + proxy + 代理 + + + + Proxy + 代理 + + + + QObject + + display + 显示器 + + + defaultapp + 默认应用 + + + power + 电源 + + + autoboot + 开机启动 + + + printer + 打印机 + + + mousecontrol + 鼠标 + + + mouse + 鼠标 - - Install layouts - 安装其他布局 + touchpad + 触摸板 keyboard 键盘 - - Keyboard - 键盘 + shortcut + 快捷键 - - - LayoutManager - - Dialog - + audio + 声音 - - Manager Keyboard Layout - 管理键盘布局 + background + 背景 - - Language - 语言 + screenlock + 锁屏 - - Country - 国家 + fonts + 字体 - - Variant - 变体 + + Screensaver + 屏保 - - Layout installed - 安装布局 + desktop + 桌面 - - Preview - 预览 + netconnect + 网络连接 - - Cancel - 取消 + vpn + VPN - - Install - 安装 + proxy + 代理 - - - LoginDialog - - Forget - 忘记密码 + userinfo + 账户信息 - - Send - 发送验证码 + datetime + 时间日期 - - User Sign in - 帐号密码登录 + area + 区域语言 - - Quick Sign in - 短信快捷登录 + update + 更新和备份 - - - Your account here - 请输入用户名 + backup + 备份 - - Your phone number here - 手机号码 + notice + 通知 - - Your password here - 输入密码 + about + 关于 - - - Your code here - 输入验证码 + experienceplan + 体验计划 - - - MCodeWidget - - SongTi - 宋体 + theme + 主题 - - - MainDialog - - - - - - - - - - Sign in - 登录 + ukui-control-center had already running! + 控制面板已经在运行! - - - - - - Sign up - 注册云账户 + basicIcon + 基础 - - Login in progress - 登录中 + classicalIcon + 经典 - - Error code: - 错误代码: + defaultIcon + 默认 - - ! - + + blue-crystal + 蓝水晶 - Internal error occurring! - 服务器错误! + + dark-sense + 深色质感 - - Internal error occurred! - 服务器错误! + + DMZ-Black + - - Failed to sign up! - 注册失败! + + DMZ-White + - - Failed attempt to return value! - + + basic + 基础 - - Check your connection! - 登录失败或网络异常! + + classical + 经典 - - Failed to get by phone! - 手机获取验证码失败! + + + default + 默认 - - Failed to get by user! - 用户名获取验证码失败! + + fashion + 时尚 - - Failed to reset password! - 重置密码失败! + + Unknown + 未知 - - Timeout! - 登录超时! + Custom Shortcut + 自定义快捷键 - - Phone binding falied! - 手机绑定失败! + + Customize Shortcut + 自定义快捷键 - - - - Please check your information! - 缺少必要信息! + Update Shortcut + 更新快捷键 - - Please check your account! - 账户或密码错误! + Add Shortcut + 添加快捷键 - - Failed due to server error! - 服务器错误! + + Display + 显示器 - - User existing! - 用户名已存在! + Defaultapp + 默认应用 - - Phone number already in used! - 手机号码已被使用! + + Power + 电源 - - Please check your format! - 手机号码格式错误! + Autoboot + 开机启动 - - Your are reach the limit! - 该手机当日接收短信次数达到上限! + + TouchScreen + 触摸屏 - - Please check your phone number! - 手机号码其他错误! + + Default App + 默认应用 - - Please check your code! - 手机验证码错误! + + Auto Boot + 开机启动 - - Account doesn't exist! - 用户名不存在! + + Printer + 打印机 - - User has bound the phone! - 用户已经绑定手机号! + + Mouse + 鼠标 - - Sending code error occurred! - 发送验证码异常! + + Touchpad + 触摸板 - Sending code error occurring! - 发送验证码异常! + + Keyboard + 键盘 - - Your code is wrong! - 验证码错误! + + Shortcut + 快捷键 - - - - Please check your password! - 两次密码设置不一致! + + Audio + 声音 - - - - At least 6 bit, include letters and digt - 至少六位,包含大小写字母、数字 + + Bluetooth + 蓝牙 - - - - - - Sign in Cloud - 登录云账户 + + Background + 背景 - - Forget - 忘记密码 + + Theme + 主题 - - Set - 设置 + + Screenlock + 锁屏 - - - - Back - 返回登录 + + Fonts + 字体 - - Create Account - 注册云账户 + + Desktop + 桌面 - - Sign up now - 立即注册 + + Connect + 网络连接 - - - Please confirm your password! - 请核对您的密码! + + Vino + 桌面共享 - - - - - Resend ( %1 ) - 重新发送(%1) + + User Info + 账户信息 - - - Get phone code - 获取绑定手机验证码 + + Date + 时间日期 - - - - - - - - Send - 发送验证码 + Dat + 时间日期 - - Binding Phone - 绑定手机 + + Security Center + 安全中心 - - Bind now - 绑定 + Netconnect + 网络连接 - - - MainWidget - - Disconnected - 未连接 + + Vpn + VPN + + + + Proxy + 代理 + + + Userinfo + 账户信息 - - - - Your account:%1 - 您的云账户:%1 + + Cloud Account + 云账户 - - - - Exit - 退出登录 + Datetime + 时间日期 - - Sync - 同步中 + + Area + 区域语言 - - Sign in - 登录 + SecurityCenter + 安全中心 - - Stop sync - 结束同步 + + Update + 安全更新 - - Sync your settings - 同步您的设置 + + Backup + 备份 - - Your account:%1 - 您的云账户:%1 + + Upgrade + 更新 - - Auto sync - 自动同步 + + Notice + 通知 - - Synchronize your personalized settings and data - 同步您账户的数据以及个性化设置 + + Search + 搜索 - - - - - - Synchronize your computer's settings into your cloud account here. - 将本机的设置同步至云账户,通过云账户随时随地开启个性设置! + + About + 关于 - Media - 麒麟影音 + + Experienceplan + 体验计划 - Weather - 麒麟天气 + + + + Never + 从不 - - Sync downloading,please wait! - 同步下载中,请稍后......! + + 10min + 10min - - Sync uploading,please wait! - 同步上传中,请稍后......! + + 20min + 20min - - - Sync failed, please check your internet connection or login out to retry! - 同步失败,请检查您的网络连接或者登出再重试一次! + + 40min + 40min - - %1, - %1, + + 80min + 80min - - Synchronized failed: %1 please retry or login out to get a better experience. - 同步失败:%1 请重试或者重新登录来获取最佳体验! + + interactive + 询问 - %1 - %1 + + + suspend + 睡眠 - Synchronized failed: %1, please retry or login out to get a better experience. - 同步失败:%1,请重试或者重新登录来获取最佳体验! + + + hibernate + 休眠 - - - MainWindow - - UKCC - 设置 + + + shutdown + 关机 - - ukcc - 控制面板 + + nothing + 无操作 - - HOME - 首页 + + blank + 关闭显示器 - - - ModulePageWidget - - QLabel{font-size: 18px; color: palette(Shadow);} - + Year + - - - MouseControl - - Mouse Key Settings - 鼠标键设置 + Jan + 一月 - - Hand habit - 惯用手 + Feb + 二月 - - Pointer Settings - 指针设置 + Mar + 三月 - - Speed - 速度 + Apr + 四月 - - - - Slow - + + May + 五月 - - mouse wheel speed - 鼠标滚轮速度 + + January + 一月 - - - - Fast - + + February + 二月 - - Doubleclick delay - 鼠标双击间隔时长 + + March + 三月 - - Short - + + April + 四月 - - Long - + + June + 六月 - - Sensitivity - 敏感度 + + July + 七月 - - Low - + + August + 八月 - - High - + + September + 九月 - - Visibility - 可见性 + + October + 十月 - - Pointer size - 指针大小 + + Novermber + 十一月 - - Cursor Settings - 光标设置 + + December + 十二月 - - Cursor weight - + Jun + 六月 - Cursor weight - 光标粗细 + Jul + 七月 - - Thin - + Aug + 八月 - - Coarse - + Sep + 九月 - - Cursor speed - 光标速度 + Oct + 十月 - - Enable flashing on text area - 启用文本区域的光标闪烁 + Nov + 十一月 - mouse - 鼠标 + Dec + 十二月 - - Mouse - 鼠标 + Day + - - Lefthand - 左手 + + ukui-control-center + 设置 - - Righthand - 右手 + + ukui-control-center is already running! + 控制面板已运行! - - Default(Recommended) - 默认(推荐) + Pwd input error, re-enter! + 密码输入错误,重新输入! - - Medium - 中等 + + Go to monitor settings page + 管理和配置显示和监视器 - - Large - 较大 + + Go to defaultapp settings page + 选择默认应用 - - - NetConnect - - Netconnect Status - 网络状态 + + Go to printer settings page + 打印机管理 - - - Waitting... - 加载中... + + Go to mouse settings page + 配置鼠标选项 - - Available Network - 可用网络 + + Go to touchpad settings page + 触摸板管理 - - Refresh - 刷新 + + Go to keyboard settings page + 键盘设置 - - open wifi - 打开wifi + + Go to shortcut settings page + 配置快捷键 - - - Network settings - 网络设置 + + Go to bluetooth settings page + 蓝牙设置 - Change net settings - 更改网络设置 + + Go to background settings page + 配置桌面壁纸 - netconnect - 网络连接 + + Go to theme settings page + 配置主题 - - Netconnect - 网络连接 + + Go to screenlock settings page + 锁屏设置 - - connected - 已连接 + + Go to screensaver settings page + 屏保设置 - - No network - 无网络链接 + + Go to fonts settings page + 配置用户字体 - Connect - 已连接 + + Go to netconnect settings page + 网络连接 - Disconnect - 未连接 + + Go to proxy settings page + 代理设置 - - - Notice - - Notice Settings - 通知 + + Go to userinfo settings page + 管理用户信息 - - Set the type of notice in the operation center - 设置在通知中心显示的通知信息 + + Go to cloudaccount settings page + 配置您的网络账户 - - Show new feature ater system upgrade - 系统版本更新后显示新增内容 + + Go to area settings page + 区域语言 - - Get notifications from the app - 获取来自应用和其他发送者的通知 + + Go to update settings page + 更新管理 - - Show notifications on the lock screen - 在锁屏界面上显示通知 + + Go to backup settings page + 备份管理 - - Notice Origin - 设置通知来源 + + Go to upgrade settings page + 更新设置 - notice - 通知 + + Go to about settings page + 此系统的信息 - - Notice - 通知 + + Go to search settings page + 搜索 - - - OutputConfig - - resolution - 分辨率 + + Go to power settings page + 配置电源管理 - - orientation - 方向 + + Go to datetime settings page + 管理日期和时间 - - arrow-up - 不旋转 + + Go to desktop settings page + 配置托盘,开始菜单图标 - - 90° arrow-right - 90° 顺时针 + + Go to audio settings page + 音量设置 - - arrow-down - 上下颠倒 + + Go to notice settings page + 通知管理模块 - - 90° arrow-left - 90° 逆时针 + + Go to vpn settings page + VPN模块 - - refresh rate - 刷新率 + + Go to autoboot settings page + 自动启动的应用程序 - - auto - 自动 + + PulseAudio Volume Control + - - - 100% + + Connection to PulseAudio failed. Automatic retry in 5s + +In this case this is likely because PULSE_SERVER in the Environment/X11 Root Window Properties +or default-server in client.conf is misconfigured. +This situation can also arrise when PulseAudio crashed and left stale details in the X11 Root Window. +If this is the case, then PulseAudio should autospawn again, or if this is not configured you should +run start-pulseaudio-x11 manually. - - - - 200% + + pa_context_subscribe() failed - - 300% + + pa_context_get_card_info_list() failed - - screen zoom - 缩放屏幕 + + Failed to initialize stream_restore extension: %s + - - %1 Hz - + + Connection failed, attempting reconnect + - - - PassDialog - - Get the phone binding code - 获取绑定手机验证码 + + pa_ext_stream_restore_read() failed + - - Your account here - 请输入用户名 + + pa_context_get_card_info_by_index() failed + - - Your new password here - 新密码 + + Card callback failure + - - Confirm your new password - 确认新密码 + + min length %1 + + - - Your code here - 输入验证码 + + min digit num %1 + + - - - At least 6 bit, include letters and digt - 至少六位,包含大小写字母、数字 + + min upper num %1 + + - - Your password is valid! - 您的密码是有效的! + + min lower num %1 + + - - - Power - - - select power plan - 电源计划 + + + min other num %1 + + - - Balance (suggest) - 平衡(推荐) + + min char class %1 + + - - Saving - 节能 + + max repeat %1 + + - - Minimize performance - 尽可能降低计算机性能 + + max class repeat %1 + + - Bala&nce (suggest) - - + + max sequence %1 + + - - Autobalance energy and performance with available hardware - 利用可用的硬件自动平衡消耗与性能 + + system upgrade new backup + 系统升级新建备份 - - Custom - 自定义 + + system upgrade increment backup + 系统升级增量备份 + + + RegDialog - - Users develop personalized power plans - 用户制定个性化电源计划 + Get + 获取验证码 - - Power supply - 电源供给 + Your password here + 输入密码 - - Battery powered - 电池供给 + Your account here + 请输入用户名 - - Change pc sleep time: - 系统进入空闲状态并于此时间后挂起: + Confirm your password + 确认密码 - - Change dp close time: - 系统进入空闲状态并于此时间后关闭显示器: + Your code here + 输入验证码 - - When close lid: - 关闭笔记本电脑上盖时: + This operation is permanent + 设置后不可更改,最高30位 - - Screen darkens use battery: - 无操作状态下与此时间后减小屏幕亮度: + At least 6 bit, include letters and digt + 至少六位,包含大小写字母、数字 - - Power Other Settings - 电源图标设置 + Your password is valid! + 您的密码是有效的! + + + ResolutionSlider - - S3 to S4 when: - 挂起此时间后转为睡眠: + (recommend) + (推荐) - Power Icon Settings - 电源图标设置 + + No available resolutions + 没有合适的分辨率 + + + Screenlock - - Power icon: - 电源图标: + + + Screenlock + 锁屏 - power - 电源 + + Screenlock Interface + 锁屏界面 - - Power - 电源 + + Screenlock Set + 锁屏设置 - - - - never - 从不 + + + Lock screen when screensaver boot + 激活屏保时锁定屏幕 + /screenlock/Lock screen when screensaver boot - - - - 10 min - 10分钟 + + Lock screen delay + 锁屏延时 - - - 30 min - 30分钟 + Min + 分钟 - - - 60 min - 60分钟 + + Select screenlock background + 选择锁屏背景 - - - 120 min - 120分钟 + + Browser online wp + 浏览线上壁纸 - - 300 min - 300分钟 + + Browser local wp + 浏览本地壁纸 - - - - 20 min - 20分钟 + + + Show picture of screenlock on screenlogin + 显示锁屏壁纸在登录页面 + /screenlock/Show picture of screenlock on screenlogin - - - 1 min - 1分钟 + Enabel screenlock + 开启锁屏 - - - 5 min - 5分钟 + Open + 浏览 - - nothing - 无操作 + screenlock + 锁屏 - - blank - 黑屏 + picture + 图片 - - suspend - 挂起 + Never + 从不 - - hibernate - 休眠 + + 1m + 1m - - shutdown - 关机 + + 5m + 5m - - always - 总是显示 + + 10m + 10m - - present - 仅当存在电池时显示 + + 30m + 30m - - charge - 仅当使用电池时显示 + + 45m + 45m - - - Printer - - Add Printers And Scanners - 添加打印机和扫描仪 + + 1h + 1h - - Add printers and scanners - 添加打印机和扫描仪 + + 1.5h + 1.5h - - List Of Existing Printers - 可用打印机列表 + + 3h + 3h - printer - 打印机 + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + 图片文件(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) - - Printer - 打印机 + + allFiles(*.*) + 所有文件(*.*) - - - Proxy - - Auto Proxy - 自动设置代理 + + select custom wallpaper file + 选择自定义壁纸文件 - - Auto proxy - 开启自动代理 + + Select + 选择 - - Auto url - 自动配置URL + + Position: + 位置: - - Manual Proxy - 手动设置代理 + + FileName: + 文件名: - - Manual proxy - 开启手动代理 + + FileType: + 文件类型: - - Http Proxy - HTTP代理 + + Cancel + 取消 + + + Screensaver - - - - - Port - 端口 + + + Screensaver + 屏保 - - Cetification - 认证 + + + Enable screensaver + 开启屏保 + /screensaver/Enable screensaver - - Https Proxy - HTTPS代理 + + + Screensaver program + 屏幕保护程序 + /screensaver/Screensaver program - - Ftp Proxy - FTP代理 + + + idle time + 等待时间 + /screensaver/idle time - - Socks Proxy - SOCKS代理 + Min + 分钟 - - List of ignored hosts. more than one entry, please separate with english semicolon(;) - 忽略的主机列表,请使用英文分号(;) + + Lock screen when screensaver boot + 激活屏保时锁定屏幕 - proxy - 代理 + screensaver + 屏保 - - Proxy - 代理 + + Default_ukui + 默认屏保 - - - QObject - display - 显示器 + + Blank_Only + 黑屏 - defaultapp - 默认应用 + + 1m + 1m - power - 电源 + + 5m + 5m - autoboot - 开机启动 + + 10m + 10m - printer - 打印机 + + 30m + 30m - mousecontrol - 鼠标 + + 45m + 45m - mouse - 鼠标 + + 1h + 1h - touchpad - 触摸板 + + 1.5h + 1.5h - keyboard - 键盘 + + 3h + 3h - shortcut - 快捷键 + Random + 随机 - audio - 声音 + Never + 从不 + + + Search - background - 背景 + + Form + - screenlock - 锁屏 + + Search + 搜索 + /search/Search - fonts - 字体 + + + Create Index + 创建索引 - - Screensaver - 屏保 + + Creating index can help you getting results quickly. + 创建索引可以帮助您快速获取搜索结果 - desktop - 桌面 + + Web Engine + 搜索引擎 - netconnect - 网络连接 + + Default web searching engine + 默认互联网搜索引擎 - vpn - VPN + + baidu + 百度 - proxy - 代理 + + sougou + 搜狗 - userinfo - 账户信息 + + 360 + 360 - datetime - 时间和日期 + + Block Folders + 屏蔽文件夹 - area - 语言和地区 + + Following folders will not be searched. You can set it by adding and removing folders. + 搜索将不再查看以下文件夹,通过添加和删除可以设置文件索引位置。 - update - 更新和备份 + + Choose folder + 添加要屏蔽的文件夹 - backup - 备份 + + delete + 删除 - notice - 通知 + + Directories + 文件夹 - about - 关于 + + select blocked folder + 选择要屏蔽的文件夹 - experienceplan - 体验计划 + + Select + 选择 - theme - 主题 + + Position: + 位置: - ukui-control-center had already running! - 控制面板已经在运行! + + FileName: + 文件名: - basicIcon - 基础 + + FileType: + 文件类型: - classicalIcon - 经典 + + Cancel + 取消 - defaultIcon - 默认 + + + + + Warning + 警告 - - basic - 基础 + + Add blocked folder failed, choosen path is empty! + 添加文件夹失败,路径为空! - - classical - 经典 + + Add blocked folder failed, it is not in home path! + 添加文件夹失败,请选择用户目录下的文件夹! - - default - 默认 + + Add blocked folder failed, its parent dir is exist! + 添加文件夹失败,父文件夹已被屏蔽! - - - Unknown - 未知 + + Add blocked folder failed, it has been already blocked! + 添加文件夹失败,该文件夹已被屏蔽! + + + SearchWidget - - Update Shortcut - + Touchpad + 触摸板 + + + SecurityCenter - Add Shortcut - 添加快捷键 + + SecurityCenter + 安全中心 - - Display - 显示器 + + + Computer Security Overview + 安全功能概览 + /securitycenter/Computer Security Overview - - Defaultapp - 默认应用 + + Understand current computer security situation and take measures + 保障系统安全性,并采取有效措施 - - Power - 电源 + Summarize + 概述 - - Autoboot - 开机启动 + Recognize the current security of the system, and can take the necessary settings + 了解系统当前安全性,并可采取必要的设置操作 - - Printer - 打印机 + + Run Security Center + 打开安全中心 - - Mouse - 鼠标 + + Security Center + 安全中心 - - Touchpad - 触摸板 + Virus Protection + 病毒防护 - - Keyboard - 键盘 + Protect system from threats + 实时防护,帮助系统免受威胁 - - Shortcut - 快捷键 + Network Protection + 网络保护 - - Audio - 声音 + Setup app that can access web + 设置可访问网络的应用 - - Background - 背景 + App Execution Control + 应用执行控制 - - Theme - 主题 + App install and exe protection + 应用程序安装和执行保护 - - Screenlock - 锁屏 + + Account Security + 账户安全 + /securitycenter/Account Security - - Fonts - 字体 + + Protect account and login security + 提供账户相关的安全保障 - - Desktop - 桌面 + + Safety check-up + 安全体检 + /securitycenter/Safety check-up - - Netconnect - 网络连接 + + Detect abnormal configuration + 检查修复系统漏洞和异常配置 - - Vpn - VPN + + Virus defense + 病毒防护 + /securitycenter/Virus defense - - Proxy - 代理 + + Real time protection from virus threat + 保护系统免受恶意程序攻击 - - Userinfo - 账户信息 + + App protection + 应用控制与保护 + /securitycenter/App protection - - NetworkAccount - 云账户 + + App install + 提供应用程序安装,运行防护 - - Datetime - 时间和日期 + + Net protection + 网络保护 + /securitycenter/Net protection - - Area - 语言和地区 + + Secure Config + 系统安全配置 + /securitycenter/Secure Config - - SecurityCenter - 安全中心 + + Simple Config + 启用系统安全功能的相关配置 - - Update - 更新 + Network protection + 网络保护 - - Backup - 备份 + + Manage and control network + 提供应用联网行为的管控 - - Notice - 通知 + Secure mode configuration + 启用系统安全功能配置 + 安全模式配置 - - About - 关于 + Simple configuraion + 启用系统安全功能简易配置 + + + ShareMain - - Experienceplan - 体验计划 + + Share + 共享 - - min length %1 - - + + Allow others to view your desktop + 允许其他人查看您的桌面 - - min digit num %1 - - + + Allow connection to control screen + 允许连接控制屏幕 - - min upper num %1 - - + + Security + 安全 - - min lower num %1 - - + + You must confirm every visit for this machine + 您必须为本机机器确认每次访问 - - min other num %1 - - + + Require user to enter this password: + 要求用户输入此密码: - - min char class %1 - - + + + Password can not be blank + 密码不能为空 - - max repeat %1 - - + + + Password length must be less than or equal to 8 + 密码长度需小于等于8 - - max class repeat %1 - - + Password length is greater than 8 + 密码长度大于8 + + + Shortcut - - max sequence %1 - - + + + + System Shortcut + 系统快捷键 + /shortcut/System Shortcut - - - Never - 从不 + Show all shortcut + 显示全部快捷键 - - Year - + + Custom Shortcut + 自定义快捷键 - - Jan - + + Customize Shortcut + 自定义快捷键 + /shortcut/Customize Shortcut - - Feb - + + Add custom shortcut + 添加自定义快捷键 + /shortcut/Add custom shortcut - - Mar - + + Edit + 编辑 - - Apr - + + Delete + 删除 - - May - + disable + 无效 - - Jun - + Reset default + 恢复默认快捷键 - - Jul - + shortcut + 快捷键 - - Aug - + + Shortcut + 快捷键 - - Sep - + Desktop + 桌面 - - Oct - + System + 系统 + + + ShowAllShortcut - - Nov - + Dialog + 更改时间 - - Dec - + System Shortcuts + 快捷键 - - Day - + Show all shortcut + 显示全部快捷键 - - ukui-control-center is already running! - + Desktop + 桌面 - RegDialog + SuccessDiaolog - - Get - 获取验证码 + Reback sign in + 重新登录 - - Your password here - 输入密码 + Sign up success! + 注册账号成功! - - Your account here - 请输入用户名 + Reset success! + 重置密码成功! - - Confirm your password - 确认密码 + Sign in success! + 登录帐号成功! - - Your code here - 输入验证码 + Binding phone success! + 绑定手机! - - This operation is permanent - 设置后不可更改 + Confirm + 确定 + + + SyncDialog - - - At least 6 bit, include letters and digt - 至少六位,包含大小写字母、数字 + + Sync + 同步 - - Your password is valid! - 您的密码是有效的! + + Do not + 放弃 - - - ResolutionSlider - (recommend) - (推荐) + + + Last sync at %1 + 上次同步于%1 - - No available resolutions - 没有合适的分辨率 + + Sync now? + 选择以下同步覆盖,继续? - - - Screenlock - - - Screenlock - 锁屏 + + Wallpaper + 桌面壁纸 - - Screenlock Interface - 锁屏界面 + + ScreenSaver + 屏保 - - Screenlock Set - 锁屏设置 + + Font + 字体 - - Lock screen when screensaver boot - 激活屏保时锁定屏幕 + + Avatar + 头像 - - Lock screen delay - 锁屏延时 + + Menu + 开始菜单 - Min - 分钟 + + Tab + 任务栏 - - Select screenlock background - 选择锁屏背景 + + Quick Start + 快速启动项 - - Browser online wp - 浏览线上壁纸 + + Themes + 主题 - - Browser local wp - 浏览本地壁纸 + + Mouse + 鼠标 - - Show picture of screenlock on screenlogin - 显示锁屏壁纸在登录页面 + + TouchPad + 触摸板 - Enabel screenlock - 开启锁屏 + + KeyBoard + 键盘 - Open - 浏览 + + ShortCut + 快捷键 - screenlock - 锁屏 + + Area + 区域语言 - picture - 图片 + + Date/Time + 时间日期 - Never - 从不 + + Default Open + 默认打开方式 - - 5m - + + Notice + 通知 - - 10m - + + Option + 登录选项 - - 30m - + + Peony + 文件管理器 - - 45m - + + Boot + 开机启动项 - - 1m - + + Power + 电源 - - 1h - + + Editor + 文本编辑器 - - 1.5h - + + Terminal + 终端 - - 3h - + + Weather + 麒麟天气 + + + + Media + 麒麟影音 - Screensaver + TabWid - - - Screensaver - 屏保 + + + + + + + + Check Update + 检查更新 - - Enable screensaver - 开启屏保 + + Service connection abnormal,please retest! + 服务连接异常,请重新检测! - - Screensaver program - 屏幕保护程序 + + + Prompt information + 提示信息 - - idle time - 等待时间 + + Update now + 立即更新 - Min - 分钟 + + Cancel update + 取消更新 - - Lock screen when screensaver boot - 激活屏保时锁定屏幕 + + No,I Don't Backup + 否,我不备份 - screensaver - 屏保 + + + Being updated... + 正在更新... - - Default_ukui - 默认屏保 + + + + + + + + UpdateAll + 全部更新 - - Blank_Only - 黑屏 + + The backup restore partition could not be found. The system will not be backed up in this update! + 未能找到备份还原分区,本次更新不会备份系统! - Random - 随机 + + Kylin backup restore tool is doing other operations, please update later. + 麒麟备份还原工具正在进行其他操作,请稍后更新 - Never - 从不 + + The source manager configuration file is abnormal, the system temporarily unable to update! + 源管理器配置文件异常,暂时无法更新! - - 5m - + + Backup already, no need to backup again. + 已备份,无需再次备份 - - 10m - + + Kylin backup restore tool does not exist, this update will not backup the system! + 麒麟备份还原工具不存在,本次更新不会备份系统 - - 30m - + + Backup complete. + 备份完成 - - 45m - + + In backup: + 备份中: - - 1m - + + + Start backup,getting progress + 开始备份,正在获取进度 - - 1h - + + Failed to write configuration file, this update will not back up the system! + 写入配置文件失败,本次更新不会备份系统! - - 1.5h - + + Insufficient backup space, this update will not backup your system! + 备份空间不足,本次更新不会备份系统! - - 3h - + + Kylin backup restore tool could not find the UUID, this update will not backup the system! + 麒麟备份还原工具无法找到UUID,本次更新不会备份系统 - - - SecurityCenter - - - SecurityCenter - 安全中心 + + Backup interrupted, stop updating! + 备份过程被中断,停止更新! - - Summarize - 概述 + + Backup finished! + 备份完成! - - Recognize the current security of the system, and can take the necessary settings - 了解系统当前安全性,并可采取必要的设置操作 + + Kylin backup restore tool exception: + 麒麟备份还原工具异常: - - Run Security Center - 打开安全中心 + + There will be no backup in this update! + 本次更新不会备份系统! - - Virus Protection - 病毒防护 + + Getting update list + 正在获取更新列表 - - Protect system from threats - 实时防护,帮助系统免受威胁 + + + Software source update failed: + 软件源更新失败: - - Network Protection - 网络保护 + + + Update software source : + 更新软件源进度: - - Setup app that can access web - 设置可访问网络的应用 + + Reconnect times: + 重连次数: - - App Execution Control - 应用执行控制 + + Update + 安全更新 - - App install and exe protection - 应用程序安装和执行保护 + + View history + 查看更新历史 - - Account Security - 账户安全 + + Update Settings + 更新设置 - - Protect account and login security - 保护账户和登录的安全性 + + Allowed to renewable notice + 允许通知可更新的应用 - - - Shortcut - - System Shortcut - 系统快捷键 + + Backup current system before updates all + 全部更新前备份系统 - - Show all shortcut - 显示全部快捷键 + + + Your system is the latest! + 您的系统已是最新! - - Custom Shortcut - 自定义快捷键 + + + Updatable app detected on your system! + 检测到你的系统有可更新的应用! - - Add custom shortcut - 添加自定义快捷键 + + + Last refresh: + 上次更新: - - Reset default - 恢复默认快捷键 + + Last Checked: + 上次检测: - shortcut - 快捷键 + + Updating the software source + 正在更新软件源 - - Shortcut - 快捷键 + + This update will not backup the current system, do you want to continue the update? + 本次更新不会备份当前系统,是否继续更新? - Desktop - 桌面 + + Yes, keep updating + 是,继续更新 - System - 系统 + + No, backup now + 否,立即备份 - - - ShowAllShortcut - - Dialog - + + Not updated + 暂不更新 - - System Shortcuts - 快捷键 + + Part of the update failed! + 部分更新失败! - - - Desktop - 桌面 + + An important update is in progress, please wait. + 正在进行一项重要更新,请等待。 - - - SuccessDiaolog - - Reback sign in - 重新登录 + + The backup restore partition is abnormal. You may not have a backup restore partition.For more details,see /var/log/backup.log + 备份还原分区异常,您可能没有备份还原分区。更多详细信息,可以参看/var/log/backup.log - - Sign up success! - 注册账号成功! + Other err! please refers /var/log/backup.txt! + 其他错误!请查看/var/log/backup.txt - - Reset success! - 重置密码成功! + + Calculating Capacity... + 计算系统空间大小 - - Sign in success! - 登录帐号成功! + Update software source progress: + 更新软件源进度: - - Binding phone success! - 绑定手机! + Reconnect times + 重连次数 - - - - - Confirm - 确定 + Allows notifications to be updatable for applications. + 允许通知可更新的应用 + + + Backup the current system as a rollback version before all updates + 全部更新前备份当前系统为可回退的版本 Theme + Theme Mode 主题模式 + /theme/Theme Mode - + Theme 主题 - + Default 系统默认 - + Light 浅色模式 - + Dark 深色模式 @@ -4304,37 +7083,45 @@ + Icon theme 图标主题 + /theme/Icon theme - + Control theme 控件主题 - + + Cursor theme 光标主题 + /theme/Cursor theme - + Effect setting 效果设置 - + + Transparency 透明度 + /theme/Transparency Transparent effects 透明特效 - + + Performance mode 特效模式 + /theme/Performance mode Transparent @@ -4349,7 +7136,7 @@ - + Reset to default 恢复默认设置 @@ -4361,18 +7148,23 @@ TimeZoneChooser - + Cancel 取消 - + Confirm 确定 - - + + Change time zone + 更改时区 + + + + change timezone 修改系统时区 @@ -4386,11 +7178,58 @@ + TouchScreen + + + + + TouchScreen + 触摸屏 + + + + monitor + 显示器 + + + + touch id + 触摸屏标识 + + + + map + 触摸映射 + + + + calibration + 触摸校准 + + + + No touch screen found + 未发现触摸屏设备 + + + + input device + 触摸设备 + + + + TextLabel + + + + Touchpad + Touchpad Settings 触摸板设置 + /touchpad/Touchpad Settings @@ -4422,37 +7261,84 @@ 触摸板 - + Touchpad 触摸板 - + + Disable rolling 禁用滚动 - + + Edge scrolling + 边界滚动 + + + + Two-finger scrolling + 双指滚动 + + + Vertical edge scrolling 垂直边界滚动 - + Horizontal edge scrolling 水平边界滚动 - + Vertical two-finger scrolling 垂直双指滚动 - + Horizontal two-finger scrolling 水平双指滚动 + UkccAbout + + + + Settings + 设置 + + + UKCC + 控制面板 + + + + Version: + 版本: + + + + Service and Support: + 服务与支持团队: + + + Developer + 开发者: + + + Vesion + 版本 + + + + The control panel provides a friendly graphical user interface to manage common configuration items of the operating system. System configuration provides system, equipment, personalization, network, account, time and date, account, time and date, update, notification and operation module operations. + “设置”提供了一个友好的用户图形界面,以及易于操作的功能模块划分,比如:系统、设备、主题、时间日期、语言、更新和安全等模块。您可以更改系统设置来自定系统。 + + + UkmediaApplicationWidget Application Volume @@ -4466,34 +7352,40 @@ UkmediaInputWidget - + Input 输入 - Input Device - 选择输入设备 + 选择输入设备 + /audio/Input Device + + + + Input Device: + 选择输入设备: + /audio/Input Device - + Volume 音量大小 + /audio/Volume - + Input Level - 输入等级 + 输入反馈 + /audio/Input Level - Low - + - High - + Select input device @@ -4520,7 +7412,7 @@ - + Connector 连接器 @@ -4528,52 +7420,89 @@ UkmediaMainWidget - + sound error 声音错误 - + load sound failed 加载声音失败 + + + Establishing connection to PulseAudio. Please wait... + + + + + pa_ext_stream_restore_write() failed + + + + + + (unplugged) + + + + + + (unavailable) + + + + + (plugged in) + + UkmediaOutputWidget - + Output 输出 - Output Device - 选择输出设备 + 选择输出设备 + /audio/Output Device - + + Output Device: + 选择输出设备: + /audio/Output Device + + + Master Volume 主音量大小 + /audio/Master Volume - + Balance 声道平衡 + /audio/Balance - + Right - + Profile 配置 + /audio/Profile - + Card 声卡 + /audio/Card Select output device @@ -4592,7 +7521,7 @@ 声道平衡 - + Left @@ -4601,7 +7530,7 @@ - + Connector 连接器 @@ -4641,92 +7570,131 @@ 注销 - + System Sound 系统音效 + /audio/System Sound - + Sound Theme 系统音效主题 + /audio/Sound Theme - + Alert Sound 提示音 + /audio/Alert Sound + + + + Alert Volume + 提示音大小 + /audio/Alert Volume + + + + Logout Music + 注销 - Boot Music - 开关机音乐 + 开关机音乐 + /audio/Boot Music - + Beep Switch 提示音量开关 - + + Poweroff Music + 关机 + + + + Startup Music + 开机 + + + + Wakeup Music + 唤醒 + + + Sleep Music + 睡眠 + + Window Closed - 窗口关闭 + 窗口关闭 - + Volume Change 音量改变 - Setting Menu - 设置菜单 + 设置菜单 UnifiedOutputConfig - + resolution 分辨率 - + orientation 方向 - + arrow-up 不旋转 - + 90° arrow-right 90°顺时针 - + arrow-down 上下颠倒 - + 90° arrow-left 90°逆时针 - - refresh rate + + frequency 刷新率 - - auto - 自动 + + + + + %1 Hz + - - aa - + refresh rate + 刷新率 + + + + + auto + 自动 @@ -4735,22 +7703,62 @@ Update - 更新 + 安全更新 + System Update 系统更新 + /update/System Update Last check time: - 上次更新检测时间: + 上次检查时间: + + + + Check for updates + 检查更新 + + + + UpdateDbus + + + ukui-control-center + 设置 + + + + ukui-control-center-update + 控制面板-更新提示 + + + + UpdateLog + + + Update log + 更新日志 + + + + UpdateSource + + + Connection failed, please reconnect! + 连接失败,请重新连接! + + + Upgrade - - CheckUpdate - 检测更新 + + Upgrade + 更新 + /upgrade/Upgrade @@ -4760,78 +7768,212 @@ 账户信息 - Userinfo + 账户信息 + + + + User Info 账户信息 - standard user - 标准用户 + 标准用户 - administrator - 管理员用户 + 管理员用户 - + root Root - + + Hint + 提示 + + + + The system only allows one user to log in automatically.After it is turned on, the automatic login of other users will be turned off.Is it turned on? + 系统只允许一个用户自动登录,开启后将关闭其他用户的自动登录,是否开启? + + + + Trun on + 开启 + + + + Close on + 取消 + + + + Add biometric feature + 添加生物密码 + + + + Rename + 重命名 + + + + Verify + 验证 + + + Delete 删除 - + + Standard + 标准用户 + + + + Admin + 管理员 + + + + Del + 删除 + + + + Warning + 警告 + + + + The user is logged in, please delete the user after logging out + 用户已经登录,请注销后删除用户 + + + Current User 当前用户 - - + Change pwd 更改密码 - - + Change type 更改类型 - Change valid - 密码时效 + 密码时效 + /userinfo/Change valid + + + User group + 用户组 Change vaild 密码时效 - + + + Password + 修改密码 + /userinfo/Password + + + + + Type + 账户类型 + /userinfo/Type + + + + Valid + 密码时效 + + + + Group + 用户组 + + + + Login no passwd 免密登录 + /userinfo/Login no passwd - + enable autoLogin - 自动登录 + 开机自动登录 + /userinfo/enable autoLogin + + + + Automatic login at boot + 开机自动登录 + + + + Currently in Live mode, please create a new user and log out + 当前处于试用模式,请创建一个新用户并注销生效 + + + + Biometric Password + 生物密码 + + + + advanced settings + 高级设置 + + + + enable biometrics + 打开生物特征 - + + types of biometric password + 生物密码类型 + + + + biometric device + 生物设备 + + + Other Users 其他用户 - + Add new user 添加新用户 + Vino + + + Vino + 桌面共享 + + + Vpn @@ -4839,16 +7981,17 @@ 添加VPN连接 - + Add vpn connect 添加VPN连接 + /vpn/Add vpn connect vpn VPN - + Vpn VPN @@ -4856,43 +7999,49 @@ Wallpaper - + Desktop Background 桌面背景 - + + Select from 选择背景形式 + /wallpaper/Select from - Picture options - 图片放置方式 + 图片放置方式 - + + Browser local wp 浏览本地壁纸 + /wallpaper/Browser local wp - + + Reset to default 恢复默认设置 + /wallpaper/Reset to default - + + Browser online wp 浏览线上壁纸 + /wallpaper/Browser online wp Restore default wp 恢复默认壁纸 - Ok - 确定 + 确定 Add @@ -4903,17 +8052,17 @@ 背景 - + Background 背景 - + picture 图片 - + color 颜色 @@ -4922,74 +8071,77 @@ 添加自定义快捷键 - + Custom color 自定义颜色 - wallpaper - 平铺 + 平铺 - centered - 居中 + 居中 - scaled - 比例放大 + 比例放大 - stretched - 伸展 + 伸展 - zoom - 缩放 + 缩放 - spanned - 适合宽度 + 适合宽度 + + + + Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + 图片文件(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp) + + + + allFiles(*.*) + 所有文件(*.*) - - + + select custom wallpaper file 选择自定义壁纸文件 - - + + Select 选择 - - + + Position: 位置: - - + + FileName: 文件名: - - + + FileType: 文件类型: - - - + + Cancel 取消 @@ -5001,47 +8153,135 @@ 屏幕缩放 - + + unify output + 统一输出 + /display/unify output + + + night mode 夜间模式 + /display/night mode - + Some applications need to be logouted to take effect - 应用程序需要注销才能生效 + 部分程序需要注销生效 + + + + monitor + 显示器 + /display/monitor + + + + Information + 信息 + + + + Theme follow night mode + 主题跟随夜间模式变化 - + + Hint + 提示 + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +the settings will be saved after 14 seconds + 修改分辨率或刷新率后,由于显示设备与 显卡兼容性问题,有可能显示不正常。系统将在14秒后保存配置 + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +the settings will be saved after 9 seconds + 修改分辨率或刷新率后,由于显示设备与 显卡兼容性问题,有可能显示不正常。系统将在9秒后保存配置 + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +The settings will be saved after 9 seconds + 修改分辨率或刷新率后,由于显示设备与 显卡兼容性问题,有可能显示不正常。系统将在9秒后保存配置 + + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +the settings will be saved after %1 seconds + 修改分辨率或刷新率后,由于显示设备与 显卡兼容性问题,有可能显示不正常。系统将在%1秒后保存配置 + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after 10 seconds + 修改分辨率或刷新率后,由于显示设备与显卡存在兼容性问题,有可能显示不正常或者无法显示.如果出现异常,系统将在10秒后还原设置 + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after 9 seconds + 修改分辨率或刷新率后,由于显示设备与显卡存在兼容性问题,有可能显示不正常或者无法显示.如果出现异常,系统将在9秒后还原设置 + + + + Save Config + 保存当前配置 + + + + Restore Config + 恢复之前配置 + + + After modifying the resolution or refresh rate, due to compatibility issues between the display device and the graphics card, the display may be abnormal or unable to display +If something goes wrong, the settings will be restored after %1 seconds + 修改分辨率或刷新率后,由于显示设备与显卡存在兼容性问题,有可能显示不正常或者无法显示.如果出现异常,系统将在%1秒后还原设置 + + + please insure at least one output! 请确保至少开启一个屏幕! - - + + Warning 警告 - + + Open time should be earlier than close time! + 开启时间必须大于关闭时间! + + Morning time should be earlier than evening time! - 早晨时刻应早于晚上的时刻! + 早晨时刻应早于晚上的时刻! + + + + Warnning + 警告 - + Sorry, your configuration could not be applied. Common reasons are that the overall screen size is too big, or you enabled more displays than supported by your GPU. 抱歉,配置不能应用. - @title:window Unsupported Configuration - 窗口 + 窗口 Some applications need to be restarted to take effect 缩放配置需要注销后生效 + + + %1 + %1 + addShortcutDialog @@ -5051,37 +8291,80 @@ - Shortcut name - 快捷键名称 + 快捷键名称 - Shortcut exec - 快捷键程序 + 快捷键程序 + + + + Exec + 打开程序 - + Open 浏览 - + + Name + 快捷键名称 + + + + Key + 快捷按键 + + + Invalid executable, please re-enter 无效的可执行程序,请重新选择 - + + Cancel 取消 - - Certain + + Save 确定 - + Certain + 确定 + + + + Add custom shortcut + 添加自定义快捷键 + + + + shortcut conflict + 快捷键冲突 + + + + invaild shortcut + 无效快捷键 + + + + repeated naming + 快捷键名称重复 + + + + Desktop files(*.desktop) + 桌面文件(*.desktop) + + + select desktop 选择桌面 @@ -5098,40 +8381,40 @@ Dialog - + 更改时间 - + current date - 时间和日期 + 时间日期 - + time 时间 - + year 年份 - + month 月份 - + day - + cancel 取消 - + confirm 确认 @@ -5231,6 +8514,24 @@ + m_updatelog + + + No content. + 暂无内容. + + + + History Log + 历史更新 + + + + Update Details + 更新详情 + + + mcode_widget SongTi @@ -5241,8 +8542,9 @@ networkaccount - NetworkAccount + Cloud Account 云账户 + /networkaccount/Cloud Account diff -Nru ukui-control-center-2.0.3/shell/res/plugins/about/logo-dark.svg ukui-control-center-3.0.3/shell/res/plugins/about/logo-dark.svg --- ukui-control-center-2.0.3/shell/res/plugins/about/logo-dark.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/about/logo-dark.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1 @@ +® \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/about/logo-light.svg ukui-control-center-3.0.3/shell/res/plugins/about/logo-light.svg --- ukui-control-center-2.0.3/shell/res/plugins/about/logo-light.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/about/logo-light.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1 @@ +® \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/eth.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/eth.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/eth.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/eth.svg 2021-04-14 01:27:20.000000000 +0000 @@ -24,7 +24,7 @@ - - - - - - + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi2.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi2.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi2.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi2.svg 2021-04-14 01:27:20.000000000 +0000 @@ -19,8 +19,8 @@ - - - - + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi3.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi3.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi3.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi3.svg 2021-04-14 01:27:20.000000000 +0000 @@ -19,8 +19,8 @@ - - - - + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi4.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi4.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi4.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi4.svg 2021-04-14 01:27:20.000000000 +0000 @@ -19,8 +19,8 @@ - - - - + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi5.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi5.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi5.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi5.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,26 @@ + + + + + + + + + + +]> + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-full-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-full-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-full-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-full-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-full-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-full-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-full-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-full-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-high-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-high-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-high-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-high-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-high-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-high-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-high-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-high-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-low-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-low-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-low-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-low-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-low-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-low-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-low-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-low-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-medium-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-medium-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-medium-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-medium-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-medium-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-medium-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-medium-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-medium-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-none-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-none-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6-none-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6-none-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-none-pwd.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-none-pwd.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi6+-none-pwd.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi6+-none-pwd.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi.svg ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi.svg --- ukui-control-center-2.0.3/shell/res/plugins/netconnect/wifi.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/netconnect/wifi.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ - - - - - - - - - - -]> - - - - - - - - - - - - diff -Nru ukui-control-center-2.0.3/shell/res/plugins/search/360.svg ukui-control-center-3.0.3/shell/res/plugins/search/360.svg --- ukui-control-center-2.0.3/shell/res/plugins/search/360.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/search/360.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,18 @@ + + + + 360 + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/search/baidu.svg ukui-control-center-3.0.3/shell/res/plugins/search/baidu.svg --- ukui-control-center-2.0.3/shell/res/plugins/search/baidu.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/search/baidu.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,17 @@ + + + + baidu + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/search/sougou.svg ukui-control-center-3.0.3/shell/res/plugins/search/sougou.svg --- ukui-control-center-2.0.3/shell/res/plugins/search/sougou.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/search/sougou.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,22 @@ + + + + sougou + Created with Sketch. + + + + + + + + + + + + + + + + + \ No newline at end of file Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/icon_scanning_b48@1x.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/icon_scanning_b48@1x.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/icon_scanning_w48@1x.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/icon_scanning_w48@1x.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/kysec_48.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/kysec_48.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/kysec_48_white.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/kysec_48_white.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/net_48.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/net_48.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/net_48_white.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/net_48_white.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/protect_48.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/protect_48.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/protect_48_white.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/protect_48_white.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/set2@2x_1.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/set2@2x_1.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/set2px.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/set2px.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/user_48.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/user_48.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/securitycenter/user_48_white.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/securitycenter/user_48_white.png differ diff -Nru ukui-control-center-2.0.3/shell/res/plugins/theme/opacityhigh.svg ukui-control-center-3.0.3/shell/res/plugins/theme/opacityhigh.svg --- ukui-control-center-2.0.3/shell/res/plugins/theme/opacityhigh.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/theme/opacityhigh.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/theme/opacitylow.svg ukui-control-center-3.0.3/shell/res/plugins/theme/opacitylow.svg --- ukui-control-center-2.0.3/shell/res/plugins/theme/opacitylow.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/theme/opacitylow.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/kylin-update-desktop-app.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/kylin-update-desktop-app.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/kylin-update-desktop-kernel-3a4000.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/kylin-update-desktop-kernel-3a4000.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/kylin-update-desktop-kernel.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/kylin-update-desktop-kernel.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/kylin-update-desktop-security.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/kylin-update-desktop-security.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/kylin-update-desktop-support.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/kylin-update-desktop-support.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/kylin-update-desktop-ukui.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/kylin-update-desktop-ukui.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/linux-generic.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/linux-generic.png differ diff -Nru ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading10.svg ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading10.svg --- ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading10.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading10.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +loading1 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading11.svg ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading11.svg --- ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading11.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading11.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +loading12 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading12.svg ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading12.svg --- ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading12.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading12.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +loading13 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading13.svg ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading13.svg --- ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading13.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading13.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +loading14 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading14.svg ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading14.svg --- ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading14.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading14.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +loading15 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading15.svg ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading15.svg --- ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading15.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading15.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +loading16 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading16.svg ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading16.svg --- ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading16.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading16.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +loading17 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading17.svg ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading17.svg --- ukui-control-center-2.0.3/shell/res/plugins/upgrade/loading17.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/plugins/upgrade/loading17.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +loading18 \ No newline at end of file Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/normal.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/normal.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/refresh.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/refresh.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/upgrade/update.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/upgrade/update.png differ Binary files /tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/plugins/userinfo/notice.png and /tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/plugins/userinfo/notice.png differ diff -Nru ukui-control-center-2.0.3/shell/res/resfile.qrc ukui-control-center-3.0.3/shell/res/resfile.qrc --- ukui-control-center-2.0.3/shell/res/resfile.qrc 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/resfile.qrc 2021-05-20 13:08:14.000000000 +0000 @@ -48,8 +48,8 @@ secondaryleftmenu/BackgroundWhite.svg secondaryleftmenu/Backup.svg secondaryleftmenu/BackupWhite.svg - secondaryleftmenu/Datetime.svg - secondaryleftmenu/DatetimeWhite.svg + secondaryleftmenu/Dat.svg + secondaryleftmenu/DatWhite.svg secondaryleftmenu/Defaultapp.svg secondaryleftmenu/DefaultappWhite.svg secondaryleftmenu/Desktop.svg @@ -105,8 +105,6 @@ primaryleftmenu/datetime.svg titlebar/min.svg titlebar/back.svg - secondaryleftmenu/NetworkAccount.svg - secondaryleftmenu/NetworkAccountWhite.svg plugins/netconnect/eth.svg plugins/netconnect/nonet.svg plugins/netconnect/wifi1.svg @@ -133,12 +131,81 @@ secondaryleftmenu/SecurityCenter.svg secondaryleftmenu/SecurityCenterWhite.svg plugins/about/logoukui.svg + titlebar/ukui-control-center.svg + plugins/userinfo/notice.png + secondaryleftmenu/Cloud Account.svg + secondaryleftmenu/Cloud AccountWhite.svg + plugins/netconnect/wifi5.svg + dropArrow/search.svg + secondaryleftmenu/Vino.svg + secondaryleftmenu/VinoWhite.svg + plugins/theme/opacitylow.svg + plugins/theme/opacityhigh.svg + secondaryleftmenu/Bluetooth.svg + secondaryleftmenu/BluetoothWhite.svg + secondaryleftmenu/TouchScreenWhite.svg + secondaryleftmenu/TouchScreen.svg + plugins/upgrade/refresh.png + secondaryleftmenu/Upgrade.svg + secondaryleftmenu/UpgradeWhite.svg + plugins/upgrade/update.png + plugins/upgrade/normal.png + plugins/securitycenter/icon_scanning_b48@1x.png + plugins/securitycenter/icon_scanning_w48@1x.png + plugins/securitycenter/kysec_48_white.png + plugins/securitycenter/kysec_48.png + plugins/securitycenter/net_48_white.png + plugins/securitycenter/net_48.png + plugins/securitycenter/protect_48_white.png + plugins/securitycenter/protect_48.png + plugins/securitycenter/set2@2x_1.png + plugins/securitycenter/set2px.png + plugins/securitycenter/user_48_white.png + plugins/securitycenter/user_48.png + plugins/upgrade/kylin-update-desktop-app.png + plugins/upgrade/kylin-update-desktop-kernel-3a4000.png + plugins/upgrade/kylin-update-desktop-security.png + plugins/upgrade/kylin-update-desktop-support.png + plugins/upgrade/kylin-update-desktop-ukui.png + plugins/upgrade/loading10.svg + plugins/upgrade/loading11.svg + plugins/upgrade/loading12.svg + plugins/upgrade/loading13.svg + plugins/upgrade/loading14.svg + plugins/upgrade/loading15.svg + plugins/upgrade/loading16.svg + plugins/upgrade/loading17.svg + secondaryleftmenu/Date.svg + secondaryleftmenu/DateWhite.svg + plugins/upgrade/kylin-update-desktop-kernel.png + plugins/upgrade/linux-generic.png + plugins/about/logo-light.svg + plugins/about/logo-dark.svg + secondaryleftmenu/Search.svg + secondaryleftmenu/SearchWhite.svg + plugins/search/360.svg + plugins/search/baidu.svg + plugins/search/sougou.svg + plugins/netconnect/wifi6-full-pwd.svg + plugins/netconnect/wifi6-high-pwd.svg + plugins/netconnect/wifi6-low-pwd.svg + plugins/netconnect/wifi6-medium-pwd.svg + plugins/netconnect/wifi6-none-pwd.svg + plugins/netconnect/wifi6+-full-pwd.svg + plugins/netconnect/wifi6+-high-pwd.svg + plugins/netconnect/wifi6+-low-pwd.svg + plugins/netconnect/wifi6+-medium-pwd.svg + plugins/netconnect/wifi6+-none-pwd.svg - i18n/zh_CN.qm - i18n/tr.qm global.qss combox.qss plugins/update/update.png + dpinyin.dict + i18n/zh_CN.ts + i18n/en_US.ts + i18n/bo.ts + i18n/tr.ts + search.xml diff -Nru ukui-control-center-2.0.3/shell/res/search.xml ukui-control-center-3.0.3/shell/res/search.xml --- ukui-control-center-2.0.3/shell/res/search.xml 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/search.xml 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,680 @@ + + + guanyu + banben + 关于 + 版本 + Version + + + guanyu + neihe + 关于 + 内核 + Kernel + + + 关于 + CPU + CPU + + + guanyu + neicun + 关于 + 内存 + Memory + + + guanyu + yingpan + 关于 + 硬盘 + Disk + + + yuyanyudiqu + dangqianquyu + 区域语言 + 当前区域 + Current Area + + + yuyanyudiqu + quyugeshishuju + 区域语言 + 区域格式数据 + Regional Format Data + + + yuyanyudiqu + tianjiashouyuyan + 语言与地区 + 添加首语言 + Add Main Language + + + kaijiqidong + kaijiqidongshezhi + 开机启动 + 开机启动设置 + Set Autoboot Program + + + xitonghuanyuan + beifen + 系统还原 + 备份 + Backup + + + xitonghuanyuan + huanyuan + 系统还原 + 还原 + Restore + + + shijianheriqi + shoudonggenggaishijian + 时间日期 + 手动更改时间 + Change Time + + + shijianheriqi + genggaishiqu + 时间日期 + 更改时区 + Change Time Zone + + + shijianheriqi + xiaoshizhi + 时间日期 + 24小时制 + 24-hour Clock + + + shijianheriqi + tongbuwangluoshijian + 时间日期 + 同步网络时间 + Sync Network Time + + + morenyingyong + liulanqi + 默认应用 + 浏览器 + Browser + + + morenyingyong + dianziyoujian + 默认应用 + 电子邮件 + Mail + + + morenyingyong + tuxiangchakanqi + 默认应用 + 图像查看器 + Image Viewer + + + morenyingyong + yinpinbofangqi + 默认应用 + 音频播放器 + Audio Player + + + morenyingyong + shipinbofangqi + 默认应用 + 视频播放器 + Video Player + + + morenyingyong + wendangbianjiqi + 默认应用 + 文档编辑器 + Text Editor + + + zhuomian + xianshizaizhuomiandetubiao + 桌面 + 显示在桌面的图标 + Icon Show On Desktop + + + zhuomian + xianshizaituopanshangdetubiao + 桌面 + 显示在托盘上的图标 + Tray icon + + + ziti + zitixuanze + 字体 + 字体选择 + Fonts Select + + + ziti + zitidaxiao + 字体 + 字体大小 + Fonts Size + + + jianpan + qiyonganjianzhongfushezhi + 键盘 + 启用按键重复设置 + Enable Repeat Key + + + jianpan + jianpanyanchi + 键盘 + 键盘延迟 + Keyboard Delay + + + jianpan + jianpansudu + 键盘 + 键盘速度 + Keyboard Speed + + + jianpan + shuruzifuceshizhongfuxiaoguo + 键盘 + 输入字符测试重复效果 + Test Repetition Effect + + + jianpan + qiyonganjiantishi + 键盘 + 启用按键提示 + Tip of Keyboard + + + jianpan + huifumorenjianpanbuju + 键盘 + 恢复默认键盘布局 + Reset Layout + + + jianpan + jianpanbuju + 键盘 + 键盘布局 + Keyboard Layout + + + shubiao + guanyongshou + 鼠标 + 惯用手 + Hand Habit + + + shubiao + shubiaosudu + 鼠标 + 鼠标速度 + Mouse Speed + + + shubiao + shubiaoshuangjijiangeshichang + 鼠标 + 鼠标双击间隔时长 + Doubleclick Delay + + + shubiao + shubiaojiasu + 鼠标 + 鼠标加速 + Acceleration + + + shubiao + shubiaomingandu + 鼠标 + 鼠标敏感度 + Sensitivity + + + shubiao + anctrlxianshizhizhenweizhi + 鼠标 + 按Ctrl键显示指针位置 + Visibility + + + shubiao + zhizhendaxiao + 鼠标 + 指针大小 + Pointer Size + + + shubiao + guangbiaoshanshuosudu + 鼠标 + 光标闪烁速度 + Cursor Flashing Speed + + + shubiao + qiyongwenbenquyudeguangbiaoshanshuo + 鼠标 + 启用文本区域的光标闪烁 + Enable Flashing on Text Area + + + wangluo + wangluozhuangtai + 网络 + 网络状态 + Netconnect Status + + + wangluo + dakaiwifi + 网络 + 打开wifi + Open Wifi + + + tongzhi + shezhizaitongzhizhongxinxianshidetongzhixinxi + 通知 + 设置在通知中心显示的通知信息 + Notification Type + + + tongzhi + shezhitongzhilaiyuan + 通知 + 设置通知来源 + Notice Origin + + + sousuo + sousuomoshi + 搜索 + 搜索模式 + Search Method + + + sousuo + pingbiwenjianjia + 搜索 + 屏蔽文件夹 + Block Folders + + + sousuo + sousuoyinqing + 搜索 + 搜索引擎 + Web Engine + + + xianshiqi + fenbianlv + 显示器 + 分辨率 + Resolution + + + xianshiqi + suofangpingmu + 显示器 + 缩放屏幕 + Screen Zoom + + + dianyuan + pingheng + 电源 + 平衡 + Balance + + + dianyuan + jieneng + 电源 + 节能 + Saving + + + dianyuan + zidingyi + 电源 + 自定义 + Custom + + + dayinji + tianjiadayinjihesaomiaoyi + 打印机 + 添加打印机和扫描仪 + Add Printers And Scanners + + + daili + kaiqizidongdaili + 代理 + 开启自动代理 + Auto Proxy + + + daili + kaiqishoudongdaili + 代理 + 开启手动代理 + Manual Proxy + + + suoping + jihuopingbaoshisuodingpingmu + 锁屏 + 激活屏保时锁定屏幕 + Lock Screen on Screensaver Boot + + + suoping + xianshisuopingbizhizaidengluyemian + 锁屏 + 显示锁屏壁纸在登录页面 + Show Picture of Screenlock on Screenlogin + + + pingbao + kaiqipingbao + 屏保 + 开启屏保 + Enable Screensaver + + + pingbao + pingmubaohuchengxu + 屏保 + 屏幕保护程序 + Screensaver Program + + + pingbao + dengdaishijian + 屏保 + 等待时间 + Idle Time + + + kuaijiejian + xitongkuaijiejian + 快捷键 + 系统快捷键 + System Shortcut + + + kuaijiejian + tianjiazidingyikuaijiejian + 快捷键 + 添加自定义快捷键 + Add Custom Shortcut + + + zhuti + zhutimoshi + 主题 + 主题模式 + Theme Mode + + + zhuti + tubiaozhuti + 主题 + 图标主题 + Icon Theme + + + zhuti + guangbiaozhuti + 主题 + 光标主题 + Cursor Theme + + + zhuti + toumingdu + 主题 + 透明度 + Transparency + + + zhuti + texiaomoshi + 主题 + 特效模式 + Performance Mode + + + chumoban + chumobanshezhi + 触摸板 + 触摸板设置 + Touchpad Settings + + + shengyin + xuanzeshurushebei + 声音 + 选择输入设备 + Input Device + + + shengyin + yinliangdaxiao + 声音 + 音量大小 + Volume + + + shengyin + shurudengji + 声音 + 输入等级 + Input Level + + + shengyin + xuanzeshuchushebei + 声音 + 选择输出设备 + Output Device + + + shengyin + zhuyinliangdaxiao + 声音 + 主音量大小 + Master Volume + + + shengyin + shengdaopingheng + 声音 + 声道平衡 + Channel Balance + + + shengyin + peizhi + 声音 + 配置 + Configuration + + + shengyin + shengqia + 声音 + 声卡 + Sound Card + + + shengyin + xitongyinxiao + 声音 + 系统音效 + System Sound + + + shengyin + xitongyinxiaozhuti + 声音 + 系统音效主题 + Sound Theme + + + shengyin + tishiyin + 声音 + 提示音 + Alert Sound + + + shengyin + tishiyindaxiao + 声音 + 提示音大小 + Alert Volume + + + shengyin + kaiguanjiyinle + 声音 + 开关机音乐 + Boot Music + + + shengyin + tishiyinliangkaiguan + 声音 + 提示音量开关 + Beep Switch + + + gengxin + xitonggengxin + 更新 + 系统更新 + Update + + + yonghuxinxi + genggaimima + 用户信息 + 更改密码 + Change Password + + + yonghuxinxi + genggaiyonghuleixing + 用户信息 + 更改用户类型 + Change Type + + + yonghuxinxi + mimashixiao + 用户信息 + 密码时效 + Change Valid + + + yonghuxinxi + mianmidenglu + 用户信息 + 免密登录 + Login without Password + + + yonghuxinxi + zidongdenglu + 用户信息 + 自动登录 + Auto Login + + + vpn + tianjiavpnlianjie + VPN + 添加VPN连接 + Add Vpn Connection + + + beijing + xuanzebeijingxingshi + 背景 + 选择背景形式 + Background Mode + + + beijing + liulanbendibizhi + 背景 + 浏览本地壁纸 + Browse Local Wallpaper + + + beijing + huifumorenshezhi + 背景 + 恢复默认设置 + Reset Wallpaper + + + beijing + liulanxianshangbizhi + 背景 + 浏览线上壁纸 + Browse Online Wallpaper + + + xianshiqi + tongyishuchu + 显示器 + 统一输出 + Unify Output + + + v101 + xianshiqi + yejianmoshi + 显示器 + 夜间模式 + Night Mode + + + cloudaccount + yunzhanghu + 云账户 + 云账户 + Cloud Account + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/About.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/About.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/About.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/About.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,25 +1,12 @@ - - - - - - - - - - -]> - - - - - - - - - - - + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Area.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Area.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Area.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Area.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,26 +1,12 @@ - - - - - - - - - - -]> - - - - - - - - - - - + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Audio.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Audio.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Audio.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Audio.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,30 +1,14 @@ - - - - - - - - - - -]> - - - - - - - - - - - - + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Autoboot.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Autoboot.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Autoboot.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Autoboot.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,26 +1,12 @@ - - - - - - - - - - -]> - - - - - - - - - - + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Background.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Background.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Background.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Background.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,29 +1,16 @@ - - - - - - - - - - -]> - - - - - - - - - - - - + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Backup.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Backup.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Backup.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Backup.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,26 +1,10 @@ - - - - - - - - - - -]> - - - - - - - - - - + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Bluetooth.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Bluetooth.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Bluetooth.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Bluetooth.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,11 @@ + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/BluetoothWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/BluetoothWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/BluetoothWhite.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/BluetoothWhite.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +蓝牙z \ No newline at end of file diff -Nru "/tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Cloud Account.svg" "/tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Cloud Account.svg" --- "/tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Cloud Account.svg" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Cloud Account.svg" 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,16 @@ + + + + + + diff -Nru "/tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Cloud AccountWhite.svg" "/tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Cloud AccountWhite.svg" --- "/tmp/tmp703tx3n2/53g0K30X1M/ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Cloud AccountWhite.svg" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmp703tx3n2/8k1iQChhly/ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Cloud AccountWhite.svg" 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ +white_24 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Date.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Date.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Date.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Date.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Datetime.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Datetime.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Datetime.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Datetime.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - - - - - - diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/DatetimeWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/DatetimeWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/DatetimeWhite.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/DatetimeWhite.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/DateWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/DateWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/DateWhite.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/DateWhite.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,37 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Dat.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Dat.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Dat.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Dat.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/DatWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/DatWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/DatWhite.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/DatWhite.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,37 @@ + + + + + + + + + + +]> + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Defaultapp.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Defaultapp.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Defaultapp.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Defaultapp.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,41 +1,27 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Desktop.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Desktop.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Desktop.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Desktop.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,28 +1,14 @@ - - - - - - - - - - -]> - - - - - - - - - - - - + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Display.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Display.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Display.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Display.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,32 +1,18 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Experienceplan.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Experienceplan.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Experienceplan.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Experienceplan.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,26 +1,12 @@ - - - - - - - - - - -]> - - - - - - - - - - + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Fonts.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Fonts.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Fonts.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Fonts.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,30 +1,16 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Keyboard.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Keyboard.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Keyboard.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Keyboard.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,29 +1,15 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - - + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Mouse.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Mouse.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Mouse.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Mouse.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,25 +1,11 @@ - - - - - - - - - - -]> - - - - - - - - - - + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Netconnect.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Netconnect.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Netconnect.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Netconnect.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,33 +1,20 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - - + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/NetworkAccount.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/NetworkAccount.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/NetworkAccount.svg 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/NetworkAccount.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -user_cloud_24 diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/NetworkAccountWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/NetworkAccountWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/NetworkAccountWhite.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/NetworkAccountWhite.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -white_24 \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Notice.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Notice.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Notice.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Notice.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,24 +1,9 @@ - - - - - - - - - - -]> - - - - - - - - - + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Power.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Power.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Power.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Power.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,25 +1,11 @@ - - - - - - - - - - -]> - - - - - - - - - - + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Printer.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Printer.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Printer.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Printer.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,28 +1,15 @@ - - - - - - - - - - -]> - - - - - - - - - - - - + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Proxy.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Proxy.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Proxy.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Proxy.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,28 +1,13 @@ - - - - - - - - - - -]> - - - - - - - - - - - - + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Screenlock.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Screenlock.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Screenlock.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Screenlock.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,27 +1,13 @@ - - - - - - - - - - -]> - - - - - - - - - - - + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Screensaver.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Screensaver.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Screensaver.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Screensaver.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,28 +1,14 @@ - - - - - - - - - - -]> - - - - - - - - - - - + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Search.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Search.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Search.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Search.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,12 @@ + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/SearchWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/SearchWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/SearchWhite.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/SearchWhite.svg 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,12 @@ + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/SecurityCenter.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/SecurityCenter.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/SecurityCenter.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/SecurityCenter.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1 +1,19 @@ -safe_center \ No newline at end of file + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Shortcut.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Shortcut.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Shortcut.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Shortcut.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,26 +1,12 @@ - - - - - - - - - - -]> - - - - - - - - - - - + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Theme.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Theme.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Theme.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Theme.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,27 +1,14 @@ - - - - - - - - - - -]> - - - - - - - - - - - - + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Touchpad.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Touchpad.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Touchpad.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Touchpad.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,26 +1,12 @@ - - - - - - - - - - -]> - - - - - - - - - - - + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/TouchScreen.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/TouchScreen.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/TouchScreen.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/TouchScreen.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,41 @@ + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/TouchScreenWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/TouchScreenWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/TouchScreenWhite.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/TouchScreenWhite.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Update.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Update.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Update.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Update.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,25 +1,12 @@ - - - - - - - - - - -]> - - - - - - - - - - - + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Upgrade.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Upgrade.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Upgrade.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Upgrade.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,12 @@ + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/UpgradeWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/UpgradeWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/UpgradeWhite.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/UpgradeWhite.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,24 @@ + + + + + + + + + + +]> + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Userinfo.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Userinfo.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Userinfo.svg 2020-06-11 05:29:25.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Userinfo.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1 +1,12 @@ -userinfo \ No newline at end of file + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Vino.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Vino.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Vino.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Vino.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,12 @@ + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/VinoWhite.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/VinoWhite.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/VinoWhite.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/VinoWhite.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file diff -Nru ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Vpn.svg ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Vpn.svg --- ukui-control-center-2.0.3/shell/res/secondaryleftmenu/Vpn.svg 2020-07-02 06:13:04.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/secondaryleftmenu/Vpn.svg 2021-04-14 01:27:20.000000000 +0000 @@ -1,34 +1,17 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - - - - - + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/res/titlebar/ukui-control-center.svg ukui-control-center-3.0.3/shell/res/titlebar/ukui-control-center.svg --- ukui-control-center-2.0.3/shell/res/titlebar/ukui-control-center.svg 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/res/titlebar/ukui-control-center.svg 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,35 @@ + + + +128 + + + + + + + + + + + + + + + + + + + diff -Nru ukui-control-center-2.0.3/shell/searchwidget.cpp ukui-control-center-3.0.3/shell/searchwidget.cpp --- ukui-control-center-2.0.3/shell/searchwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/searchwidget.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,544 @@ +#include "searchwidget.h" +#include "pinyin.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +} + +class ukCompleter : public QCompleter +{ +public: + ukCompleter(QAbstractItemModel *model, QObject *parent = nullptr) + : QCompleter(model, parent) + { + } + +public: + bool eventFilter(QObject *o, QEvent *e) override; +}; + +SearchWidget::SearchWidget(QWidget *parent) + : QLineEdit(parent) + , m_xmlExplain("") + , m_bIsChinese(false) + , m_searchValue("") + , m_bIstextEdited(false) +{ + initExcludeSearch(); + + m_model = new QStandardItemModel(this); + m_completer = new ukCompleter(m_model, this); + m_completer->popup()->setAttribute(Qt::WA_InputMethodEnabled); + m_completer->setFilterMode(Qt::MatchContains);//设置QCompleter支持匹配字符搜索 + m_completer->setCaseSensitivity(Qt::CaseInsensitive);//这个属性可设置进行匹配时的大小写敏感性 + m_completer->setCompletionRole(Qt::UserRole); //设置ItemDataRole + this->setCompleter(m_completer); + m_completer->setWrapAround(false); + m_completer->installEventFilter(this); + + connect(this, &QLineEdit::textEdited, this, [ = ] { + if (text() != "") { + m_bIstextEdited = true; + } else { + m_bIstextEdited = false; + } + }); + + connect(this, &QLineEdit::textChanged, this, [ = ] { + QString retValue = text(); + if (m_bIstextEdited) { + m_bIstextEdited = false; + return ; + } + + //避免输入单个字符,直接匹配到第一个完整字符(导致不能匹配正确的字符) + if ("" == retValue || m_searchValue.contains(retValue, Qt::CaseInsensitive)) { + m_searchValue = retValue; + return ; + } + + retValue = transPinyinToChinese(text()); + + //拼音转化没找到,再搜索字符包含关联字符 + if (retValue == text()) { + retValue = containTxtData(retValue); + } + + m_searchValue = retValue; + + this->setText(retValue); + }); + + connect(this, &QLineEdit::returnPressed, this, [ = ] { + + if (!text().isEmpty()) { + //enter defalt set first + if (!jumpContentPathWidget(text())) { + const QString ¤tCompletion = this->completer()->currentCompletion(); + qDebug() << Q_FUNC_INFO << " [SearchWidget] currentCompletion : " << currentCompletion; + + //中文遍历一遍,若没有匹配再遍历将拼音转化为中文再遍历 + //解决输入拼音时,有配置数据后,直接回车无法进入第一个匹配数据页面的问题 + if (!jumpContentPathWidget(currentCompletion)) { + jumpContentPathWidget(transPinyinToChinese(currentCompletion)); + } + } + } + }); +#if QT_VERSION <= QT_VERSION_CHECK(5, 12, 0) + connect(m_completer, static_cast(&QCompleter::activated), + [=](const QString &text) { +#else + //鼠标点击后直接页面跳转(https://doc.qt.io/qt-5/qcompleter.html#activated-1) + connect(m_completer, QOverload::of(&QCompleter::activated), + [=](const QString &text) { +#endif + Q_UNUSED(text); + Q_EMIT returnPressed(); + }); +} + +SearchWidget::~SearchWidget() { + +} + +bool SearchWidget::jumpContentPathWidget(QString path) { + qDebug() << Q_FUNC_INFO << path; + bool bResult = false; + + if (m_EnterNewPagelist.count() > 0) { + SearchBoxStruct data = getModuleBtnString(path); + if (data.translateContent != "" && data.fullPagePath != "") { + for (int i = 0; i < m_EnterNewPagelist.count(); i++) { + if (m_EnterNewPagelist[i].translateContent == data.fullPagePath) {//getModuleBtnString解析SearchBoxStruct.fullPagePath,满足此处判断 +#if DEBUG_XML_SWITCH + qDebug() << " [SearchWidget] m_EnterNewPagelist[i].translateContent : " << m_EnterNewPagelist[i].translateContent << " , fullPagePath : " << m_EnterNewPagelist[i].fullPagePath << " , actualModuleName: " << m_EnterNewPagelist[i].actualModuleName; + qDebug() << " [SearchWidget] data.translateContent : " << data.translateContent << " , data.fullPagePath : " << data.fullPagePath << " , data.actualModuleName: " << data.actualModuleName; +#endif + //the data.actualModuleName had translate to All lowercase + qDebug() <<" actulaModuleName is:" << data.translateContent << " " << m_EnterNewPagelist[i].fullPagePath << m_EnterNewPagelist[i].fullPagePath.section('/', 1, 1); + Q_EMIT notifyModuleSearch(data.translateContent, m_EnterNewPagelist[i].fullPagePath.section('/', 1, 1));//fullPagePath need delete moduleName + bResult = true; + break; + } + } + } else { + qWarning() << "[SearchWidget] translateContent : " << data.translateContent << " , fullPagePath : " << data.fullPagePath; + } + } else { + qWarning() << " [SearchWidget] QList is nullptr."; + } + + return bResult; +} + +void SearchWidget::loadxml() { + if (!m_EnterNewPagelist.isEmpty()) { + m_EnterNewPagelist.clear(); + } + + if (!m_inputList.isEmpty()) { + m_inputList.clear(); + } + + if (m_model->rowCount() > 0) { + QStandardItem *item = nullptr; + for (int i = 0; i < m_model->rowCount(); i++) { + item = m_model->takeItem(i); + delete item; + item = nullptr; + } + m_model->clear(); + } + + //添加一项空数据,为了防止使用setText输入错误数据时直接跳转到list中正确的第一个页面 + m_searchBoxStruct.fullPagePath = ""; + m_searchBoxStruct.actualModuleName = ""; + m_searchBoxStruct.translateContent = ""; + m_searchBoxStruct.childPageName = ""; + m_EnterNewPagelist.append(m_searchBoxStruct); + m_inputList.append(SearchDataStruct()); + m_model->appendRow(new QStandardItem("")); + + auto isChineseFunc = [](const QString &str)->bool { + QRegularExpression rex_expression(R"(^[^a-zA-Z]+$)"); + return rex_expression.match(str).hasMatch(); + }; + + + for (const QString i : m_xmlFilePath) { + + QString xmlPath = i.arg(m_lang); + QFile file(xmlPath); + + if (!file.exists()) { + qWarning() << " [SearchWidget] File not exist"; + continue; + } + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << " [SearchWidget] File open failed"; + continue; + } + + QXmlStreamReader xmlRead(&file); + QStringRef dataName; + QXmlStreamReader::TokenType type = QXmlStreamReader::Invalid; + + //遍历XML文件,读取每一行的xml数据都会 + //先进入StartElement读取出<>中的内容; + //再进入Characters读取出中间数据部分; + //最后进入时进入EndElement读取出中的内容 + while (!xmlRead.atEnd()) { + type = xmlRead.readNext(); + + switch (type) { + case QXmlStreamReader::StartElement: + m_xmlExplain = xmlRead.name().toString(); + break; + case QXmlStreamReader::Characters: + if (!xmlRead.isWhitespace()) { + if (m_xmlExplain == XML_Source) { // get xml source date + + m_searchBoxStruct.translateContent = xmlRead.text().toString(); + + } else if (m_xmlExplain == XML_Title) { + if (xmlRead.text().toString() != "") // translation not nullptr can set it + m_searchBoxStruct.translateContent = xmlRead.text().toString(); + } else if (m_xmlExplain == XML_Numerusform) { + if (xmlRead.text().toString() != "") // translation not nullptr can set it + m_searchBoxStruct.translateContent = xmlRead.text().toString(); + } else if (m_xmlExplain == XML_Explain_Path) { + m_searchBoxStruct.fullPagePath = xmlRead.text().toString(); + // follow path module name to get actual module name -> Left module dispaly can support + // mulLanguages + m_searchBoxStruct.actualModuleName = + getModulesName(m_searchBoxStruct.fullPagePath.section('/', 1, 1)); + + if (!isChineseFunc(m_searchBoxStruct.translateContent)) { + if (!m_TxtList.contains(m_searchBoxStruct.translateContent)) { + m_TxtList.append(m_searchBoxStruct.translateContent); + } + } + + if ((!g_file_test("/usr/sbin/ksc-defender", G_FILE_TEST_EXISTS) && m_searchBoxStruct.fullPagePath.contains("securitycenter",Qt::CaseInsensitive)) + || (!MainWindow::isExitBluetooth() && m_searchBoxStruct.fullPagePath.contains("bluetooth",Qt::CaseInsensitive)) + || (!Utils::isCommunity() && m_searchBoxStruct.fullPagePath.contains("update")) ) { + break; + } + m_EnterNewPagelist.append(m_searchBoxStruct); + + // Add search result content + if (!m_bIsChinese && mEnExclude.contains(m_searchBoxStruct.translateContent, Qt::CaseInsensitive)) { + if ("" == m_searchBoxStruct.childPageName) { + m_model->appendRow(new QStandardItem( + QString("%1 --> %2") + .arg(m_searchBoxStruct.actualModuleName) + .arg(m_searchBoxStruct.translateContent))); + } else { + m_model->appendRow(new QStandardItem( + QString("%1 --> %2 / %3") + .arg(m_searchBoxStruct.actualModuleName) + .arg(m_searchBoxStruct.childPageName) + .arg(m_searchBoxStruct.translateContent))); + } + } else { + if (!mCnExclude.contains(m_searchBoxStruct.translateContent, Qt::CaseInsensitive)) { + appendChineseData(m_searchBoxStruct); + } + } + clearSearchData(); + } else { + // donthing + } + } else { + // qDebug() << " QXmlStreamReader::Characters with whitespaces."; + } + break; + case QXmlStreamReader::EndElement: +#if DEBUG_XML_SWITCH + qDebug() << " [SearchWidget] -::EndElement: " << xmlRead.name(); +#endif + // if (m_xmlExplain != "") { + // m_xmlExplain = ""; + // } + break; + default: + break; + } + } + + m_xmlExplain = ""; + clearSearchData(); + qDebug() << " [SearchWidget] m_EnterNewPagelist.count : " << m_EnterNewPagelist.count(); + + file.close(); + } +} + +//Follow display content to Analysis SearchBoxStruct data +SearchWidget::SearchBoxStruct SearchWidget::getModuleBtnString(QString value) { + SearchBoxStruct data; + + data.translateContent = value.section('-', 0, 1).remove('-').trimmed(); + //follow actual module name to get path module name + data.actualModuleName = getModulesName(data.translateContent, false); + data.fullPagePath = value.section('>', 1, -1).remove('>').trimmed(); + + if (data.fullPagePath.contains('/', Qt::CaseInsensitive)) { + data.fullPagePath = data.fullPagePath.section('/', 0, 0).remove('/').trimmed(); + } + +#if DEBUG_XML_SWITCH + qDebug() << Q_FUNC_INFO << " [SearchWidget] data.translateContent : " << data.translateContent << " , data.fullPagePath : " << data.fullPagePath; +#endif + + return data; +} + +//tranlate the path name to tr("name") +QString SearchWidget::getModulesName(QString name, bool state) { + QString strResult = ""; + + for (auto it : m_moduleNameList) { + if (state) { //true : follow first search second (use pathName translate to actual moduleName) + if (it.first == name) { + strResult = it.second; + break; + } + } else { //false : follow second search first (use actual moduleName translate to pathName) + if (it.second == name) { + strResult = it.first; + break; + } + } + } + + return strResult; +} + +QString SearchWidget::removeDigital(QString input) { + if ("" == input) + return ""; + + QString value = ""; + QByteArray ba = input.toLocal8Bit(); + char *data = nullptr; + data = ba.data(); + while (*data) { + if (!(*data >= '0' && *data <= '9')) { + value += *data; + } + data++; + } + + return value; +} + +QString SearchWidget::transPinyinToChinese(QString pinyin) { + QString value = pinyin; + + //遍历"汉字-拼音"列表,将存在的"拼音"转换为"汉字" + for (auto data : m_inputList) { + if (value == data.pinyin) { + value = data.chiese; + break; + } + } + + return value; +} + +QString SearchWidget::containTxtData(QString txt) { + QString value = txt; + + //遍历"汉字-拼音"列表,将存在的"拼音"转换为"汉字" + for (auto data : m_inputList) { + if (data.chiese.contains(txt, Qt::CaseInsensitive) || + data.pinyin.contains(txt, Qt::CaseInsensitive)) { + value = data.chiese; + break; + } + } + + return value; +} + +void SearchWidget::appendChineseData(SearchWidget::SearchBoxStruct data) { + if ("" == data.childPageName) { + //先添加使用appenRow添加Qt::EditRole数据(用于下拉框显示),然后添加Qt::UserRole数据(用于输入框搜索) + //Qt::EditRole数据用于显示搜索到的结果(汉字) + //Qt::UserRole数据用于输入框输入的数据(拼音/汉字 均可) + //即在输入框搜索Qt::UserRole的数据,就会在下拉框显示Qt::EditRole的数据 + m_model->appendRow(new QStandardItem(//icon.value(), + QString("%1 --> %2").arg(data.actualModuleName).arg(data.translateContent))); + + //设置汉字的Qt::UserRole数据 + m_model->setData(m_model->index(m_model->rowCount() - 1, 0), + QString("%1 --> %2") + .arg(data.actualModuleName) + .arg(data.translateContent), + Qt::UserRole); + + QString hanziTxt = QString("%1 --> %2").arg(data.actualModuleName).arg(data.translateContent); + + for (auto datas : m_TxtList) { + for (int i = 0; i < datas.count(); i++) { + if( data.translateContent == datas){ + return; + } + } + } + + QString pinyinTxt = QString("%1 --> %2") + .arg(removeDigital(Chinese2Pinyin(data.actualModuleName))) + .arg(removeDigital(Chinese2Pinyin(data.translateContent))); + + //添加显示的汉字(用于拼音搜索显示) + m_model->appendRow(new QStandardItem(/*icon.value(),*/ hanziTxt)); + //设置Qt::UserRole搜索的拼音(即搜索拼音会显示上面的汉字) + m_model->setData(m_model->index(m_model->rowCount() - 1, 0), pinyinTxt, Qt::UserRole); + + SearchDataStruct transdata; + transdata.chiese = hanziTxt; + transdata.pinyin = pinyinTxt; + //存储 汉字和拼音 : 在选择对应的下拉框数据后,会将Qt::UserRole数据设置到输入框(即pinyin) + //而在输入框发送 DSearchEdit::textChanged 信号时,会遍历m_inputList,根据pinyin获取到对应汉字,再将汉字设置到输入框 + m_inputList.append(transdata); + } else { + //先添加使用appenRow添加Qt::EditRole数据(用于下拉框显示),然后添加Qt::UserRole数据(用于输入框搜索) + //Qt::EditRole数据用于显示搜索到的结果(汉字) + //Qt::UserRole数据用于输入框输入的数据(拼音/汉字 均可) + //即在输入框搜索Qt::UserRole的数据,就会在下拉框显示Qt::EditRole的数据 + m_model->appendRow(new QStandardItem(//icon.value(), + QString("%1 --> %2 / %3").arg(data.actualModuleName).arg(data.childPageName).arg(data.translateContent))); + + //设置汉字的Qt::UserRole数据 + m_model->setData(m_model->index(m_model->rowCount() - 1, 0), + QString("%1 --> %2 / %3") + .arg(data.actualModuleName) + .arg(data.childPageName) + .arg(data.translateContent), + Qt::UserRole); + + QString hanziTxt = QString("%1 --> %2 / %3").arg(data.actualModuleName).arg(data.childPageName).arg(data.translateContent); + QString pinyinTxt = QString("%1 --> %2 / %3") + .arg(removeDigital(Chinese2Pinyin(data.actualModuleName))) + .arg(removeDigital(Chinese2Pinyin(data.childPageName))) + .arg(removeDigital(Chinese2Pinyin(data.translateContent))); + + m_model->appendRow(new QStandardItem(/*icon.value(),*/ hanziTxt)); + //设置Qt::UserRole搜索的拼音(即搜索拼音会显示上面的汉字) + m_model->setData(m_model->index(m_model->rowCount() - 1, 0), pinyinTxt, Qt::UserRole); + + SearchDataStruct transdata; + transdata.chiese = hanziTxt; + transdata.pinyin = pinyinTxt; + //存储 汉字和拼音 : 在选择对应的下拉框数据后,会将Qt::UserRole数据设置到输入框(即pinyin) + //而在输入框发送 DSearchEdit::textChanged 信号时,会遍历m_inputList,根据pinyin获取到对应汉字,再将汉字设置到输入框 + m_inputList.append(transdata); + } +} + +void SearchWidget::clearSearchData() { + m_searchBoxStruct.translateContent = ""; + m_searchBoxStruct.actualModuleName = ""; + m_searchBoxStruct.childPageName = ""; + m_searchBoxStruct.fullPagePath = ""; +} + +void SearchWidget::initExcludeSearch() { + if (!Utils::isExistEffect()) { + mCnExclude << "特效模式" << "透明度"; + mEnExclude << "Performance mode" << "Transparency"; + } + + if (Utils::isWayland() || !Utils::isExistEffect()) { + mCnExclude << "夜间模式"; + mEnExclude << "night mode"; + } +} + +void SearchWidget::setLanguage(QString type) { + m_lang = type; + + if (type == "zh_CN" || type == "zh_HK" || type == "zh_TW") { + m_bIsChinese = true; + m_completer->setCompletionRole(Qt::UserRole); //设置ItemDataRole + } else { + m_completer->setCompletionRole(Qt::DisplayRole); + } + + loadxml(); +} + +//save all modules moduleInteface name and actual moduleName +//moduleName : moduleInteface name (used to path module to translate searchName) +//searchName : actual module +void SearchWidget::addModulesName(QString moduleName, QString searchName, QString translation) { + QPair data; + data.first = moduleName; + data.second = searchName; + m_moduleNameList.append(data); + + if (!translation.isEmpty()) { + m_xmlFilePath.insert(translation); + } + +} + +void SearchWidget::onCompleterActivated(QString value) { + qDebug() << Q_FUNC_INFO << value; + Q_EMIT returnPressed(); +} + +bool ukCompleter::eventFilter(QObject *o, QEvent *e) { + if (e->type() == QEvent::FocusOut) { + return QCompleter::eventFilter(o, e); + } + + if (e->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(e); + QModelIndex keyIndex; + switch (ke->key()) { + case Qt::Key_Up: { + if (popup()->currentIndex().row() == 0) { + keyIndex = popup()->model()->index(popup()->model()->rowCount() - 1, 0); + popup()->setCurrentIndex(keyIndex); + } else { + keyIndex = popup()->model()->index(popup()->currentIndex().row() - 1, 0); + popup()->setCurrentIndex(keyIndex); + } + return true; + } + case Qt::Key_Down: { + if (popup()->currentIndex().row() == popup()->model()->rowCount() - 1) { + keyIndex = popup()->model()->index(0, 0); + popup()->setCurrentIndex(keyIndex); + } else { + keyIndex = popup()->model()->index(popup()->currentIndex().row() + 1, 0); + popup()->setCurrentIndex(keyIndex); + } + return true; + } + case Qt::Key_Enter: { + if (popup()->isVisible() && !popup()->currentIndex().isValid()) { + keyIndex = popup()->model()->index(0, 0); + popup()->setCurrentIndex(keyIndex); + } + popup()->hide(); + } + } + } + return QCompleter::eventFilter(o, e); +} diff -Nru ukui-control-center-2.0.3/shell/searchwidget.h ukui-control-center-3.0.3/shell/searchwidget.h --- ukui-control-center-2.0.3/shell/searchwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/searchwidget.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,85 @@ +#ifndef SEARCHWIDGET_H +#define SEARCHWIDGET_H + +#include "../utils/utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const QString XML_Source = "source"; +const QString XML_Title = "translation"; +const QString XML_Numerusform = "numerusform"; +const QString XML_Explain_Path = "extra-contents_path"; + +class SearchWidget : public QLineEdit +{ + Q_OBJECT +public: + struct SearchBoxStruct { + QString translateContent; + QString actualModuleName; + QString childPageName; + QString fullPagePath; + }; + + struct SearchDataStruct { + QString chiese; + QString pinyin; + }; + +public: + SearchWidget(QWidget *parent = nullptr); + ~SearchWidget() override; + + bool jumpContentPathWidget(QString path); + void setLanguage(QString type); + void addModulesName(QString moduleName, QString searchName, QString translation = ""); + +private Q_SLOTS: + void onCompleterActivated(QString value); + +Q_SIGNALS: + void notifyModuleSearch(QString, QString); + +private: + void loadxml(); + SearchBoxStruct getModuleBtnString(QString value); + QString getModulesName(QString name, bool state = true); + QString removeDigital(QString input); + QString transPinyinToChinese(QString pinyin); + QString containTxtData(QString txt); + void appendChineseData(SearchBoxStruct data); + void clearSearchData(); + + void initExcludeSearch(); + +private: + QStandardItemModel *m_model; + QCompleter *m_completer; + QList m_EnterNewPagelist; + SearchBoxStruct m_searchBoxStruct; + QString m_xmlExplain; + QSet m_xmlFilePath; + QString m_lang; + QList> m_moduleNameList;//用于存储如 "update"和"Update" + QList m_inputList; + bool m_bIsChinese; + QString m_searchValue; + bool m_bIstextEdited; + QStringList m_defaultRemoveableList;//存储已知全部模块是否存在 + QList m_TxtList; + + QStringList mCnExclude; + QStringList mEnExclude; +}; +#endif // SEARCHWIDGET_H diff -Nru ukui-control-center-2.0.3/shell/shell.pro ukui-control-center-3.0.3/shell/shell.pro --- ukui-control-center-2.0.3/shell/shell.pro 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/shell/shell.pro 2021-05-20 13:08:14.000000000 +0000 @@ -4,9 +4,9 @@ # #------------------------------------------------- -QT += core gui network x11extras svg +QT += core gui network x11extras svg xml dbus -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets quickwidgets TARGET = ukui-control-center DESTDIR = .. @@ -17,10 +17,12 @@ #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 include(../env.pri) +include($$PROJECT_COMPONENTSOURCE/imageutil.pri) DEFINES += PLUGIN_INSTALL_DIRS='\\"$${PLUGIN_INSTALL_DIRS}\\"' -LIBS += -L$$[QT_INSTALL_LIBS] -lX11 -lgsettings-qt + +LIBS += -L$$[QT_INSTALL_LIBS] -lX11 -lgsettings-qt -lXi #LIBS += -L$$[QT_INSTALL_LIBS] -lkylinssoclient @@ -29,8 +31,8 @@ C++11 PKGCONFIG += gio-2.0 \ gio-unix-2.0 \ - libmatemixer \ gsettings-qt \ + libmatemixer desktop.files += ukui-control-center.desktop desktop.path = /usr/share/applications @@ -44,20 +46,39 @@ mo.files += $$PROJECT_ROOTDIR/data/installer-timezones.mo mo.path = /usr/share/locale/zh_CN/LC_MESSAGES/ +contains(QMAKE_HOST.arch, sw_64){ + guideCN.files += $$PROJECT_ROOTDIR/data/zh_CN_SW/zh_CN/ + guideCN.path += /usr/share/kylin-user-guide/data/guide/ukui-control-center/ +}else{ + guideCN.files += $$PROJECT_ROOTDIR/data/zh_CN/ + guideCN.path += /usr/share/kylin-user-guide/data/guide/ukui-control-center/ +} + +guideEN.files += $$PROJECT_ROOTDIR/data/en_US/ +guideEN.path += /usr/share/kylin-user-guide/data/guide/ukui-control-center/ + +imageformats.files += $$PROJECT_ROOTDIR/data/ukui-control-center.png +imageformats.path = /usr/share/kylin-user-guide/data/guide/ukui-control-center/ + target.source += $$TARGET target.path = /usr/bin + INSTALLS += \ - target \ + target \ desktop \ schemes \ - face \ - mo + face \ + mo \ + guideCN \ + imageformats \ + guideEN \ INCLUDEPATH += qtsingleapplication DEPENDPATH += qtsingleapplication SOURCES += \ + component/leftmenulist.cpp \ customstyle.cpp \ main.cpp \ mainwindow.cpp \ @@ -66,16 +87,25 @@ framelessExtended/widgethandlerealize.cpp \ homepagewidget.cpp \ modulepagewidget.cpp \ + pinyin.cpp \ + prescene.cpp \ + searchwidget.cpp \ + ukccabout.cpp \ + utils/devicesmonitor.cpp \ utils/keyvalueconverter.cpp \ component/leftwidgetitem.cpp \ component/clicklabel.cpp \ utils/functionselect.cpp \ component/hoverwidget.cpp \ qtsingleapplication/qtsingleapplication.cpp \ - qtsingleapplication/qtlocalpeer.cpp + qtsingleapplication/qtlocalpeer.cpp \ + utils/utils.cpp \ + utils/xatom-helper.cpp HEADERS += \ + component/leftmenulist.h \ customstyle.h \ + devicesmonitor.h \ mainwindow.h \ interface.h \ framelessExtended/cursorposcalculator.h \ @@ -84,6 +114,10 @@ framelessExtended/widgethandlerealize.h \ homepagewidget.h \ modulepagewidget.h \ + pinyin.h \ + prescene.h \ + searchwidget.h \ + ukccabout.h \ utils/keyvalueconverter.h \ component/leftwidgetitem.h \ component/clicklabel.h \ @@ -91,7 +125,9 @@ component/hoverwidget.h \ qtsingleapplication/qtsingleapplication_copy.h \ qtsingleapplication/qtsingleapplication.h \ - qtsingleapplication/qtlocalpeer.h + qtsingleapplication/qtlocalpeer.h \ + utils/utils.h \ + utils/xatom-helper.h FORMS += \ mainwindow.ui \ @@ -105,4 +141,6 @@ ../data/installer-timezones.mo \ ../data/org.ukui.control-center.panel.plugins.gschema.xml \ ../data/org.ukui.control-center.personalise.gschema.xml \ - ../data/org.ukui.control-center.wifi.switch.gschema.xml + ../data/org.ukui.control-center.wifi.switch.gschema.xml \ + ../data/org.ukui.control-center.vino.xml \ + res/search.xml diff -Nru ukui-control-center-2.0.3/shell/ukccabout.cpp ukui-control-center-3.0.3/shell/ukccabout.cpp --- ukui-control-center-2.0.3/shell/ukccabout.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/ukccabout.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,172 @@ +/* -*- 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 "ukccabout.h" +#include "../utils/xatom-helper.h" + +#include +#include +#include + +UkccAbout::UkccAbout(QWidget *parent) + : QDialog(parent) { + + setFixedSize(420, 560); + + XAtomHelper::getInstance()->setUKUIDecoraiontHint(this->winId(), true); + MotifWmHints hints; + hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS; + hints.functions = MWM_FUNC_ALL; + hints.decorations = MWM_DECOR_BORDER; + XAtomHelper::getInstance()->setWindowMotifHint(this->winId(), hints); + initUI(); + initConnection(); +} + +void UkccAbout::initUI() { + + mMainVLayout = new QVBoxLayout(); + mTitleLayout = new QHBoxLayout(); + mCenterIconLayout = new QHBoxLayout(); + mCenterTitleLayout = new QHBoxLayout(); + mCenterVersionLayout = new QHBoxLayout(); + mUkccDetailLayout = new QHBoxLayout(); + mUkccDeveloperLayout = new QHBoxLayout(); + + mMainVLayout->setContentsMargins(8, 4, 4, 4); + mTitleLayout->setSpacing(0); + + QIcon titleIcon = QIcon::fromTheme("ukui-control-center"); + + mUkccIcon = new QLabel(); + mUkccIcon->setPixmap(titleIcon.pixmap(titleIcon.actualSize(QSize(24, 24)))); + + mUkccTitle = new QLabel(tr("Settings")); + + mUkccCloseBtn = new QPushButton(); + mUkccCloseBtn->setIcon(QIcon::fromTheme("window-close-symbolic")); + mUkccCloseBtn->setProperty("isWindowButton", 0x02); + mUkccCloseBtn->setProperty("useIconHighlightEffect", 0x08); + mUkccCloseBtn->setFlat(true); + mUkccCloseBtn->setFixedSize(30, 30); + + mTitleLayout->addWidget(mUkccIcon); + mTitleLayout->addSpacing(8); + mTitleLayout->addWidget(mUkccTitle); + mTitleLayout->addStretch(); + mTitleLayout->addWidget(mUkccCloseBtn); + + mUkccCenterIcon = new QLabel(); + mUkccCenterIcon->setPixmap(titleIcon.pixmap(titleIcon.actualSize(QSize(96, 96)))); + + mCenterIconLayout->addStretch(); + mCenterIconLayout->addWidget(mUkccCenterIcon); + mCenterIconLayout->addStretch(); + + mUkccCenterTitle = new QLabel(tr("Settings")); + mUkccCenterTitle->setFixedHeight(28); + + mCenterTitleLayout->addStretch(); + mCenterTitleLayout->addWidget(mUkccCenterTitle); + mCenterTitleLayout->addStretch(); + + mUkccVersion = new QLabel(tr("Version: ") + getUkccVersion()); + mUkccVersion->setFixedHeight(24); + + mCenterVersionLayout->addStretch(); + mCenterVersionLayout->addWidget(mUkccVersion); + mCenterVersionLayout->addStretch(); + + mUkccDetail = new QTextEdit(tr("The control panel provides a friendly graphical user interface to manage common configuration items of the operating system. " + "System configuration provides system, equipment, personalization, network, account, time and date, account, time and date, update, notification and operation module operations. ")); + + mUkccDetail->setReadOnly(true); + mUkccDetailLayout->addSpacing(32); + mUkccDetailLayout->addWidget(mUkccDetail); + mUkccDetailLayout->addSpacing(32); + + mUkccDeveloper = new QLabel(tr("Service and Support:")); + + mUkccDeveloperLayout->addSpacing(32); + mUkccDeveloperLayout->addWidget(mUkccDeveloper); + + mUkccDeveloperEmailBtn = new QPushButton("support@kylinos.cn"); + mUkccDeveloperEmailBtn->setFocusPolicy(Qt::NoFocus); + mUkccDeveloperEmailBtn->setContentsMargins(0,0,0,0); + mUkccDeveloperEmailBtn->setCursor( QCursor(Qt::PointingHandCursor)); + mUkccDeveloperEmailBtn->setStyleSheet("QPushButton{background: transparent;border-radius: 4px;text-decoration: underline;} "); + + mUkccDeveloperLayout->addWidget(mUkccDeveloperEmailBtn); + mUkccDeveloperLayout->setAlignment(Qt::AlignLeft); + connect(mUkccDeveloperEmailBtn, &QPushButton::clicked, this,[=] { + QDesktopServices::openUrl(QUrl(QLatin1String("mailto:support@kylinos.cn"))); + }); + + mMainVLayout->addLayout(mTitleLayout); + mMainVLayout->addSpacing(42); + mMainVLayout->addLayout(mCenterIconLayout); + mMainVLayout->addSpacing(16); + mMainVLayout->addLayout(mCenterTitleLayout); + mMainVLayout->addSpacing(12); + mMainVLayout->addLayout(mCenterVersionLayout); + mMainVLayout->addSpacing(12); + mMainVLayout->addLayout(mUkccDetailLayout); + mMainVLayout->addSpacing(24); + mMainVLayout->addLayout(mUkccDeveloperLayout); + mMainVLayout->addSpacing(40); + + this->setLayout(mMainVLayout); +} + +void UkccAbout::initConnection() { + connect(mUkccCloseBtn, &QPushButton::clicked, this, [=]() { + this->close(); + }); +} + +QString UkccAbout::getUkccVersion() { + FILE *pp = NULL; + char *line = NULL; + size_t len = 0; + ssize_t read; + char *q = NULL; + QString version = "none"; + + pp = popen("dpkg -l ukui-control-center | grep ukui-control-center", "r"); + if(NULL == pp) + return version; + + while((read = getline(&line, &len, pp)) != -1){ + q = strrchr(line, '\n'); + *q = '\0'; + + QString content = line; + QStringList list = content.split(" "); + + list.removeAll(""); + + if (list.size() >= 3) + version = list.at(2); + } + + free(line); + line = NULL; + pclose(pp); + return version; +} diff -Nru ukui-control-center-2.0.3/shell/ukccabout.h ukui-control-center-3.0.3/shell/ukccabout.h --- ukui-control-center-2.0.3/shell/ukccabout.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/ukccabout.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,67 @@ +/* -*- 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 UKCCABOUT_H +#define UKCCABOUT_H + +#include +#include +#include +#include +#include +#include +#include + +class UkccAbout : public QDialog +{ + Q_OBJECT +public: + explicit UkccAbout(QWidget *parent = nullptr); + +private: + QLabel *mUkccIcon; + QLabel *mUkccTitle; + QPushButton *mUkccCloseBtn; + + QLabel *mUkccCenterIcon; + QLabel *mUkccCenterTitle; + QLabel *mUkccVersion; + QLabel *mUkccDeveloper; + QPushButton *mUkccDeveloperEmailBtn; + + QTextEdit *mUkccDetail; + + QHBoxLayout *mCenterIconLayout; + QHBoxLayout *mCenterTitleLayout; + QHBoxLayout *mCenterVersionLayout; + QHBoxLayout *mUkccDetailLayout; + QHBoxLayout *mUkccDeveloperLayout; + QHBoxLayout *mTitleLayout; + QVBoxLayout *mMainVLayout; + +private: + void initUI(); + void initConnection(); + QString getUkccVersion(); + +signals: + +}; + +#endif // UKCCABOUT_H diff -Nru ukui-control-center-2.0.3/shell/ukui-control-center.desktop ukui-control-center-3.0.3/shell/ukui-control-center.desktop --- ukui-control-center-2.0.3/shell/ukui-control-center.desktop 2020-07-13 05:36:57.000000000 +0000 +++ ukui-control-center-3.0.3/shell/ukui-control-center.desktop 2021-04-14 01:27:20.000000000 +0000 @@ -1,8 +1,8 @@ [Desktop Entry] -Name=UKUI Control Center -Name[zh_CN]=控制面板 -Name[zh_HK]=控制面板 -Name[zh_TW]=控制面板 +Name=Settings +Name[zh_CN]=设置 +Name[zh_HK]=设置 +Name[zh_TW]=设置 Name[tr]=Denetim Merkezi Comment=UKUI控制面板 Comment[tr]=UKUI Kontrol Merkezi diff -Nru ukui-control-center-2.0.3/shell/utils/devicesmonitor.cpp ukui-control-center-3.0.3/shell/utils/devicesmonitor.cpp --- ukui-control-center-2.0.3/shell/utils/devicesmonitor.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/utils/devicesmonitor.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +bool isExitTouchScreen(){ + + int ndevices = 0; + bool retval=false; + + Display *dpy = XOpenDisplay(NULL); + XIDeviceInfo *info = XIQueryDevice(dpy, XIAllDevices, &ndevices); + + for (int i = 0; i < ndevices; i++) + { + XIDeviceInfo* dev = &info[i]; + // 判断当前设备是不是触摸屏 + if(dev->use != XISlavePointer) continue; + if(!dev->enabled) continue; + for (int j = 0; j < dev->num_classes; j++) + { + if (dev->classes[j]->type == XITouchClass) + { + retval = true; + } + } + } + + XIFreeDeviceInfo(info); + XCloseDisplay(dpy); + + return retval; +} diff -Nru ukui-control-center-2.0.3/shell/utils/functionselect.cpp ukui-control-center-3.0.3/shell/utils/functionselect.cpp --- ukui-control-center-2.0.3/shell/utils/functionselect.cpp 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/shell/utils/functionselect.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -49,13 +49,15 @@ } systemList[DISPLAY].nameString = QString("Display"); systemList[DISPLAY].namei18nString = QObject::tr("Display"); + systemList[TOUCHSCREEN].nameString = QString("TouchScreen"); + systemList[TOUCHSCREEN].namei18nString = QObject::tr("TouchScreen"); systemList[DEFAULTAPP].nameString = QString("Defaultapp"); - systemList[DEFAULTAPP].namei18nString = QObject::tr("Defaultapp"); + systemList[DEFAULTAPP].namei18nString = QObject::tr("Default App"); systemList[DEFAULTAPP].mainShow = false; systemList[POWER].nameString = QString("Power"); systemList[POWER].namei18nString = QObject::tr("Power"); systemList[AUTOBOOT].nameString = QString("Autoboot"); - systemList[AUTOBOOT].namei18nString = QObject::tr("Autoboot"); + systemList[AUTOBOOT].namei18nString = QObject::tr("Auto Boot"); funcinfoList.append(systemList); @@ -83,6 +85,9 @@ devicesList[AUDIO].nameString = QString("Audio"); devicesList[AUDIO].namei18nString = QObject::tr("Audio"); devicesList[AUDIO].mainShow = false; + devicesList[BLUETOOTH].nameString = QString("Bluetooth"); + devicesList[BLUETOOTH].namei18nString = QObject::tr("Bluetooth"); + devicesList[BLUETOOTH].mainShow = false; funcinfoList.append(devicesList); @@ -122,11 +127,14 @@ networkList.append(funcStruct); } networkList[NETCONNECT].nameString = QString("Netconnect"); - networkList[NETCONNECT].namei18nString = QObject::tr("Netconnect"); + networkList[NETCONNECT].namei18nString = QObject::tr("Connect"); networkList[VPN].nameString = QString("Vpn"); networkList[VPN].namei18nString = QObject::tr("Vpn"); networkList[PROXY].nameString = QString("Proxy"); networkList[PROXY].namei18nString = QObject::tr("Proxy"); + networkList[VINO].nameString = QString("Vino"); + networkList[VINO].namei18nString = QObject::tr("Vino"); + networkList[VINO].mainShow = false; funcinfoList.append(networkList); @@ -141,9 +149,9 @@ } accountList[USERINFO].nameString = QString("Userinfo"); - accountList[USERINFO].namei18nString = QObject::tr("Userinfo"); - accountList[NETWORKACCOUNT].nameString = QString("NetworkAccount"); - accountList[NETWORKACCOUNT].namei18nString = QObject::tr("NetworkAccount"); + accountList[USERINFO].namei18nString = QObject::tr("User Info"); + accountList[NETWORKACCOUNT].nameString = QString("Cloud Account"); + accountList[NETWORKACCOUNT].namei18nString = QObject::tr("Cloud Account"); funcinfoList.append(accountList); @@ -157,8 +165,8 @@ datetimeList.append(funcStruct); } - datetimeList[DAT].nameString = QString("Datetime"); - datetimeList[DAT].namei18nString = QObject::tr("Datetime"); + datetimeList[DAT].nameString = QString("Date"); + datetimeList[DAT].namei18nString = QObject::tr("Date"); datetimeList[AREA].nameString = QString("Area"); datetimeList[AREA].namei18nString = QObject::tr("Area"); @@ -175,11 +183,13 @@ } seupdatesList[SECURITYCENTER].nameString = QString("SecurityCenter"); - seupdatesList[SECURITYCENTER].namei18nString = QObject::tr("SecurityCenter"); - seupdatesList[UPDATES].nameString = QString("Update"); - seupdatesList[UPDATES].namei18nString = QObject::tr("Update"); + seupdatesList[SECURITYCENTER].namei18nString = QObject::tr("Security Center"); seupdatesList[BACKUP].nameString = QString("Backup"); seupdatesList[BACKUP].namei18nString = QObject::tr("Backup"); + seupdatesList[UPDATES].nameString = QString("Update"); + seupdatesList[UPDATES].namei18nString = QObject::tr("Update"); + seupdatesList[UPGRADE].nameString = QString("Upgrade"); + seupdatesList[UPGRADE].namei18nString = QObject::tr("Upgrade"); funcinfoList.append(seupdatesList); @@ -195,6 +205,8 @@ natList[NOTICE].nameString = QString("Notice"); natList[NOTICE].namei18nString = QObject::tr("Notice"); + natList[SEARCH].nameString = QString("Search"); + natList[SEARCH].namei18nString = QObject::tr("Search"); natList[ABOUT].nameString = QString("About"); natList[ABOUT].namei18nString = QObject::tr("About"); natList[EXPERIENCEPLAN].nameString = QString("Experienceplan"); @@ -215,6 +227,8 @@ } } -void FunctionSelect::popRecordValue(){ - recordFuncStack.pop(); +void FunctionSelect::popRecordValue() { + if (!recordFuncStack.isEmpty()) { + recordFuncStack.pop(); + } } diff -Nru ukui-control-center-2.0.3/shell/utils/utils.cpp ukui-control-center-3.0.3/shell/utils/utils.cpp --- ukui-control-center-2.0.3/shell/utils/utils.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/utils/utils.cpp 2021-05-20 13:08:14.000000000 +0000 @@ -0,0 +1,268 @@ +/* -*- 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 "utils.h" + +#include +#include +#include + +#ifdef WITHKYSEC +#include +#include +#endif + +void Utils::centerToScreen(QWidget* widget) { + if (!widget) + return; + QDesktopWidget* m = QApplication::desktop(); + QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos())); + int desk_x = desk_rect.width(); + int desk_y = desk_rect.height(); + int x = widget->width(); + int y = widget->height(); + widget->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top()); +} + +void Utils::setCLIName(QCommandLineParser &parser) { + + QCommandLineOption monitorRoleOption(QStringList() << "m" << "display", QObject::tr("Go to monitor settings page")); + QCommandLineOption defaultRoleOption("defaultapp", QObject::tr("Go to defaultapp settings page")); + QCommandLineOption powerRoleOption(QStringList() << "p" << "power", QObject::tr("Go to power settings page")); + QCommandLineOption autobootRoleOption("autoboot", QObject::tr("Go to autoboot settings page")); + + QCommandLineOption printerRoleOption("printer", QObject::tr("Go to printer settings page")); + QCommandLineOption mouseRoleOption("mouse", QObject::tr("Go to mouse settings page")); + QCommandLineOption touchpadRoleOption("touchpad", QObject::tr("Go to touchpad settings page")); +// QCommandLineOption keyboardRoleOption("keyboard", QObject::tr("Go to keyboard settings page")); + QCommandLineOption keyboardRoleOption(QStringList() << "k" << "keyboard", QObject::tr("Go to keyboard settings page")); + QCommandLineOption shortcutRoleOption("shortcut", QObject::tr("Go to shortcut settings page")); + QCommandLineOption audioRoleOption(QStringList() << "s" << "audio", QObject::tr("Go to audio settings page")); + QCommandLineOption blutetoothRoleOption("bluetooth", QObject::tr("Go to bluetooth settings page")); + + QCommandLineOption backgroundRoleOption(QStringList() << "b" << "background", QObject::tr("Go to background settings page")); + QCommandLineOption themeRoleOption("theme", QObject::tr("Go to theme settings page")); + QCommandLineOption screenlockRoleOption("screenlock", QObject::tr("Go to screenlock settings page")); + QCommandLineOption screensaverRoleOption("screensaver", QObject::tr("Go to screensaver settings page")); + QCommandLineOption fontsRoleOption("fonts", QObject::tr("Go to fonts settings page")); + QCommandLineOption desktopRoleOption(QStringList() << "d" << "desktop", QObject::tr("Go to desktop settings page")); + + QCommandLineOption netconnectRoleOption("netconnect", QObject::tr("Go to netconnect settings page")); + QCommandLineOption vpnRoleOption(QStringList() << "g" << "vpn", QObject::tr("Go to vpn settings page")); + QCommandLineOption proxyRoleOption("proxy", QObject::tr("Go to proxy settings page")); + + QCommandLineOption userinfoRoleOption(QStringList() << "u" << "userinfo", QObject::tr("Go to userinfo settings page")); + QCommandLineOption cloudaccountRoleOption("cloudaccount", QObject::tr("Go to cloudaccount settings page")); + + QCommandLineOption datetimeRoleOption(QStringList() << "t" << "datetime", QObject::tr("Go to datetime settings page")); + QCommandLineOption areaRoleOption("area", QObject::tr("Go to area settings page")); + + QCommandLineOption updateRoleOption("update", QObject::tr("Go to update settings page")); + QCommandLineOption backupRoleOption("backup", QObject::tr("Go to backup settings page")); + QCommandLineOption upgradeRoleOption("upgrade", QObject::tr("Go to upgrade settings page")); + + QCommandLineOption noticeRoleOption(QStringList() << "n" << "notice", QObject::tr("Go to notice settings page")); + QCommandLineOption aboutRoleOption(QStringList() << "a" << "about", QObject::tr("Go to about settings page")); + QCommandLineOption searchRoleOption("search", QObject::tr("Go to search settings page")); + + parser.addHelpOption(); + parser.addVersionOption(); + + //三权分立开启 +#ifdef WITHKYSEC + if (!kysec_is_disabled() && kysec_get_3adm_status()){ + if (!getuid() || !geteuid()){ + //时间和日期 | 用户账户 | 电源管理 |网络连接 |网络代理|更新 + parser.addOption(powerRoleOption); + parser.addOption(netconnectRoleOption); + parser.addOption(vpnRoleOption); + parser.addOption(proxyRoleOption); + parser.addOption(userinfoRoleOption); + parser.addOption(datetimeRoleOption); + parser.addOption(updateRoleOption); + parser.addOption(upgradeRoleOption); + parser.addOption(backupRoleOption); + } + + } else { + parser.addOption(powerRoleOption); + parser.addOption(netconnectRoleOption); + parser.addOption(vpnRoleOption); + parser.addOption(proxyRoleOption); + parser.addOption(userinfoRoleOption); + parser.addOption(datetimeRoleOption); + parser.addOption(updateRoleOption); + parser.addOption(upgradeRoleOption); + parser.addOption(backupRoleOption); + } + +#else + parser.addOption(powerRoleOption); + parser.addOption(netconnectRoleOption); + parser.addOption(vpnRoleOption); + parser.addOption(proxyRoleOption); + parser.addOption(userinfoRoleOption); + parser.addOption(datetimeRoleOption); + parser.addOption(updateRoleOption); + parser.addOption(upgradeRoleOption); + +#endif + + parser.addOption(monitorRoleOption); + parser.addOption(defaultRoleOption); + parser.addOption(autobootRoleOption); + + parser.addOption(printerRoleOption); + parser.addOption(mouseRoleOption); + parser.addOption(touchpadRoleOption); + parser.addOption(keyboardRoleOption); + parser.addOption(shortcutRoleOption); + parser.addOption(audioRoleOption); + parser.addOption(blutetoothRoleOption); + + parser.addOption(backgroundRoleOption); + parser.addOption(themeRoleOption); + parser.addOption(screenlockRoleOption); + parser.addOption(screensaverRoleOption); + parser.addOption(fontsRoleOption); + parser.addOption(desktopRoleOption); + + parser.addOption(cloudaccountRoleOption); + + parser.addOption(areaRoleOption); + + parser.addOption(noticeRoleOption); + parser.addOption(aboutRoleOption); + parser.addOption(searchRoleOption); +} + +QVariantMap Utils::getModuleHideStatus() { + QDBusInterface m_interface( "org.ukui.ukcc.session", + "/", + "org.ukui.ukcc.session.interface", + QDBusConnection::sessionBus()); + + QDBusReply obj_reply = m_interface.call("getModuleHideStatus"); + if (!obj_reply.isValid()) { + qDebug()<<"execute dbus method getModuleHideStatus failed"; + } + return obj_reply.value(); +} + +QString Utils::getCpuInfo() { + QDBusInterface youkerInterface("com.kylin.assistant.systemdaemon", + "/com/kylin/assistant/systemdaemon", + "com.kylin.assistant.systemdaemon", + QDBusConnection::systemBus()); + if (!youkerInterface.isValid()) { + qCritical() << "Create youker Interface Failed When Get Computer info: " << QDBusConnection::systemBus().lastError(); + return QString(); + } + + QDBusReply> cpuinfo; + QString cpuType; + cpuinfo = youkerInterface.call("get_cpu_info"); + if (!cpuinfo.isValid()) { + qDebug() << "cpuinfo is invalid" << endl; + } else { + QMap res = cpuinfo.value(); + cpuType = res["CpuVersion"].toString(); + } + return cpuType; +} + +bool Utils::isExistEffect() { + QString filename = QDir::homePath() + "/.config/ukui-kwinrc"; + QSettings kwinSettings(filename, QSettings::IniFormat); + + QStringList keys = kwinSettings.childGroups(); + + kwinSettings.beginGroup("Plugins"); + bool kwin = kwinSettings.value("blurEnabled", kwin).toBool(); + + if (!kwinSettings.childKeys().contains("blurEnabled")) { + kwin = true; + } + kwinSettings.endGroup(); + + QFileInfo dir(filename); + if (!dir.isFile()) { + return true; + } + + if (keys.contains("Compositing")) { + kwinSettings.beginGroup("Compositing"); + QString xder; + bool kwinOG = false; + bool kwinEN = true; + xder = kwinSettings.value("Backend", xder).toString(); + kwinOG = kwinSettings.value("OpenGLIsUnsafe", kwinOG).toBool(); + kwinEN = kwinSettings.value("Enabled", kwinEN).toBool(); + if ("XRender" == xder || kwinOG || !kwinEN) { + return false; + } else { + return true; + } + kwinSettings.endGroup(); + } + return true; +} + +void Utils::setKwinMouseSize(int size) { + + QString filename = QDir::homePath() + "/.config/kcminputrc"; + QSettings *mouseSettings = new QSettings(filename, QSettings::IniFormat); + + mouseSettings->beginGroup("Mouse"); + mouseSettings->setValue("cursorSize", size); + mouseSettings->endGroup(); + + delete mouseSettings; + mouseSettings = nullptr; + + QDBusMessage message = QDBusMessage::createSignal("/KGlobalSettings", "org.kde.KGlobalSettings", "notifyChange"); + QList args; + args.append(5); + args.append(0); + message.setArguments(args); + QDBusConnection::sessionBus().send(message); +} + +bool Utils::isWayland() { + QString sessionType = getenv("XDG_SESSION_TYPE"); + + if (!sessionType.compare("wayland", Qt::CaseSensitive)) { + return true; + } else { + return false; + } +} + +bool Utils::isCommunity() +{ + QString filename = "/etc/os-release"; + QSettings osSettings(filename, QSettings::IniFormat); + + QString versionID = osSettings.value("VERSION_ID").toString(); + + if (versionID.compare("20.04", Qt::CaseSensitive)) { + return false; + } + return true; +} diff -Nru ukui-control-center-2.0.3/shell/utils/utils.h ukui-control-center-3.0.3/shell/utils/utils.h --- ukui-control-center-2.0.3/shell/utils/utils.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/utils/utils.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,48 @@ +/* -*- 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 UTILS_H +#define UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Utils +{ + void centerToScreen(QWidget *widget); + void setCLIName(QCommandLineParser &parser); + QVariantMap getModuleHideStatus(); + QString getCpuInfo(); + bool isExistEffect(); + void setKwinMouseSize(int size); + bool isWayland(); + bool isCommunity(); +} +#endif // UTILS_H diff -Nru ukui-control-center-2.0.3/shell/utils/xatom-helper.cpp ukui-control-center-3.0.3/shell/utils/xatom-helper.cpp --- ukui-control-center-2.0.3/shell/utils/xatom-helper.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/utils/xatom-helper.cpp 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,215 @@ +/* + * KWin Style UKUI + * + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authors: Yue Lan + * + */ + +#include "xatom-helper.h" + +#include + +#include + +#include +#include +#include + +static XAtomHelper *global_instance = nullptr; + +XAtomHelper *XAtomHelper::getInstance() +{ + if (!global_instance) + global_instance = new XAtomHelper; + return global_instance; +} + +bool XAtomHelper::isFrameLessWindow(int winId) +{ + auto hints = getInstance()->getWindowMotifHint(winId); + if (hints.flags == MWM_HINTS_DECORATIONS && hints.functions == 1) { + return true; + } + return false; +} + +bool XAtomHelper::isWindowDecorateBorderOnly(int winId) +{ + return isWindowMotifHintDecorateBorderOnly(getInstance()->getWindowMotifHint(winId)); +} + +bool XAtomHelper::isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint) +{ + bool isDeco = false; + if (hint.flags & MWM_HINTS_DECORATIONS && hint.flags != MWM_HINTS_DECORATIONS) { + if (hint.decorations == MWM_DECOR_BORDER) + isDeco = true; + } + return isDeco; +} + +bool XAtomHelper::isUKUICsdSupported() +{ + // fixme: + return false; +} + +bool XAtomHelper::isUKUIDecorationWindow(int winId) +{ + if (m_ukuiDecorationAtion == None) + return false; + + Atom type; + int format; + ulong nitems; + ulong bytes_after; + uchar *data; + + bool isUKUIDecoration = false; + + XGetWindowProperty(QX11Info::display(), winId, m_ukuiDecorationAtion, + 0, LONG_MAX, false, + m_ukuiDecorationAtion, &type, + &format, &nitems, + &bytes_after, &data); + + if (type == m_ukuiDecorationAtion) { + if (nitems == 1) { + isUKUIDecoration = data[0]; + } + } + + return isUKUIDecoration; +} + +UnityCorners XAtomHelper::getWindowBorderRadius(int winId) +{ + UnityCorners corners; + + Atom type; + int format; + ulong nitems; + ulong bytes_after; + uchar *data; + + if (m_unityBorderRadiusAtom != None) { + XGetWindowProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, + 0, LONG_MAX, false, + XA_CARDINAL, &type, + &format, &nitems, + &bytes_after, &data); + + if (type == XA_CARDINAL) { + if (nitems == 4) { + corners.topLeft = static_cast(data[0]); + corners.topRight = static_cast(data[1*sizeof (ulong)]); + corners.bottomLeft = static_cast(data[2*sizeof (ulong)]); + corners.bottomRight = static_cast(data[3*sizeof (ulong)]); + } + XFree(data); + } + } + + return corners; +} + +void XAtomHelper::setWindowBorderRadius(int winId, const UnityCorners &data) +{ + if (m_unityBorderRadiusAtom == None) + return; + + ulong corners[4] = {data.topLeft, data.topRight, data.bottomLeft, data.bottomRight}; + + XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL, + 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof (corners)/sizeof (corners[0])); +} + +void XAtomHelper::setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight) +{ + if (m_unityBorderRadiusAtom == None) + return; + + ulong corners[4] = {(ulong)topLeft, (ulong)topRight, (ulong)bottomLeft, (ulong)bottomRight}; + + XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL, + 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof (corners)/sizeof (corners[0])); +} + +void XAtomHelper::setUKUIDecoraiontHint(int winId, bool set) +{ + if (m_ukuiDecorationAtion == None) + return; + + XChangeProperty(QX11Info::display(), winId, m_ukuiDecorationAtion, m_ukuiDecorationAtion, 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &set, 1); +} + +void XAtomHelper::setWindowMotifHint(int winId, const MotifWmHints &hints) +{ + if (m_unityBorderRadiusAtom == None) + return; + + XChangeProperty(QX11Info::display(), winId, m_motifWMHintsAtom, m_motifWMHintsAtom, + 32, XCB_PROP_MODE_REPLACE, (const unsigned char *)&hints, sizeof (MotifWmHints)/ sizeof (ulong)); +} + +MotifWmHints XAtomHelper::getWindowMotifHint(int winId) +{ + MotifWmHints hints; + + if (m_unityBorderRadiusAtom == None) + return hints; + + uchar *data; + Atom type; + int format; + ulong nitems; + ulong bytes_after; + + XGetWindowProperty(QX11Info::display(), winId, m_motifWMHintsAtom, + 0, sizeof (MotifWmHints)/sizeof (long), false, AnyPropertyType, &type, + &format, &nitems, &bytes_after, &data); + + if (type == None) { + return hints; + } else { + hints = *(MotifWmHints *)data; + XFree(data); + } + return hints; +} + +XAtomHelper::XAtomHelper(QObject *parent) : QObject(parent) +{ + if (!QX11Info::isPlatformX11()) + return; + + m_motifWMHintsAtom = XInternAtom(QX11Info::display(), "_MOTIF_WM_HINTS", true); + m_unityBorderRadiusAtom = XInternAtom(QX11Info::display(), "_UNITY_GTK_BORDER_RADIUS", false); + m_ukuiDecorationAtion = XInternAtom(QX11Info::display(), "_KWIN_UKUI_DECORAION", false); +} + +Atom XAtomHelper::registerUKUICsdNetWmSupportAtom() +{ + // fixme: + return None; +} + +void XAtomHelper::unregisterUKUICsdNetWmSupportAtom() +{ + // fixme: +} diff -Nru ukui-control-center-2.0.3/shell/utils/xatom-helper.h ukui-control-center-3.0.3/shell/utils/xatom-helper.h --- ukui-control-center-2.0.3/shell/utils/xatom-helper.h 1970-01-01 00:00:00.000000000 +0000 +++ ukui-control-center-3.0.3/shell/utils/xatom-helper.h 2021-04-14 01:27:20.000000000 +0000 @@ -0,0 +1,108 @@ +/* + * KWin Style UKUI + * + * Copyright (C) 2020, KylinSoft Co., Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authors: Yue Lan + * + */ + +#ifndef XATOMHELPER_H +#define XATOMHELPER_H + +#include + +struct UnityCorners { + ulong topLeft = 0; + ulong topRight = 0; + ulong bottomLeft = 0; + ulong bottomRight = 0; +}; + +typedef struct { + ulong flags = 0; + ulong functions = 0; + ulong decorations = 0; + long input_mode = 0; + ulong status = 0; +} MotifWmHints, MwmHints; + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL + +#define MWM_TEAROFF_WINDOW (1L<<0) + +namespace UKUI { +class Decoration; +} + +class XAtomHelper : public QObject +{ + friend class UKUI::Decoration; + Q_OBJECT +public: + static XAtomHelper *getInstance(); + + static bool isFrameLessWindow(int winId); + + bool isWindowDecorateBorderOnly(int winId); + bool isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint); + bool isUKUICsdSupported(); + bool isUKUIDecorationWindow(int winId); + + UnityCorners getWindowBorderRadius(int winId); + void setWindowBorderRadius(int winId, const UnityCorners &data); + void setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight); + void setUKUIDecoraiontHint(int winId, bool set = true); + + void setWindowMotifHint(int winId, const MotifWmHints &hints); + MotifWmHints getWindowMotifHint(int winId); + +private: + explicit XAtomHelper(QObject *parent = nullptr); + + ulong registerUKUICsdNetWmSupportAtom(); + void unregisterUKUICsdNetWmSupportAtom(); + + ulong m_motifWMHintsAtom = 0L; + ulong m_unityBorderRadiusAtom = 0L; + ulong m_ukuiDecorationAtion = 0L; +}; + +#endif // XATOMHELPER_H diff -Nru ukui-control-center-2.0.3/translate_generation.sh ukui-control-center-3.0.3/translate_generation.sh --- ukui-control-center-2.0.3/translate_generation.sh 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/translate_generation.sh 2021-04-14 01:27:20.000000000 +0000 @@ -7,7 +7,7 @@ for ts in "${ts_list[@]}" do printf "\nprocess ${ts}\n" - if [ "$version" == "fedora" ];then + if [ "$version" == "fedora" ] || [ "$version" == "opensuse-leap" ] || [ "$version" == "opensuse-tumbleweed" ];then lrelease-qt5 "${ts}" else lrelease "${ts}" diff -Nru ukui-control-center-2.0.3/ukui-control-center.pro ukui-control-center-3.0.3/ukui-control-center.pro --- ukui-control-center-2.0.3/ukui-control-center.pro 2020-07-15 08:33:28.000000000 +0000 +++ ukui-control-center-3.0.3/ukui-control-center.pro 2021-04-14 01:27:20.000000000 +0000 @@ -3,16 +3,21 @@ CONFIG += ordered SUBDIRS = \ + checkUserPwd \ + checkUserPwdWithPAM \ registeredQDbus \ plugins\ + registeredSession \ shell \ + group-manager-server \ # tastenbrett \ TRANSLATIONS += \ shell/res/i18n/zh_CN.ts \ shell/res/i18n/tr.ts \ - shell/res/i18n/bo.ts + shell/res/i18n/bo.ts \ + shell/res/i18n/en_US.ts \ # Automating generation .qm files from .ts files @@ -27,4 +32,14 @@ qm_files.path = $${PREFIX}/share/ukui-control-center/shell/res/i18n/ qm_files.files = shell/res/i18n/*.qm -INSTALLS += qm_files +search_file.path = $${PREFIX}/share/ukui-control-center/shell/res/ +search_file.files = shell/res/search.xml + +INSTALLS += qm_files \ + search_file + +HEADERS += \ + shell/utils/xatom-helper.h + +SOURCES += \ + shell/utils/xatom-helper.cpp